-
Notifications
You must be signed in to change notification settings - Fork 137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Chinese characters are chopped #227
Comments
I think you need to convert the whole string to a width, not just the glyphs, especially in Unicode which can have reverse text, subscripts etc. https://developer.apple.com/documentation/foundation/nsstring/1524729-boundingrectwithsize |
I think it's not the string width but glyph postions in line are wrong. You just point out a right direction of this issue, because the CoreText calculate each character's position not just using the char width multiply the index of it in a line. |
The patch above sort of works, but there are some additional tasks that are required involving the cursor rendering - otherwise what the cursor renders when it is blinking and the text in the terminals are out of sync. And we have an additional problem with Emoji Emoji Problem If I have this text on the first column:
With Emacs, the contents of the buffer are:
For vi, instead, I get this:
The way this happens is that vi prints the emoji first at columb, then manually sets the cursor location to column 3, and prints "hello". This is why we have a 0 in the buffer at position [1]. With Chinese characters, we have a different situation, both vi and emacs output the character directly, without doing the cursor positioning trick, so this does not pose a problem. The challenge seems to be that we might need to detect an Emoji, and in that case, if the next column contains a zero, not insert a space The problem with the vi case is that when the offsets are computed, the emoji is at position 0, then the space corresponding to the 0 value is given the slot in column 3, rather than column 1. So we produce this: Instead of: Cursor Rendering
There are a few scenarios to handle. Bad news for vi When we query the runs, we get two runs
106 glyphs for So the “3” is a space, the good news is that it does not render anything, but we start rendering it at the wrong position, because we have a nil there. This new patch handles the vi special scenario, and would need to also be replicated for cursors: https://gist.github.com/migueldeicaza/b3451fb7880def299112e5e362c94323 |
Perhaps an alternative is to allocate cells when the characters are generated. So when double-width characters like Chinese characters or emoji are produced, I record both the character and an empty slot after, and use this information while rendering, so I can normalize all output into a grid. And perhaps rather than trying to create a single attributed string for the whole line, I need to break up the attributed string at these width-changing boundaries |
Some of the suggestion above already existed in the codebase, and I should addressed a few scenarios for characters that did not have the right metrics. There might be more places where I need to add this information. |
Yes, when the terminal builds attributed string for rendering, it appends a whitespace char after some special chars( double width chars Chinese char or Emoji, or something else). But when drawing the attributed string, the whitespace char is also drawn, it must be handled specially. |
If we use an empty slot, we must handle it when drawing the attributed string CTFontDrawGlyphs(runFont, runGlyphs, &positions, positions.count, context) Or we can use zero width space character (https://en.wikipedia.org/wiki/Zero-width_space) as an empty slot. But the selection still has some problem |
Taken from: migueldeicaza#227
Given a chinese character that uses more than one cell, and another one, we get two CTRuns, one for the Chinese character, and one that contains both a space and the second character. The space when we render seems to be overwriting the second half of the Chinese character:
The patch below extracts the position of the rune relative to the line, and helps a bit, but now the last character of the line is chopped, so there is some clipping somewhere I need to find, this is what it looks like now:
The text was updated successfully, but these errors were encountered: