commit
63bc6be0cf
|
@ -373,6 +373,8 @@ hb_font_glyph_from_string
|
|||
hb_font_glyph_to_string
|
||||
hb_font_is_immutable
|
||||
hb_font_make_immutable
|
||||
hb_font_get_serial
|
||||
hb_font_changed
|
||||
hb_font_reference
|
||||
hb_font_set_face
|
||||
hb_font_set_funcs
|
||||
|
|
|
@ -1623,6 +1623,9 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
|
|||
{
|
||||
HB_OBJECT_HEADER_STATIC,
|
||||
|
||||
0, /* serial */
|
||||
0, /* serial_coords */
|
||||
|
||||
nullptr, /* parent */
|
||||
const_cast<hb_face_t *> (&_hb_Null_hb_face_t),
|
||||
|
||||
|
@ -1852,6 +1855,9 @@ hb_font_set_user_data (hb_font_t *font,
|
|||
hb_destroy_func_t destroy /* May be NULL. */,
|
||||
hb_bool_t replace)
|
||||
{
|
||||
if (!hb_object_is_immutable (font))
|
||||
font->serial++;
|
||||
|
||||
return hb_object_set_user_data (font, key, data, destroy, replace);
|
||||
}
|
||||
|
||||
|
@ -1910,6 +1916,45 @@ hb_font_is_immutable (hb_font_t *font)
|
|||
return hb_object_is_immutable (font);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_font_get_serial:
|
||||
* @font: #hb_font_t to work upon
|
||||
*
|
||||
* Returns the internal serial number of the font. The serial
|
||||
* number is increased every time a setting on the font is
|
||||
* changed, using a setter function.
|
||||
*
|
||||
* Return value: serial number
|
||||
*
|
||||
* Since: REPLACEME.
|
||||
**/
|
||||
unsigned int
|
||||
hb_font_get_serial (hb_font_t *font)
|
||||
{
|
||||
return font->serial;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_font_changed:
|
||||
* @font: #hb_font_t to work upon
|
||||
*
|
||||
* Notifies the @font that underlying font data has changed.
|
||||
* This has the effect of increasing the serial as returned
|
||||
* by hb_font_get_serial(), which invalidates internal caches.
|
||||
*
|
||||
* Since: REPLACEME.
|
||||
**/
|
||||
void
|
||||
hb_font_changed (hb_font_t *font)
|
||||
{
|
||||
if (hb_object_is_immutable (font))
|
||||
return;
|
||||
|
||||
font->serial++;
|
||||
|
||||
font->mults_changed ();
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_font_set_parent:
|
||||
* @font: #hb_font_t to work upon
|
||||
|
@ -1926,6 +1971,11 @@ hb_font_set_parent (hb_font_t *font,
|
|||
if (hb_object_is_immutable (font))
|
||||
return;
|
||||
|
||||
if (parent == font->parent)
|
||||
return;
|
||||
|
||||
font->serial++;
|
||||
|
||||
if (!parent)
|
||||
parent = hb_font_get_empty ();
|
||||
|
||||
|
@ -1968,6 +2018,11 @@ hb_font_set_face (hb_font_t *font,
|
|||
if (hb_object_is_immutable (font))
|
||||
return;
|
||||
|
||||
if (face == font->face)
|
||||
return;
|
||||
|
||||
font->serial++;
|
||||
|
||||
if (unlikely (!face))
|
||||
face = hb_face_get_empty ();
|
||||
|
||||
|
@ -2022,6 +2077,8 @@ hb_font_set_funcs (hb_font_t *font,
|
|||
return;
|
||||
}
|
||||
|
||||
font->serial++;
|
||||
|
||||
if (font->destroy)
|
||||
font->destroy (font->user_data);
|
||||
|
||||
|
@ -2059,6 +2116,8 @@ hb_font_set_funcs_data (hb_font_t *font,
|
|||
return;
|
||||
}
|
||||
|
||||
font->serial++;
|
||||
|
||||
if (font->destroy)
|
||||
font->destroy (font->user_data);
|
||||
|
||||
|
@ -2085,6 +2144,11 @@ hb_font_set_scale (hb_font_t *font,
|
|||
if (hb_object_is_immutable (font))
|
||||
return;
|
||||
|
||||
if (font->x_scale == x_scale && font->y_scale == y_scale)
|
||||
return;
|
||||
|
||||
font->serial++;
|
||||
|
||||
font->x_scale = x_scale;
|
||||
font->y_scale = y_scale;
|
||||
font->mults_changed ();
|
||||
|
@ -2127,6 +2191,11 @@ hb_font_set_ppem (hb_font_t *font,
|
|||
if (hb_object_is_immutable (font))
|
||||
return;
|
||||
|
||||
if (font->x_ppem == x_ppem && font->y_ppem == y_ppem)
|
||||
return;
|
||||
|
||||
font->serial++;
|
||||
|
||||
font->x_ppem = x_ppem;
|
||||
font->y_ppem = y_ppem;
|
||||
}
|
||||
|
@ -2169,6 +2238,11 @@ hb_font_set_ptem (hb_font_t *font,
|
|||
if (hb_object_is_immutable (font))
|
||||
return;
|
||||
|
||||
if (font->ptem == ptem)
|
||||
return;
|
||||
|
||||
font->serial++;
|
||||
|
||||
font->ptem = ptem;
|
||||
}
|
||||
|
||||
|
@ -2216,6 +2290,11 @@ hb_font_set_synthetic_slant (hb_font_t *font, float slant)
|
|||
if (hb_object_is_immutable (font))
|
||||
return;
|
||||
|
||||
if (font->slant == slant)
|
||||
return;
|
||||
|
||||
font->serial++;
|
||||
|
||||
font->slant = slant;
|
||||
font->mults_changed ();
|
||||
}
|
||||
|
@ -2263,6 +2342,8 @@ hb_font_set_variations (hb_font_t *font,
|
|||
if (hb_object_is_immutable (font))
|
||||
return;
|
||||
|
||||
font->serial_coords = ++font->serial;
|
||||
|
||||
if (!variations_length)
|
||||
{
|
||||
hb_font_set_var_coords_normalized (font, nullptr, 0);
|
||||
|
@ -2322,6 +2403,8 @@ hb_font_set_var_coords_design (hb_font_t *font,
|
|||
if (hb_object_is_immutable (font))
|
||||
return;
|
||||
|
||||
font->serial_coords = ++font->serial;
|
||||
|
||||
int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr;
|
||||
float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
|
||||
|
||||
|
@ -2355,6 +2438,8 @@ hb_font_set_var_named_instance (hb_font_t *font,
|
|||
if (hb_object_is_immutable (font))
|
||||
return;
|
||||
|
||||
font->serial_coords = ++font->serial;
|
||||
|
||||
unsigned int coords_length = hb_ot_var_named_instance_get_design_coords (font->face, instance_index, nullptr, nullptr);
|
||||
|
||||
float *coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
|
||||
|
@ -2391,6 +2476,8 @@ hb_font_set_var_coords_normalized (hb_font_t *font,
|
|||
if (hb_object_is_immutable (font))
|
||||
return;
|
||||
|
||||
font->serial_coords = ++font->serial;
|
||||
|
||||
int *copy = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr;
|
||||
int *unmapped = coords_length ? (int *) hb_calloc (coords_length, sizeof (coords[0])) : nullptr;
|
||||
float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (design_coords[0])) : nullptr;
|
||||
|
|
|
@ -1002,6 +1002,12 @@ hb_font_make_immutable (hb_font_t *font);
|
|||
HB_EXTERN hb_bool_t
|
||||
hb_font_is_immutable (hb_font_t *font);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_font_get_serial (hb_font_t *font);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_changed (hb_font_t *font);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_font_set_parent (hb_font_t *font,
|
||||
hb_font_t *parent);
|
||||
|
|
|
@ -104,6 +104,8 @@ DECLARE_NULL_INSTANCE (hb_font_funcs_t);
|
|||
struct hb_font_t
|
||||
{
|
||||
hb_object_header_t header;
|
||||
unsigned int serial;
|
||||
unsigned int serial_coords;
|
||||
|
||||
hb_font_t *parent;
|
||||
hb_face_t *face;
|
||||
|
|
104
src/hb-ft.cc
104
src/hb-ft.cc
|
@ -86,7 +86,7 @@ struct hb_ft_font_t
|
|||
|
||||
mutable hb_mutex_t lock;
|
||||
FT_Face ft_face;
|
||||
mutable int cached_x_scale;
|
||||
mutable unsigned cached_serial;
|
||||
mutable hb_advance_cache_t advance_cache;
|
||||
};
|
||||
|
||||
|
@ -103,7 +103,7 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref)
|
|||
|
||||
ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
|
||||
|
||||
ft_font->cached_x_scale = 0;
|
||||
ft_font->cached_serial = (unsigned) -1;
|
||||
ft_font->advance_cache.init ();
|
||||
|
||||
return ft_font;
|
||||
|
@ -130,6 +130,56 @@ _hb_ft_font_destroy (void *data)
|
|||
hb_free (ft_font);
|
||||
}
|
||||
|
||||
|
||||
/* hb_font changed, update FT_Face. */
|
||||
static void _hb_ft_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);
|
||||
#if 0
|
||||
font->x_ppem * 72 * 64 / font->x_scale,
|
||||
font->y_ppem * 72 * 64 / font->y_scale);
|
||||
#endif
|
||||
if (font->x_scale < 0 || font->y_scale < 0)
|
||||
{
|
||||
FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0,
|
||||
0, font->y_scale < 0 ? -1 : +1};
|
||||
FT_Set_Transform (ft_face, &matrix, nullptr);
|
||||
}
|
||||
|
||||
#if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR)
|
||||
unsigned int num_coords;
|
||||
const int *coords = hb_font_get_var_coords_normalized (font, &num_coords);
|
||||
if (num_coords)
|
||||
{
|
||||
FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed));
|
||||
if (ft_coords)
|
||||
{
|
||||
for (unsigned int i = 0; i < num_coords; i++)
|
||||
ft_coords[i] = coords[i] * 4;
|
||||
FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords);
|
||||
hb_free (ft_coords);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Check if hb_font changed, update FT_Face. */
|
||||
static inline bool
|
||||
_hb_ft_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);
|
||||
ft_font->cached_serial = font->serial;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hb_ft_font_set_load_flags:
|
||||
* @font: #hb_font_t to work upon
|
||||
|
@ -337,11 +387,8 @@ 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 (font->x_scale != ft_font->cached_x_scale)
|
||||
{
|
||||
if (_hb_ft_check_changed (font, ft_font))
|
||||
ft_font->advance_cache.clear ();
|
||||
ft_font->cached_x_scale = font->x_scale;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -374,6 +421,8 @@ 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;
|
||||
|
||||
|
@ -400,6 +449,8 @@ 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;
|
||||
|
||||
|
@ -429,6 +480,8 @@ 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;
|
||||
|
@ -448,6 +501,8 @@ 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;
|
||||
|
||||
|
@ -481,6 +536,8 @@ 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;
|
||||
|
||||
|
@ -557,6 +614,9 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED,
|
|||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||
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);
|
||||
|
@ -620,6 +680,8 @@ 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);
|
||||
|
||||
if (unlikely (FT_Load_Glyph (ft_face, glyph,
|
||||
FT_LOAD_NO_BITMAP | ft_font->load_flags)))
|
||||
return;
|
||||
|
@ -1082,35 +1144,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);
|
||||
|
||||
FT_Set_Char_Size (ft_face,
|
||||
abs (font->x_scale), abs (font->y_scale),
|
||||
0, 0);
|
||||
#if 0
|
||||
font->x_ppem * 72 * 64 / font->x_scale,
|
||||
font->y_ppem * 72 * 64 / font->y_scale);
|
||||
#endif
|
||||
if (font->x_scale < 0 || font->y_scale < 0)
|
||||
{
|
||||
FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0,
|
||||
0, font->y_scale < 0 ? -1 : +1};
|
||||
FT_Set_Transform (ft_face, &matrix, nullptr);
|
||||
}
|
||||
|
||||
#if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR)
|
||||
unsigned int num_coords;
|
||||
const int *coords = hb_font_get_var_coords_normalized (font, &num_coords);
|
||||
if (num_coords)
|
||||
{
|
||||
FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed));
|
||||
if (ft_coords)
|
||||
{
|
||||
for (unsigned int i = 0; i < num_coords; i++)
|
||||
ft_coords[i] = coords[i] * 4;
|
||||
FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords);
|
||||
hb_free (ft_coords);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
_hb_ft_changed (font, ft_face);
|
||||
|
||||
ft_face->generic.data = blob;
|
||||
ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob;
|
||||
|
|
|
@ -1333,7 +1333,7 @@ struct cff1
|
|||
if (names)
|
||||
{
|
||||
names->fini ();
|
||||
free (names);
|
||||
hb_free (names);
|
||||
}
|
||||
|
||||
SUPER::fini ();
|
||||
|
@ -1379,7 +1379,7 @@ struct cff1
|
|||
hb_sorted_vector_t<gname_t> *names = glyph_names.get ();
|
||||
if (unlikely (!names))
|
||||
{
|
||||
names = (hb_sorted_vector_t<gname_t> *) calloc (sizeof (hb_sorted_vector_t<gname_t>), 1);
|
||||
names = (hb_sorted_vector_t<gname_t> *) hb_calloc (sizeof (hb_sorted_vector_t<gname_t>), 1);
|
||||
if (likely (names))
|
||||
{
|
||||
names->init ();
|
||||
|
@ -1409,7 +1409,7 @@ struct cff1
|
|||
if (names)
|
||||
{
|
||||
names->fini ();
|
||||
free (names);
|
||||
hb_free (names);
|
||||
}
|
||||
goto retry;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "hb-ot.h"
|
||||
|
||||
#include "hb-cache.hh"
|
||||
#include "hb-font.hh"
|
||||
#include "hb-machinery.hh"
|
||||
#include "hb-ot-face.hh"
|
||||
|
@ -58,6 +59,41 @@
|
|||
* never need to call these functions directly.
|
||||
**/
|
||||
|
||||
struct hb_ot_font_t
|
||||
{
|
||||
const hb_ot_face_t *ot_face;
|
||||
|
||||
/* h_advance caching */
|
||||
mutable hb_atomic_int_t cached_coords_serial;
|
||||
mutable hb_atomic_ptr_t<hb_advance_cache_t> advance_cache;
|
||||
};
|
||||
|
||||
static hb_ot_font_t *
|
||||
_hb_ot_font_create (hb_font_t *font)
|
||||
{
|
||||
hb_ot_font_t *ot_font = (hb_ot_font_t *) hb_calloc (1, sizeof (hb_ot_font_t));
|
||||
if (unlikely (!ot_font))
|
||||
return nullptr;
|
||||
|
||||
ot_font->ot_face = &font->face->table;
|
||||
|
||||
return ot_font;
|
||||
}
|
||||
|
||||
static void
|
||||
_hb_ot_font_destroy (void *font_data)
|
||||
{
|
||||
hb_ot_font_t *ot_font = (hb_ot_font_t *) font_data;
|
||||
|
||||
auto *cache = ot_font->advance_cache.get_relaxed ();
|
||||
if (cache)
|
||||
{
|
||||
cache->fini ();
|
||||
hb_free (cache);
|
||||
}
|
||||
|
||||
hb_free (ot_font);
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED,
|
||||
|
@ -66,7 +102,8 @@ hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED,
|
|||
hb_codepoint_t *glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
const hb_ot_face_t *ot_face = ot_font->ot_face;
|
||||
return ot_face->cmap->get_nominal_glyph (unicode, glyph);
|
||||
}
|
||||
|
||||
|
@ -80,7 +117,8 @@ hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED,
|
|||
unsigned int glyph_stride,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
const hb_ot_face_t *ot_face = ot_font->ot_face;
|
||||
return ot_face->cmap->get_nominal_glyphs (count,
|
||||
first_unicode, unicode_stride,
|
||||
first_glyph, glyph_stride);
|
||||
|
@ -94,7 +132,8 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED,
|
|||
hb_codepoint_t *glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
const hb_ot_face_t *ot_face = ot_font->ot_face;
|
||||
return ot_face->cmap->get_variation_glyph (unicode, variation_selector, glyph);
|
||||
}
|
||||
|
||||
|
@ -107,26 +146,82 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data,
|
|||
unsigned advance_stride,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
const hb_ot_face_t *ot_face = ot_font->ot_face;
|
||||
const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx;
|
||||
|
||||
#ifndef HB_NO_VAR
|
||||
const OT::HVARVVAR &HVAR = *hmtx.var_table;
|
||||
const OT::VariationStore &varStore = &HVAR + HVAR.varStore;
|
||||
OT::VariationStore::cache_t *cache = font->num_coords ? varStore.create_cache () : nullptr;
|
||||
OT::VariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr;
|
||||
|
||||
bool use_cache = font->num_coords;
|
||||
#else
|
||||
OT::VariationStore::cache_t *cache = nullptr;
|
||||
OT::VariationStore::cache_t *varStore_cache = nullptr;
|
||||
bool use_cache = false;
|
||||
#endif
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
hb_advance_cache_t *cache = nullptr;
|
||||
if (use_cache)
|
||||
{
|
||||
*first_advance = font->em_scale_x (hmtx.get_advance (*first_glyph, font, cache));
|
||||
first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
|
||||
first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
|
||||
retry:
|
||||
cache = ot_font->advance_cache.get ();
|
||||
if (unlikely (!cache))
|
||||
{
|
||||
cache = (hb_advance_cache_t *) hb_malloc (sizeof (hb_advance_cache_t));
|
||||
if (unlikely (!cache))
|
||||
{
|
||||
use_cache = false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cache->init ();
|
||||
if (unlikely (!ot_font->advance_cache.cmpexch (nullptr, cache)))
|
||||
{
|
||||
hb_free (cache);
|
||||
goto retry;
|
||||
}
|
||||
ot_font->cached_coords_serial.set (font->serial_coords);
|
||||
}
|
||||
}
|
||||
out:
|
||||
|
||||
if (!use_cache)
|
||||
{
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
*first_advance = font->em_scale_x (hmtx.get_advance (*first_glyph, font, varStore_cache));
|
||||
first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
|
||||
first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* Use cache. */
|
||||
if (ot_font->cached_coords_serial.get () != (int) font->serial_coords)
|
||||
{
|
||||
ot_font->advance_cache->init ();
|
||||
ot_font->cached_coords_serial.set (font->serial_coords);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
hb_position_t v;
|
||||
unsigned cv;
|
||||
if (ot_font->advance_cache->get (*first_glyph, &cv))
|
||||
v = cv;
|
||||
else
|
||||
{
|
||||
v = hmtx.get_advance (*first_glyph, font, varStore_cache);
|
||||
ot_font->advance_cache->set (*first_glyph, v);
|
||||
}
|
||||
*first_advance = font->em_scale_x (v);
|
||||
first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
|
||||
first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef HB_NO_VAR
|
||||
OT::VariationStore::destroy_cache (cache);
|
||||
OT::VariationStore::destroy_cache (varStore_cache);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -140,7 +235,8 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
|
|||
unsigned advance_stride,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
const hb_ot_face_t *ot_face = ot_font->ot_face;
|
||||
const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
|
||||
|
||||
if (vmtx.has_data ())
|
||||
|
@ -148,20 +244,20 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
|
|||
#ifndef HB_NO_VAR
|
||||
const OT::HVARVVAR &VVAR = *vmtx.var_table;
|
||||
const OT::VariationStore &varStore = &VVAR + VVAR.varStore;
|
||||
OT::VariationStore::cache_t *cache = font->num_coords ? varStore.create_cache () : nullptr;
|
||||
OT::VariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr;
|
||||
#else
|
||||
OT::VariationStore::cache_t *cache = nullptr;
|
||||
OT::VariationStore::cache_t *varStore_cache = nullptr;
|
||||
#endif
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
*first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font, cache));
|
||||
*first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font, varStore_cache));
|
||||
first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
|
||||
first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
|
||||
}
|
||||
|
||||
#ifndef HB_NO_VAR
|
||||
OT::VariationStore::destroy_cache (cache);
|
||||
OT::VariationStore::destroy_cache (varStore_cache);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
@ -189,7 +285,8 @@ hb_ot_get_glyph_v_origin (hb_font_t *font,
|
|||
hb_position_t *y,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
const hb_ot_face_t *ot_face = ot_font->ot_face;
|
||||
|
||||
*x = font->get_glyph_h_advance (glyph) / 2;
|
||||
|
||||
|
@ -234,7 +331,8 @@ hb_ot_get_glyph_extents (hb_font_t *font,
|
|||
hb_glyph_extents_t *extents,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
const hb_ot_face_t *ot_face = ot_font->ot_face;
|
||||
|
||||
#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
|
||||
if (ot_face->sbix->get_extents (font, glyph, extents)) return true;
|
||||
|
@ -260,7 +358,9 @@ hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
|
|||
char *name, unsigned int size,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
const hb_ot_face_t *ot_face = ot_font->ot_face;
|
||||
|
||||
if (ot_face->post->get_glyph_name (glyph, name, size)) return true;
|
||||
#ifndef HB_NO_OT_FONT_CFF
|
||||
if (ot_face->cff1->get_glyph_name (glyph, name, size)) return true;
|
||||
|
@ -274,7 +374,9 @@ hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
|
|||
hb_codepoint_t *glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
const hb_ot_face_t *ot_face = ot_font->ot_face;
|
||||
|
||||
if (ot_face->post->get_glyph_from_name (name, len, glyph)) return true;
|
||||
#ifndef HB_NO_OT_FONT_CFF
|
||||
if (ot_face->cff1->get_glyph_from_name (name, len, glyph)) return true;
|
||||
|
@ -390,10 +492,14 @@ _hb_ot_get_font_funcs ()
|
|||
void
|
||||
hb_ot_font_set_funcs (hb_font_t *font)
|
||||
{
|
||||
hb_ot_font_t *ot_font = _hb_ot_font_create (font);
|
||||
if (unlikely (!ot_font))
|
||||
return;
|
||||
|
||||
hb_font_set_funcs (font,
|
||||
_hb_ot_get_font_funcs (),
|
||||
&font->face->table,
|
||||
nullptr);
|
||||
ot_font,
|
||||
_hb_ot_font_destroy);
|
||||
}
|
||||
|
||||
#ifndef HB_NO_VAR
|
||||
|
|
Loading…
Reference in New Issue