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