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
