11/*
22 * Copyright © 2009 Red Hat, Inc.
33 * Copyright © 2009 Keith Stribley
4+ * Copyright © 2015 Google, Inc.
45 *
56 * This is part of HarfBuzz, a text shaping library.
67 *
2324 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
2425 *
2526 * Red Hat Author(s): Behdad Esfahbod
27+ * Google Author(s): Behdad Esfahbod
2628 */
2729
2830#include " hb-private.hh"
6668 */
6769
6870
71+ struct hb_ft_font_t
72+ {
73+ FT_Face ft_face;
74+ int load_flags;
75+ bool unref; /* Whether to destroy ft_face when done. */
76+ };
77+
78+ static hb_ft_font_t *
79+ _hb_ft_font_create (FT_Face ft_face, bool unref)
80+ {
81+ hb_ft_font_t *ft_font = (hb_ft_font_t *) calloc (1 , sizeof (hb_ft_font_t ));
82+
83+ if (unlikely (!ft_font))
84+ return NULL ;
85+
86+ ft_font->ft_face = ft_face;
87+ ft_font->unref = unref;
88+
89+ ft_font->load_flags = FT_LOAD_DEFAULT;
90+
91+ return ft_font;
92+ }
93+
94+ static void
95+ _hb_ft_font_destroy (hb_ft_font_t *ft_font)
96+ {
97+ if (ft_font->unref )
98+ FT_Done_Face (ft_font->ft_face );
99+
100+ free (ft_font);
101+ }
102+
103+ void
104+ hb_ft_font_set_load_flags (hb_font_t *font, int load_flags)
105+ {
106+ if (font->immutable )
107+ return ;
108+
109+ if (font->destroy != (hb_destroy_func_t ) _hb_ft_font_destroy)
110+ return ;
111+
112+ hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data ;
113+
114+ ft_font->load_flags = load_flags;
115+ }
116+
117+ int
118+ hb_ft_font_get_load_flags (hb_font_t *font)
119+ {
120+ if (font->destroy != (hb_destroy_func_t ) _hb_ft_font_destroy)
121+ return 0 ;
122+
123+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data ;
124+
125+ return ft_font->load_flags ;
126+ }
127+
128+ FT_Face
129+ hb_ft_font_get_face (hb_font_t *font)
130+ {
131+ if (font->destroy != (hb_destroy_func_t ) _hb_ft_font_destroy)
132+ return NULL ;
133+
134+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data ;
135+
136+ return ft_font->ft_face ;
137+ }
138+
139+
140+
69141static hb_bool_t
70142hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
71143 void *font_data,
@@ -75,13 +147,13 @@ hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
75147 void *user_data HB_UNUSED)
76148
77149{
150+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
78151 unsigned int g;
79- FT_Face ft_face = (FT_Face) font_data;
80152
81153 if (likely (!variation_selector))
82- g = FT_Get_Char_Index (ft_face, unicode);
154+ g = FT_Get_Char_Index (ft_font-> ft_face , unicode);
83155 else
84- g = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
156+ g = FT_Face_GetCharVariantIndex (ft_font-> ft_face , unicode, variation_selector);
85157
86158 if (unlikely (!g))
87159 return false ;
@@ -96,11 +168,10 @@ hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
96168 hb_codepoint_t glyph,
97169 void *user_data HB_UNUSED)
98170{
99- FT_Face ft_face = (FT_Face) font_data;
100- int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
171+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
101172 FT_Fixed v;
102173
103- if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v)))
174+ if (unlikely (FT_Get_Advance (ft_font-> ft_face , glyph, ft_font-> load_flags , &v)))
104175 return 0 ;
105176
106177 if (font->x_scale < 0 )
@@ -115,11 +186,10 @@ hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
115186 hb_codepoint_t glyph,
116187 void *user_data HB_UNUSED)
117188{
118- FT_Face ft_face = (FT_Face) font_data;
119- int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING | FT_LOAD_VERTICAL_LAYOUT;
189+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
120190 FT_Fixed v;
121191
122- if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v)))
192+ if (unlikely (FT_Get_Advance (ft_font-> ft_face , glyph, ft_font-> load_flags | FT_LOAD_VERTICAL_LAYOUT , &v)))
123193 return 0 ;
124194
125195 if (font->y_scale < 0 )
@@ -150,10 +220,10 @@ hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
150220 hb_position_t *y,
151221 void *user_data HB_UNUSED)
152222{
153- FT_Face ft_face = (FT_Face ) font_data;
154- int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING ;
223+ const hb_ft_font_t *ft_font = (const hb_ft_font_t * ) font_data;
224+ FT_Face ft_face = ft_font-> ft_face ;
155225
156- if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
226+ if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font-> load_flags )))
157227 return false ;
158228
159229 /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
@@ -176,11 +246,11 @@ hb_ft_get_glyph_h_kerning (hb_font_t *font,
176246 hb_codepoint_t right_glyph,
177247 void *user_data HB_UNUSED)
178248{
179- FT_Face ft_face = (FT_Face ) font_data;
249+ const hb_ft_font_t *ft_font = (const hb_ft_font_t * ) font_data;
180250 FT_Vector kerningv;
181251
182252 FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED;
183- if (FT_Get_Kerning (ft_face, left_glyph, right_glyph, mode, &kerningv))
253+ if (FT_Get_Kerning (ft_font-> ft_face , left_glyph, right_glyph, mode, &kerningv))
184254 return 0 ;
185255
186256 return kerningv.x ;
@@ -204,10 +274,10 @@ hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
204274 hb_glyph_extents_t *extents,
205275 void *user_data HB_UNUSED)
206276{
207- FT_Face ft_face = (FT_Face ) font_data;
208- int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING ;
277+ const hb_ft_font_t *ft_font = (const hb_ft_font_t * ) font_data;
278+ FT_Face ft_face = ft_font-> ft_face ;
209279
210- if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
280+ if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font-> load_flags )))
211281 return false ;
212282
213283 extents->x_bearing = ft_face->glyph ->metrics .horiBearingX ;
@@ -226,10 +296,10 @@ hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
226296 hb_position_t *y,
227297 void *user_data HB_UNUSED)
228298{
229- FT_Face ft_face = (FT_Face ) font_data;
230- int load_flags = FT_LOAD_DEFAULT ;
299+ const hb_ft_font_t *ft_font = (const hb_ft_font_t * ) font_data;
300+ FT_Face ft_face = ft_font-> ft_face ;
231301
232- if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
302+ if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font-> load_flags )))
233303 return false ;
234304
235305 if (unlikely (ft_face->glyph ->format != FT_GLYPH_FORMAT_OUTLINE))
@@ -251,9 +321,9 @@ hb_ft_get_glyph_name (hb_font_t *font HB_UNUSED,
251321 char *name, unsigned int size,
252322 void *user_data HB_UNUSED)
253323{
254- FT_Face ft_face = (FT_Face ) font_data;
324+ const hb_ft_font_t *ft_font = (const hb_ft_font_t * ) font_data;
255325
256- hb_bool_t ret = !FT_Get_Glyph_Name (ft_face, glyph, name, size);
326+ hb_bool_t ret = !FT_Get_Glyph_Name (ft_font-> ft_face , glyph, name, size);
257327 if (ret && (size && !*name))
258328 ret = false ;
259329
@@ -267,7 +337,8 @@ hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED,
267337 hb_codepoint_t *glyph,
268338 void *user_data HB_UNUSED)
269339{
270- FT_Face ft_face = (FT_Face) font_data;
340+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
341+ FT_Face ft_face = ft_font->ft_face ;
271342
272343 if (len < 0 )
273344 *glyph = FT_Get_Name_Index (ft_face, (FT_String *) name);
@@ -293,8 +364,8 @@ hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED,
293364}
294365
295366
296- static hb_font_funcs_t *
297- _hb_ft_get_font_funcs ( void )
367+ static void
368+ _hb_ft_font_set_funcs ( hb_font_t *font, FT_Face ft_face, bool unref )
298369{
299370 static const hb_font_funcs_t ft_ffuncs = {
300371 HB_OBJECT_HEADER_STATIC,
@@ -308,7 +379,10 @@ _hb_ft_get_font_funcs (void)
308379 }
309380 };
310381
311- return const_cast <hb_font_funcs_t *> (&ft_ffuncs);
382+ hb_font_set_funcs (font,
383+ const_cast <hb_font_funcs_t *> (&ft_ffuncs),
384+ _hb_ft_font_create (ft_face, unref),
385+ (hb_destroy_func_t ) _hb_ft_font_destroy);
312386}
313387
314388
@@ -420,11 +494,6 @@ hb_ft_face_create_cached (FT_Face ft_face)
420494 return hb_face_reference ((hb_face_t *) ft_face->generic .data );
421495}
422496
423- static void
424- _do_nothing (void )
425- {
426- }
427-
428497
429498/* *
430499 * hb_ft_font_create:
@@ -446,9 +515,7 @@ hb_ft_font_create (FT_Face ft_face,
446515 face = hb_ft_face_create (ft_face, destroy);
447516 font = hb_font_create (face);
448517 hb_face_destroy (face);
449- hb_font_set_funcs (font,
450- _hb_ft_get_font_funcs (),
451- ft_face, (hb_destroy_func_t ) _do_nothing);
518+ _hb_ft_font_set_funcs (font, ft_face, false );
452519 hb_font_set_scale (font,
453520 (int ) (((uint64_t ) ft_face->size ->metrics .x_scale * (uint64_t ) ft_face->units_per_EM + (1 <<15 )) >> 16 ),
454521 (int ) (((uint64_t ) ft_face->size ->metrics .y_scale * (uint64_t ) ft_face->units_per_EM + (1 <<15 )) >> 16 ));
@@ -562,18 +629,6 @@ hb_ft_font_set_funcs (hb_font_t *font)
562629 ft_face->generic .data = blob;
563630 ft_face->generic .finalizer = (FT_Generic_Finalizer) _release_blob;
564631
565- hb_font_set_funcs (font,
566- _hb_ft_get_font_funcs (),
567- ft_face,
568- (hb_destroy_func_t ) FT_Done_Face);
569- }
570-
571- FT_Face
572- hb_ft_font_get_face (hb_font_t *font)
573- {
574- if (font->destroy == (hb_destroy_func_t ) FT_Done_Face ||
575- font->destroy == (hb_destroy_func_t ) _do_nothing)
576- return (FT_Face) font->user_data ;
577-
578- return NULL ;
632+ _hb_ft_font_set_funcs (font, ft_face, true );
633+ hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING);
579634}
0 commit comments