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-blob.h"
35 #include "hb-open-file-private.hh"
36 #include "hb-ot-head-table.hh"
37 #include "hb-ot-maxp-table.hh"
38
39 #include "hb-cache-private.hh"
40
41 #include <string.h>
42
43
44 /*
45 * hb_font_funcs_t
46 */
47
48 static hb_bool_t
hb_font_get_glyph_nil(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)49 hb_font_get_glyph_nil (hb_font_t *font,
50 void *font_data HB_UNUSED,
51 hb_codepoint_t unicode,
52 hb_codepoint_t variation_selector,
53 hb_codepoint_t *glyph,
54 void *user_data HB_UNUSED)
55 {
56 if (font->parent)
57 return font->parent->get_glyph (unicode, variation_selector, glyph);
58
59 *glyph = 0;
60 return false;
61 }
62
63 static hb_position_t
hb_font_get_glyph_h_advance_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,void * user_data HB_UNUSED)64 hb_font_get_glyph_h_advance_nil (hb_font_t *font,
65 void *font_data HB_UNUSED,
66 hb_codepoint_t glyph,
67 void *user_data HB_UNUSED)
68 {
69 if (font->parent)
70 return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
71
72 return font->x_scale;
73 }
74
75 static hb_position_t
hb_font_get_glyph_v_advance_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,void * user_data HB_UNUSED)76 hb_font_get_glyph_v_advance_nil (hb_font_t *font,
77 void *font_data HB_UNUSED,
78 hb_codepoint_t glyph,
79 void *user_data HB_UNUSED)
80 {
81 if (font->parent)
82 return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
83
84 return font->y_scale;
85 }
86
87 static hb_bool_t
hb_font_get_glyph_h_origin_nil(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)88 hb_font_get_glyph_h_origin_nil (hb_font_t *font,
89 void *font_data HB_UNUSED,
90 hb_codepoint_t glyph,
91 hb_position_t *x,
92 hb_position_t *y,
93 void *user_data HB_UNUSED)
94 {
95 if (font->parent) {
96 hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
97 if (ret)
98 font->parent_scale_position (x, y);
99 return ret;
100 }
101
102 *x = *y = 0;
103 return false;
104 }
105
106 static hb_bool_t
hb_font_get_glyph_v_origin_nil(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)107 hb_font_get_glyph_v_origin_nil (hb_font_t *font,
108 void *font_data HB_UNUSED,
109 hb_codepoint_t glyph,
110 hb_position_t *x,
111 hb_position_t *y,
112 void *user_data HB_UNUSED)
113 {
114 if (font->parent) {
115 hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
116 if (ret)
117 font->parent_scale_position (x, y);
118 return ret;
119 }
120
121 *x = *y = 0;
122 return false;
123 }
124
125 static hb_position_t
hb_font_get_glyph_h_kerning_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t left_glyph,hb_codepoint_t right_glyph,void * user_data HB_UNUSED)126 hb_font_get_glyph_h_kerning_nil (hb_font_t *font,
127 void *font_data HB_UNUSED,
128 hb_codepoint_t left_glyph,
129 hb_codepoint_t right_glyph,
130 void *user_data HB_UNUSED)
131 {
132 if (font->parent)
133 return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
134
135 return 0;
136 }
137
138 static hb_position_t
hb_font_get_glyph_v_kerning_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t top_glyph,hb_codepoint_t bottom_glyph,void * user_data HB_UNUSED)139 hb_font_get_glyph_v_kerning_nil (hb_font_t *font,
140 void *font_data HB_UNUSED,
141 hb_codepoint_t top_glyph,
142 hb_codepoint_t bottom_glyph,
143 void *user_data HB_UNUSED)
144 {
145 if (font->parent)
146 return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
147
148 return 0;
149 }
150
151 static hb_bool_t
hb_font_get_glyph_extents_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,hb_glyph_extents_t * extents,void * user_data HB_UNUSED)152 hb_font_get_glyph_extents_nil (hb_font_t *font,
153 void *font_data HB_UNUSED,
154 hb_codepoint_t glyph,
155 hb_glyph_extents_t *extents,
156 void *user_data HB_UNUSED)
157 {
158 if (font->parent) {
159 hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
160 if (ret) {
161 font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
162 font->parent_scale_distance (&extents->width, &extents->height);
163 }
164 return ret;
165 }
166
167 memset (extents, 0, sizeof (*extents));
168 return false;
169 }
170
171 static hb_bool_t
hb_font_get_glyph_contour_point_nil(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)172 hb_font_get_glyph_contour_point_nil (hb_font_t *font,
173 void *font_data HB_UNUSED,
174 hb_codepoint_t glyph,
175 unsigned int point_index,
176 hb_position_t *x,
177 hb_position_t *y,
178 void *user_data HB_UNUSED)
179 {
180 if (font->parent) {
181 hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y);
182 if (ret)
183 font->parent_scale_position (x, y);
184 return ret;
185 }
186
187 *x = *y = 0;
188 return false;
189 }
190
191 static hb_bool_t
hb_font_get_glyph_name_nil(hb_font_t * font,void * font_data HB_UNUSED,hb_codepoint_t glyph,char * name,unsigned int size,void * user_data HB_UNUSED)192 hb_font_get_glyph_name_nil (hb_font_t *font,
193 void *font_data HB_UNUSED,
194 hb_codepoint_t glyph,
195 char *name, unsigned int size,
196 void *user_data HB_UNUSED)
197 {
198 if (font->parent)
199 return font->parent->get_glyph_name (glyph, name, size);
200
201 if (size) *name = '\0';
202 return false;
203 }
204
205 static hb_bool_t
hb_font_get_glyph_from_name_nil(hb_font_t * font,void * font_data HB_UNUSED,const char * name,int len,hb_codepoint_t * glyph,void * user_data HB_UNUSED)206 hb_font_get_glyph_from_name_nil (hb_font_t *font,
207 void *font_data HB_UNUSED,
208 const char *name, int len, /* -1 means nul-terminated */
209 hb_codepoint_t *glyph,
210 void *user_data HB_UNUSED)
211 {
212 if (font->parent)
213 return font->parent->get_glyph_from_name (name, len, glyph);
214
215 *glyph = 0;
216 return false;
217 }
218
219
220 static const hb_font_funcs_t _hb_font_funcs_nil = {
221 HB_OBJECT_HEADER_STATIC,
222
223 true, /* immutable */
224
225 {
226 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
227 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
228 #undef HB_FONT_FUNC_IMPLEMENT
229 }
230 };
231
232
233 /**
234 * hb_font_funcs_create: (Xconstructor)
235 *
236 *
237 *
238 * Return value: (transfer full):
239 *
240 * Since: 1.0
241 **/
242 hb_font_funcs_t *
hb_font_funcs_create(void)243 hb_font_funcs_create (void)
244 {
245 hb_font_funcs_t *ffuncs;
246
247 if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
248 return hb_font_funcs_get_empty ();
249
250 ffuncs->get = _hb_font_funcs_nil.get;
251
252 return ffuncs;
253 }
254
255 /**
256 * hb_font_funcs_get_empty:
257 *
258 *
259 *
260 * Return value: (transfer full):
261 *
262 * Since: 1.0
263 **/
264 hb_font_funcs_t *
hb_font_funcs_get_empty(void)265 hb_font_funcs_get_empty (void)
266 {
267 return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil);
268 }
269
270 /**
271 * hb_font_funcs_reference: (skip)
272 * @ffuncs: font functions.
273 *
274 *
275 *
276 * Return value:
277 *
278 * Since: 1.0
279 **/
280 hb_font_funcs_t *
hb_font_funcs_reference(hb_font_funcs_t * ffuncs)281 hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
282 {
283 return hb_object_reference (ffuncs);
284 }
285
286 /**
287 * hb_font_funcs_destroy: (skip)
288 * @ffuncs: font functions.
289 *
290 *
291 *
292 * Since: 1.0
293 **/
294 void
hb_font_funcs_destroy(hb_font_funcs_t * ffuncs)295 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
296 {
297 if (!hb_object_destroy (ffuncs)) return;
298
299 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
300 ffuncs->destroy.name (ffuncs->user_data.name);
301 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
302 #undef HB_FONT_FUNC_IMPLEMENT
303
304 free (ffuncs);
305 }
306
307 /**
308 * hb_font_funcs_set_user_data: (skip)
309 * @ffuncs: font functions.
310 * @key:
311 * @data:
312 * @destroy:
313 * @replace:
314 *
315 *
316 *
317 * Return value:
318 *
319 * Since: 1.0
320 **/
321 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)322 hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
323 hb_user_data_key_t *key,
324 void * data,
325 hb_destroy_func_t destroy,
326 hb_bool_t replace)
327 {
328 return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
329 }
330
331 /**
332 * hb_font_funcs_get_user_data: (skip)
333 * @ffuncs: font functions.
334 * @key:
335 *
336 *
337 *
338 * Return value: (transfer none):
339 *
340 * Since: 1.0
341 **/
342 void *
hb_font_funcs_get_user_data(hb_font_funcs_t * ffuncs,hb_user_data_key_t * key)343 hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
344 hb_user_data_key_t *key)
345 {
346 return hb_object_get_user_data (ffuncs, key);
347 }
348
349
350 /**
351 * hb_font_funcs_make_immutable:
352 * @ffuncs: font functions.
353 *
354 *
355 *
356 * Since: 1.0
357 **/
358 void
hb_font_funcs_make_immutable(hb_font_funcs_t * ffuncs)359 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
360 {
361 if (hb_object_is_inert (ffuncs))
362 return;
363
364 ffuncs->immutable = true;
365 }
366
367 /**
368 * hb_font_funcs_is_immutable:
369 * @ffuncs: font functions.
370 *
371 *
372 *
373 * Return value:
374 *
375 * Since: 1.0
376 **/
377 hb_bool_t
hb_font_funcs_is_immutable(hb_font_funcs_t * ffuncs)378 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
379 {
380 return ffuncs->immutable;
381 }
382
383
384 #define HB_FONT_FUNC_IMPLEMENT(name) \
385 \
386 void \
387 hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \
388 hb_font_get_##name##_func_t func, \
389 void *user_data, \
390 hb_destroy_func_t destroy) \
391 { \
392 if (ffuncs->immutable) { \
393 if (destroy) \
394 destroy (user_data); \
395 return; \
396 } \
397 \
398 if (ffuncs->destroy.name) \
399 ffuncs->destroy.name (ffuncs->user_data.name); \
400 \
401 if (func) { \
402 ffuncs->get.name = func; \
403 ffuncs->user_data.name = user_data; \
404 ffuncs->destroy.name = destroy; \
405 } else { \
406 ffuncs->get.name = hb_font_get_##name##_nil; \
407 ffuncs->user_data.name = NULL; \
408 ffuncs->destroy.name = NULL; \
409 } \
410 }
411
412 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
413 #undef HB_FONT_FUNC_IMPLEMENT
414
415
416 /* Public getters */
417
418 /**
419 * hb_font_get_glyph:
420 * @font: a font.
421 * @unicode:
422 * @variation_selector:
423 * @glyph: (out):
424 *
425 *
426 *
427 * Return value:
428 *
429 * Since: 1.0
430 **/
431 hb_bool_t
hb_font_get_glyph(hb_font_t * font,hb_codepoint_t unicode,hb_codepoint_t variation_selector,hb_codepoint_t * glyph)432 hb_font_get_glyph (hb_font_t *font,
433 hb_codepoint_t unicode, hb_codepoint_t variation_selector,
434 hb_codepoint_t *glyph)
435 {
436 return font->get_glyph (unicode, variation_selector, glyph);
437 }
438
439 /**
440 * hb_font_get_glyph_h_advance:
441 * @font: a font.
442 * @glyph:
443 *
444 *
445 *
446 * Return value:
447 *
448 * Since: 1.0
449 **/
450 hb_position_t
hb_font_get_glyph_h_advance(hb_font_t * font,hb_codepoint_t glyph)451 hb_font_get_glyph_h_advance (hb_font_t *font,
452 hb_codepoint_t glyph)
453 {
454 return font->get_glyph_h_advance (glyph);
455 }
456
457 /**
458 * hb_font_get_glyph_v_advance:
459 * @font: a font.
460 * @glyph:
461 *
462 *
463 *
464 * Return value:
465 *
466 * Since: 1.0
467 **/
468 hb_position_t
hb_font_get_glyph_v_advance(hb_font_t * font,hb_codepoint_t glyph)469 hb_font_get_glyph_v_advance (hb_font_t *font,
470 hb_codepoint_t glyph)
471 {
472 return font->get_glyph_v_advance (glyph);
473 }
474
475 /**
476 * hb_font_get_glyph_h_origin:
477 * @font: a font.
478 * @glyph:
479 * @x: (out):
480 * @y: (out):
481 *
482 *
483 *
484 * Return value:
485 *
486 * Since: 1.0
487 **/
488 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)489 hb_font_get_glyph_h_origin (hb_font_t *font,
490 hb_codepoint_t glyph,
491 hb_position_t *x, hb_position_t *y)
492 {
493 return font->get_glyph_h_origin (glyph, x, y);
494 }
495
496 /**
497 * hb_font_get_glyph_v_origin:
498 * @font: a font.
499 * @glyph:
500 * @x: (out):
501 * @y: (out):
502 *
503 *
504 *
505 * Return value:
506 *
507 * Since: 1.0
508 **/
509 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)510 hb_font_get_glyph_v_origin (hb_font_t *font,
511 hb_codepoint_t glyph,
512 hb_position_t *x, hb_position_t *y)
513 {
514 return font->get_glyph_v_origin (glyph, x, y);
515 }
516
517 /**
518 * hb_font_get_glyph_h_kerning:
519 * @font: a font.
520 * @left_glyph:
521 * @right_glyph:
522 *
523 *
524 *
525 * Return value:
526 *
527 * Since: 1.0
528 **/
529 hb_position_t
hb_font_get_glyph_h_kerning(hb_font_t * font,hb_codepoint_t left_glyph,hb_codepoint_t right_glyph)530 hb_font_get_glyph_h_kerning (hb_font_t *font,
531 hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
532 {
533 return font->get_glyph_h_kerning (left_glyph, right_glyph);
534 }
535
536 /**
537 * hb_font_get_glyph_v_kerning:
538 * @font: a font.
539 * @top_glyph:
540 * @bottom_glyph:
541 *
542 *
543 *
544 * Return value:
545 *
546 * Since: 1.0
547 **/
548 hb_position_t
hb_font_get_glyph_v_kerning(hb_font_t * font,hb_codepoint_t top_glyph,hb_codepoint_t bottom_glyph)549 hb_font_get_glyph_v_kerning (hb_font_t *font,
550 hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
551 {
552 return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
553 }
554
555 /**
556 * hb_font_get_glyph_extents:
557 * @font: a font.
558 * @glyph:
559 * @extents: (out):
560 *
561 *
562 *
563 * Return value:
564 *
565 * Since: 1.0
566 **/
567 hb_bool_t
hb_font_get_glyph_extents(hb_font_t * font,hb_codepoint_t glyph,hb_glyph_extents_t * extents)568 hb_font_get_glyph_extents (hb_font_t *font,
569 hb_codepoint_t glyph,
570 hb_glyph_extents_t *extents)
571 {
572 return font->get_glyph_extents (glyph, extents);
573 }
574
575 /**
576 * hb_font_get_glyph_contour_point:
577 * @font: a font.
578 * @glyph:
579 * @point_index:
580 * @x: (out):
581 * @y: (out):
582 *
583 *
584 *
585 * Return value:
586 *
587 * Since: 1.0
588 **/
589 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)590 hb_font_get_glyph_contour_point (hb_font_t *font,
591 hb_codepoint_t glyph, unsigned int point_index,
592 hb_position_t *x, hb_position_t *y)
593 {
594 return font->get_glyph_contour_point (glyph, point_index, x, y);
595 }
596
597 /**
598 * hb_font_get_glyph_name:
599 * @font: a font.
600 * @glyph:
601 * @name: (array length=size):
602 * @size:
603 *
604 *
605 *
606 * Return value:
607 *
608 * Since: 1.0
609 **/
610 hb_bool_t
hb_font_get_glyph_name(hb_font_t * font,hb_codepoint_t glyph,char * name,unsigned int size)611 hb_font_get_glyph_name (hb_font_t *font,
612 hb_codepoint_t glyph,
613 char *name, unsigned int size)
614 {
615 return font->get_glyph_name (glyph, name, size);
616 }
617
618 /**
619 * hb_font_get_glyph_from_name:
620 * @font: a font.
621 * @name: (array length=len):
622 * @len:
623 * @glyph: (out):
624 *
625 *
626 *
627 * Return value:
628 *
629 * Since: 1.0
630 **/
631 hb_bool_t
hb_font_get_glyph_from_name(hb_font_t * font,const char * name,int len,hb_codepoint_t * glyph)632 hb_font_get_glyph_from_name (hb_font_t *font,
633 const char *name, int len, /* -1 means nul-terminated */
634 hb_codepoint_t *glyph)
635 {
636 return font->get_glyph_from_name (name, len, glyph);
637 }
638
639
640 /* A bit higher-level, and with fallback */
641
642 /**
643 * hb_font_get_glyph_advance_for_direction:
644 * @font: a font.
645 * @glyph:
646 * @direction:
647 * @x: (out):
648 * @y: (out):
649 *
650 *
651 *
652 * Since: 1.0
653 **/
654 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)655 hb_font_get_glyph_advance_for_direction (hb_font_t *font,
656 hb_codepoint_t glyph,
657 hb_direction_t direction,
658 hb_position_t *x, hb_position_t *y)
659 {
660 return font->get_glyph_advance_for_direction (glyph, direction, x, y);
661 }
662
663 /**
664 * hb_font_get_glyph_origin_for_direction:
665 * @font: a font.
666 * @glyph:
667 * @direction:
668 * @x: (out):
669 * @y: (out):
670 *
671 *
672 *
673 * Since: 1.0
674 **/
675 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)676 hb_font_get_glyph_origin_for_direction (hb_font_t *font,
677 hb_codepoint_t glyph,
678 hb_direction_t direction,
679 hb_position_t *x, hb_position_t *y)
680 {
681 return font->get_glyph_origin_for_direction (glyph, direction, x, y);
682 }
683
684 /**
685 * hb_font_add_glyph_origin_for_direction:
686 * @font: a font.
687 * @glyph:
688 * @direction:
689 * @x: (out):
690 * @y: (out):
691 *
692 *
693 *
694 * Since: 1.0
695 **/
696 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)697 hb_font_add_glyph_origin_for_direction (hb_font_t *font,
698 hb_codepoint_t glyph,
699 hb_direction_t direction,
700 hb_position_t *x, hb_position_t *y)
701 {
702 return font->add_glyph_origin_for_direction (glyph, direction, x, y);
703 }
704
705 /**
706 * hb_font_subtract_glyph_origin_for_direction:
707 * @font: a font.
708 * @glyph:
709 * @direction:
710 * @x: (out):
711 * @y: (out):
712 *
713 *
714 *
715 * Since: 1.0
716 **/
717 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)718 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
719 hb_codepoint_t glyph,
720 hb_direction_t direction,
721 hb_position_t *x, hb_position_t *y)
722 {
723 return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
724 }
725
726 /**
727 * hb_font_get_glyph_kerning_for_direction:
728 * @font: a font.
729 * @first_glyph:
730 * @second_glyph:
731 * @direction:
732 * @x: (out):
733 * @y: (out):
734 *
735 *
736 *
737 * Since: 1.0
738 **/
739 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)740 hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
741 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
742 hb_direction_t direction,
743 hb_position_t *x, hb_position_t *y)
744 {
745 return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
746 }
747
748 /**
749 * hb_font_get_glyph_extents_for_origin:
750 * @font: a font.
751 * @glyph:
752 * @direction:
753 * @extents: (out):
754 *
755 *
756 *
757 * Return value:
758 *
759 * Since: 1.0
760 **/
761 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)762 hb_font_get_glyph_extents_for_origin (hb_font_t *font,
763 hb_codepoint_t glyph,
764 hb_direction_t direction,
765 hb_glyph_extents_t *extents)
766 {
767 return font->get_glyph_extents_for_origin (glyph, direction, extents);
768 }
769
770 /**
771 * hb_font_get_glyph_contour_point_for_origin:
772 * @font: a font.
773 * @glyph:
774 * @point_index:
775 * @direction:
776 * @x: (out):
777 * @y: (out):
778 *
779 *
780 *
781 * Return value:
782 *
783 * Since: 1.0
784 **/
785 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)786 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
787 hb_codepoint_t glyph, unsigned int point_index,
788 hb_direction_t direction,
789 hb_position_t *x, hb_position_t *y)
790 {
791 return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
792 }
793
794 /* Generates gidDDD if glyph has no name. */
795 /**
796 * hb_font_glyph_to_string:
797 * @font: a font.
798 * @glyph:
799 * @s: (array length=size):
800 * @size:
801 *
802 *
803 *
804 * Since: 1.0
805 **/
806 void
hb_font_glyph_to_string(hb_font_t * font,hb_codepoint_t glyph,char * s,unsigned int size)807 hb_font_glyph_to_string (hb_font_t *font,
808 hb_codepoint_t glyph,
809 char *s, unsigned int size)
810 {
811 font->glyph_to_string (glyph, s, size);
812 }
813
814 /* Parses gidDDD and uniUUUU strings automatically. */
815 /**
816 * hb_font_glyph_from_string:
817 * @font: a font.
818 * @s: (array length=len):
819 * @len:
820 * @glyph: (out):
821 *
822 *
823 *
824 * Return value:
825 *
826 * Since: 1.0
827 **/
828 hb_bool_t
hb_font_glyph_from_string(hb_font_t * font,const char * s,int len,hb_codepoint_t * glyph)829 hb_font_glyph_from_string (hb_font_t *font,
830 const char *s, int len, /* -1 means nul-terminated */
831 hb_codepoint_t *glyph)
832 {
833 return font->glyph_from_string (s, len, glyph);
834 }
835
836
837 /*
838 * hb_font_t
839 */
840
841 /**
842 * hb_font_create: (Xconstructor)
843 * @face: a face.
844 *
845 *
846 *
847 * Return value: (transfer full):
848 *
849 * Since: 1.0
850 **/
851 hb_font_t *
hb_font_create(hb_face_t * face)852 hb_font_create (hb_face_t *face)
853 {
854 hb_font_t *font;
855
856 if (unlikely (!face))
857 face = hb_face_get_empty ();
858 if (unlikely (hb_object_is_inert (face)))
859 return hb_font_get_empty ();
860 if (!(font = hb_object_create<hb_font_t> ()))
861 return hb_font_get_empty ();
862
863 hb_face_make_immutable (face);
864 font->face = hb_face_reference (face);
865 font->klass = hb_font_funcs_get_empty ();
866
867 return font;
868 }
869
870 /**
871 * hb_font_create_sub_font:
872 * @parent: parent font.
873 *
874 *
875 *
876 * Return value: (transfer full):
877 *
878 * Since: 1.0
879 **/
880 hb_font_t *
hb_font_create_sub_font(hb_font_t * parent)881 hb_font_create_sub_font (hb_font_t *parent)
882 {
883 if (unlikely (!parent))
884 return hb_font_get_empty ();
885
886 hb_font_t *font = hb_font_create (parent->face);
887
888 if (unlikely (hb_object_is_inert (font)))
889 return font;
890
891 hb_font_make_immutable (parent);
892 font->parent = hb_font_reference (parent);
893
894 font->x_scale = parent->x_scale;
895 font->y_scale = parent->y_scale;
896 font->x_ppem = parent->x_ppem;
897 font->y_ppem = parent->y_ppem;
898
899 return font;
900 }
901
902 /**
903 * hb_font_get_empty:
904 *
905 *
906 *
907 * Return value: (transfer full)
908 *
909 * Since: 1.0
910 **/
911 hb_font_t *
hb_font_get_empty(void)912 hb_font_get_empty (void)
913 {
914 static const hb_font_t _hb_font_nil = {
915 HB_OBJECT_HEADER_STATIC,
916
917 true, /* immutable */
918
919 NULL, /* parent */
920 const_cast<hb_face_t *> (&_hb_face_nil),
921
922 0, /* x_scale */
923 0, /* y_scale */
924
925 0, /* x_ppem */
926 0, /* y_ppem */
927
928 const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
929 NULL, /* user_data */
930 NULL, /* destroy */
931
932 {
933 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
934 #include "hb-shaper-list.hh"
935 #undef HB_SHAPER_IMPLEMENT
936 }
937 };
938
939 return const_cast<hb_font_t *> (&_hb_font_nil);
940 }
941
942 /**
943 * hb_font_reference: (skip)
944 * @font: a font.
945 *
946 *
947 *
948 * Return value: (transfer full):
949 *
950 * Since: 1.0
951 **/
952 hb_font_t *
hb_font_reference(hb_font_t * font)953 hb_font_reference (hb_font_t *font)
954 {
955 return hb_object_reference (font);
956 }
957
958 /**
959 * hb_font_destroy: (skip)
960 * @font: a font.
961 *
962 *
963 *
964 * Since: 1.0
965 **/
966 void
hb_font_destroy(hb_font_t * font)967 hb_font_destroy (hb_font_t *font)
968 {
969 if (!hb_object_destroy (font)) return;
970
971 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font);
972 #include "hb-shaper-list.hh"
973 #undef HB_SHAPER_IMPLEMENT
974
975 if (font->destroy)
976 font->destroy (font->user_data);
977
978 hb_font_destroy (font->parent);
979 hb_face_destroy (font->face);
980 hb_font_funcs_destroy (font->klass);
981
982 free (font);
983 }
984
985 /**
986 * hb_font_set_user_data: (skip)
987 * @font: a font.
988 * @key:
989 * @data:
990 * @destroy:
991 * @replace:
992 *
993 *
994 *
995 * Return value:
996 *
997 * Since: 1.0
998 **/
999 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)1000 hb_font_set_user_data (hb_font_t *font,
1001 hb_user_data_key_t *key,
1002 void * data,
1003 hb_destroy_func_t destroy,
1004 hb_bool_t replace)
1005 {
1006 return hb_object_set_user_data (font, key, data, destroy, replace);
1007 }
1008
1009 /**
1010 * hb_font_get_user_data: (skip)
1011 * @font: a font.
1012 * @key:
1013 *
1014 *
1015 *
1016 * Return value: (transfer none):
1017 *
1018 * Since: 1.0
1019 **/
1020 void *
hb_font_get_user_data(hb_font_t * font,hb_user_data_key_t * key)1021 hb_font_get_user_data (hb_font_t *font,
1022 hb_user_data_key_t *key)
1023 {
1024 return hb_object_get_user_data (font, key);
1025 }
1026
1027 /**
1028 * hb_font_make_immutable:
1029 * @font: a font.
1030 *
1031 *
1032 *
1033 * Since: 1.0
1034 **/
1035 void
hb_font_make_immutable(hb_font_t * font)1036 hb_font_make_immutable (hb_font_t *font)
1037 {
1038 if (hb_object_is_inert (font))
1039 return;
1040
1041 font->immutable = true;
1042 }
1043
1044 /**
1045 * hb_font_is_immutable:
1046 * @font: a font.
1047 *
1048 *
1049 *
1050 * Return value:
1051 *
1052 * Since: 1.0
1053 **/
1054 hb_bool_t
hb_font_is_immutable(hb_font_t * font)1055 hb_font_is_immutable (hb_font_t *font)
1056 {
1057 return font->immutable;
1058 }
1059
1060 /**
1061 * hb_font_get_parent:
1062 * @font: a font.
1063 *
1064 *
1065 *
1066 * Return value: (transfer none):
1067 *
1068 * Since: 1.0
1069 **/
1070 hb_font_t *
hb_font_get_parent(hb_font_t * font)1071 hb_font_get_parent (hb_font_t *font)
1072 {
1073 return font->parent;
1074 }
1075
1076 /**
1077 * hb_font_get_face:
1078 * @font: a font.
1079 *
1080 *
1081 *
1082 * Return value: (transfer none):
1083 *
1084 * Since: 1.0
1085 **/
1086 hb_face_t *
hb_font_get_face(hb_font_t * font)1087 hb_font_get_face (hb_font_t *font)
1088 {
1089 return font->face;
1090 }
1091
1092
1093 /**
1094 * hb_font_set_funcs:
1095 * @font: a font.
1096 * @klass: (closure font_data) (destroy destroy) (scope notified):
1097 * @font_data:
1098 * @destroy:
1099 *
1100 *
1101 *
1102 * Since: 1.0
1103 **/
1104 void
hb_font_set_funcs(hb_font_t * font,hb_font_funcs_t * klass,void * font_data,hb_destroy_func_t destroy)1105 hb_font_set_funcs (hb_font_t *font,
1106 hb_font_funcs_t *klass,
1107 void *font_data,
1108 hb_destroy_func_t destroy)
1109 {
1110 if (font->immutable) {
1111 if (destroy)
1112 destroy (font_data);
1113 return;
1114 }
1115
1116 if (font->destroy)
1117 font->destroy (font->user_data);
1118
1119 if (!klass)
1120 klass = hb_font_funcs_get_empty ();
1121
1122 hb_font_funcs_reference (klass);
1123 hb_font_funcs_destroy (font->klass);
1124 font->klass = klass;
1125 font->user_data = font_data;
1126 font->destroy = destroy;
1127 }
1128
1129 /**
1130 * hb_font_set_funcs_data:
1131 * @font: a font.
1132 * @font_data: (destroy destroy) (scope notified):
1133 * @destroy:
1134 *
1135 *
1136 *
1137 * Since: 1.0
1138 **/
1139 void
hb_font_set_funcs_data(hb_font_t * font,void * font_data,hb_destroy_func_t destroy)1140 hb_font_set_funcs_data (hb_font_t *font,
1141 void *font_data,
1142 hb_destroy_func_t destroy)
1143 {
1144 /* Destroy user_data? */
1145 if (font->immutable) {
1146 if (destroy)
1147 destroy (font_data);
1148 return;
1149 }
1150
1151 if (font->destroy)
1152 font->destroy (font->user_data);
1153
1154 font->user_data = font_data;
1155 font->destroy = destroy;
1156 }
1157
1158
1159 /**
1160 * hb_font_set_scale:
1161 * @font: a font.
1162 * @x_scale:
1163 * @y_scale:
1164 *
1165 *
1166 *
1167 * Since: 1.0
1168 **/
1169 void
hb_font_set_scale(hb_font_t * font,int x_scale,int y_scale)1170 hb_font_set_scale (hb_font_t *font,
1171 int x_scale,
1172 int y_scale)
1173 {
1174 if (font->immutable)
1175 return;
1176
1177 font->x_scale = x_scale;
1178 font->y_scale = y_scale;
1179 }
1180
1181 /**
1182 * hb_font_get_scale:
1183 * @font: a font.
1184 * @x_scale: (out):
1185 * @y_scale: (out):
1186 *
1187 *
1188 *
1189 * Since: 1.0
1190 **/
1191 void
hb_font_get_scale(hb_font_t * font,int * x_scale,int * y_scale)1192 hb_font_get_scale (hb_font_t *font,
1193 int *x_scale,
1194 int *y_scale)
1195 {
1196 if (x_scale) *x_scale = font->x_scale;
1197 if (y_scale) *y_scale = font->y_scale;
1198 }
1199
1200 /**
1201 * hb_font_set_ppem:
1202 * @font: a font.
1203 * @x_ppem:
1204 * @y_ppem:
1205 *
1206 *
1207 *
1208 * Since: 1.0
1209 **/
1210 void
hb_font_set_ppem(hb_font_t * font,unsigned int x_ppem,unsigned int y_ppem)1211 hb_font_set_ppem (hb_font_t *font,
1212 unsigned int x_ppem,
1213 unsigned int y_ppem)
1214 {
1215 if (font->immutable)
1216 return;
1217
1218 font->x_ppem = x_ppem;
1219 font->y_ppem = y_ppem;
1220 }
1221
1222 /**
1223 * hb_font_get_ppem:
1224 * @font: a font.
1225 * @x_ppem: (out):
1226 * @y_ppem: (out):
1227 *
1228 *
1229 *
1230 * Since: 1.0
1231 **/
1232 void
hb_font_get_ppem(hb_font_t * font,unsigned int * x_ppem,unsigned int * y_ppem)1233 hb_font_get_ppem (hb_font_t *font,
1234 unsigned int *x_ppem,
1235 unsigned int *y_ppem)
1236 {
1237 if (x_ppem) *x_ppem = font->x_ppem;
1238 if (y_ppem) *y_ppem = font->y_ppem;
1239 }
1240