Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upSelection or insertion point renders incorrectly when inside ligature #11302
Comments
|
Can I give it a try? |
|
How do I create a
The selection seems to be rendered correctly, but it is treated as a single character. |
|
ping @mbrubeck |
|
Yes, using the example code, "ffi" (three characters) should be rendered as a ligature automatically as long as the font supports it. If the default font doesn't, you can try setting font-family to one that does. |
|
@shinglyu add to my dashboard |
|
@mbrubeck Thanks! I was able to see the ligature using I used keyboard, and I tried to use mouse to select the middle This is different from what you described. Did I stumble upon another bug? (p.s. I also tried Firefox, it can let me select the |
|
That screencast shows the bug that I was trying to describe. Servo always paints the entire ligature as selected, even if internally only part of it is selected. (You can type another letter like "x" and only the "real" selection will be replaced.) |
|
Thanks! typing the "x" reveals the secret! |
|
@shinglyu Still holding up okay on this issue? |
|
@KiChjang ya, still working on it, just has a vacation and a workweek coming, so probably not much progress until next week. |
|
@mbrubeck I went through the code and got some rough idea on how to implement this. But I'm a little confused about how to use the various |
Here's a quick overview of the different types:
In the end we have a GlyphStore, which contains an sequence of GlyphEntries and a sequence of DetailedGlyphs.
Yes, the Fixing this bug will require re-adding those flags, and making sure save_glyph_results passes correct values for them. Then |
|
Thanks! That's super helpful! |
|
@mbrubeck : Should I follow the old convention and use a negative flag? Although I don't quite understand what "missing chars can be memset with zeros in one fell swoop" means. |
|
I almost finished porting the Gecko algorithm to Servo. But there are a few blockers I need to fix before it works:
|
|
@mbrubeck : I'm a little bit confused about how ligature continuations are processed. The second |
|
When the string "ffi" is shaped as a ligature, there is only one glyph. The first |
|
@mbrubeck Do you think we should use a negative or positive flag? I don't quite understand the reason for a negative flag in Gecko. And does it imply that we only need to explictly set the "Not ligature start" case if we use a positive flag? |
|
I'm removing the assigned and less easy tags because it seems like this was abandoned, and it also turned out to be more complicated than anticipated. |
|
Sorry I was distracted by other tasks. I had a partial implementation here, which is able to select part of the ligature, but the rendering is not 100% correct. ANyone interested can pick it up. |

If Servo renders this textbox with a font that has an
ffiligature (which includes the default fonts on most systems), and you use the arrow and/or shift keys to position the insertion point or selection boundary within the "ffi" string, then Servo draws the selection or insertion point at the wrong location (after the ligature instead of inside it):We could fix this by re-running text shaping when a selection boundary is moved into a ligature, splitting the text run at the selection boundary so the characters on opposite sides no longer form ligatures. But this would require reconstructing flows (which is expensive), and it would make glyphs change as the cursor moves around (which is ugly).
A better solution is to compute where inside the ligature to draw the selection or caret. Gecko does this just by dividing the total width of the ligature evenly over each grapheme clusters it contains. This will require extra flags in the glyph store to record which glyph entries are ligature starts and cluster starts. Then advance_for_byte_range will need to use this information to adjust the result if the range includes partial ligatures. For comparison, Gecko’s code for this is mostly in GetAdvanceWidth and ComputeLigatureData.