[PATCH v3] Fixes CJK wide character display
Kristian Høgsberg
hoegsberg at gmail.com
Tue Aug 13 17:30:53 PDT 2013
On Thu, Aug 01, 2013 at 01:49:03PM +0800, Peng Wu wrote:
> By jumping two columns when wide character prints,
> and draw wide cursor under wide character.
Hi Peng,
I do want this feature in weston-terminal, but there's still a few
issues to address - see below.
> ---
> clients/Makefile.am | 2 +-
> clients/terminal.c | 26 ++++++++++++++++++++++++--
> 2 files changed, 25 insertions(+), 3 deletions(-)
>
> diff --git a/clients/Makefile.am b/clients/Makefile.am
> index 09963cc..e7c0ece 100644
> --- a/clients/Makefile.am
> +++ b/clients/Makefile.am
> @@ -113,7 +113,7 @@ weston_screenshooter_SOURCES = \
> weston_screenshooter_LDADD = libtoytoolkit.la
>
> weston_terminal_SOURCES = terminal.c
> -weston_terminal_LDADD = libtoytoolkit.la -lutil
> +weston_terminal_LDADD = libtoytoolkit.la -lutil $(PANGO_LIBS)
Again, I don't want to link to pango or glib... remember, the only
reason for weston-terminal to exist is that it doesn't have any
dependencies except cairo and the wayland libraries.
> weston_image_SOURCES = image.c
> weston_image_LDADD = libtoytoolkit.la
> diff --git a/clients/terminal.c b/clients/terminal.c
> index 0d4f726..dc56745 100644
> --- a/clients/terminal.c
> +++ b/clients/terminal.c
> @@ -33,6 +33,10 @@
> #include <ctype.h>
> #include <cairo.h>
> #include <sys/epoll.h>
> +#include <glib.h>
> +#define __USE_XOPEN
> +#include <wchar.h>
> +#include <locale.h>
>
> #include <wayland-client.h>
>
> @@ -93,6 +97,11 @@ union utf8_char {
> uint32_t ch;
> };
>
> +static bool is_wide(union utf8_char utf8){
> + gunichar unichar = g_utf8_get_char((const char*) utf8.byte);
> + return wcwidth(unichar) > 1;
> +}
... but I just committed a patch to make the utf-8 state machine
assemble the unicode value from the utf-8, so you can now use
get_unicode() instead of g_utf8_get_char().
Please follow the coding conventions and leave 'static int' on it's
own line and put the opening '{' of the function on it's own line.
> enum utf8_state {
> utf8state_start,
> utf8state_accept,
> @@ -942,6 +951,7 @@ redraw_handler(struct widget *widget, void *data)
> struct glyph_run run;
> cairo_font_extents_t extents;
> double average_width;
> + double unichar_width;
>
> surface = window_get_surface(terminal->window);
> widget_get_allocation(terminal->widget, &allocation);
> @@ -967,6 +977,7 @@ redraw_handler(struct widget *widget, void *data)
> allocation.y + top_margin);
> /* paint the background */
> for (row = 0; row < terminal->height; row++) {
> + p_row = terminal_get_row(terminal, row);
> for (col = 0; col < terminal->width; col++) {
> /* get the attributes for this character cell */
> terminal_decode_attr(terminal, row, col, &attr);
> @@ -974,12 +985,17 @@ redraw_handler(struct widget *widget, void *data)
> if (attr.attr.bg == terminal->color_scheme->border)
> continue;
>
> + if(is_wide(p_row[col]))
> + unichar_width = 2 * average_width;
> + else
> + unichar_width = average_width;
> +
> terminal_set_color(terminal, cr, attr.attr.bg);
> cairo_move_to(cr, col * average_width,
> row * extents.height);
> - cairo_rel_line_to(cr, average_width, 0);
> + cairo_rel_line_to(cr, unichar_width, 0);
> cairo_rel_line_to(cr, 0, extents.height);
> - cairo_rel_line_to(cr, -average_width, 0);
> + cairo_rel_line_to(cr, -unichar_width, 0);
> cairo_close_path(cr);
> cairo_fill(cr);
> }
> @@ -1871,6 +1887,10 @@ handle_char(struct terminal *terminal, union utf8_char utf8)
> row[terminal->column] = utf8;
> attr_row[terminal->column++] = terminal->curr_attr;
>
> + /* cursor jump for wide character. */
> + if (is_wide(utf8))
> + row[terminal->column++].ch = 0;
Inserting this 0 here confuses the selection logic which thinks 0
means "end of line". I think we can use an invalid utf-8 character
instead to indicate that this cell is a wide-char filler. We then
also need to handle that in terminal_send_selection(), where we must
ignore those filler cells when writing the selection to the fd.
> if (utf8.ch != terminal->last_char.ch)
> terminal->last_char = utf8;
> }
> @@ -2711,6 +2731,8 @@ int main(int argc, char *argv[])
> struct terminal *terminal;
> int config_fd;
>
> + setlocale(LC_ALL, "");
What is this for?
Otherwise the patch looks good.
Kristian
> option_shell = getenv("SHELL");
> if (!option_shell)
> option_shell = "/bin/bash";
> --
> 1.8.3.1
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list