[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [ft-devel] autohinting and spacing

From: Graham Asher
Subject: RE: [ft-devel] autohinting and spacing
Date: Tue, 21 Aug 2007 10:33:16 +0100


I have finally got back to this issue and think I understand it a little
better. The trouble is that, for the moment I have to live with the fact
that (in the system I am working on) glyph advances and other metrics are
integral pixels; glyphs are cached, and I don't want to add new fields to my
cached glyphs storing the two delta values you have described.

My current solution, arrived at after much experimentation, is not to round
the positions of the two phantom points used to calculate the advance; this
sets lsb_delta and rsb_delta to zero and effectively applies the correction

Thus lines 206-7 of afloader.c change from

          loader->pp1.x = FT_PIX_ROUND( pp1x_uh );
          loader->pp2.x = FT_PIX_ROUND( pp2x_uh );


          loader->pp1.x = pp1x_uh;
          loader->pp2.x = pp2x_uh;

The disadvantage is that - because the left side bearing is no longer
grid-fitted - horizontal stems are no longer grid-fitted either. However,
the overall effect is much better.

Best regards,


-----Original Message-----
From: David Turner [mailto:address@hidden 
Sent: 08 August 2007 16:07
To: Graham Asher; address@hidden
Subject: Re: [ft-devel] autohinting and spacing

Hello Graham,

this is normal, the auto-hinter basically rounds the advance widths, and
alters the left/right bearing of a typical glyphs. this explains the spacing
you're seeing now.

fortunately, the auto-hinter also returns information about the bearing
it makes, and it is possible to compensate this distortion by using the
"lsb_delta" and
"rsb_delta" fields of a FT_GlyphSlot.

the algorithm to implement this is rather simple and is described in the
for FT_GlyphSlotRec, here it is:

  /*    Here a small pseudo code fragment which shows how to use
  /*    `lsb_delta' and `rsb_delta':
  /*    {
  /*      FT_Pos  origin_x       = 0;
  /*      FT_Pos  prev_rsb_delta = 0;
  /*      for all glyphs do
  /*        <compute kern between current and previous glyph and add it to
  /*         `origin_x'>
  /*        <load glyph with `FT_Load_Glyph'>
  /*        if ( prev_rsb_delta - face->glyph->lsb_delta >= 32 )
  /*          origin_x -= 64;
  /*        else if ( prev_rsb_delta - face->glyph->lsb_delta < -32 )
  /*          origin_x += 64;
  /*        prev_rsb_delta = face->glyph->rsb_delta;
  /*        <save glyph image, or render glyph, or ...>
  /*        origin_x += face->glyph->advance.x;
  /*      endfor
  /*    }

the idea is that it is possible to measure the spacing distortion between
auto-hinted glyphs, and adjust their position accordingly. this minimizes
error to less than 1/2 pixel and improves things dramatically.

this feature is usually called "auto-kerning", and the "ftdiff" demo program
implements it. Simply Press "d" (like "deltas") to toggle it on/off in a
text column. You'll see that this makes a large difference in overall

Sadly, this scheme is not implemented in typical Linux desktop libraries

Hope this helps,

- David

On Wed, 8 Aug 2007 11:43:15 +0100, "Graham Asher"
<address@hidden> said:
> Hi everybody - here is a problem that I am trying to solve myself, but
> which
> may very well have been solved already, or at least someone might have an
> idea about it.
> Autohinting seems to make the space between letters wrong in many cases.
> I
> attach a small picture showing the letters "mp" in DejaVu Serif Bold at
> 16
> ppem, rendered using the grey-scale rasterizer, with no hinting above and
> auto-hinted below. The spacing is clearly wrong in the autohinted
> version.
> This is very probably caused by bugs in the part of af_loader_load_g() in
> afloader.c that adjusts side bearings after auto-hinting has been done.
> Suggestions welcome.
> Best regards,
> Graham Asher

reply via email to

[Prev in Thread] Current Thread [Next in Thread]