[ft] Add API to notify that hb_font_t changed

New API:
- hb_ft_hb_font_changed()

Mostly reverts 56e0ff9ea1

Related https://github.com/harfbuzz/harfbuzz/issues/2270

Fixes https://github.com/harfbuzz/harfbuzz/issues/3619
This commit is contained in:
Behdad Esfahbod 2022-06-01 05:19:23 -06:00
parent a31fd97c35
commit fc4d42ff99
2 changed files with 41 additions and 22 deletions

View File

@ -132,8 +132,9 @@ _hb_ft_font_destroy (void *data)
/* hb_font changed, update FT_Face. */
static void _hb_ft_changed (hb_font_t *font, FT_Face ft_face)
static void _hb_ft_hb_font_changed (hb_font_t *font, FT_Face ft_face)
{
FT_Set_Char_Size (ft_face,
abs (font->x_scale), abs (font->y_scale),
0, 0);
@ -167,12 +168,13 @@ static void _hb_ft_changed (hb_font_t *font, FT_Face ft_face)
/* Check if hb_font changed, update FT_Face. */
static inline bool
_hb_ft_check_changed (hb_font_t *font,
_hb_ft_hb_font_check_changed (hb_font_t *font,
const hb_ft_font_t *ft_font)
{
if (font->serial != ft_font->cached_serial)
{
_hb_ft_changed (font, ft_font->ft_face);
_hb_ft_hb_font_changed (font, ft_font->ft_face);
ft_font->advance_cache.clear ();
ft_font->cached_serial = font->serial;
return true;
}
@ -387,9 +389,6 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data,
int load_flags = ft_font->load_flags;
int mult = font->x_scale < 0 ? -1 : +1;
if (_hb_ft_check_changed (font, ft_font))
ft_font->advance_cache.clear ();
for (unsigned int i = 0; i < count; i++)
{
FT_Fixed v = 0;
@ -421,8 +420,6 @@ hb_ft_get_glyph_v_advance (hb_font_t *font,
hb_lock_t lock (ft_font->lock);
FT_Fixed v;
_hb_ft_check_changed (font, ft_font);
if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v)))
return 0;
@ -449,8 +446,6 @@ hb_ft_get_glyph_v_origin (hb_font_t *font,
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
_hb_ft_check_changed (font, ft_font);
if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
return false;
@ -480,8 +475,6 @@ hb_ft_get_glyph_h_kerning (hb_font_t *font,
hb_lock_t lock (ft_font->lock);
FT_Vector kerningv;
_hb_ft_check_changed (font, ft_font);
FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED;
if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv))
return 0;
@ -501,8 +494,6 @@ hb_ft_get_glyph_extents (hb_font_t *font,
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
_hb_ft_check_changed (font, ft_font);
if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
return false;
@ -536,8 +527,6 @@ hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
_hb_ft_check_changed (font, ft_font);
if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
return false;
@ -615,8 +604,6 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED,
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
_hb_ft_check_changed (font, ft_font);
metrics->ascender = FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale);
metrics->descender = FT_MulFix(ft_face->descender, ft_face->size->metrics.y_scale);
metrics->line_gap = FT_MulFix( ft_face->height, ft_face->size->metrics.y_scale ) - (metrics->ascender - metrics->descender);
@ -680,7 +667,7 @@ hb_ft_get_glyph_shape (hb_font_t *font HB_UNUSED,
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
_hb_ft_check_changed (font, ft_font);
_hb_ft_hb_font_check_changed (font, ft_font);
if (unlikely (FT_Load_Glyph (ft_face, glyph,
FT_LOAD_NO_BITMAP | ft_font->load_flags)))
@ -1026,6 +1013,31 @@ hb_ft_font_changed (hb_font_t *font)
#endif
}
/**
* hb_ft_hb_font_changed:
* @font: #hb_font_t to work upon
*
* Refreshes the state of the underlying FT_Face of @font when the hb_font_t
* @font has changed.
* This function should be called after changing the size or
* variation-axis settings on the @font.
* This call is fast if nothing has changed on @font.
*
* Return value: true if changed, false otherwise
*
* Since: REPLACEME
**/
hb_bool_t
hb_ft_hb_font_changed (hb_font_t *font)
{
if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
return false;
hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
return _hb_ft_hb_font_check_changed (font, ft_font);
}
/**
* hb_ft_font_create_referenced:
* @ft_face: FT_Face to work upon
@ -1144,7 +1156,7 @@ hb_ft_font_set_funcs (hb_font_t *font)
if (FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL))
FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE);
_hb_ft_changed (font, ft_face);
_hb_ft_hb_font_changed (font, ft_face);
ft_face->generic.data = blob;
ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob;

View File

@ -122,10 +122,17 @@ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags);
HB_EXTERN int
hb_ft_font_get_load_flags (hb_font_t *font);
/* Call when size or variations settings on underlying FT_Face change. */
/* Call when size or variations settings on underlying FT_Face changed,
* and you want to update the hb_font_t from it. */
HB_EXTERN void
hb_ft_font_changed (hb_font_t *font);
/* Call when size or variations settings on underlying hb_font_t may have
* changed, and you want to update the FT_Face from it. This call is fast
* if nothing changed on hb_font_t. Returns true if changed. */
HB_EXTERN hb_bool_t
hb_ft_hb_font_changed (hb_font_t *font);
/* Makes an hb_font_t use FreeType internally to implement font functions.
* Note: this internally creates an FT_Face. Use it when you create your
* hb_face_t using hb_face_create(). */