[Fontconfig] libxft2 kerning difficulty

Dan Egnor fontconfig@fontconfig.org
Mon, 3 Mar 2003 19:14:12 -0800 (PST)


Hi,

I'm using libxft2 and fontconfig (version 2.1), as currently packaged
for Debian unstable.

I'm trying to understand the precise meaning of the XGlyphInfo structure
as returned by the XftTextExtents*() functions with libxft2.  The 
structure has six members: x, y, width, height, xOff, yOff.  Here's my 
understanding (from reading documentation) of their meaning:

   Consider a rectangle with the upper left corner at (0, 0) and size
   (width, height).  This is a sort of "bounding rectangle" that
   represents the extent of the text's ink.  If the text is drawn inside 
   this rectangle, the location (x, y) marks the "hot spot", which is the 
   position at the "start" of the "baseline", whatever that means for 
   this particular string.  The location (x + xOff, y + yOff) represents 
   the "natural start" of the "baseline" for any text that would follow.

   When you actually go to draw text with XftDraw*(), you specify the
   location of that "hot spot".  If you actually pass in (x, y), you
   should expect the text to go from (0, 0) to (width, height).

How'd I do?

Now let's take some example glyphs.  I'm going to be using MS fonts
for these examples (from msttcorefonts).  If this is actually a bug 
in the fonts, consider my question to be "how do I work around the 
bugs in real-world fonts".  These are also not isolated examples, and 
I can try to find them in other fonts as well.

First example is the lowercase 'd' and 'b' in 'Comic Sans MS-8'.  
(Antialiasing is off for these examples.)  I'm going to outline that 
rectangle I described above with |, mark the hot spot with [ ], and 
use -->[ ] to mark the "logical start" defined by xOff and yOff.

  |. . . . * .|      |* . . . . .|
  |. . . . * .|      |* . . . . .|
  |. . . . * .|      |* . . . . .|
  |. * * * * .|      |* * * * . .|
  |* . . . * .|      |* . . . * .|
  |* . . . * .|      |* . . . * .|
  |* . . . * .|      |* . . . * .|
  |* . . . * .|      |* . . . * .|
  |. * * * * .|      |* * * * . .|
[ ]-------->[ ]        [ ]------->[ ]

  width = 6          width = 6
  height = 9         height = 9
  x = -1             x = 1
  y = 9              y = 9
  xOff = 6           xOff = 6
  yOff = 0           yOff = 0

The immediate question is why the hot spot is moved to the left for the 
'd' character, and what that's supposed to mean, and why isn't xOff one
greater for 'd' than it is for 'b'?  Also, width=6, but the actual ink
is only 5 pixels wide; is the 'width' value supposed to include 
intercharacter spacing?  If so, why bother with xOff, and how would I
find the extent of the physical ink?

Next example is the lowercase 'g' and 'p' in 'Arial-8'.

  |. . * * . *|      |* . * * .|
  |. * . . * *|      |* * . . *|
  |. * . . . *|      |* . . . *|
  |. * . . . *|      |* . . . *|
  |. * . . * *|      |* * . . *|
  |. . * * . *|      |* . * * .|
  |.[.]------*->[ ]  [*]-------->[ ]
  |. * * * * .|      |* . . . .|

  width = 6          width = 5
  height = 8         height = 8
  x = 1              x = 0
  y = 6              y = 6
  xOff = 6           xOff = 6
  yOff = 0           yOff = 0

Here the 'g' seems to include some margin -- at the left, this time --
but the 'p' does not.  The hot spot seems more accurately placed than
it was for Comic Sans, though.

Is it just that the FreeType renderer has trouble at smaller font 
sizes?  I can complain to them, but I don't know what these Xft 
concepts translate into at the FreeType level.  The glyphs *look*
just great (as long as antialiasing is off!); I'm just having trouble
lining them up properly!

(If I turn the autohinter on, the spacing is more regular, but the
glyphs look like hell.)

Dan