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