[Fontconfig] Text extent question - sum of advance not scaling exactly as Font Size * DPI

mathog mathog at caltech.edu
Mon Oct 15 11:11:12 PDT 2012


On 12-Oct-2012 23:56, Felix Miata wrote:
> On 2012-10-12 18:15 (GMT-0400) mathog composed:
>
>> Can somebody suggest what I might be doing wrong to cause the
>> cumulative
>> text extent to not scale linearly with font size * DPI?

> I would give it another try using DPIs that M$ expects most desktops
> to be using, all multiples of 12. So, use e.g. 72, 96, 120, 144, 192,
> 288 and see if you like the results better. Key on 96 as your
> baseline, since that's what most Windows and Mac desktops use, many
> Linux environments force, and clueless web designers presume whether
> they know it or not. 96 is even in the CSS specs.

More data:

   FT_LOAD_TARGET_NORMAL,FT_KERNING_UNFITTED
   Pnts  Dpi  Tot.Adv.  Ratio
   16     72    8173
   32     72   16539     2.023614
   64     72   33590     2.030957
  128     72   66732     1.986663
  256     72  133336     1.998082

   16     75    8621
   32     75   16985     1.970189
   64     75   34995     2.060347
  128     75   69478     1.985369
  256     75  139468     2.007369

   16     96   10919
   32     96   22543     2.064566
   64     96   44381     1.968726
  128     96   89275     2.011559
  256     96  178165     1.995687

   16    150   16985
   32    150   34995     2.060347
   64    150   69478     1.985369
  128    150  139468     2.007369
  256    150  278039     1.993568

In all cases the total extent starts to approach the expeced FS*DPI 
ratio,but only at very large font sizes.
Vary a couple of other parameters:

   FT_LOAD_TARGET_NORMAL,FT_KERNING_UNFITTED
   Pnts  Dpi  Tot.Adv.  Ratio     kern   Adv-kern   Ratio-kern
   16     72     8173              -19    8192
   32     72    16539   2.023614   -37   16576        2.023438
   64     72    33590   2.030957   -74   33664        2.030888
  128     72    66732   1.986663  -148   66880        1.986692
  256     72   133336   1.998082  -296  133632        1.998086

   FT_LOAD_TARGET_NORMAL,FT_KERNING_DEFAULT
   Pnts  Dpi  Tot.Adv.  Ratio     kern   Adv-kern   Ratio-kern
   16     72     8192                0    8192
   32     72    16512   2.015625   -64   16576        2.023438
   64     72    33600   2.034884   -64   33664        2.030888
  128     72    66752   1.986667  -128   66880        1.986692
  256     72   133312   1.997124  -320  133632        1.998086

   FT_LOAD_NO_SCALE,FT_KERNING_UNFITTED
   Pnts  Dpi  Tot.Adv.  Ratio     kern   Adv-kern   Ratio-kern
   16     72    16712              -19   16731        1.000000
   32     72    16694   1.001078   -37   16731        1.000000
   64     72    16657   1.002221   -74   16731        1.000000
  128     72    16583   1.004462  -148   16731        1.000000
  256     72    16435   1.009005  -296   16731        1.000000

   FT_LOAD_NO_SCALE,FT_KERNING_DEFAULT
   Pnts  Dpi  Tot.Adv.  Ratio     kern   Adv-kern   Ratio-kern
   16     72    16731                0   16731        1.000000
   32     72    16667   1.003840   -64   16731        1.000000
   64     72    16667   1.000000   -64   16731        1.000000
  128     72    16603   1.003855  -128   16731        1.000000
  256     72    16411   1.011699  -320   16731        1.000000


Clearly the last two have a problem - when FT_LOAD_NO_SCALE is employed 
the kerning still scales
with font size, while the advance does not.  Moreover, it does not do 
so consistently, because
Pnt32 should be -32, not -64, and Pnt16 sould be -16, not 0.  Take the 
kerning out of the advances
calculated in the last two groups and the ratio is 1.0, as it should 
be.  For the first groups the total
scaled advance, including kerning, approaches the expected FS*DPI 
scaling factor for very large font sizes.

One more test...

    FT_LOAD_NO_SCALE,FT_KERNING_UNFITTED
    Pnts  Dpi  Tot.Adv.  Ratio     kern   Adv-kern   Ratio-kern
    16    144    16694              -37   16731        1.000000
    32    144    16657   1.002221   -74   16731        1.000000
    64    144    16583   1.004462  -148   16731        1.000000
   128    144    16435   1.009005  -296   16731        1.000000
   256    144    16139   1.018341  -592   16731        1.000000

As expected, kern values doubled, so kerning is always scaled by 
(FS*DPI) even when advance is not scaled.

The application here is the automatic reassembly of formatted text.  
That is if the original
text was "Red Green Blue", with the words colored as indicated by their 
names, then when written to EMF, PDF,
(or most other graphics formats) the result would be three strings "Red 
", "Green ", "Blue".  To reassemble
the offset from the end of "Red " to the start of "Green " must be 
known precisely, and that appears to be very
much a function of how the application that reads these three strings 
in has set up FreeType.  This one
happens to be for Inkscape, and that has:

src/libnrtype/FontInstance.cpp:        if (FT_Load_Glyph (theFace, 
glyph_id, FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)) {

and no call to FT_Get_Kerning(), at least directly.

Now the million dollar question:  what are the units for advance.x and 
what determines the scale for
advance.x for FT_LOAD_NO_SCALE?

These examples all used Arial, which is a 12 point TT font (weight 80, 
width 100) and the measured distance of "First Second Third" starting on 
the origin of the "F", and ending on the origin of the next following 
character is 129.448 points.
The relationship between total advance calculated, total advance 
measured, and point size is apparently not "simple":

16731/129.448      = 129.248810
16731/(12*129.448) = 10.770734
16731/(129.448/12) = 1550.985724


Thanks,

David Mathog
mathog at caltech.edu
Manager, Sequence Analysis Facility, Biology Division, Caltech


More information about the Fontconfig mailing list