Re: Absolute font sizes

On Tue, 2006-10-31 at 12:02 +0100, Kristian Rietveld wrote:
> Hey Behdad,

Hey Kris,

> We noticed this week that nothing in GTK+ currently checks whether the 
> font size returned by pango_font_description_get_size() is absolute or not.

This is a very unfortunate side effect of the fact that absolute size
was added in a much later version than normal sizes.  And indeed a
horrible API design choice to add
pango_font_description_get_size_is_absolute() instead of

> Looking at some uses of pango_font_description_get_size_is_absolute() in 
> Pango, it seemed to me that the correct code snippet to get the font 
> size in GTK+ should be:
>    if (pango_font_description_get_size_is_absolute (font_desc))
>      font_size = pango_font_description_get_size (font_desc) / PANGO_SCALE;
>    else
>      {
>        gdouble dpi = gdk_screen_get_resolution (gtk_widget_get_screen 
> (widget));
>        font_size = dpi * (pango_font_description_get_size (font_desc) / 
> PANGO_SCALE) / 72.;
>      }

This is correct if you want the font_size in pixels (aka dots, aka
device units).  Beware of the integer division in both branches,
particularly the second one.

> However, Tim thinks that the condition above is actually inverted. After 

That would be almost the case if you wanted the font_size in points
(device independent).

> some more searching in Pango source code, I found that cairo-fcfont, 
> cairo-win32font and fc-fontmap use the code as above and win32-fontmap 
> uses the code above with the condition inverted.

The win32 case wants to get to the size in points, so it does:

  if (pango_font_description_get_size_is_absolute (description))
    size = (int) 0.5 + (size * win32fontmap->resolution) / PANGO_SCALE;

while it looks like the second branch above, it's actually the inverse
of it if you look at the definition of ->resolution:

  win32fontmap->resolution = (PANGO_SCALE / (double) GetDeviceCaps
(pango_win32_hdc, LOGPIXELSY)) * 72.0

so, ->resolution is essentially PANGO_SCALE * 72. / dpi.

> Our question is: which is right?

The cheatsheet is:

  1 dot = one device unit (pixels for screen, points for PS/PDF)
  72 points = 1 inch
  PANGO_SCALE PangoUnits = 1.0 unit

=> font_size in dots = font_size in points / (72 points per inch) * (dpi
dots per inch)


=> font_size in PangoUnits = PANGO_SCALE * font_size in floating points

Now the confusing parts are:

  - For PS/PDF, a device unit is one point.  This is ok as long as you
don't mess up with the fontmap resolution which takes a default of 72
for PS/PDF backends, but if you confuse them and set something like
300dpi or 600dpi, god knows what happens :)

  - All the stuff above completely ignores any scale you may have on
your PangoContext.  That's not very common though.

> I hope you can enlighten us, so the backends can be brought in sync and 
> GTK+ be fixed :)

I think the Pango uses are fine.  GTK+ never uses
pango_font_description_set_absolute_size(). That's good.  But I see one
can set a font_desc property on a texttag, and that may have absolute
size.  Also, in other places, GTK+ creates a font description from an
string.  Until very recently that always generated non-absolute font
descriptions, but (in 1.14 I guess) I added ability to parse sizes like
18px to result in font descriptions with absolute sizes.  So, you want
to check that.

Also, an undocumented guarantee of Pango has been that
pango_font_describe() always generates a font description with a
non-absolute font size.  I added an alternative in 1.14 called
pango_font_describe_with_absolute_size() for the other case.

> thanks,
> -kris.

It's all black magic.  Let me know if you need further help.


"Commandment Three says Do Not Kill, Amendment Two says Blood Will Spill"
        -- Dan Bern, "New American Language"

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