Pango logical extents

Hi,

Some glyphs are bigger than their reported logical extents, for example:

Is it something expected?
or a bug in Pango or in the font itself?

When used in GtkEntries, such glyphs sometimes let pixels artifacts behind, seems related to the insert cursor painting itself just over those out-of-bounds pixels, and gtk only repainting the blue area when the cursor moves away.

Hi @gwillems!

Blue should depict the logical extents and red the ink extents: Making sure you're not a bot!, as retrieved by Pango.Layout.get_extents. Aside: PangoCairo, which GTK uses, gets metrics from Cairo: Making sure you're not a bot!. So Cairo is used not only for rendering , but also to retrieve metrics.

Hereā€™s a description of logical and ink extents: Pango.GlyphString.extents.

Now, I donā€™t know why, but thereā€™s a small issue: the red and blue channels are swapped. Try inserting an emoji instead of ā€˜2ā€™ and youā€™ll see it :slightly_smiling_face:

So in the above picture blue is the ink rect and red is the logical rect (which makes sense). Ink rects can be a bit wider than the actual glyph image, that doesnā€™t cause any issue. As an example, the Cairo DirectWrite backend inflates ink rects by one pixel: https://gitlab.freedesktop.org/cairo/cairo/-/blob/bdd12408a72f/src/win32/cairo-dwrite-font.cpp#L906 (I have a patch to get exact ink rects, so this is will change very soon). However ink rects must not be smaller

Could it be that the ink rect is right, but the glyph is offset one pixel on the right?

1 Like

It could be that the ink rect is right, but the glyph is offset one pixel on the right

Probably the demo (and GTK?) should take the left-side bearing in account. Glyphs origins are at the left of the l-bearing:

Arghā€¦ thanks for pointing that out, now things make a lot more sense.

Hmmā€¦ seems that can happen:

Yeah, could beā€¦

Probably the demo (and GTK?) should take the left-side bearing in account

Scratch that, Pango already offsets the ink rect by the l-bearing:

$ git grep x_bearing
pango/pangocairo-font.c:  entry->ink_rect.x = pango_units_from_double (extents.x_bearing);
pango/pangofc-font.c:     ink_rect->x = extents.x_bearing;
pango/shape.c:      extents->x_bearing = ink.x;

Could you upload the font here?

The DejaVu font is usually packaged by distros
On msys2 there is Package: mingw-w64-ucrt-x86_64-ttf-dejavu - MSYS2 Packages
Official downloads: DejaVu Fonts ā€” License

The fontconfig backend was used for these tests.

On my PCs I also set this env var:

FREETYPE_PROPERTIES=truetype:interpreter-version=35

to use the pre-cleartype renderer, which has much better hinting, especially with grayscale.

Mmh I cannot reproduce with the DejaVu fonts that I have installed on my Windows 10 box. Letā€™s try with the MSYS2 packageā€¦

Neither :confused:

I noticed that the FontConfig cache cannot be updated while an app is running:

:: Processing package changes...
(1/1) installing mingw-w64-clang-x86_64-ttf-dejavu           [###############################] 100%
:: Running post-transaction hooks...
(1/1) Updating fontconfig cache...
C:/WINDOWS/fonts: failed to write cache
C:/Users/lucab/AppData/Local/fontconfig/cache\ef9c9ad8cc5857eb63cb3660bc8bd202-le64.cache-9: Permission denied
error: command failed to execute correctly

I had to close gtk4-demo.exe and reinstall the package. Could you try the same, just to rule out any potential issue with the cache?

Ink rects and logical rects are entirely unrelated. Ink rects can be smaller than logical rects (example: " " - the ink rect is empty but the logical rect is not) and the ink rect can of course be larger than the logical rect (with Pango, the best way to get a vertical one is with a PANGO_UNDERLINE_LOW, but any long tail on a ā€œgā€ or ā€œyā€ will work. And for horizontal ink rects, pick an italic font and a diagonal glyph, say / or V)

The reason is that the logical rect is used for measuring things, and if you put 2 pieces of text (labels, PangoLayouts, whatever next to each other, one saying ā€œAā€ and the other saying ā€œVā€, you want the result to read ā€œAVā€ and not ā€œA Vā€. In fact, thatā€™s even relevant in a single piece of text because you want to place the cursor using logical rects.

2 Likes

Strangeā€¦ that works on both msys2-Win11 and linux on my side.
(though for linux I remember I had to export the env var from my user environment and restart to apply)

Sure, Iā€™ll check that tomorrow.

Tried, works fine, no changes in the rendering.
I also deleted the fc cache in my appdata to force re-creation, no change either.

1 Like

Hi @otte,

Ink rects and logical rects are entirely unrelated. Ink rects can be smaller than logical rects

Yeah, what I wanted to say is that ink rects must not be smaller than the glyph image. For example, ink rects is what one would use to build a glyph atlas. If the rect doesnā€™t cover all of the glyph image, you end up drawing on other glyphs. If the ink rect is a bit wider you get some unused blank space in the atlas, which isnā€™t a big deal.

Ok, I can reproduce by running with GDK_SCALE=2!

fontrendering.c doesnā€™t set a device scale on the cairo_surface_t, but calls gtk_widget_create_pango_context, which ends up in gtk_widget_update_pango_context.

It can be a somewhat big deal if the ink rect is wider than it needs to be, because then GTK needs to redraw a larger area. And that larger area can extend into regions that are expensive to redraw (like shadows around the window) and that can have measurable performance impacts on lower power devices (like smartphones or 10-15 year old laptops) when scrolling.
If youā€™re really unlucky that can even make the redraw region enter the non-opaque region of the window, which will force the compositor to do a more expensive redraw, too.

I remember Christian Hergert and me doing measurements to that effect in gnome-text-editor and/or VTE and it was one of the reasons at that time that he added padding to the outside of the scrollarea.

So weā€™ve been trying very hard to get the ink rects accurate with the new renderers so that that doesnā€™t happen.
Btw, thereā€™s a bunch of things that we fixed recently about that with hidpi, that I wanted to talk to you about that wrt the win32 Pango backend. So you could poke me on IRC sometime, so I donā€™t forget.

1 Like