From 33993326d595d2dea046e3d5d8e3f54f8db38e63 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gerd=20M=C3=B6llmann?= Date: Wed, 23 Oct 2024 09:55:26 +0200 Subject: [PATCH] Deal with wide characters * src/dispnew.c (make_glyph_space): New function. (neutralize_wide_char): New function. (produce_box_sides, copy_child_glyphs): Call neutralize_wide_char. (cherry picked from commit d1fd1d8fba8a6cfe774f6982bb6ad6c874d0c960) --- src/dispnew.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/src/dispnew.c b/src/dispnew.c index 8aa8e0fb5f5..1235ab431c0 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -3510,6 +3510,45 @@ prepare_desired_root_row (struct frame *root, int y) return root_row; } +/* Change GLYPH to be a space glyph. */ + +static void +make_glyph_space (struct glyph *glyph) +{ + glyph->u.ch = ' '; + glyph->pixel_width = 1; + glyph->padding_p = 0; +} + +/* On root frame ROOT, if the glyph in ROW at position X is part of a + sequence of glyphs for a wide character, change every glyph belonging + to the sequence to a space. If X is outside of ROOT, do nothing. */ + +static void +neutralize_wide_char (struct frame *root, struct glyph_row *row, int x) +{ + if (x < 0 || x >= root->desired_matrix->matrix_w) + return; + + struct glyph *glyph = row->glyphs[0] + x; + if (glyph->type == CHAR_GLYPH && CHARACTER_WIDTH (glyph->u.ch) > 1) + { + struct glyph *row_start = row->glyphs[0]; + struct glyph *row_limit = row_start + row->used[0]; + + /* Glyph is somewhere in a sequence of glyphs for a wide + character, find the start. */ + while (glyph > row_start && glyph->padding_p) + --glyph; + + /* Make everything in the sequence a space glyph. */ + eassert (!glyph->padding_p); + make_glyph_space (glyph); + for (++glyph; glyph < row_limit && glyph->padding_p; ++glyph) + make_glyph_space (glyph); + } +} + /* Produce glyphs for box character BOX in ROW. X is the position in ROW where to start producing glyphs. N is the number of glyphs to produce. CHILD is the frame to use for the face of the glyphs. */ @@ -3579,9 +3618,16 @@ produce_box_sides (enum box left, enum box right, struct glyph_row *root_row, in int w, struct frame *root, struct frame *child) { if (x > 0) - produce_box_glyphs (left, root_row, x - 1, 1, child); + { + neutralize_wide_char (root, root_row, x - 1); + produce_box_glyphs (left, root_row, x - 1, 1, child); + } + if (x + w < root->desired_matrix->matrix_w) - produce_box_glyphs (right, root_row, x + w, 1, child); + { + neutralize_wide_char (root, root_row, x + w); + produce_box_glyphs (right, root_row, x + w, 1, child); + } } static void @@ -3645,6 +3691,14 @@ copy_child_glyphs (struct frame *root, struct frame *child) { struct glyph_row *root_row = prepare_desired_root_row (root, y); + /* Deal with wide characters unless already done as part of + drawing a box around the child frame. */ + if (FRAME_UNDECORATED (child)) + { + neutralize_wide_char (root, root_row, r.x - 1); + neutralize_wide_char (root, root_row, r.x + r.w); + } + /* Copy what's visible from the child's current row. */ struct glyph_row *child_row = MATRIX_ROW (child->current_matrix, child_y); memcpy (root_row->glyphs[0] + r.x, child_row->glyphs[0] + child_x, -- 2.39.5