34 #include "hb-ot-cbdt-table.hh" |
34 #include "hb-ot-cbdt-table.hh" |
35 #include "hb-ot-glyf-table.hh" |
35 #include "hb-ot-glyf-table.hh" |
36 #include "hb-ot-head-table.hh" |
36 #include "hb-ot-head-table.hh" |
37 #include "hb-ot-hhea-table.hh" |
37 #include "hb-ot-hhea-table.hh" |
38 #include "hb-ot-hmtx-table.hh" |
38 #include "hb-ot-hmtx-table.hh" |
|
39 #include "hb-ot-kern-table.hh" |
39 #include "hb-ot-os2-table.hh" |
40 #include "hb-ot-os2-table.hh" |
40 //#include "hb-ot-post-table.hh" |
41 #include "hb-ot-post-table.hh" |
|
42 #include "hb-ot-var-hvar-table.hh" |
41 |
43 |
42 |
44 |
43 struct hb_ot_face_metrics_accelerator_t |
45 struct hb_ot_face_metrics_accelerator_t |
44 { |
46 { |
45 unsigned int num_metrics; |
47 unsigned int num_metrics; |
48 unsigned short ascender; |
50 unsigned short ascender; |
49 unsigned short descender; |
51 unsigned short descender; |
50 unsigned short line_gap; |
52 unsigned short line_gap; |
51 bool has_font_extents; |
53 bool has_font_extents; |
52 |
54 |
53 const OT::_mtx *table; |
55 const OT::hmtxvmtx *table; |
54 hb_blob_t *blob; |
56 hb_blob_t *blob; |
|
57 |
|
58 const OT::HVARVVAR *var; |
|
59 hb_blob_t *var_blob; |
55 |
60 |
56 inline void init (hb_face_t *face, |
61 inline void init (hb_face_t *face, |
57 hb_tag_t _hea_tag, |
62 hb_tag_t _hea_tag, |
58 hb_tag_t _mtx_tag, |
63 hb_tag_t _mtx_tag, |
|
64 hb_tag_t _var_tag, |
59 hb_tag_t os2_tag, |
65 hb_tag_t os2_tag, |
60 unsigned int default_advance = 0) |
66 unsigned int default_advance = 0) |
61 { |
67 { |
62 this->default_advance = default_advance ? default_advance : face->get_upem (); |
68 this->default_advance = default_advance ? default_advance : face->get_upem (); |
63 |
69 |
105 { |
111 { |
106 this->num_metrics = this->num_advances = 0; |
112 this->num_metrics = this->num_advances = 0; |
107 hb_blob_destroy (this->blob); |
113 hb_blob_destroy (this->blob); |
108 this->blob = hb_blob_get_empty (); |
114 this->blob = hb_blob_get_empty (); |
109 } |
115 } |
110 this->table = OT::Sanitizer<OT::_mtx>::lock_instance (this->blob); |
116 this->table = OT::Sanitizer<OT::hmtxvmtx>::lock_instance (this->blob); |
|
117 |
|
118 this->var_blob = OT::Sanitizer<OT::HVARVVAR>::sanitize (face->reference_table (_var_tag)); |
|
119 this->var = OT::Sanitizer<OT::HVARVVAR>::lock_instance (this->var_blob); |
111 } |
120 } |
112 |
121 |
113 inline void fini (void) |
122 inline void fini (void) |
114 { |
123 { |
115 hb_blob_destroy (this->blob); |
124 hb_blob_destroy (this->blob); |
116 } |
125 hb_blob_destroy (this->var_blob); |
117 |
126 } |
118 inline unsigned int get_advance (hb_codepoint_t glyph) const |
127 |
|
128 inline unsigned int get_advance (hb_codepoint_t glyph, |
|
129 hb_font_t *font) const |
119 { |
130 { |
120 if (unlikely (glyph >= this->num_metrics)) |
131 if (unlikely (glyph >= this->num_metrics)) |
121 { |
132 { |
122 /* If this->num_metrics is zero, it means we don't have the metrics table |
133 /* If this->num_metrics is zero, it means we don't have the metrics table |
123 * for this direction: return default advance. Otherwise, it means that the |
134 * for this direction: return default advance. Otherwise, it means that the |
214 hb_blob_t *cbdt_blob; |
223 hb_blob_t *cbdt_blob; |
215 const OT::CBLC *cblc; |
224 const OT::CBLC *cblc; |
216 const OT::CBDT *cbdt; |
225 const OT::CBDT *cbdt; |
217 |
226 |
218 unsigned int cbdt_len; |
227 unsigned int cbdt_len; |
219 float upem; |
228 unsigned int upem; |
220 |
229 |
221 inline void init (hb_face_t *face) |
230 inline void init (hb_face_t *face) |
222 { |
231 { |
223 upem = face->get_upem(); |
232 upem = face->get_upem(); |
224 |
233 |
225 cblc_blob = OT::Sanitizer<OT::CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC)); |
234 cblc_blob = OT::Sanitizer<OT::CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC)); |
226 cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT)); |
235 cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT)); |
227 cbdt_len = hb_blob_get_length (cbdt_blob); |
236 cbdt_len = hb_blob_get_length (cbdt_blob); |
228 |
237 |
229 if (hb_blob_get_length (cblc_blob) == 0) { |
238 if (hb_blob_get_length (cblc_blob) == 0) { |
230 cblc = NULL; |
239 cblc = nullptr; |
231 cbdt = NULL; |
240 cbdt = nullptr; |
232 return; /* Not a bitmap font. */ |
241 return; /* Not a bitmap font. */ |
233 } |
242 } |
234 cblc = OT::Sanitizer<OT::CBLC>::lock_instance (cblc_blob); |
243 cblc = OT::Sanitizer<OT::CBLC>::lock_instance (cblc_blob); |
235 cbdt = OT::Sanitizer<OT::CBDT>::lock_instance (cbdt_blob); |
244 cbdt = OT::Sanitizer<OT::CBDT>::lock_instance (cbdt_blob); |
236 |
245 |
291 |
300 |
292 return true; |
301 return true; |
293 } |
302 } |
294 }; |
303 }; |
295 |
304 |
|
305 struct hb_ot_face_post_accelerator_t |
|
306 { |
|
307 hb_blob_t *post_blob; |
|
308 OT::post::accelerator_t accel; |
|
309 |
|
310 inline void init (hb_face_t *face) |
|
311 { |
|
312 hb_blob_t *blob = this->post_blob = OT::Sanitizer<OT::post>::sanitize (face->reference_table (HB_OT_TAG_post)); |
|
313 accel.init (OT::Sanitizer<OT::post>::lock_instance (blob), hb_blob_get_length (blob)); |
|
314 } |
|
315 |
|
316 inline void fini (void) |
|
317 { |
|
318 accel.fini (); |
|
319 hb_blob_destroy (this->post_blob); |
|
320 } |
|
321 |
|
322 inline bool get_glyph_name (hb_codepoint_t glyph, |
|
323 char *name, unsigned int size) const |
|
324 { |
|
325 return this->accel.get_glyph_name (glyph, name, size); |
|
326 } |
|
327 |
|
328 inline bool get_glyph_from_name (const char *name, int len, |
|
329 hb_codepoint_t *glyph) const |
|
330 { |
|
331 if (unlikely (!len)) |
|
332 return false; |
|
333 |
|
334 return this->accel.get_glyph_from_name (name, len, glyph); |
|
335 } |
|
336 }; |
|
337 |
|
338 struct hb_ot_face_kern_accelerator_t |
|
339 { |
|
340 hb_blob_t *kern_blob; |
|
341 OT::kern::accelerator_t accel; |
|
342 |
|
343 inline void init (hb_face_t *face) |
|
344 { |
|
345 hb_blob_t *blob = this->kern_blob = OT::Sanitizer<OT::kern>::sanitize (face->reference_table (HB_OT_TAG_kern)); |
|
346 accel.init (OT::Sanitizer<OT::kern>::lock_instance (blob), hb_blob_get_length (blob)); |
|
347 } |
|
348 |
|
349 inline void fini (void) |
|
350 { |
|
351 accel.fini (); |
|
352 hb_blob_destroy (this->kern_blob); |
|
353 } |
|
354 |
|
355 inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const |
|
356 { return accel.get_h_kerning (left, right); } |
|
357 }; |
|
358 |
296 typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, |
359 typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, |
297 hb_codepoint_t codepoint, |
360 hb_codepoint_t codepoint, |
298 hb_codepoint_t *glyph); |
361 hb_codepoint_t *glyph); |
299 |
362 |
300 template <typename Type> |
363 template <typename Type> |
339 |
402 |
340 inline void init (hb_face_t *face) |
403 inline void init (hb_face_t *face) |
341 { |
404 { |
342 this->blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap)); |
405 this->blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap)); |
343 const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob); |
406 const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob); |
344 const OT::CmapSubtable *subtable = NULL; |
407 const OT::CmapSubtable *subtable = nullptr; |
345 const OT::CmapSubtableFormat14 *subtable_uvs = NULL; |
408 const OT::CmapSubtableFormat14 *subtable_uvs = nullptr; |
346 |
409 |
347 bool symbol = false; |
410 bool symbol = false; |
348 /* 32-bit subtables. */ |
411 /* 32-bit subtables. */ |
349 if (!subtable) subtable = cmap->find_subtable (3, 10); |
412 if (!subtable) subtable = cmap->find_subtable (3, 10); |
350 if (!subtable) subtable = cmap->find_subtable (0, 6); |
413 if (!subtable) subtable = cmap->find_subtable (0, 6); |
419 |
482 |
420 return get_nominal_glyph (unicode, glyph); |
483 return get_nominal_glyph (unicode, glyph); |
421 } |
484 } |
422 }; |
485 }; |
423 |
486 |
424 template <typename T> |
|
425 struct hb_lazy_loader_t |
|
426 { |
|
427 inline void init (hb_face_t *face_) |
|
428 { |
|
429 face = face_; |
|
430 instance = NULL; |
|
431 } |
|
432 |
|
433 inline void fini (void) |
|
434 { |
|
435 if (instance && instance != &OT::Null(T)) |
|
436 { |
|
437 instance->fini(); |
|
438 free (instance); |
|
439 } |
|
440 } |
|
441 |
|
442 inline const T* operator-> (void) const |
|
443 { |
|
444 retry: |
|
445 T *p = (T *) hb_atomic_ptr_get (&instance); |
|
446 if (unlikely (!p)) |
|
447 { |
|
448 p = (T *) calloc (1, sizeof (T)); |
|
449 if (unlikely (!p)) |
|
450 return &OT::Null(T); |
|
451 p->init (face); |
|
452 if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), NULL, p))) |
|
453 { |
|
454 p->fini (); |
|
455 goto retry; |
|
456 } |
|
457 } |
|
458 return p; |
|
459 } |
|
460 |
|
461 private: |
|
462 hb_face_t *face; |
|
463 T *instance; |
|
464 }; |
|
465 |
|
466 struct hb_ot_font_t |
487 struct hb_ot_font_t |
467 { |
488 { |
468 hb_ot_face_cmap_accelerator_t cmap; |
489 hb_ot_face_cmap_accelerator_t cmap; |
469 hb_ot_face_metrics_accelerator_t h_metrics; |
490 hb_ot_face_metrics_accelerator_t h_metrics; |
470 hb_ot_face_metrics_accelerator_t v_metrics; |
491 hb_ot_face_metrics_accelerator_t v_metrics; |
471 hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf; |
492 OT::hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf; |
472 hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt; |
493 OT::hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt; |
|
494 OT::hb_lazy_loader_t<hb_ot_face_post_accelerator_t> post; |
|
495 OT::hb_lazy_loader_t<hb_ot_face_kern_accelerator_t> kern; |
473 }; |
496 }; |
474 |
497 |
475 |
498 |
476 static hb_ot_font_t * |
499 static hb_ot_font_t * |
477 _hb_ot_font_create (hb_face_t *face) |
500 _hb_ot_font_create (hb_face_t *face) |
478 { |
501 { |
479 hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t)); |
502 hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t)); |
480 |
503 |
481 if (unlikely (!ot_font)) |
504 if (unlikely (!ot_font)) |
482 return NULL; |
505 return nullptr; |
483 |
506 |
484 ot_font->cmap.init (face); |
507 ot_font->cmap.init (face); |
485 ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_os2); |
508 ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_HVAR, HB_OT_TAG_os2); |
486 ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_TAG_NONE, |
509 ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_OT_TAG_VVAR, HB_TAG_NONE, |
487 ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */ |
510 ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */ |
488 ot_font->glyf.init (face); |
511 ot_font->glyf.init (face); |
489 ot_font->cbdt.init (face); |
512 ot_font->cbdt.init (face); |
|
513 ot_font->post.init (face); |
|
514 ot_font->kern.init (face); |
490 |
515 |
491 return ot_font; |
516 return ot_font; |
492 } |
517 } |
493 |
518 |
494 static void |
519 static void |
495 _hb_ot_font_destroy (hb_ot_font_t *ot_font) |
520 _hb_ot_font_destroy (void *data) |
496 { |
521 { |
|
522 hb_ot_font_t *ot_font = (hb_ot_font_t *) data; |
|
523 |
497 ot_font->cmap.fini (); |
524 ot_font->cmap.fini (); |
498 ot_font->h_metrics.fini (); |
525 ot_font->h_metrics.fini (); |
499 ot_font->v_metrics.fini (); |
526 ot_font->v_metrics.fini (); |
500 ot_font->glyf.fini (); |
527 ot_font->glyf.fini (); |
501 ot_font->cbdt.fini (); |
528 ot_font->cbdt.fini (); |
|
529 ot_font->post.fini (); |
|
530 ot_font->kern.fini (); |
502 |
531 |
503 free (ot_font); |
532 free (ot_font); |
504 } |
533 } |
505 |
534 |
506 |
535 |
527 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
556 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
528 return ot_font->cmap.get_variation_glyph (unicode, variation_selector, glyph); |
557 return ot_font->cmap.get_variation_glyph (unicode, variation_selector, glyph); |
529 } |
558 } |
530 |
559 |
531 static hb_position_t |
560 static hb_position_t |
532 hb_ot_get_glyph_h_advance (hb_font_t *font HB_UNUSED, |
561 hb_ot_get_glyph_h_advance (hb_font_t *font, |
533 void *font_data, |
562 void *font_data, |
534 hb_codepoint_t glyph, |
563 hb_codepoint_t glyph, |
535 void *user_data HB_UNUSED) |
564 void *user_data HB_UNUSED) |
536 { |
565 { |
537 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
566 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
538 return font->em_scale_x (ot_font->h_metrics.get_advance (glyph)); |
567 return font->em_scale_x (ot_font->h_metrics.get_advance (glyph, font)); |
539 } |
568 } |
540 |
569 |
541 static hb_position_t |
570 static hb_position_t |
542 hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED, |
571 hb_ot_get_glyph_v_advance (hb_font_t *font, |
543 void *font_data, |
572 void *font_data, |
544 hb_codepoint_t glyph, |
573 hb_codepoint_t glyph, |
545 void *user_data HB_UNUSED) |
574 void *user_data HB_UNUSED) |
546 { |
575 { |
547 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
576 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
548 return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph)); |
577 return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph, font)); |
|
578 } |
|
579 |
|
580 static hb_position_t |
|
581 hb_ot_get_glyph_h_kerning (hb_font_t *font, |
|
582 void *font_data, |
|
583 hb_codepoint_t left_glyph, |
|
584 hb_codepoint_t right_glyph, |
|
585 void *user_data HB_UNUSED) |
|
586 { |
|
587 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
|
588 return font->em_scale_x (ot_font->kern->get_h_kerning (left_glyph, right_glyph)); |
549 } |
589 } |
550 |
590 |
551 static hb_bool_t |
591 static hb_bool_t |
552 hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, |
592 hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, |
553 void *font_data, |
593 void *font_data, |
557 { |
597 { |
558 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
598 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
559 bool ret = ot_font->glyf->get_extents (glyph, extents); |
599 bool ret = ot_font->glyf->get_extents (glyph, extents); |
560 if (!ret) |
600 if (!ret) |
561 ret = ot_font->cbdt->get_extents (glyph, extents); |
601 ret = ot_font->cbdt->get_extents (glyph, extents); |
|
602 // TODO Hook up side-bearings variations. |
562 extents->x_bearing = font->em_scale_x (extents->x_bearing); |
603 extents->x_bearing = font->em_scale_x (extents->x_bearing); |
563 extents->y_bearing = font->em_scale_y (extents->y_bearing); |
604 extents->y_bearing = font->em_scale_y (extents->y_bearing); |
564 extents->width = font->em_scale_x (extents->width); |
605 extents->width = font->em_scale_x (extents->width); |
565 extents->height = font->em_scale_y (extents->height); |
606 extents->height = font->em_scale_y (extents->height); |
566 return ret; |
607 return ret; |
567 } |
608 } |
568 |
609 |
569 static hb_bool_t |
610 static hb_bool_t |
|
611 hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED, |
|
612 void *font_data, |
|
613 hb_codepoint_t glyph, |
|
614 char *name, unsigned int size, |
|
615 void *user_data HB_UNUSED) |
|
616 { |
|
617 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
|
618 return ot_font->post->get_glyph_name (glyph, name, size); |
|
619 } |
|
620 |
|
621 static hb_bool_t |
|
622 hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED, |
|
623 void *font_data, |
|
624 const char *name, int len, |
|
625 hb_codepoint_t *glyph, |
|
626 void *user_data HB_UNUSED) |
|
627 { |
|
628 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
|
629 return ot_font->post->get_glyph_from_name (name, len, glyph); |
|
630 } |
|
631 |
|
632 static hb_bool_t |
570 hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED, |
633 hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED, |
571 void *font_data, |
634 void *font_data, |
572 hb_font_extents_t *metrics, |
635 hb_font_extents_t *metrics, |
573 void *user_data HB_UNUSED) |
636 void *user_data HB_UNUSED) |
574 { |
637 { |
575 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
638 const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; |
576 metrics->ascender = font->em_scale_y (ot_font->h_metrics.ascender); |
639 metrics->ascender = font->em_scale_y (ot_font->h_metrics.ascender); |
577 metrics->descender = font->em_scale_y (ot_font->h_metrics.descender); |
640 metrics->descender = font->em_scale_y (ot_font->h_metrics.descender); |
578 metrics->line_gap = font->em_scale_y (ot_font->h_metrics.line_gap); |
641 metrics->line_gap = font->em_scale_y (ot_font->h_metrics.line_gap); |
|
642 // TODO Hook up variations. |
579 return ot_font->h_metrics.has_font_extents; |
643 return ot_font->h_metrics.has_font_extents; |
580 } |
644 } |
581 |
645 |
582 static hb_bool_t |
646 static hb_bool_t |
583 hb_ot_get_font_v_extents (hb_font_t *font HB_UNUSED, |
647 hb_ot_get_font_v_extents (hb_font_t *font HB_UNUSED, |
610 |
675 |
611 if (unlikely (!funcs)) |
676 if (unlikely (!funcs)) |
612 { |
677 { |
613 funcs = hb_font_funcs_create (); |
678 funcs = hb_font_funcs_create (); |
614 |
679 |
615 hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, NULL, NULL); |
680 hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr); |
616 hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, NULL, NULL); |
681 hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr); |
617 hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, NULL, NULL); |
682 hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr); |
618 hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, NULL, NULL); |
683 hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr); |
619 hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, NULL, NULL); |
684 hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, nullptr, nullptr); |
620 hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, NULL, NULL); |
685 hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, nullptr, nullptr); |
621 //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, NULL, NULL); |
686 //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr); |
622 //hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, NULL, NULL); |
687 //hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr); |
623 //hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, NULL, NULL); TODO |
688 hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, nullptr, nullptr); |
624 //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, NULL, NULL); |
689 //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, nullptr, nullptr); |
625 hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, NULL, NULL); |
690 hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr); |
626 //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, NULL, NULL); TODO |
691 //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr); TODO |
627 //hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, NULL, NULL); TODO |
692 hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr); |
628 //hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, NULL, NULL); TODO |
693 hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr); |
629 |
694 |
630 hb_font_funcs_make_immutable (funcs); |
695 hb_font_funcs_make_immutable (funcs); |
631 |
696 |
632 if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, NULL, funcs)) { |
697 if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, nullptr, funcs)) { |
633 hb_font_funcs_destroy (funcs); |
698 hb_font_funcs_destroy (funcs); |
634 goto retry; |
699 goto retry; |
635 } |
700 } |
636 |
701 |
637 #ifdef HB_USE_ATEXIT |
702 #ifdef HB_USE_ATEXIT |