Hi Behdad,

> Hi David,
> I'm not sure if I understand what these lsb/rsb stuff is.  Is there
> anything here that cairo/pango should be doing that it's not already?

I'll try to summarize the issue as succintly as I can. Basically, rsb/lsb_delta
correspond to the displacement of the right/left edges of a glyph due to
auto-hinting, and they can be used to adjust inter-character spacing.

- the rsb (right side bearing) is the distance between the right-most edge
  of a glyph and its advance.

- the lsb (left side bearing) is the distance between the left-most edge
  of a glyph and its origin.

- the space between the right-most and left-most edges of two consecutive
  glyphs, respectively, is always computed as rsb(glyph1) + lsb(glyph2)

- Imagine that you have a pair of glyphs to display, like "po"

  Consider unhinted rendering, and let's assume that the scaled rsb of "p" is
  0.3 pixels, and the scaled lsb of "o" is 0.45 pixels. This means that the
  right edge of the "p" and the left edge of the "o" should be spaced by
  0.75 pixels, which is pretty close to 1

  Consider auto-hinting, which tends to round these distances. Now, the rsb
  of "p" is 0, and the lsb of "o" is also 0. Both auto-hinted glyphs will
  appear "stuck" to each other

the values of rsb_delta and lsb_delta simply tell us how the rsb/lsb changed
due to the auto-hinting; we can compute the old inter-character space as:

    old_space = (rsb-rsb_delta) + (lsb-lsb_delta) 
              = (rsb+lsb) - (rsb_delta+lsb_delta)
              = new_space - (rsb_delta+lsb_delta)

so the sum of rsb_delta and lsb_delta corresponds to the inter-character space
distortion that is due to the hinting.

    (rsb_delta+lsb_delta) = new_space - old_space

If we find that it is bigger than a half pixel, we simply substract 1 to the
new space in order to reduce the spacing error while preserving the
grid-aligned rendering
Similarly, if the "error" is smaller than -1/2 pixel, we increase the new space
by 1.

    error = (rsb_delta(glyph1) + lsb_delta(glyph2))
    if (error >= 32)
      origin -= 64;
    else if (error <= -32)
      origin += 64;    

the result is text that looks much better, as demonstrated by the ftdiff
program. Note that you can mix this with scaled but unrounded kerning for
maximal effect.

The issue is that the lsb/rsb_delta values depend on the hinting mode, and
current character size and need to be cached in order to get good
performance (you can hardly recompute them quickly on each pair)

So it means changing the caching scheme of any text layout library that wants
to use it. Either store the values with the glyph images themselves, or in
another table.

Owen Taylor wrote a paper on this subject, with nice graphics explaining the
issues. I can't find it anymore. I'm putting him in CC: in case he has it

Hope this helps,

- David

> cheers
> behdad
> > An alternative would be to hack FT_Get_Kerning to return "adjusted" values, 
> > but
> > this would require implementing a rather complicated caching scheme within 
> > the
> > engine if we don't want performance to suck horribly. Moreover, this is 
> > likely
> > to break some libraries...
> > 
> > - David
> -- 
> behdad
> http://behdad.org/
> "Those who would give up Essential Liberty to purchase a little
>  Temporary Safety, deserve neither Liberty nor Safety."
>         -- Benjamin Franklin, 1759

Freetype-devel mailing list

Reply via email to