[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
FT_GlyphSlot: load hinted + lsb_delta - rsb_delta xadvance differs with
From: |
takase1121 |
Subject: |
FT_GlyphSlot: load hinted + lsb_delta - rsb_delta xadvance differs with unhinted |
Date: |
Sun, 07 Jul 2024 14:22:00 +0000 |
Hi,
According to the documentation on lsb and rsb_delta:
https://freetype.org/freetype2/docs/reference/ft2-glyph_retrieval.html#ft_glyphslotrec
The fields are described as the "difference between hinted and unhinted
left/right-side bearing", and the code underneath describes how to calculate
the xadvance based on the values. However, the xadvance I got from using
FT_Load_Glyph with FT_LOAD_TARGET_LIGHT & lsb/rsb_delta is sometimes different
than FT_Load_Glyph with FT_LOAD_NO_HINTING, especially with whitespace.
I tested this with a simple C program that prints a message if the hinted and
unhinted xadvances are different. I tested this program with JetBrains Mono and
Fira Sans, and both fonts have differing xadvances on U+000D (CR), U+0020
(Space), U+00A0 (No-Break Space), U+2007 (Figure Space), U+2008 (Punctuation
Space). I guess that the lsb_delta and rsb_delta are not set because there is
nothing to hint (they're all whitespaces). I would like to confirm if this is a
bug with FreeType or is to be expected. Any help would be greatly appreciated.
The C program:
---
// compile with: gcc -o test -I/usr/include/freetype2 test.c -lfreetype
#include <ft2build.h>
#include FT_FREETYPE_H
int main(int argc, const char **argv) {
FT_Library lib;
FT_Face face;
if (argc != 2) return 1;
if (FT_Init_FreeType(&lib) != 0)
return 1;
if (FT_New_Face(lib, argv[1], 0, &face) != 0)
return 1;
if (FT_Set_Pixel_Sizes(face, 0, 14) != 0)
return 1;
printf("Family: %s\n", face->family_name);
for (int i = 0; i < 0x10FFFF; i++) {
if (FT_Load_Char(face, i, FT_LOAD_TARGET_LIGHT |
FT_LOAD_FORCE_AUTOHINT) != 0)
return 1;
double hinted_xadv = (face->glyph->advance.x + (face->glyph->lsb_delta
- face->glyph->rsb_delta)) / 64.0f;
double bearing_delta = (face->glyph->lsb_delta - face->glyph->rsb_delta) /
64.0f;
if (FT_Load_Char(face, i, FT_LOAD_BITMAP_METRICS_ONLY |
FT_LOAD_NO_HINTING) != 0)
return 1;
double unhinted_xadv = (face->glyph->advance.x) / 64.0f;
if (hinted_xadv != unhinted_xadv) {
printf("different advances (U+%04X): %lf hinted, %lf unhinted\n",
i, hinted_xadv, unhinted_xadv);
printf("lsb_delta - rsb_delta: %f\n", bearing_delta);
}
}
printf("\n\n");
return 0;
}
---
Sample results:
---
Family: Fira Sansdifferent advances (U+000D): 4.000000 hinted, 3.703125 unhinted
lsb_delta - rsb_delta: 0.000000
different advances (U+0020): 4.000000 hinted, 3.703125 unhinted
lsb_delta - rsb_delta: 0.000000
different advances (U+00A0): 4.000000 hinted, 3.703125 unhinted
lsb_delta - rsb_delta: 0.000000
different advances (U+2007): 8.000000 hinted, 7.843750 unhinted
lsb_delta - rsb_delta: 0.000000
different advances (U+2008): 4.000000 hinted, 3.703125 unhinted
lsb_delta - rsb_delta: 0.000000
---
JetBrains Mono: https://www.jetbrains.com/lp/mono/
Fira Sans: https://fonts.google.com/specimen/Fira+Sans
Thanks,
Kelvin
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- FT_GlyphSlot: load hinted + lsb_delta - rsb_delta xadvance differs with unhinted,
takase1121 <=