[HarfBuzz] Kerning at the end of a line vs. line breaks

Lóránt Pintér lorant.pinter at prezi.com
Wed Oct 17 20:22:51 PDT 2012


Hi, 

I'm having some difficulty with breaking lines with kerning on. Let me explain.

My current implementation of breaking lines simply shapes the whole paragraph with HarfBuzz, then finds line-break opportunities, and then jams as many segments into a line as possible.

shapes = hb_shape(text)
foreach segment in find_line_breaks(shapes)
    if line.width + segment.x_advance > text.width
        start_a_new_line()
    line.add(segment)

But I see a problem with glyphs kerned with spaces at the end of a line (sorry if I'm stating the obvious here, or if I'm completely mistaking something).

Consider the following:

Input text is "MM 1T MM 2T"
Width of each glyph, including space is 1000 units
Kerning between "T" and "space" is -50 units
Text width is 4990 units

If I layout the text without kerning, the lines will look like this:

"MM " -- width: 2000 (+1000 for the space)
"1T " -- width: 2000 (+1000 for the space)
"MM " -- width: 2000 (+1000 for the space)
"2T"  -- width: 2000

However, if I enable kerning, because of the kerning at the end of the first line between "T" and "space", it would look like this (with my naive algorithm at least):

"MM 1T " -- width 4950 (+1000 for the space)
"MM "    -- width 2000 (+1000 for the space)
"2T"     -- width 2000

Now this is surely not good, having two pieces of identical text laid out in different ways. So my idea is that before deciding if a piece of text fits, I should get it shaped without kerning at the end as well.

shapes = hb_shape(text)
foreach segment in find_line_breaks(shapes)
    if line.width + segment.x_advance > text.width
        start_a_new_line()
    else
segment_without-kerning = hb_shape_without_kerning_at_the_end(segment)
        if line.width + segment_without_kerning.x_advance > text.width
            start_a_new_line()
    line.add(segment)



This could work, but I would basically have to shape the whole text twice. That doesn't sound right. Or does it?

Another issue is, say, there is a context-sensitive substitution that applies only if there is a space before "1". When I shape the whole text, the lookup will trigger for the "1" in "1T", because it has a space before. But when I re-shape only "1T" at the end of the line, the lookup won't be applied.

I feel like I'm on the wrong track here. Am I missing something obvious?

-- 
Thanks,
Lorant

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/harfbuzz/attachments/20121018/a85b4631/attachment.html>


More information about the HarfBuzz mailing list