1 /*
2 * Copyright © 2009 Red Hat, Inc.
3 * Copyright © 2012 Google, Inc.
4 *
5 * This is part of HarfBuzz, a text shaping library.
6 *
7 * Permission is hereby granted, without written agreement and without
8 * license or royalty fees, to use, copy, modify, and distribute this
9 * software and its documentation for any purpose, provided that the
10 * above copyright notice and the following two paragraphs appear in
11 * all copies of this software.
12 *
13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17 * DAMAGE.
18 *
19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
22 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24 *
25 * Red Hat Author(s): Behdad Esfahbod
26 * Google Author(s): Behdad Esfahbod
27 */
28
29 #include "hb-private.hh"
30
31 #include "hb-ot-layout-private.hh"
32
33 #include "hb-font-private.hh"
34 #include "hb-open-file-private.hh"
35 #include "hb-ot-head-table.hh"
36 #include "hb-ot-maxp-table.hh"
37
38 #include "hb-cache-private.hh"
39
40 #include <string.h>
41
42
43 /*
44 * hb_font_funcs_t
45 */
46
47 static hb_bool_t
hb_font_get_font_h_extents_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_font_extents_t * metrics,void * user_data HB_UNUSED)48 hb_font_get_font_h_extents_nil (hb_font_t *font,
49 void *font_data HB_UNUSED,
50 hb_font_extents_t *metrics,
51 void *user_data HB_UNUSED)
52 {
53 memset (metrics, 0, sizeof (*metrics));
54 return false;
55 }
56 static hb_bool_t
hb_font_get_font_h_extents_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_font_extents_t * metrics,void * user_data HB_UNUSED)57 hb_font_get_font_h_extents_parent (hb_font_t *font,
58 void *font_data HB_UNUSED,
59 hb_font_extents_t *metrics,
60 void *user_data HB_UNUSED)
61 {
62 hb_bool_t ret = font->parent->get_font_h_extents (metrics);
63 if (ret) {
64 metrics->ascender = font->parent_scale_y_distance (metrics->ascender);
65 metrics->descender = font->parent_scale_y_distance (metrics->descender);
66 metrics->line_gap = font->parent_scale_y_distance (metrics->line_gap);
67 }
68 return ret;
69 }
70
71 static hb_bool_t
hb_font_get_font_v_extents_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_font_extents_t * metrics,void * user_data HB_UNUSED)72 hb_font_get_font_v_extents_nil (hb_font_t *font,
73 void *font_data HB_UNUSED,
74 hb_font_extents_t *metrics,
75 void *user_data HB_UNUSED)
76 {
77 memset (metrics, 0, sizeof (*metrics));
78 return false;
79 }
80 static hb_bool_t
hb_font_get_font_v_extents_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_font_extents_t * metrics,void * user_data HB_UNUSED)81 hb_font_get_font_v_extents_parent (hb_font_t *font,
82 void *font_data HB_UNUSED,
83 hb_font_extents_t *metrics,
84 void *user_data HB_UNUSED)
85 {
86 hb_bool_t ret = font->parent->get_font_v_extents (metrics);
87 if (ret) {
88 metrics->ascender = font->parent_scale_x_distance (metrics->ascender);
89 metrics->descender = font->parent_scale_x_distance (metrics->descender);
90 metrics->line_gap = font->parent_scale_x_distance (metrics->line_gap);
91 }
92 return ret;
93 }
94
95 static hb_bool_t
hb_font_get_nominal_glyph_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t unicode,hb_codepoint_t * glyph,void * user_data HB_UNUSED)96 hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED,
97 void *font_data HB_UNUSED,
98 hb_codepoint_t unicode,
99 hb_codepoint_t *glyph,
100 void *user_data HB_UNUSED)
101 {
102 *glyph = 0;
103 return false;
104 }
105 static hb_bool_t
hb_font_get_nominal_glyph_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t unicode,hb_codepoint_t * glyph,void * user_data HB_UNUSED)106 hb_font_get_nominal_glyph_parent (hb_font_t *font,
107 void *font_data HB_UNUSED,
108 hb_codepoint_t unicode,
109 hb_codepoint_t *glyph,
110 void *user_data HB_UNUSED)
111 {
112 return font->parent->get_nominal_glyph (unicode, glyph);
113 }
114
115 static hb_bool_t
hb_font_get_variation_glyph_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t unicode,hb_codepoint_t variation_selector,hb_codepoint_t * glyph,void * user_data HB_UNUSED)116 hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED,
117 void *font_data HB_UNUSED,
118 hb_codepoint_t unicode,
119 hb_codepoint_t variation_selector,
120 hb_codepoint_t *glyph,
121 void *user_data HB_UNUSED)
122 {
123 *glyph = 0;
124 return false;
125 }
126 static hb_bool_t
hb_font_get_variation_glyph_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t unicode,hb_codepoint_t variation_selector,hb_codepoint_t * glyph,void * user_data HB_UNUSED)127 hb_font_get_variation_glyph_parent (hb_font_t *font,
128 void *font_data HB_UNUSED,
129 hb_codepoint_t unicode,
130 hb_codepoint_t variation_selector,
131 hb_codepoint_t *glyph,
132 void *user_data HB_UNUSED)
133 {
134 return font->parent->get_variation_glyph (unicode, variation_selector, glyph);
135 }
136
137
138 static hb_position_t
hb_font_get_glyph_h_advance_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t glyph,void * user_data HB_UNUSED)139 hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED,
140 void *font_data HB_UNUSED,
141 hb_codepoint_t glyph,
142 void *user_data HB_UNUSED)
143 {
144 return font->x_scale;
145 }
146 static hb_position_t
hb_font_get_glyph_h_advance_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,void * user_data HB_UNUSED)147 hb_font_get_glyph_h_advance_parent (hb_font_t *font,
148 void *font_data HB_UNUSED,
149 hb_codepoint_t glyph,
150 void *user_data HB_UNUSED)
151 {
152 return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
153 }
154
155 static hb_position_t
hb_font_get_glyph_v_advance_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t glyph,void * user_data HB_UNUSED)156 hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED,
157 void *font_data HB_UNUSED,
158 hb_codepoint_t glyph,
159 void *user_data HB_UNUSED)
160 {
161 return font->y_scale;
162 }
163 static hb_position_t
hb_font_get_glyph_v_advance_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,void * user_data HB_UNUSED)164 hb_font_get_glyph_v_advance_parent (hb_font_t *font,
165 void *font_data HB_UNUSED,
166 hb_codepoint_t glyph,
167 void *user_data HB_UNUSED)
168 {
169 return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
170 }
171
172 static hb_bool_t
hb_font_get_glyph_h_origin_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_position_t * x,hb_position_t * y,void * user_data HB_UNUSED)173 hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
174 void *font_data HB_UNUSED,
175 hb_codepoint_t glyph,
176 hb_position_t *x,
177 hb_position_t *y,
178 void *user_data HB_UNUSED)
179 {
180 *x = *y = 0;
181 return true;
182 }
183 static hb_bool_t
hb_font_get_glyph_h_origin_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_position_t * x,hb_position_t * y,void * user_data HB_UNUSED)184 hb_font_get_glyph_h_origin_parent (hb_font_t *font,
185 void *font_data HB_UNUSED,
186 hb_codepoint_t glyph,
187 hb_position_t *x,
188 hb_position_t *y,
189 void *user_data HB_UNUSED)
190 {
191 hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
192 if (ret)
193 font->parent_scale_position (x, y);
194 return ret;
195 }
196
197 static hb_bool_t
hb_font_get_glyph_v_origin_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_position_t * x,hb_position_t * y,void * user_data HB_UNUSED)198 hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
199 void *font_data HB_UNUSED,
200 hb_codepoint_t glyph,
201 hb_position_t *x,
202 hb_position_t *y,
203 void *user_data HB_UNUSED)
204 {
205 *x = *y = 0;
206 return false;
207 }
208 static hb_bool_t
hb_font_get_glyph_v_origin_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_position_t * x,hb_position_t * y,void * user_data HB_UNUSED)209 hb_font_get_glyph_v_origin_parent (hb_font_t *font,
210 void *font_data HB_UNUSED,
211 hb_codepoint_t glyph,
212 hb_position_t *x,
213 hb_position_t *y,
214 void *user_data HB_UNUSED)
215 {
216 hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
217 if (ret)
218 font->parent_scale_position (x, y);
219 return ret;
220 }
221
222 static hb_position_t
hb_font_get_glyph_h_kerning_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t left_glyph,hb_codepoint_t right_glyph,void * user_data HB_UNUSED)223 hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
224 void *font_data HB_UNUSED,
225 hb_codepoint_t left_glyph,
226 hb_codepoint_t right_glyph,
227 void *user_data HB_UNUSED)
228 {
229 return 0;
230 }
231 static hb_position_t
hb_font_get_glyph_h_kerning_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t left_glyph,hb_codepoint_t right_glyph,void * user_data HB_UNUSED)232 hb_font_get_glyph_h_kerning_parent (hb_font_t *font,
233 void *font_data HB_UNUSED,
234 hb_codepoint_t left_glyph,
235 hb_codepoint_t right_glyph,
236 void *user_data HB_UNUSED)
237 {
238 return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
239 }
240
241 static hb_position_t
hb_font_get_glyph_v_kerning_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t top_glyph,hb_codepoint_t bottom_glyph,void * user_data HB_UNUSED)242 hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
243 void *font_data HB_UNUSED,
244 hb_codepoint_t top_glyph,
245 hb_codepoint_t bottom_glyph,
246 void *user_data HB_UNUSED)
247 {
248 return 0;
249 }
250 static hb_position_t
hb_font_get_glyph_v_kerning_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t top_glyph,hb_codepoint_t bottom_glyph,void * user_data HB_UNUSED)251 hb_font_get_glyph_v_kerning_parent (hb_font_t *font,
252 void *font_data HB_UNUSED,
253 hb_codepoint_t top_glyph,
254 hb_codepoint_t bottom_glyph,
255 void *user_data HB_UNUSED)
256 {
257 return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
258 }
259
260 static hb_bool_t
hb_font_get_glyph_extents_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_glyph_extents_t * extents,void * user_data HB_UNUSED)261 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
262 void *font_data HB_UNUSED,
263 hb_codepoint_t glyph,
264 hb_glyph_extents_t *extents,
265 void *user_data HB_UNUSED)
266 {
267 memset (extents, 0, sizeof (*extents));
268 return false;
269 }
270 static hb_bool_t
hb_font_get_glyph_extents_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_glyph_extents_t * extents,void * user_data HB_UNUSED)271 hb_font_get_glyph_extents_parent (hb_font_t *font,
272 void *font_data HB_UNUSED,
273 hb_codepoint_t glyph,
274 hb_glyph_extents_t *extents,
275 void *user_data HB_UNUSED)
276 {
277 hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
278 if (ret) {
279 font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
280 font->parent_scale_distance (&extents->width, &extents->height);
281 }
282 return ret;
283 }
284
285 static hb_bool_t
hb_font_get_glyph_contour_point_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t glyph,unsigned int point_index,hb_position_t * x,hb_position_t * y,void * user_data HB_UNUSED)286 hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED,
287 void *font_data HB_UNUSED,
288 hb_codepoint_t glyph,
289 unsigned int point_index,
290 hb_position_t *x,
291 hb_position_t *y,
292 void *user_data HB_UNUSED)
293 {
294 *x = *y = 0;
295 return false;
296 }
297 static hb_bool_t
hb_font_get_glyph_contour_point_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,unsigned int point_index,hb_position_t * x,hb_position_t * y,void * user_data HB_UNUSED)298 hb_font_get_glyph_contour_point_parent (hb_font_t *font,
299 void *font_data HB_UNUSED,
300 hb_codepoint_t glyph,
301 unsigned int point_index,
302 hb_position_t *x,
303 hb_position_t *y,
304 void *user_data HB_UNUSED)
305 {
306 hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y);
307 if (ret)
308 font->parent_scale_position (x, y);
309 return ret;
310 }
311
312 static hb_bool_t
hb_font_get_glyph_name_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,hb_codepoint_t glyph,char * name,unsigned int size,void * user_data HB_UNUSED)313 hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED,
314 void *font_data HB_UNUSED,
315 hb_codepoint_t glyph,
316 char *name, unsigned int size,
317 void *user_data HB_UNUSED)
318 {
319 if (size) *name = '\0';
320 return false;
321 }
322 static hb_bool_t
hb_font_get_glyph_name_parent(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,char * name,unsigned int size,void * user_data HB_UNUSED)323 hb_font_get_glyph_name_parent (hb_font_t *font,
324 void *font_data HB_UNUSED,
325 hb_codepoint_t glyph,
326 char *name, unsigned int size,
327 void *user_data HB_UNUSED)
328 {
329 return font->parent->get_glyph_name (glyph, name, size);
330 }
331
332 static hb_bool_t
hb_font_get_glyph_from_name_nil(hb_font_t * font HB_UNUSED,void * font_data HB_UNUSED,const char * name,int len,hb_codepoint_t * glyph,void * user_data HB_UNUSED)333 hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED,
334 void *font_data HB_UNUSED,
335 const char *name, int len, /* -1 means nul-terminated */
336 hb_codepoint_t *glyph,
337 void *user_data HB_UNUSED)
338 {
339 *glyph = 0;
340 return false;
341 }
342 static hb_bool_t
hb_font_get_glyph_from_name_parent(hb_font_t * font,void * font_data HB_UNUSED,const char * name,int len,hb_codepoint_t * glyph,void * user_data HB_UNUSED)343 hb_font_get_glyph_from_name_parent (hb_font_t *font,
344 void *font_data HB_UNUSED,
345 const char *name, int len, /* -1 means nul-terminated */
346 hb_codepoint_t *glyph,
347 void *user_data HB_UNUSED)
348 {
349 return font->parent->get_glyph_from_name (name, len, glyph);
350 }
351
352 static const hb_font_funcs_t _hb_font_funcs_nil = {
353 HB_OBJECT_HEADER_STATIC,
354
355 true, /* immutable */
356
357 {
358 #define HB_FONT_FUNC_IMPLEMENT(name) NULL,
359 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
360 #undef HB_FONT_FUNC_IMPLEMENT
361 },
362 {
363 #define HB_FONT_FUNC_IMPLEMENT(name) NULL,
364 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
365 #undef HB_FONT_FUNC_IMPLEMENT
366 },
367 {
368 {
369 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
370 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
371 #undef HB_FONT_FUNC_IMPLEMENT
372 }
373 }
374 };
375 static const hb_font_funcs_t _hb_font_funcs_parent = {
376 HB_OBJECT_HEADER_STATIC,
377
378 true, /* immutable */
379
380 {
381 #define HB_FONT_FUNC_IMPLEMENT(name) NULL,
382 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
383 #undef HB_FONT_FUNC_IMPLEMENT
384 },
385 {
386 #define HB_FONT_FUNC_IMPLEMENT(name) NULL,
387 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
388 #undef HB_FONT_FUNC_IMPLEMENT
389 },
390 {
391 {
392 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_parent,
393 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
394 #undef HB_FONT_FUNC_IMPLEMENT
395 }
396 }
397 };
398
399
400 /**
401 * hb_font_funcs_create: (Xconstructor)
402 *
403 *
404 *
405 * Return value: (transfer full):
406 *
407 * Since: 0.9.2
408 **/
409 hb_font_funcs_t *
hb_font_funcs_create(void)410 hb_font_funcs_create (void)
411 {
412 hb_font_funcs_t *ffuncs;
413
414 if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
415 return hb_font_funcs_get_empty ();
416
417 ffuncs->get = _hb_font_funcs_parent.get;
418
419 return ffuncs;
420 }
421
422 /**
423 * hb_font_funcs_get_empty:
424 *
425 *
426 *
427 * Return value: (transfer full):
428 *
429 * Since: 0.9.2
430 **/
431 hb_font_funcs_t *
hb_font_funcs_get_empty(void)432 hb_font_funcs_get_empty (void)
433 {
434 return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_parent);
435 }
436
437 /**
438 * hb_font_funcs_reference: (skip)
439 * @ffuncs: font functions.
440 *
441 *
442 *
443 * Return value:
444 *
445 * Since: 0.9.2
446 **/
447 hb_font_funcs_t *
hb_font_funcs_reference(hb_font_funcs_t * ffuncs)448 hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
449 {
450 return hb_object_reference (ffuncs);
451 }
452
453 /**
454 * hb_font_funcs_destroy: (skip)
455 * @ffuncs: font functions.
456 *
457 *
458 *
459 * Since: 0.9.2
460 **/
461 void
hb_font_funcs_destroy(hb_font_funcs_t * ffuncs)462 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
463 {
464 if (!hb_object_destroy (ffuncs)) return;
465
466 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
467 ffuncs->destroy.name (ffuncs->user_data.name);
468 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
469 #undef HB_FONT_FUNC_IMPLEMENT
470
471 free (ffuncs);
472 }
473
474 /**
475 * hb_font_funcs_set_user_data: (skip)
476 * @ffuncs: font functions.
477 * @key:
478 * @data:
479 * @destroy:
480 * @replace:
481 *
482 *
483 *
484 * Return value:
485 *
486 * Since: 0.9.2
487 **/
488 hb_bool_t
hb_font_funcs_set_user_data(hb_font_funcs_t * ffuncs,hb_user_data_key_t * key,void * data,hb_destroy_func_t destroy,hb_bool_t replace)489 hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
490 hb_user_data_key_t *key,
491 void * data,
492 hb_destroy_func_t destroy,
493 hb_bool_t replace)
494 {
495 return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
496 }
497
498 /**
499 * hb_font_funcs_get_user_data: (skip)
500 * @ffuncs: font functions.
501 * @key:
502 *
503 *
504 *
505 * Return value: (transfer none):
506 *
507 * Since: 0.9.2
508 **/
509 void *
hb_font_funcs_get_user_data(hb_font_funcs_t * ffuncs,hb_user_data_key_t * key)510 hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
511 hb_user_data_key_t *key)
512 {
513 return hb_object_get_user_data (ffuncs, key);
514 }
515
516
517 /**
518 * hb_font_funcs_make_immutable:
519 * @ffuncs: font functions.
520 *
521 *
522 *
523 * Since: 0.9.2
524 **/
525 void
hb_font_funcs_make_immutable(hb_font_funcs_t * ffuncs)526 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
527 {
528 if (unlikely (hb_object_is_inert (ffuncs)))
529 return;
530
531 ffuncs->immutable = true;
532 }
533
534 /**
535 * hb_font_funcs_is_immutable:
536 * @ffuncs: font functions.
537 *
538 *
539 *
540 * Return value:
541 *
542 * Since: 0.9.2
543 **/
544 hb_bool_t
hb_font_funcs_is_immutable(hb_font_funcs_t * ffuncs)545 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
546 {
547 return ffuncs->immutable;
548 }
549
550
551 #define HB_FONT_FUNC_IMPLEMENT(name) \
552 \
553 void \
554 hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \
555 hb_font_get_##name##_func_t func, \
556 void *user_data, \
557 hb_destroy_func_t destroy) \
558 { \
559 if (ffuncs->immutable) { \
560 if (destroy) \
561 destroy (user_data); \
562 return; \
563 } \
564 \
565 if (ffuncs->destroy.name) \
566 ffuncs->destroy.name (ffuncs->user_data.name); \
567 \
568 if (func) { \
569 ffuncs->get.f.name = func; \
570 ffuncs->user_data.name = user_data; \
571 ffuncs->destroy.name = destroy; \
572 } else { \
573 ffuncs->get.f.name = hb_font_get_##name##_parent; \
574 ffuncs->user_data.name = NULL; \
575 ffuncs->destroy.name = NULL; \
576 } \
577 }
578
579 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
580 #undef HB_FONT_FUNC_IMPLEMENT
581
582 bool
has_func(unsigned int i)583 hb_font_t::has_func (unsigned int i)
584 {
585 if (parent && parent != hb_font_get_empty () && parent->has_func (i))
586 return true;
587 return this->klass->get.array[i] != _hb_font_funcs_parent.get.array[i];
588 }
589
590 /* Public getters */
591
592 /**
593 * hb_font_get_h_extents:
594 * @font: a font.
595 * @extents: (out):
596 *
597 *
598 *
599 * Return value:
600 *
601 * Since: 1.1.3
602 **/
603 hb_bool_t
hb_font_get_h_extents(hb_font_t * font,hb_font_extents_t * extents)604 hb_font_get_h_extents (hb_font_t *font,
605 hb_font_extents_t *extents)
606 {
607 return font->get_font_h_extents (extents);
608 }
609
610 /**
611 * hb_font_get_v_extents:
612 * @font: a font.
613 * @extents: (out):
614 *
615 *
616 *
617 * Return value:
618 *
619 * Since: 1.1.3
620 **/
621 hb_bool_t
hb_font_get_v_extents(hb_font_t * font,hb_font_extents_t * extents)622 hb_font_get_v_extents (hb_font_t *font,
623 hb_font_extents_t *extents)
624 {
625 return font->get_font_v_extents (extents);
626 }
627
628 /**
629 * hb_font_get_glyph:
630 * @font: a font.
631 * @unicode:
632 * @variation_selector:
633 * @glyph: (out):
634 *
635 *
636 *
637 * Return value:
638 *
639 * Since: 0.9.2
640 **/
641 hb_bool_t
hb_font_get_glyph(hb_font_t * font,hb_codepoint_t unicode,hb_codepoint_t variation_selector,hb_codepoint_t * glyph)642 hb_font_get_glyph (hb_font_t *font,
643 hb_codepoint_t unicode, hb_codepoint_t variation_selector,
644 hb_codepoint_t *glyph)
645 {
646 if (unlikely (variation_selector))
647 return font->get_variation_glyph (unicode, variation_selector, glyph);
648 return font->get_nominal_glyph (unicode, glyph);
649 }
650
651 /**
652 * hb_font_get_nominal_glyph:
653 * @font: a font.
654 * @unicode:
655 * @glyph: (out):
656 *
657 *
658 *
659 * Return value:
660 *
661 * Since: 1.2.3
662 **/
663 hb_bool_t
hb_font_get_nominal_glyph(hb_font_t * font,hb_codepoint_t unicode,hb_codepoint_t * glyph)664 hb_font_get_nominal_glyph (hb_font_t *font,
665 hb_codepoint_t unicode,
666 hb_codepoint_t *glyph)
667 {
668 return font->get_nominal_glyph (unicode, glyph);
669 }
670
671 /**
672 * hb_font_get_variation_glyph:
673 * @font: a font.
674 * @unicode:
675 * @variation_selector:
676 * @glyph: (out):
677 *
678 *
679 *
680 * Return value:
681 *
682 * Since: 1.2.3
683 **/
684 hb_bool_t
hb_font_get_variation_glyph(hb_font_t * font,hb_codepoint_t unicode,hb_codepoint_t variation_selector,hb_codepoint_t * glyph)685 hb_font_get_variation_glyph (hb_font_t *font,
686 hb_codepoint_t unicode, hb_codepoint_t variation_selector,
687 hb_codepoint_t *glyph)
688 {
689 return font->get_variation_glyph (unicode, variation_selector, glyph);
690 }
691
692 /**
693 * hb_font_get_glyph_h_advance:
694 * @font: a font.
695 * @glyph:
696 *
697 *
698 *
699 * Return value:
700 *
701 * Since: 0.9.2
702 **/
703 hb_position_t
hb_font_get_glyph_h_advance(hb_font_t * font,hb_codepoint_t glyph)704 hb_font_get_glyph_h_advance (hb_font_t *font,
705 hb_codepoint_t glyph)
706 {
707 return font->get_glyph_h_advance (glyph);
708 }
709
710 /**
711 * hb_font_get_glyph_v_advance:
712 * @font: a font.
713 * @glyph:
714 *
715 *
716 *
717 * Return value:
718 *
719 * Since: 0.9.2
720 **/
721 hb_position_t
hb_font_get_glyph_v_advance(hb_font_t * font,hb_codepoint_t glyph)722 hb_font_get_glyph_v_advance (hb_font_t *font,
723 hb_codepoint_t glyph)
724 {
725 return font->get_glyph_v_advance (glyph);
726 }
727
728 /**
729 * hb_font_get_glyph_h_origin:
730 * @font: a font.
731 * @glyph:
732 * @x: (out):
733 * @y: (out):
734 *
735 *
736 *
737 * Return value:
738 *
739 * Since: 0.9.2
740 **/
741 hb_bool_t
hb_font_get_glyph_h_origin(hb_font_t * font,hb_codepoint_t glyph,hb_position_t * x,hb_position_t * y)742 hb_font_get_glyph_h_origin (hb_font_t *font,
743 hb_codepoint_t glyph,
744 hb_position_t *x, hb_position_t *y)
745 {
746 return font->get_glyph_h_origin (glyph, x, y);
747 }
748
749 /**
750 * hb_font_get_glyph_v_origin:
751 * @font: a font.
752 * @glyph:
753 * @x: (out):
754 * @y: (out):
755 *
756 *
757 *
758 * Return value:
759 *
760 * Since: 0.9.2
761 **/
762 hb_bool_t
hb_font_get_glyph_v_origin(hb_font_t * font,hb_codepoint_t glyph,hb_position_t * x,hb_position_t * y)763 hb_font_get_glyph_v_origin (hb_font_t *font,
764 hb_codepoint_t glyph,
765 hb_position_t *x, hb_position_t *y)
766 {
767 return font->get_glyph_v_origin (glyph, x, y);
768 }
769
770 /**
771 * hb_font_get_glyph_h_kerning:
772 * @font: a font.
773 * @left_glyph:
774 * @right_glyph:
775 *
776 *
777 *
778 * Return value:
779 *
780 * Since: 0.9.2
781 **/
782 hb_position_t
hb_font_get_glyph_h_kerning(hb_font_t * font,hb_codepoint_t left_glyph,hb_codepoint_t right_glyph)783 hb_font_get_glyph_h_kerning (hb_font_t *font,
784 hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
785 {
786 return font->get_glyph_h_kerning (left_glyph, right_glyph);
787 }
788
789 /**
790 * hb_font_get_glyph_v_kerning:
791 * @font: a font.
792 * @top_glyph:
793 * @bottom_glyph:
794 *
795 *
796 *
797 * Return value:
798 *
799 * Since: 0.9.2
800 **/
801 hb_position_t
hb_font_get_glyph_v_kerning(hb_font_t * font,hb_codepoint_t top_glyph,hb_codepoint_t bottom_glyph)802 hb_font_get_glyph_v_kerning (hb_font_t *font,
803 hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
804 {
805 return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
806 }
807
808 /**
809 * hb_font_get_glyph_extents:
810 * @font: a font.
811 * @glyph:
812 * @extents: (out):
813 *
814 *
815 *
816 * Return value:
817 *
818 * Since: 0.9.2
819 **/
820 hb_bool_t
hb_font_get_glyph_extents(hb_font_t * font,hb_codepoint_t glyph,hb_glyph_extents_t * extents)821 hb_font_get_glyph_extents (hb_font_t *font,
822 hb_codepoint_t glyph,
823 hb_glyph_extents_t *extents)
824 {
825 return font->get_glyph_extents (glyph, extents);
826 }
827
828 /**
829 * hb_font_get_glyph_contour_point:
830 * @font: a font.
831 * @glyph:
832 * @point_index:
833 * @x: (out):
834 * @y: (out):
835 *
836 *
837 *
838 * Return value:
839 *
840 * Since: 0.9.2
841 **/
842 hb_bool_t
hb_font_get_glyph_contour_point(hb_font_t * font,hb_codepoint_t glyph,unsigned int point_index,hb_position_t * x,hb_position_t * y)843 hb_font_get_glyph_contour_point (hb_font_t *font,
844 hb_codepoint_t glyph, unsigned int point_index,
845 hb_position_t *x, hb_position_t *y)
846 {
847 return font->get_glyph_contour_point (glyph, point_index, x, y);
848 }
849
850 /**
851 * hb_font_get_glyph_name:
852 * @font: a font.
853 * @glyph:
854 * @name: (array length=size):
855 * @size:
856 *
857 *
858 *
859 * Return value:
860 *
861 * Since: 0.9.2
862 **/
863 hb_bool_t
hb_font_get_glyph_name(hb_font_t * font,hb_codepoint_t glyph,char * name,unsigned int size)864 hb_font_get_glyph_name (hb_font_t *font,
865 hb_codepoint_t glyph,
866 char *name, unsigned int size)
867 {
868 return font->get_glyph_name (glyph, name, size);
869 }
870
871 /**
872 * hb_font_get_glyph_from_name:
873 * @font: a font.
874 * @name: (array length=len):
875 * @len:
876 * @glyph: (out):
877 *
878 *
879 *
880 * Return value:
881 *
882 * Since: 0.9.2
883 **/
884 hb_bool_t
hb_font_get_glyph_from_name(hb_font_t * font,const char * name,int len,hb_codepoint_t * glyph)885 hb_font_get_glyph_from_name (hb_font_t *font,
886 const char *name, int len, /* -1 means nul-terminated */
887 hb_codepoint_t *glyph)
888 {
889 return font->get_glyph_from_name (name, len, glyph);
890 }
891
892
893 /* A bit higher-level, and with fallback */
894
895 /**
896 * hb_font_get_extents_for_direction:
897 * @font: a font.
898 * @direction:
899 * @extents:
900 *
901 *
902 *
903 * Since: 1.1.3
904 **/
905 void
hb_font_get_extents_for_direction(hb_font_t * font,hb_direction_t direction,hb_font_extents_t * extents)906 hb_font_get_extents_for_direction (hb_font_t *font,
907 hb_direction_t direction,
908 hb_font_extents_t *extents)
909 {
910 return font->get_extents_for_direction (direction, extents);
911 }
912 /**
913 * hb_font_get_glyph_advance_for_direction:
914 * @font: a font.
915 * @glyph:
916 * @direction:
917 * @x: (out):
918 * @y: (out):
919 *
920 *
921 *
922 * Since: 0.9.2
923 **/
924 void
hb_font_get_glyph_advance_for_direction(hb_font_t * font,hb_codepoint_t glyph,hb_direction_t direction,hb_position_t * x,hb_position_t * y)925 hb_font_get_glyph_advance_for_direction (hb_font_t *font,
926 hb_codepoint_t glyph,
927 hb_direction_t direction,
928 hb_position_t *x, hb_position_t *y)
929 {
930 return font->get_glyph_advance_for_direction (glyph, direction, x, y);
931 }
932
933 /**
934 * hb_font_get_glyph_origin_for_direction:
935 * @font: a font.
936 * @glyph:
937 * @direction:
938 * @x: (out):
939 * @y: (out):
940 *
941 *
942 *
943 * Since: 0.9.2
944 **/
945 void
hb_font_get_glyph_origin_for_direction(hb_font_t * font,hb_codepoint_t glyph,hb_direction_t direction,hb_position_t * x,hb_position_t * y)946 hb_font_get_glyph_origin_for_direction (hb_font_t *font,
947 hb_codepoint_t glyph,
948 hb_direction_t direction,
949 hb_position_t *x, hb_position_t *y)
950 {
951 return font->get_glyph_origin_for_direction (glyph, direction, x, y);
952 }
953
954 /**
955 * hb_font_add_glyph_origin_for_direction:
956 * @font: a font.
957 * @glyph:
958 * @direction:
959 * @x: (out):
960 * @y: (out):
961 *
962 *
963 *
964 * Since: 0.9.2
965 **/
966 void
hb_font_add_glyph_origin_for_direction(hb_font_t * font,hb_codepoint_t glyph,hb_direction_t direction,hb_position_t * x,hb_position_t * y)967 hb_font_add_glyph_origin_for_direction (hb_font_t *font,
968 hb_codepoint_t glyph,
969 hb_direction_t direction,
970 hb_position_t *x, hb_position_t *y)
971 {
972 return font->add_glyph_origin_for_direction (glyph, direction, x, y);
973 }
974
975 /**
976 * hb_font_subtract_glyph_origin_for_direction:
977 * @font: a font.
978 * @glyph:
979 * @direction:
980 * @x: (out):
981 * @y: (out):
982 *
983 *
984 *
985 * Since: 0.9.2
986 **/
987 void
hb_font_subtract_glyph_origin_for_direction(hb_font_t * font,hb_codepoint_t glyph,hb_direction_t direction,hb_position_t * x,hb_position_t * y)988 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
989 hb_codepoint_t glyph,
990 hb_direction_t direction,
991 hb_position_t *x, hb_position_t *y)
992 {
993 return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
994 }
995
996 /**
997 * hb_font_get_glyph_kerning_for_direction:
998 * @font: a font.
999 * @first_glyph:
1000 * @second_glyph:
1001 * @direction:
1002 * @x: (out):
1003 * @y: (out):
1004 *
1005 *
1006 *
1007 * Since: 0.9.2
1008 **/
1009 void
hb_font_get_glyph_kerning_for_direction(hb_font_t * font,hb_codepoint_t first_glyph,hb_codepoint_t second_glyph,hb_direction_t direction,hb_position_t * x,hb_position_t * y)1010 hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
1011 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
1012 hb_direction_t direction,
1013 hb_position_t *x, hb_position_t *y)
1014 {
1015 return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
1016 }
1017
1018 /**
1019 * hb_font_get_glyph_extents_for_origin:
1020 * @font: a font.
1021 * @glyph:
1022 * @direction:
1023 * @extents: (out):
1024 *
1025 *
1026 *
1027 * Return value:
1028 *
1029 * Since: 0.9.2
1030 **/
1031 hb_bool_t
hb_font_get_glyph_extents_for_origin(hb_font_t * font,hb_codepoint_t glyph,hb_direction_t direction,hb_glyph_extents_t * extents)1032 hb_font_get_glyph_extents_for_origin (hb_font_t *font,
1033 hb_codepoint_t glyph,
1034 hb_direction_t direction,
1035 hb_glyph_extents_t *extents)
1036 {
1037 return font->get_glyph_extents_for_origin (glyph, direction, extents);
1038 }
1039
1040 /**
1041 * hb_font_get_glyph_contour_point_for_origin:
1042 * @font: a font.
1043 * @glyph:
1044 * @point_index:
1045 * @direction:
1046 * @x: (out):
1047 * @y: (out):
1048 *
1049 *
1050 *
1051 * Return value:
1052 *
1053 * Since: 0.9.2
1054 **/
1055 hb_bool_t
hb_font_get_glyph_contour_point_for_origin(hb_font_t * font,hb_codepoint_t glyph,unsigned int point_index,hb_direction_t direction,hb_position_t * x,hb_position_t * y)1056 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
1057 hb_codepoint_t glyph, unsigned int point_index,
1058 hb_direction_t direction,
1059 hb_position_t *x, hb_position_t *y)
1060 {
1061 return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
1062 }
1063
1064 /* Generates gidDDD if glyph has no name. */
1065 /**
1066 * hb_font_glyph_to_string:
1067 * @font: a font.
1068 * @glyph:
1069 * @s: (array length=size):
1070 * @size:
1071 *
1072 *
1073 *
1074 * Since: 0.9.2
1075 **/
1076 void
hb_font_glyph_to_string(hb_font_t * font,hb_codepoint_t glyph,char * s,unsigned int size)1077 hb_font_glyph_to_string (hb_font_t *font,
1078 hb_codepoint_t glyph,
1079 char *s, unsigned int size)
1080 {
1081 font->glyph_to_string (glyph, s, size);
1082 }
1083
1084 /* Parses gidDDD and uniUUUU strings automatically. */
1085 /**
1086 * hb_font_glyph_from_string:
1087 * @font: a font.
1088 * @s: (array length=len) (element-type uint8_t):
1089 * @len:
1090 * @glyph: (out):
1091 *
1092 *
1093 *
1094 * Return value:
1095 *
1096 * Since: 0.9.2
1097 **/
1098 hb_bool_t
hb_font_glyph_from_string(hb_font_t * font,const char * s,int len,hb_codepoint_t * glyph)1099 hb_font_glyph_from_string (hb_font_t *font,
1100 const char *s, int len, /* -1 means nul-terminated */
1101 hb_codepoint_t *glyph)
1102 {
1103 return font->glyph_from_string (s, len, glyph);
1104 }
1105
1106
1107 /*
1108 * hb_font_t
1109 */
1110
1111 /**
1112 * hb_font_create: (Xconstructor)
1113 * @face: a face.
1114 *
1115 *
1116 *
1117 * Return value: (transfer full):
1118 *
1119 * Since: 0.9.2
1120 **/
1121 hb_font_t *
hb_font_create(hb_face_t * face)1122 hb_font_create (hb_face_t *face)
1123 {
1124 hb_font_t *font;
1125
1126 if (unlikely (!face))
1127 face = hb_face_get_empty ();
1128 if (!(font = hb_object_create<hb_font_t> ()))
1129 return hb_font_get_empty ();
1130
1131 hb_face_make_immutable (face);
1132 font->parent = hb_font_get_empty ();
1133 font->face = hb_face_reference (face);
1134 font->klass = hb_font_funcs_get_empty ();
1135
1136 font->x_scale = font->y_scale = hb_face_get_upem (face);
1137
1138 return font;
1139 }
1140
1141 /**
1142 * hb_font_create_sub_font:
1143 * @parent: parent font.
1144 *
1145 *
1146 *
1147 * Return value: (transfer full):
1148 *
1149 * Since: 0.9.2
1150 **/
1151 hb_font_t *
hb_font_create_sub_font(hb_font_t * parent)1152 hb_font_create_sub_font (hb_font_t *parent)
1153 {
1154 if (unlikely (!parent))
1155 parent = hb_font_get_empty ();
1156
1157 hb_font_t *font = hb_font_create (parent->face);
1158
1159 if (unlikely (hb_object_is_inert (font)))
1160 return font;
1161
1162 font->parent = hb_font_reference (parent);
1163
1164 font->x_scale = parent->x_scale;
1165 font->y_scale = parent->y_scale;
1166 font->x_ppem = parent->x_ppem;
1167 font->y_ppem = parent->y_ppem;
1168
1169 return font;
1170 }
1171
1172 /**
1173 * hb_font_get_empty:
1174 *
1175 *
1176 *
1177 * Return value: (transfer full)
1178 *
1179 * Since: 0.9.2
1180 **/
1181 hb_font_t *
hb_font_get_empty(void)1182 hb_font_get_empty (void)
1183 {
1184 static const hb_font_t _hb_font_nil = {
1185 HB_OBJECT_HEADER_STATIC,
1186
1187 true, /* immutable */
1188
1189 NULL, /* parent */
1190 const_cast<hb_face_t *> (&_hb_face_nil),
1191
1192 1000, /* x_scale */
1193 1000, /* y_scale */
1194
1195 0, /* x_ppem */
1196 0, /* y_ppem */
1197
1198 const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
1199 NULL, /* user_data */
1200 NULL, /* destroy */
1201
1202 {
1203 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
1204 #include "hb-shaper-list.hh"
1205 #undef HB_SHAPER_IMPLEMENT
1206 }
1207 };
1208
1209 return const_cast<hb_font_t *> (&_hb_font_nil);
1210 }
1211
1212 /**
1213 * hb_font_reference: (skip)
1214 * @font: a font.
1215 *
1216 *
1217 *
1218 * Return value: (transfer full):
1219 *
1220 * Since: 0.9.2
1221 **/
1222 hb_font_t *
hb_font_reference(hb_font_t * font)1223 hb_font_reference (hb_font_t *font)
1224 {
1225 return hb_object_reference (font);
1226 }
1227
1228 /**
1229 * hb_font_destroy: (skip)
1230 * @font: a font.
1231 *
1232 *
1233 *
1234 * Since: 0.9.2
1235 **/
1236 void
hb_font_destroy(hb_font_t * font)1237 hb_font_destroy (hb_font_t *font)
1238 {
1239 if (!hb_object_destroy (font)) return;
1240
1241 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font);
1242 #include "hb-shaper-list.hh"
1243 #undef HB_SHAPER_IMPLEMENT
1244
1245 if (font->destroy)
1246 font->destroy (font->user_data);
1247
1248 hb_font_destroy (font->parent);
1249 hb_face_destroy (font->face);
1250 hb_font_funcs_destroy (font->klass);
1251
1252 free (font);
1253 }
1254
1255 /**
1256 * hb_font_set_user_data: (skip)
1257 * @font: a font.
1258 * @key:
1259 * @data:
1260 * @destroy:
1261 * @replace:
1262 *
1263 *
1264 *
1265 * Return value:
1266 *
1267 * Since: 0.9.2
1268 **/
1269 hb_bool_t
hb_font_set_user_data(hb_font_t * font,hb_user_data_key_t * key,void * data,hb_destroy_func_t destroy,hb_bool_t replace)1270 hb_font_set_user_data (hb_font_t *font,
1271 hb_user_data_key_t *key,
1272 void * data,
1273 hb_destroy_func_t destroy,
1274 hb_bool_t replace)
1275 {
1276 return hb_object_set_user_data (font, key, data, destroy, replace);
1277 }
1278
1279 /**
1280 * hb_font_get_user_data: (skip)
1281 * @font: a font.
1282 * @key:
1283 *
1284 *
1285 *
1286 * Return value: (transfer none):
1287 *
1288 * Since: 0.9.2
1289 **/
1290 void *
hb_font_get_user_data(hb_font_t * font,hb_user_data_key_t * key)1291 hb_font_get_user_data (hb_font_t *font,
1292 hb_user_data_key_t *key)
1293 {
1294 return hb_object_get_user_data (font, key);
1295 }
1296
1297 /**
1298 * hb_font_make_immutable:
1299 * @font: a font.
1300 *
1301 *
1302 *
1303 * Since: 0.9.2
1304 **/
1305 void
hb_font_make_immutable(hb_font_t * font)1306 hb_font_make_immutable (hb_font_t *font)
1307 {
1308 if (unlikely (hb_object_is_inert (font)))
1309 return;
1310
1311 if (font->parent)
1312 hb_font_make_immutable (font->parent);
1313
1314 font->immutable = true;
1315 }
1316
1317 /**
1318 * hb_font_is_immutable:
1319 * @font: a font.
1320 *
1321 *
1322 *
1323 * Return value:
1324 *
1325 * Since: 0.9.2
1326 **/
1327 hb_bool_t
hb_font_is_immutable(hb_font_t * font)1328 hb_font_is_immutable (hb_font_t *font)
1329 {
1330 return font->immutable;
1331 }
1332
1333 /**
1334 * hb_font_set_parent:
1335 * @font: a font.
1336 * @parent: new parent.
1337 *
1338 * Sets parent font of @font.
1339 *
1340 * Since: 1.0.5
1341 **/
1342 void
hb_font_set_parent(hb_font_t * font,hb_font_t * parent)1343 hb_font_set_parent (hb_font_t *font,
1344 hb_font_t *parent)
1345 {
1346 if (font->immutable)
1347 return;
1348
1349 if (!parent)
1350 parent = hb_font_get_empty ();
1351
1352 hb_font_t *old = font->parent;
1353
1354 font->parent = hb_font_reference (parent);
1355
1356 hb_font_destroy (old);
1357 }
1358
1359 /**
1360 * hb_font_get_parent:
1361 * @font: a font.
1362 *
1363 *
1364 *
1365 * Return value: (transfer none):
1366 *
1367 * Since: 0.9.2
1368 **/
1369 hb_font_t *
hb_font_get_parent(hb_font_t * font)1370 hb_font_get_parent (hb_font_t *font)
1371 {
1372 return font->parent;
1373 }
1374
1375 /**
1376 * hb_font_get_face:
1377 * @font: a font.
1378 *
1379 *
1380 *
1381 * Return value: (transfer none):
1382 *
1383 * Since: 0.9.2
1384 **/
1385 hb_face_t *
hb_font_get_face(hb_font_t * font)1386 hb_font_get_face (hb_font_t *font)
1387 {
1388 return font->face;
1389 }
1390
1391
1392 /**
1393 * hb_font_set_funcs:
1394 * @font: a font.
1395 * @klass: (closure font_data) (destroy destroy) (scope notified):
1396 * @font_data:
1397 * @destroy:
1398 *
1399 *
1400 *
1401 * Since: 0.9.2
1402 **/
1403 void
hb_font_set_funcs(hb_font_t * font,hb_font_funcs_t * klass,void * font_data,hb_destroy_func_t destroy)1404 hb_font_set_funcs (hb_font_t *font,
1405 hb_font_funcs_t *klass,
1406 void *font_data,
1407 hb_destroy_func_t destroy)
1408 {
1409 if (font->immutable) {
1410 if (destroy)
1411 destroy (font_data);
1412 return;
1413 }
1414
1415 if (font->destroy)
1416 font->destroy (font->user_data);
1417
1418 if (!klass)
1419 klass = hb_font_funcs_get_empty ();
1420
1421 hb_font_funcs_reference (klass);
1422 hb_font_funcs_destroy (font->klass);
1423 font->klass = klass;
1424 font->user_data = font_data;
1425 font->destroy = destroy;
1426 }
1427
1428 /**
1429 * hb_font_set_funcs_data:
1430 * @font: a font.
1431 * @font_data: (destroy destroy) (scope notified):
1432 * @destroy:
1433 *
1434 *
1435 *
1436 * Since: 0.9.2
1437 **/
1438 void
hb_font_set_funcs_data(hb_font_t * font,void * font_data,hb_destroy_func_t destroy)1439 hb_font_set_funcs_data (hb_font_t *font,
1440 void *font_data,
1441 hb_destroy_func_t destroy)
1442 {
1443 /* Destroy user_data? */
1444 if (font->immutable) {
1445 if (destroy)
1446 destroy (font_data);
1447 return;
1448 }
1449
1450 if (font->destroy)
1451 font->destroy (font->user_data);
1452
1453 font->user_data = font_data;
1454 font->destroy = destroy;
1455 }
1456
1457
1458 /**
1459 * hb_font_set_scale:
1460 * @font: a font.
1461 * @x_scale:
1462 * @y_scale:
1463 *
1464 *
1465 *
1466 * Since: 0.9.2
1467 **/
1468 void
hb_font_set_scale(hb_font_t * font,int x_scale,int y_scale)1469 hb_font_set_scale (hb_font_t *font,
1470 int x_scale,
1471 int y_scale)
1472 {
1473 if (font->immutable)
1474 return;
1475
1476 font->x_scale = x_scale;
1477 font->y_scale = y_scale;
1478 }
1479
1480 /**
1481 * hb_font_get_scale:
1482 * @font: a font.
1483 * @x_scale: (out):
1484 * @y_scale: (out):
1485 *
1486 *
1487 *
1488 * Since: 0.9.2
1489 **/
1490 void
hb_font_get_scale(hb_font_t * font,int * x_scale,int * y_scale)1491 hb_font_get_scale (hb_font_t *font,
1492 int *x_scale,
1493 int *y_scale)
1494 {
1495 if (x_scale) *x_scale = font->x_scale;
1496 if (y_scale) *y_scale = font->y_scale;
1497 }
1498
1499 /**
1500 * hb_font_set_ppem:
1501 * @font: a font.
1502 * @x_ppem:
1503 * @y_ppem:
1504 *
1505 *
1506 *
1507 * Since: 0.9.2
1508 **/
1509 void
hb_font_set_ppem(hb_font_t * font,unsigned int x_ppem,unsigned int y_ppem)1510 hb_font_set_ppem (hb_font_t *font,
1511 unsigned int x_ppem,
1512 unsigned int y_ppem)
1513 {
1514 if (font->immutable)
1515 return;
1516
1517 font->x_ppem = x_ppem;
1518 font->y_ppem = y_ppem;
1519 }
1520
1521 /**
1522 * hb_font_get_ppem:
1523 * @font: a font.
1524 * @x_ppem: (out):
1525 * @y_ppem: (out):
1526 *
1527 *
1528 *
1529 * Since: 0.9.2
1530 **/
1531 void
hb_font_get_ppem(hb_font_t * font,unsigned int * x_ppem,unsigned int * y_ppem)1532 hb_font_get_ppem (hb_font_t *font,
1533 unsigned int *x_ppem,
1534 unsigned int *y_ppem)
1535 {
1536 if (x_ppem) *x_ppem = font->x_ppem;
1537 if (y_ppem) *y_ppem = font->y_ppem;
1538 }
1539
1540
1541 #ifndef HB_DISABLE_DEPRECATED
1542
1543 /*
1544 * Deprecated get_glyph_func():
1545 */
1546
1547 struct hb_trampoline_closure_t
1548 {
1549 void *user_data;
1550 hb_destroy_func_t destroy;
1551 unsigned int ref_count;
1552 };
1553
1554 template <typename FuncType>
1555 struct hb_trampoline_t
1556 {
1557 hb_trampoline_closure_t closure; /* Must be first. */
1558 FuncType func;
1559 };
1560
1561 template <typename FuncType>
1562 static hb_trampoline_t<FuncType> *
trampoline_create(FuncType func,void * user_data,hb_destroy_func_t destroy)1563 trampoline_create (FuncType func,
1564 void *user_data,
1565 hb_destroy_func_t destroy)
1566 {
1567 typedef hb_trampoline_t<FuncType> trampoline_t;
1568
1569 trampoline_t *trampoline = (trampoline_t *) calloc (1, sizeof (trampoline_t));
1570
1571 if (unlikely (!trampoline))
1572 return NULL;
1573
1574 trampoline->closure.user_data = user_data;
1575 trampoline->closure.destroy = destroy;
1576 trampoline->closure.ref_count = 1;
1577 trampoline->func = func;
1578
1579 return trampoline;
1580 }
1581
1582 static void
trampoline_reference(hb_trampoline_closure_t * closure)1583 trampoline_reference (hb_trampoline_closure_t *closure)
1584 {
1585 closure->ref_count++;
1586 }
1587
1588 static void
trampoline_destroy(void * user_data)1589 trampoline_destroy (void *user_data)
1590 {
1591 hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data;
1592
1593 if (--closure->ref_count)
1594 return;
1595
1596 if (closure->destroy)
1597 closure->destroy (closure->user_data);
1598 free (closure);
1599 }
1600
1601 typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t;
1602
1603 static hb_bool_t
hb_font_get_nominal_glyph_trampoline(hb_font_t * font,void * font_data,hb_codepoint_t unicode,hb_codepoint_t * glyph,void * user_data)1604 hb_font_get_nominal_glyph_trampoline (hb_font_t *font,
1605 void *font_data,
1606 hb_codepoint_t unicode,
1607 hb_codepoint_t *glyph,
1608 void *user_data)
1609 {
1610 hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
1611 return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data);
1612 }
1613
1614 static hb_bool_t
hb_font_get_variation_glyph_trampoline(hb_font_t * font,void * font_data,hb_codepoint_t unicode,hb_codepoint_t variation_selector,hb_codepoint_t * glyph,void * user_data)1615 hb_font_get_variation_glyph_trampoline (hb_font_t *font,
1616 void *font_data,
1617 hb_codepoint_t unicode,
1618 hb_codepoint_t variation_selector,
1619 hb_codepoint_t *glyph,
1620 void *user_data)
1621 {
1622 hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
1623 return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data);
1624 }
1625
1626 /**
1627 * hb_font_funcs_set_glyph_func:
1628 * @ffuncs: font functions.
1629 * @func: (closure user_data) (destroy destroy) (scope notified):
1630 * @user_data:
1631 * @destroy:
1632 *
1633 * Deprecated. Use hb_font_funcs_set_nominal_glyph_func() and
1634 * hb_font_funcs_set_variation_glyph_func() instead.
1635 *
1636 * Since: 0.9.2
1637 * Deprecated: 1.2.3
1638 **/
1639 void
hb_font_funcs_set_glyph_func(hb_font_funcs_t * ffuncs,hb_font_get_glyph_func_t func,void * user_data,hb_destroy_func_t destroy)1640 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
1641 hb_font_get_glyph_func_t func,
1642 void *user_data, hb_destroy_func_t destroy)
1643 {
1644 hb_font_get_glyph_trampoline_t *trampoline;
1645
1646 trampoline = trampoline_create (func, user_data, destroy);
1647 if (unlikely (!trampoline))
1648 {
1649 if (destroy)
1650 destroy (user_data);
1651 return;
1652 }
1653
1654 hb_font_funcs_set_nominal_glyph_func (ffuncs,
1655 hb_font_get_nominal_glyph_trampoline,
1656 trampoline,
1657 trampoline_destroy);
1658
1659 trampoline_reference (&trampoline->closure);
1660 hb_font_funcs_set_variation_glyph_func (ffuncs,
1661 hb_font_get_variation_glyph_trampoline,
1662 trampoline,
1663 trampoline_destroy);
1664 }
1665
1666 #endif /* HB_DISABLE_DEPRECATED */
1667