|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 * |
|
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 * |
|
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 * |
|
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 |
|
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 |
|
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 * |
|
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 |
|
358 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) |
|
359 { |
|
360 if (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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 * |
|
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 * |
|
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 * |
|
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 * |
|
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 |
|
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 |
|
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 * |
|
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 |
|
1035 hb_font_make_immutable (hb_font_t *font) |
|
1036 { |
|
1037 if (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 |
|
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 * |
|
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 * |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 } |