Gerd Möllmann writes: > Eli Zaretskii writes: > >>> From: Gerd Möllmann >>> Cc: Emacs Devel >>> Date: Wed, 23 Oct 2024 06:40:11 +0200 >>> >>> Gerd Möllmann writes: >>> >>> > Feng Shu writes: >>> > >>> >> Gerd Möllmann writes: >>> >> >>> >>> Feng Shu writes: >>> >>> >>> >>>> border do not work well when current buffer is CJK, maybe because CJK >>> >>>> Char width is not 1 >>> >>> >>> >>> Could you please send me a bit of CJK text so that I have something I >>> >>> can test this with? >>> > >>> > Thanks! >>> >>> Hm, okay, but not sure how to fix that. >>> >>> The problem comes indeed from the root frame displaying characters that >>> are more then 1 column wide, say N. When we output such a character to >>> the terminal, the cursor moves by N columns. Emacs represents that in >>> the glyph matrix by producing N glyphs for the character, all bu tthe >>> first have a padding flag set. So we have >>> >>> ... (C, 0) (C, 1) ... >>> >>> in the glpyh matrix, where C is the character, and the number is the >>> padding flag. >>> >>> Now assume, for example, that the child frame is posititoned so that its >>> left border where we want to display a '|' is in the column for the (C, >>> 1). >>> >>> That can't work, because writing C to the terminal moves 2 columns and >>> will skip over the column where we want the '|' to appear. >> >> I think the solution should be the same as what we do when a line >> needs to wrap (i.e. be continued) and we don't have enough columns to >> put all the N glyphs before the continuation glyph: we don't show the >> entire N-glyph group. IOW, the border glyph should be shown instead >> of multi-column character, padded with enough spaces before it to make >> up for the M < N glyphs of C that could be shown before the border. >> In your example above, C will not be shown, and instead we will show >> one space glyph followed by the '|' glyph. > > Yes, I came up with this (WIP): > > /* If the glyph in ROW at position X is part of a wide character, change > every glyph belonging to the wide character to a space glyph. */ > > static void > neutralize_wide_char (struct frame *root, struct glyph_row *row, int x) > { > eassert (x >= 0 && x < root->desired_matrix->matrix_w); > 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); > } > } > > I have some problems reproducing the whole thing on my system with the > CJK file Feng Shu gave me. Hm. The below adjust will show more issue:-) 1. Reduce terminal's width 2. let a long line auto wrap to many lines.