src/Makefile.am | 3 src/hb-ot-cbdt-table.hh | 91 +++++++++ src/hb-ot-cmap-table.hh | 149 ++++++++++++++- src/hb-ot-font.cc | 467 +----------------------------------------------- src/hb-ot-glyf-table.hh | 118 +++++++++--- src/hb-ot-hmtx-table.hh | 119 +++++++++++- src/hb-ot-kern-table.hh | 13 - src/hb-ot-post-table.hh | 10 - 8 files changed, 470 insertions(+), 500 deletions(-)
New commits: commit e20e47eaa1b7dd33ac63ab0eaa8f5ea1bf7775c2 Author: Behdad Esfahbod <[email protected]> Date: Tue Nov 14 20:25:29 2017 -0800 [glyf] Try fixing undefined-behavior Might fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1463 diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index dba10226..1ac12557 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -54,11 +54,8 @@ struct loca } protected: - union { - USHORT shortsZ[VAR]; /* Location offset divided by 2. */ - ULONG longsZ[VAR]; /* Location offset. */ - } u; - DEFINE_SIZE_ARRAY (0, u.longsZ); + BYTE dataX[VAR]; /* Location data. */ + DEFINE_SIZE_ARRAY (0, dataX); }; @@ -134,13 +131,15 @@ struct glyf unsigned int start_offset, end_offset; if (short_offset) { - start_offset = 2 * loca_table->u.shortsZ[glyph]; - end_offset = 2 * loca_table->u.shortsZ[glyph + 1]; + const USHORT *offsets = (const USHORT *) loca_table->dataX; + start_offset = 2 * offsets[glyph]; + end_offset = 2 * offsets[glyph + 1]; } else { - start_offset = loca_table->u.longsZ[glyph]; - end_offset = loca_table->u.longsZ[glyph + 1]; + const ULONG *offsets = (const ULONG *) loca_table->dataX; + start_offset = offsets[glyph]; + end_offset = offsets[glyph + 1]; } if (start_offset > end_offset || end_offset > glyf_len) commit 7b40876a58d331200e1d7cda1dec72578139ff9c Author: Behdad Esfahbod <[email protected]> Date: Tue Nov 14 20:22:05 2017 -0800 [ot] Remove unneeded TODO item Looks like hb-ot-font is complete after all! CFF font names and CFF glyph metrics don't work though... diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 9d7d4bc9..9864064b 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -241,7 +241,7 @@ retry: hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, nullptr, nullptr); //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, nullptr, nullptr); hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr); - //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr); TODO + //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr); hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr); hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr); commit eab4feb5e221b8219c071ea882de79405aca4e84 Author: Behdad Esfahbod <[email protected]> Date: Tue Nov 14 20:16:45 2017 -0800 [hmtx] Use curiously recurring template pattern https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 4b328d99..9d7d4bc9 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -33,8 +33,6 @@ #include "hb-ot-cmap-table.hh" #include "hb-ot-cbdt-table.hh" #include "hb-ot-glyf-table.hh" -#include "hb-ot-head-table.hh" -#include "hb-ot-hhea-table.hh" #include "hb-ot-hmtx-table.hh" #include "hb-ot-kern-table.hh" #include "hb-ot-post-table.hh" @@ -43,8 +41,8 @@ struct hb_ot_font_t { OT::cmap::accelerator_t cmap; - OT::hmtxvmtx::accelerator_t h_metrics; - OT::hmtxvmtx::accelerator_t v_metrics; + OT::hmtx::accelerator_t h_metrics; + OT::vmtx::accelerator_t v_metrics; OT::hb_lazy_loader_t<OT::glyf::accelerator_t> glyf; OT::hb_lazy_loader_t<OT::CBDT::accelerator_t> cbdt; OT::hb_lazy_loader_t<OT::post::accelerator_t> post; @@ -61,9 +59,8 @@ _hb_ot_font_create (hb_face_t *face) return nullptr; ot_font->cmap.init (face); - ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_HVAR, HB_OT_TAG_os2); - ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_OT_TAG_VVAR, HB_TAG_NONE, - ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */ + ot_font->h_metrics.init (face); + ot_font->v_metrics.init (face, ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */ ot_font->glyf.init (face); ot_font->cbdt.init (face); ot_font->post.init (face); diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index 16e284b7..e710aee4 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -28,6 +28,7 @@ #define HB_OT_HMTX_TABLE_HH #include "hb-open-type-private.hh" +#include "hb-ot-hhea-table.hh" #include "hb-ot-os2-table.hh" #include "hb-ot-var-hvar-table.hh" @@ -52,11 +53,9 @@ struct LongMetric DEFINE_SIZE_STATIC (4); }; +template <typename T> struct hmtxvmtx { - static const hb_tag_t hmtxTag = HB_OT_TAG_hmtx; - static const hb_tag_t vmtxTag = HB_OT_TAG_vmtx; - inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -68,18 +67,14 @@ struct hmtxvmtx struct accelerator_t { inline void init (hb_face_t *face, - hb_tag_t _hea_tag, - hb_tag_t _mtx_tag, - hb_tag_t _var_tag, - hb_tag_t os2_tag, unsigned int default_advance_ = 0) { default_advance = default_advance_ ? default_advance_ : face->get_upem (); bool got_font_extents = false; - if (os2_tag) + if (T::os2Tag) { - hb_blob_t *os2_blob = Sanitizer<os2>::sanitize (face->reference_table (os2_tag)); + hb_blob_t *os2_blob = Sanitizer<os2>::sanitize (face->reference_table (T::os2Tag)); const os2 *os2_table = Sanitizer<os2>::lock_instance (os2_blob); #define USE_TYPO_METRICS (1u<<7) if (0 != (os2_table->fsSelection & USE_TYPO_METRICS)) @@ -92,7 +87,7 @@ struct hmtxvmtx hb_blob_destroy (os2_blob); } - hb_blob_t *_hea_blob = Sanitizer<_hea>::sanitize (face->reference_table (_hea_tag)); + hb_blob_t *_hea_blob = Sanitizer<_hea>::sanitize (face->reference_table (T::headerTag)); const _hea *_hea_table = Sanitizer<_hea>::lock_instance (_hea_blob); num_advances = _hea_table->numberOfLongMetrics; if (!got_font_extents) @@ -106,7 +101,7 @@ struct hmtxvmtx has_font_extents = got_font_extents; - blob = Sanitizer<hmtxvmtx>::sanitize (face->reference_table (_mtx_tag)); + blob = Sanitizer<hmtxvmtx>::sanitize (face->reference_table (T::tableTag)); /* Cap num_metrics() and num_advances() based on table length. */ unsigned int len = hb_blob_get_length (blob); @@ -124,7 +119,7 @@ struct hmtxvmtx } table = Sanitizer<hmtxvmtx>::lock_instance (blob); - var_blob = Sanitizer<HVARVVAR>::sanitize (face->reference_table (_var_tag)); + var_blob = Sanitizer<HVARVVAR>::sanitize (face->reference_table (T::variationsTag)); var_table = Sanitizer<HVARVVAR>::lock_instance (var_blob); } @@ -195,11 +190,17 @@ struct hmtxvmtx DEFINE_SIZE_ARRAY2 (0, longMetric, leadingBearingX); }; -struct hmtx : hmtxvmtx { +struct hmtx : hmtxvmtx<hmtx> { static const hb_tag_t tableTag = HB_OT_TAG_hmtx; + static const hb_tag_t headerTag = HB_OT_TAG_hhea; + static const hb_tag_t variationsTag = HB_OT_TAG_HVAR; + static const hb_tag_t os2Tag = HB_OT_TAG_os2; }; -struct vmtx : hmtxvmtx { +struct vmtx : hmtxvmtx<vmtx> { static const hb_tag_t tableTag = HB_OT_TAG_vmtx; + static const hb_tag_t headerTag = HB_OT_TAG_vhea; + static const hb_tag_t variationsTag = HB_OT_TAG_VVAR; + static const hb_tag_t os2Tag = HB_TAG_NONE; }; } /* namespace OT */ commit 977ddff1f1e0f0f71a46c60ba713d160b96f5a3c Author: Behdad Esfahbod <[email protected]> Date: Tue Nov 14 20:06:19 2017 -0800 [ot] Move hb_ot_face_cmap_accelerator_t diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 93f38c56..4602eac8 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -496,6 +496,146 @@ struct cmap { static const hb_tag_t tableTag = HB_OT_TAG_cmap; + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + likely (version == 0) && + encodingRecord.sanitize (c, this)); + } + + struct accelerator_t + { + inline void init (hb_face_t *face) + { + this->blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap)); + const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob); + const OT::CmapSubtable *subtable = nullptr; + const OT::CmapSubtableFormat14 *subtable_uvs = nullptr; + + bool symbol = false; + /* 32-bit subtables. */ + if (!subtable) subtable = cmap->find_subtable (3, 10); + if (!subtable) subtable = cmap->find_subtable (0, 6); + if (!subtable) subtable = cmap->find_subtable (0, 4); + /* 16-bit subtables. */ + if (!subtable) subtable = cmap->find_subtable (3, 1); + if (!subtable) subtable = cmap->find_subtable (0, 3); + if (!subtable) subtable = cmap->find_subtable (0, 2); + if (!subtable) subtable = cmap->find_subtable (0, 1); + if (!subtable) subtable = cmap->find_subtable (0, 0); + if (!subtable) + { + subtable = cmap->find_subtable (3, 0); + if (subtable) symbol = true; + } + /* Meh. */ + if (!subtable) subtable = &OT::Null(OT::CmapSubtable); + + /* UVS subtable. */ + if (!subtable_uvs) + { + const OT::CmapSubtable *st = cmap->find_subtable (0, 5); + if (st && st->u.format == 14) + subtable_uvs = &st->u.format14; + } + /* Meh. */ + if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtableFormat14); + + this->uvs_table = subtable_uvs; + + this->get_glyph_data = subtable; + if (unlikely (symbol)) + this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>; + else + switch (subtable->u.format) { + /* Accelerate format 4 and format 12. */ + default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; break; + case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>; break; + case 4: + { + this->format4_accel.init (&subtable->u.format4); + this->get_glyph_data = &this->format4_accel; + this->get_glyph_func = this->format4_accel.get_glyph_func; + } + break; + } + } + + inline void fini (void) + { + hb_blob_destroy (this->blob); + } + + inline bool get_nominal_glyph (hb_codepoint_t unicode, + hb_codepoint_t *glyph) const + { + return this->get_glyph_func (this->get_glyph_data, unicode, glyph); + } + + inline bool get_variation_glyph (hb_codepoint_t unicode, + hb_codepoint_t variation_selector, + hb_codepoint_t *glyph) const + { + switch (this->uvs_table->get_glyph_variant (unicode, + variation_selector, + glyph)) + { + case OT::GLYPH_VARIANT_NOT_FOUND: return false; + case OT::GLYPH_VARIANT_FOUND: return true; + case OT::GLYPH_VARIANT_USE_DEFAULT: break; + } + + return get_nominal_glyph (unicode, glyph); + } + + protected: + typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph); + + template <typename Type> + static inline bool get_glyph_from (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph) + { + const Type *typed_obj = (const Type *) obj; + return typed_obj->get_glyph (codepoint, glyph); + } + + template <typename Type> + static inline bool get_glyph_from_symbol (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph) + { + const Type *typed_obj = (const Type *) obj; + if (likely (typed_obj->get_glyph (codepoint, glyph))) + return true; + + if (codepoint <= 0x00FFu) + { + /* For symbol-encoded OpenType fonts, we duplicate the + * U+F000..F0FF range at U+0000..U+00FF. That's what + * Windows seems to do, and that's hinted about at: + * http://www.microsoft.com/typography/otspec/recom.htm + * under "Non-Standard (Symbol) Fonts". */ + return typed_obj->get_glyph (0xF000u + codepoint, glyph); + } + + return false; + } + + private: + hb_cmap_get_glyph_func_t get_glyph_func; + const void *get_glyph_data; + OT::CmapSubtableFormat4::accelerator_t format4_accel; + + const OT::CmapSubtableFormat14 *uvs_table; + hb_blob_t *blob; + }; + + protected: + inline const CmapSubtable *find_subtable (unsigned int platform_id, unsigned int encoding_id) const { @@ -513,14 +653,7 @@ struct cmap return &(this+encodingRecord[result].subtable); } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - likely (version == 0) && - encodingRecord.sanitize (c, this)); - } - + protected: USHORT version; /* Table version number (0). */ SortedArrayOf<EncodingRecord> encodingRecord; /* Encoding tables. */ diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index d1ae238e..4b328d99 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -40,137 +40,9 @@ #include "hb-ot-post-table.hh" -typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, - hb_codepoint_t codepoint, - hb_codepoint_t *glyph); - -template <typename Type> -static inline bool get_glyph_from (const void *obj, - hb_codepoint_t codepoint, - hb_codepoint_t *glyph) -{ - const Type *typed_obj = (const Type *) obj; - return typed_obj->get_glyph (codepoint, glyph); -} - -template <typename Type> -static inline bool get_glyph_from_symbol (const void *obj, - hb_codepoint_t codepoint, - hb_codepoint_t *glyph) -{ - const Type *typed_obj = (const Type *) obj; - if (likely (typed_obj->get_glyph (codepoint, glyph))) - return true; - - if (codepoint <= 0x00FFu) - { - /* For symbol-encoded OpenType fonts, we duplicate the - * U+F000..F0FF range at U+0000..U+00FF. That's what - * Windows seems to do, and that's hinted about at: - * http://www.microsoft.com/typography/otspec/recom.htm - * under "Non-Standard (Symbol) Fonts". */ - return typed_obj->get_glyph (0xF000u + codepoint, glyph); - } - - return false; -} - -struct hb_ot_face_cmap_accelerator_t -{ - hb_cmap_get_glyph_func_t get_glyph_func; - const void *get_glyph_data; - OT::CmapSubtableFormat4::accelerator_t format4_accel; - - const OT::CmapSubtableFormat14 *uvs_table; - hb_blob_t *blob; - - inline void init (hb_face_t *face) - { - this->blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap)); - const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob); - const OT::CmapSubtable *subtable = nullptr; - const OT::CmapSubtableFormat14 *subtable_uvs = nullptr; - - bool symbol = false; - /* 32-bit subtables. */ - if (!subtable) subtable = cmap->find_subtable (3, 10); - if (!subtable) subtable = cmap->find_subtable (0, 6); - if (!subtable) subtable = cmap->find_subtable (0, 4); - /* 16-bit subtables. */ - if (!subtable) subtable = cmap->find_subtable (3, 1); - if (!subtable) subtable = cmap->find_subtable (0, 3); - if (!subtable) subtable = cmap->find_subtable (0, 2); - if (!subtable) subtable = cmap->find_subtable (0, 1); - if (!subtable) subtable = cmap->find_subtable (0, 0); - if (!subtable) - { - subtable = cmap->find_subtable (3, 0); - if (subtable) symbol = true; - } - /* Meh. */ - if (!subtable) subtable = &OT::Null(OT::CmapSubtable); - - /* UVS subtable. */ - if (!subtable_uvs) - { - const OT::CmapSubtable *st = cmap->find_subtable (0, 5); - if (st && st->u.format == 14) - subtable_uvs = &st->u.format14; - } - /* Meh. */ - if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtableFormat14); - - this->uvs_table = subtable_uvs; - - this->get_glyph_data = subtable; - if (unlikely (symbol)) - this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>; - else - switch (subtable->u.format) { - /* Accelerate format 4 and format 12. */ - default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; break; - case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>; break; - case 4: - { - this->format4_accel.init (&subtable->u.format4); - this->get_glyph_data = &this->format4_accel; - this->get_glyph_func = this->format4_accel.get_glyph_func; - } - break; - } - } - - inline void fini (void) - { - hb_blob_destroy (this->blob); - } - - inline bool get_nominal_glyph (hb_codepoint_t unicode, - hb_codepoint_t *glyph) const - { - return this->get_glyph_func (this->get_glyph_data, unicode, glyph); - } - - inline bool get_variation_glyph (hb_codepoint_t unicode, - hb_codepoint_t variation_selector, - hb_codepoint_t *glyph) const - { - switch (this->uvs_table->get_glyph_variant (unicode, - variation_selector, - glyph)) - { - case OT::GLYPH_VARIANT_NOT_FOUND: return false; - case OT::GLYPH_VARIANT_FOUND: return true; - case OT::GLYPH_VARIANT_USE_DEFAULT: break; - } - - return get_nominal_glyph (unicode, glyph); - } -}; - struct hb_ot_font_t { - hb_ot_face_cmap_accelerator_t cmap; + OT::cmap::accelerator_t cmap; OT::hmtxvmtx::accelerator_t h_metrics; OT::hmtxvmtx::accelerator_t v_metrics; OT::hb_lazy_loader_t<OT::glyf::accelerator_t> glyf; commit a7f15959b5e6e14e5241a3155c413ff70e7d1eb3 Author: Behdad Esfahbod <[email protected]> Date: Tue Nov 14 20:02:24 2017 -0800 Shuffle diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index 3485a6d0..16e284b7 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -67,20 +67,14 @@ struct hmtxvmtx struct accelerator_t { - const hmtxvmtx *table; - hb_blob_t *blob; - - const HVARVVAR *var; - hb_blob_t *var_blob; - inline void init (hb_face_t *face, hb_tag_t _hea_tag, hb_tag_t _mtx_tag, hb_tag_t _var_tag, hb_tag_t os2_tag, - unsigned int default_advance = 0) + unsigned int default_advance_ = 0) { - this->default_advance = default_advance ? default_advance : face->get_upem (); + default_advance = default_advance_ ? default_advance_ : face->get_upem (); bool got_font_extents = false; if (os2_tag) @@ -90,72 +84,72 @@ struct hmtxvmtx #define USE_TYPO_METRICS (1u<<7) if (0 != (os2_table->fsSelection & USE_TYPO_METRICS)) { - this->ascender = os2_table->sTypoAscender; - this->descender = os2_table->sTypoDescender; - this->line_gap = os2_table->sTypoLineGap; - got_font_extents = (this->ascender | this->descender) != 0; + ascender = os2_table->sTypoAscender; + descender = os2_table->sTypoDescender; + line_gap = os2_table->sTypoLineGap; + got_font_extents = (ascender | descender) != 0; } hb_blob_destroy (os2_blob); } hb_blob_t *_hea_blob = Sanitizer<_hea>::sanitize (face->reference_table (_hea_tag)); const _hea *_hea_table = Sanitizer<_hea>::lock_instance (_hea_blob); - this->num_advances = _hea_table->numberOfLongMetrics; + num_advances = _hea_table->numberOfLongMetrics; if (!got_font_extents) { - this->ascender = _hea_table->ascender; - this->descender = _hea_table->descender; - this->line_gap = _hea_table->lineGap; - got_font_extents = (this->ascender | this->descender) != 0; + ascender = _hea_table->ascender; + descender = _hea_table->descender; + line_gap = _hea_table->lineGap; + got_font_extents = (ascender | descender) != 0; } hb_blob_destroy (_hea_blob); - this->has_font_extents = got_font_extents; + has_font_extents = got_font_extents; - this->blob = Sanitizer<hmtxvmtx>::sanitize (face->reference_table (_mtx_tag)); + blob = Sanitizer<hmtxvmtx>::sanitize (face->reference_table (_mtx_tag)); /* Cap num_metrics() and num_advances() based on table length. */ - unsigned int len = hb_blob_get_length (this->blob); - if (unlikely (this->num_advances * 4 > len)) - this->num_advances = len / 4; - this->num_metrics = this->num_advances + (len - 4 * this->num_advances) / 2; + unsigned int len = hb_blob_get_length (blob); + if (unlikely (num_advances * 4 > len)) + num_advances = len / 4; + num_metrics = num_advances + (len - 4 * num_advances) / 2; /* We MUST set num_metrics to zero if num_advances is zero. * Our get_advance() depends on that. */ - if (unlikely (!this->num_advances)) + if (unlikely (!num_advances)) { - this->num_metrics = this->num_advances = 0; - hb_blob_destroy (this->blob); - this->blob = hb_blob_get_empty (); + num_metrics = num_advances = 0; + hb_blob_destroy (blob); + blob = hb_blob_get_empty (); } - this->table = Sanitizer<hmtxvmtx>::lock_instance (this->blob); + table = Sanitizer<hmtxvmtx>::lock_instance (blob); - this->var_blob = Sanitizer<HVARVVAR>::sanitize (face->reference_table (_var_tag)); - this->var = Sanitizer<HVARVVAR>::lock_instance (this->var_blob); + var_blob = Sanitizer<HVARVVAR>::sanitize (face->reference_table (_var_tag)); + var_table = Sanitizer<HVARVVAR>::lock_instance (var_blob); } inline void fini (void) { - hb_blob_destroy (this->blob); - hb_blob_destroy (this->var_blob); + hb_blob_destroy (blob); + hb_blob_destroy (var_blob); } inline unsigned int get_advance (hb_codepoint_t glyph, hb_font_t *font) const { - if (unlikely (glyph >= this->num_metrics)) + if (unlikely (glyph >= num_metrics)) { - /* If this->num_metrics is zero, it means we don't have the metrics table + /* If num_metrics is zero, it means we don't have the metrics table * for this direction: return default advance. Otherwise, it means that the * glyph index is out of bound: return zero. */ - if (this->num_metrics) + if (num_metrics) return 0; else - return this->default_advance; + return default_advance; } - return this->table->longMetric[MIN (glyph, (uint32_t) this->num_advances - 1)].advance - + this->var->get_advance_var (glyph, font->coords, font->num_coords); // TODO Optimize?! + return table->longMetric[MIN (glyph, (uint32_t) num_advances - 1)].advance + + var_table->get_advance_var (glyph, font->coords, font->num_coords); // TODO Optimize?! } public: @@ -163,10 +157,16 @@ struct hmtxvmtx unsigned short ascender; unsigned short descender; unsigned short line_gap; + private: unsigned int num_metrics; unsigned int num_advances; unsigned int default_advance; + + const hmtxvmtx *table; + hb_blob_t *blob; + const HVARVVAR *var_table; + hb_blob_t *var_blob; }; protected: commit a85d7ead04aff81d2f9df9110316892dbbefe1c2 Author: Behdad Esfahbod <[email protected]> Date: Tue Nov 14 20:00:34 2017 -0800 [ot] Move hb_ot_face_metrics_accelerator_t diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index eb497e57..d1ae238e 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -37,113 +37,9 @@ #include "hb-ot-hhea-table.hh" #include "hb-ot-hmtx-table.hh" #include "hb-ot-kern-table.hh" -#include "hb-ot-os2-table.hh" #include "hb-ot-post-table.hh" -#include "hb-ot-var-hvar-table.hh" -struct hb_ot_face_metrics_accelerator_t -{ - unsigned int num_metrics; - unsigned int num_advances; - unsigned int default_advance; - unsigned short ascender; - unsigned short descender; - unsigned short line_gap; - bool has_font_extents; - - const OT::hmtxvmtx *table; - hb_blob_t *blob; - - const OT::HVARVVAR *var; - hb_blob_t *var_blob; - - inline void init (hb_face_t *face, - hb_tag_t _hea_tag, - hb_tag_t _mtx_tag, - hb_tag_t _var_tag, - hb_tag_t os2_tag, - unsigned int default_advance = 0) - { - this->default_advance = default_advance ? default_advance : face->get_upem (); - - bool got_font_extents = false; - if (os2_tag) - { - hb_blob_t *os2_blob = OT::Sanitizer<OT::os2>::sanitize (face->reference_table (os2_tag)); - const OT::os2 *os2 = OT::Sanitizer<OT::os2>::lock_instance (os2_blob); -#define USE_TYPO_METRICS (1u<<7) - if (0 != (os2->fsSelection & USE_TYPO_METRICS)) - { - this->ascender = os2->sTypoAscender; - this->descender = os2->sTypoDescender; - this->line_gap = os2->sTypoLineGap; - got_font_extents = (this->ascender | this->descender) != 0; - } - hb_blob_destroy (os2_blob); - } - - hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_table (_hea_tag)); - const OT::_hea *_hea = OT::Sanitizer<OT::_hea>::lock_instance (_hea_blob); - this->num_advances = _hea->numberOfLongMetrics; - if (!got_font_extents) - { - this->ascender = _hea->ascender; - this->descender = _hea->descender; - this->line_gap = _hea->lineGap; - got_font_extents = (this->ascender | this->descender) != 0; - } - hb_blob_destroy (_hea_blob); - - this->has_font_extents = got_font_extents; - - this->blob = OT::Sanitizer<OT::hmtxvmtx>::sanitize (face->reference_table (_mtx_tag)); - - /* Cap num_metrics() and num_advances() based on table length. */ - unsigned int len = hb_blob_get_length (this->blob); - if (unlikely (this->num_advances * 4 > len)) - this->num_advances = len / 4; - this->num_metrics = this->num_advances + (len - 4 * this->num_advances) / 2; - - /* We MUST set num_metrics to zero if num_advances is zero. - * Our get_advance() depends on that. */ - if (unlikely (!this->num_advances)) - { - this->num_metrics = this->num_advances = 0; - hb_blob_destroy (this->blob); - this->blob = hb_blob_get_empty (); - } - this->table = OT::Sanitizer<OT::hmtxvmtx>::lock_instance (this->blob); - - this->var_blob = OT::Sanitizer<OT::HVARVVAR>::sanitize (face->reference_table (_var_tag)); - this->var = OT::Sanitizer<OT::HVARVVAR>::lock_instance (this->var_blob); - } - - inline void fini (void) - { - hb_blob_destroy (this->blob); - hb_blob_destroy (this->var_blob); - } - - inline unsigned int get_advance (hb_codepoint_t glyph, - hb_font_t *font) const - { - if (unlikely (glyph >= this->num_metrics)) - { - /* If this->num_metrics is zero, it means we don't have the metrics table - * for this direction: return default advance. Otherwise, it means that the - * glyph index is out of bound: return zero. */ - if (this->num_metrics) - return 0; - else - return this->default_advance; - } - - return this->table->longMetric[MIN (glyph, (uint32_t) this->num_advances - 1)].advance - + this->var->get_advance_var (glyph, font->coords, font->num_coords); // TODO Optimize?! - } -}; - typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph); @@ -275,8 +171,8 @@ struct hb_ot_face_cmap_accelerator_t struct hb_ot_font_t { hb_ot_face_cmap_accelerator_t cmap; - hb_ot_face_metrics_accelerator_t h_metrics; - hb_ot_face_metrics_accelerator_t v_metrics; + OT::hmtxvmtx::accelerator_t h_metrics; + OT::hmtxvmtx::accelerator_t v_metrics; OT::hb_lazy_loader_t<OT::glyf::accelerator_t> glyf; OT::hb_lazy_loader_t<OT::CBDT::accelerator_t> cbdt; OT::hb_lazy_loader_t<OT::post::accelerator_t> post; diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index 30aa6253..3485a6d0 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -28,6 +28,8 @@ #define HB_OT_HMTX_TABLE_HH #include "hb-open-type-private.hh" +#include "hb-ot-os2-table.hh" +#include "hb-ot-var-hvar-table.hh" namespace OT { @@ -63,7 +65,111 @@ struct hmtxvmtx return_trace (true); } - public: + struct accelerator_t + { + const hmtxvmtx *table; + hb_blob_t *blob; + + const HVARVVAR *var; + hb_blob_t *var_blob; + + inline void init (hb_face_t *face, + hb_tag_t _hea_tag, + hb_tag_t _mtx_tag, + hb_tag_t _var_tag, + hb_tag_t os2_tag, + unsigned int default_advance = 0) + { + this->default_advance = default_advance ? default_advance : face->get_upem (); + + bool got_font_extents = false; + if (os2_tag) + { + hb_blob_t *os2_blob = Sanitizer<os2>::sanitize (face->reference_table (os2_tag)); + const os2 *os2_table = Sanitizer<os2>::lock_instance (os2_blob); +#define USE_TYPO_METRICS (1u<<7) + if (0 != (os2_table->fsSelection & USE_TYPO_METRICS)) + { + this->ascender = os2_table->sTypoAscender; + this->descender = os2_table->sTypoDescender; + this->line_gap = os2_table->sTypoLineGap; + got_font_extents = (this->ascender | this->descender) != 0; + } + hb_blob_destroy (os2_blob); + } + + hb_blob_t *_hea_blob = Sanitizer<_hea>::sanitize (face->reference_table (_hea_tag)); + const _hea *_hea_table = Sanitizer<_hea>::lock_instance (_hea_blob); + this->num_advances = _hea_table->numberOfLongMetrics; + if (!got_font_extents) + { + this->ascender = _hea_table->ascender; + this->descender = _hea_table->descender; + this->line_gap = _hea_table->lineGap; + got_font_extents = (this->ascender | this->descender) != 0; + } + hb_blob_destroy (_hea_blob); + + this->has_font_extents = got_font_extents; + + this->blob = Sanitizer<hmtxvmtx>::sanitize (face->reference_table (_mtx_tag)); + + /* Cap num_metrics() and num_advances() based on table length. */ + unsigned int len = hb_blob_get_length (this->blob); + if (unlikely (this->num_advances * 4 > len)) + this->num_advances = len / 4; + this->num_metrics = this->num_advances + (len - 4 * this->num_advances) / 2; + + /* We MUST set num_metrics to zero if num_advances is zero. + * Our get_advance() depends on that. */ + if (unlikely (!this->num_advances)) + { + this->num_metrics = this->num_advances = 0; + hb_blob_destroy (this->blob); + this->blob = hb_blob_get_empty (); + } + this->table = Sanitizer<hmtxvmtx>::lock_instance (this->blob); + + this->var_blob = Sanitizer<HVARVVAR>::sanitize (face->reference_table (_var_tag)); + this->var = Sanitizer<HVARVVAR>::lock_instance (this->var_blob); + } + + inline void fini (void) + { + hb_blob_destroy (this->blob); + hb_blob_destroy (this->var_blob); + } + + inline unsigned int get_advance (hb_codepoint_t glyph, + hb_font_t *font) const + { + if (unlikely (glyph >= this->num_metrics)) + { + /* If this->num_metrics is zero, it means we don't have the metrics table + * for this direction: return default advance. Otherwise, it means that the + * glyph index is out of bound: return zero. */ + if (this->num_metrics) + return 0; + else + return this->default_advance; + } + + return this->table->longMetric[MIN (glyph, (uint32_t) this->num_advances - 1)].advance + + this->var->get_advance_var (glyph, font->coords, font->num_coords); // TODO Optimize?! + } + + public: + bool has_font_extents; + unsigned short ascender; + unsigned short descender; + unsigned short line_gap; + private: + unsigned int num_metrics; + unsigned int num_advances; + unsigned int default_advance; + }; + + protected: LongMetric longMetric[VAR]; /* Paired advance width and leading * bearing values for each glyph. The * value numOfHMetrics comes from commit f00a94e1ec73c08d4bde1f50bff57d2dc9583ca8 Author: Behdad Esfahbod <[email protected]> Date: Tue Nov 14 19:54:48 2017 -0800 Adjust privacy for recent changes diff --git a/src/hb-ot-cbdt-table.hh b/src/hb-ot-cbdt-table.hh index 000f6021..ca2859eb 100644 --- a/src/hb-ot-cbdt-table.hh +++ b/src/hb-ot-cbdt-table.hh @@ -288,7 +288,7 @@ struct BitmapSizeTable BYTE bitDepth; CHAR flags; -public: + public: DEFINE_SIZE_STATIC(48); }; @@ -315,6 +315,8 @@ struct GlyphBitmapDataFormat17 struct CBLC { + friend struct CBDT; + static const hb_tag_t tableTag = HB_OT_TAG_CBLC; inline bool sanitize (hb_sanitize_context_t *c) const @@ -325,7 +327,7 @@ struct CBLC sizeTables.sanitize (c, this)); } - public: + protected: const IndexSubtableRecord *find_table (hb_codepoint_t glyph, unsigned int *x_ppem, unsigned int *y_ppem) const { diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index b05c37e0..dba10226 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -43,6 +43,8 @@ namespace OT { struct loca { + friend struct glyf; + static const hb_tag_t tableTag = HB_OT_TAG_loca; inline bool sanitize (hb_sanitize_context_t *c) const @@ -51,7 +53,7 @@ struct loca return_trace (true); } - public: + protected: union { USHORT shortsZ[VAR]; /* Location offset divided by 2. */ ULONG longsZ[VAR]; /* Location offset. */ @@ -167,7 +169,7 @@ struct glyf unsigned int glyf_len; }; - public: + protected: BYTE dataX[VAR]; /* Glyphs data. */ DEFINE_SIZE_ARRAY (0, dataX); commit 7e2839c438beea216c7c8a3881e88961940e67be Author: Behdad Esfahbod <[email protected]> Date: Tue Nov 14 19:52:09 2017 -0800 [ot] Move hb_ot_face_glyf_accelerator_t diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 1ff58f2f..eb497e57 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -144,79 +144,6 @@ struct hb_ot_face_metrics_accelerator_t } }; -struct hb_ot_face_glyf_accelerator_t -{ - bool short_offset; - unsigned int num_glyphs; - const OT::loca *loca; - const OT::glyf *glyf; - hb_blob_t *loca_blob; - hb_blob_t *glyf_blob; - unsigned int glyf_len; - - inline void init (hb_face_t *face) - { - hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (face->reference_table (HB_OT_TAG_head)); - const OT::head *head = OT::Sanitizer<OT::head>::lock_instance (head_blob); - if ((unsigned int) head->indexToLocFormat > 1 || head->glyphDataFormat != 0) - { - /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ - hb_blob_destroy (head_blob); - return; - } - this->short_offset = 0 == head->indexToLocFormat; - hb_blob_destroy (head_blob); - - this->loca_blob = OT::Sanitizer<OT::loca>::sanitize (face->reference_table (HB_OT_TAG_loca)); - this->loca = OT::Sanitizer<OT::loca>::lock_instance (this->loca_blob); - this->glyf_blob = OT::Sanitizer<OT::glyf>::sanitize (face->reference_table (HB_OT_TAG_glyf)); - this->glyf = OT::Sanitizer<OT::glyf>::lock_instance (this->glyf_blob); - - this->num_glyphs = MAX (1u, hb_blob_get_length (this->loca_blob) / (this->short_offset ? 2 : 4)) - 1; - this->glyf_len = hb_blob_get_length (this->glyf_blob); - } - - inline void fini (void) - { - hb_blob_destroy (this->loca_blob); - hb_blob_destroy (this->glyf_blob); - } - - inline bool get_extents (hb_codepoint_t glyph, - hb_glyph_extents_t *extents) const - { - if (unlikely (glyph >= this->num_glyphs)) - return false; - - unsigned int start_offset, end_offset; - if (this->short_offset) - { - start_offset = 2 * this->loca->u.shortsZ[glyph]; - end_offset = 2 * this->loca->u.shortsZ[glyph + 1]; - } - else - { - start_offset = this->loca->u.longsZ[glyph]; - end_offset = this->loca->u.longsZ[glyph + 1]; - } - - if (start_offset > end_offset || end_offset > this->glyf_len) - return false; - - if (end_offset - start_offset < OT::glyfGlyphHeader::static_size) - return true; /* Empty glyph; zero extents. */ - - const OT::glyfGlyphHeader &glyph_header = OT::StructAtOffset<OT::glyfGlyphHeader> (this->glyf, start_offset); - - extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax); - extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax); - extents->width = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing; - extents->height = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing; - - return true; - } -}; - typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph); @@ -350,7 +277,7 @@ struct hb_ot_font_t hb_ot_face_cmap_accelerator_t cmap; hb_ot_face_metrics_accelerator_t h_metrics; hb_ot_face_metrics_accelerator_t v_metrics; - OT::hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf; + OT::hb_lazy_loader_t<OT::glyf::accelerator_t> glyf; OT::hb_lazy_loader_t<OT::CBDT::accelerator_t> cbdt; OT::hb_lazy_loader_t<OT::post::accelerator_t> post; OT::hb_lazy_loader_t<OT::kern::accelerator_t> kern; diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index dc7aa846..b05c37e0 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -28,6 +28,7 @@ #define HB_OT_GLYF_TABLE_HH #include "hb-open-type-private.hh" +#include "hb-ot-head-table.hh" namespace OT { @@ -78,26 +79,100 @@ struct glyf return_trace (true); } + struct GlyphHeader + { + SHORT numberOfContours; /* If the number of contours is + * greater than or equal to zero, + * this is a simple glyph; if negative, + * this is a composite glyph. */ + FWORD xMin; /* Minimum x for coordinate data. */ + FWORD yMin; /* Minimum y for coordinate data. */ + FWORD xMax; /* Maximum x for coordinate data. */ + FWORD yMax; /* Maximum y for coordinate data. */ + + DEFINE_SIZE_STATIC (10); + }; + + struct accelerator_t + { + inline void init (hb_face_t *face) + { + hb_blob_t *head_blob = Sanitizer<head>::sanitize (face->reference_table (HB_OT_TAG_head)); + const head *head_table = Sanitizer<head>::lock_instance (head_blob); + if ((unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0) + { + /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ + hb_blob_destroy (head_blob); + return; + } + short_offset = 0 == head_table->indexToLocFormat; + hb_blob_destroy (head_blob); + + loca_blob = Sanitizer<loca>::sanitize (face->reference_table (HB_OT_TAG_loca)); + loca_table = Sanitizer<loca>::lock_instance (loca_blob); + glyf_blob = Sanitizer<glyf>::sanitize (face->reference_table (HB_OT_TAG_glyf)); + glyf_table = Sanitizer<glyf>::lock_instance (glyf_blob); + + num_glyphs = MAX (1u, hb_blob_get_length (loca_blob) / (short_offset ? 2 : 4)) - 1; + glyf_len = hb_blob_get_length (glyf_blob); + } + + inline void fini (void) + { + hb_blob_destroy (loca_blob); + hb_blob_destroy (glyf_blob); + } + + inline bool get_extents (hb_codepoint_t glyph, + hb_glyph_extents_t *extents) const + { + if (unlikely (glyph >= num_glyphs)) + return false; + + unsigned int start_offset, end_offset; + if (short_offset) + { + start_offset = 2 * loca_table->u.shortsZ[glyph]; + end_offset = 2 * loca_table->u.shortsZ[glyph + 1]; + } + else + { + start_offset = loca_table->u.longsZ[glyph]; + end_offset = loca_table->u.longsZ[glyph + 1]; + } + + if (start_offset > end_offset || end_offset > glyf_len) + return false; + + if (end_offset - start_offset < GlyphHeader::static_size) + return true; /* Empty glyph; zero extents. */ + + const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset); + + extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax); + extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax); + extents->width = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing; + extents->height = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing; + + return true; + } + + private: + bool short_offset; + unsigned int num_glyphs; + const loca *loca_table; + const glyf *glyf_table; + hb_blob_t *loca_blob; + hb_blob_t *glyf_blob; + unsigned int glyf_len; + }; + public: BYTE dataX[VAR]; /* Glyphs data. */ DEFINE_SIZE_ARRAY (0, dataX); }; -struct glyfGlyphHeader -{ - SHORT numberOfContours; /* If the number of contours is - * greater than or equal to zero, - * this is a simple glyph; if negative, - * this is a composite glyph. */ - FWORD xMin; /* Minimum x for coordinate data. */ - FWORD yMin; /* Minimum y for coordinate data. */ - FWORD xMax; /* Maximum x for coordinate data. */ - FWORD yMax; /* Maximum y for coordinate data. */ - - DEFINE_SIZE_STATIC (10); -}; - } /* namespace OT */ commit c4e18e54dc5ffecac7b327bde9f52dd0927d6a08 Author: Behdad Esfahbod <[email protected]> Date: Tue Nov 14 19:47:31 2017 -0800 [ot] Move hb_ot_face_cbdt_accelerator_t diff --git a/src/hb-ot-cbdt-table.hh b/src/hb-ot-cbdt-table.hh index 3c6855b0..000f6021 100644 --- a/src/hb-ot-cbdt-table.hh +++ b/src/hb-ot-cbdt-table.hh @@ -371,6 +371,91 @@ struct CBDT likely (version.major == 2 || version.major == 3)); } + struct accelerator_t + { + inline void init (hb_face_t *face) + { + upem = face->get_upem(); + + cblc_blob = Sanitizer<CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC)); + cbdt_blob = Sanitizer<CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT)); + cbdt_len = hb_blob_get_length (cbdt_blob); + + if (hb_blob_get_length (cblc_blob) == 0) { + cblc = nullptr; + cbdt = nullptr; + return; /* Not a bitmap font. */ + } + cblc = Sanitizer<CBLC>::lock_instance (cblc_blob); + cbdt = Sanitizer<CBDT>::lock_instance (cbdt_blob); + + } + + inline void fini (void) + { + hb_blob_destroy (this->cblc_blob); + hb_blob_destroy (this->cbdt_blob); + } + + inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const + { + unsigned int x_ppem = upem, y_ppem = upem; /* TODO Use font ppem if available. */ + + if (!cblc) + return false; // Not a color bitmap font. + + const IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem); + if (!subtable_record || !x_ppem || !y_ppem) + return false; + + if (subtable_record->get_extents (extents)) + return true; + + unsigned int image_offset = 0, image_length = 0, image_format = 0; + if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, &image_format)) + return false; + + { + if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length)) + return false; + + switch (image_format) + { + case 17: { + if (unlikely (image_length < GlyphBitmapDataFormat17::min_size)) + return false; + + const GlyphBitmapDataFormat17& glyphFormat17 = + StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset); + glyphFormat17.glyphMetrics.get_extents (extents); + } + break; + default: + // TODO: Support other image formats. + return false; + } + } + + /* Convert to the font units. */ + extents->x_bearing *= upem / (float) x_ppem; + extents->y_bearing *= upem / (float) y_ppem; + extents->width *= upem / (float) x_ppem; + extents->height *= upem / (float) y_ppem; + + return true; + } + + private: + hb_blob_t *cblc_blob; + hb_blob_t *cbdt_blob; + const CBLC *cblc; + const CBDT *cbdt; + + unsigned int cbdt_len; + unsigned int upem; + }; + + protected: FixedVersion<>version; BYTE dataZ[VAR]; diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 2878c6f5..1ff58f2f 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -217,91 +217,6 @@ struct hb_ot_face_glyf_accelerator_t } }; -struct hb_ot_face_cbdt_accelerator_t -{ - hb_blob_t *cblc_blob; - hb_blob_t *cbdt_blob; - const OT::CBLC *cblc; - const OT::CBDT *cbdt; - - unsigned int cbdt_len; - unsigned int upem; - - inline void init (hb_face_t *face) - { - upem = face->get_upem(); - - cblc_blob = OT::Sanitizer<OT::CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC)); - cbdt_blob = OT::Sanitizer<OT::CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT)); - cbdt_len = hb_blob_get_length (cbdt_blob); - - if (hb_blob_get_length (cblc_blob) == 0) { - cblc = nullptr; - cbdt = nullptr; - return; /* Not a bitmap font. */ - } - cblc = OT::Sanitizer<OT::CBLC>::lock_instance (cblc_blob); - cbdt = OT::Sanitizer<OT::CBDT>::lock_instance (cbdt_blob); - - } - - inline void fini (void) - { - hb_blob_destroy (this->cblc_blob); - hb_blob_destroy (this->cbdt_blob); - } - - inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const - { - unsigned int x_ppem = upem, y_ppem = upem; /* TODO Use font ppem if available. */ - - if (!cblc) - return false; // Not a color bitmap font. - - const OT::IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem); - if (!subtable_record || !x_ppem || !y_ppem) - return false; - - if (subtable_record->get_extents (extents)) - return true; - - unsigned int image_offset = 0, image_length = 0, image_format = 0; - if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, &image_format)) - return false; - - { - /* TODO Move the following into CBDT struct when adding more formats. */ - - if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length)) - return false; - - switch (image_format) - { - case 17: { - if (unlikely (image_length < OT::GlyphBitmapDataFormat17::min_size)) - return false; - - const OT::GlyphBitmapDataFormat17& glyphFormat17 = - OT::StructAtOffset<OT::GlyphBitmapDataFormat17> (this->cbdt, image_offset); - glyphFormat17.glyphMetrics.get_extents (extents); - } - break; - default: - // TODO: Support other image formats. - return false; - } - } - - /* Convert to the font units. */ - extents->x_bearing *= upem / (float) x_ppem; - extents->y_bearing *= upem / (float) y_ppem; - extents->width *= upem / (float) x_ppem; - extents->height *= upem / (float) y_ppem; - - return true; - } -}; - typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph); @@ -436,7 +351,7 @@ struct hb_ot_font_t hb_ot_face_metrics_accelerator_t h_metrics; hb_ot_face_metrics_accelerator_t v_metrics; OT::hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf; - OT::hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt; + OT::hb_lazy_loader_t<OT::CBDT::accelerator_t> cbdt; OT::hb_lazy_loader_t<OT::post::accelerator_t> post; OT::hb_lazy_loader_t<OT::kern::accelerator_t> kern; }; diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh index 0c1aaed9..e3952a41 100644 --- a/src/hb-ot-post-table.hh +++ b/src/hb-ot-post-table.hh @@ -231,6 +231,7 @@ struct post return hb_string_t ((const char *) data, name_length); } + private: hb_blob_t *blob; uint32_t version; const ArrayOf<USHORT> *glyphNameIndex; commit 9b04b0384fe746bdb1885c57e1ce73c4c6cae9e5 Author: Behdad Esfahbod <[email protected]> Date: Tue Nov 14 19:31:50 2017 -0800 [ot] Fold hb_ot_face_post_accelerator_t diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 8d8d68b1..2878c6f5 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -302,39 +302,6 @@ struct hb_ot_face_cbdt_accelerator_t } }; -struct hb_ot_face_post_accelerator_t -{ - hb_blob_t *post_blob; - OT::post::accelerator_t accel; - - inline void init (hb_face_t *face) - { - hb_blob_t *blob = this->post_blob = OT::Sanitizer<OT::post>::sanitize (face->reference_table (HB_OT_TAG_post)); - accel.init (OT::Sanitizer<OT::post>::lock_instance (blob), hb_blob_get_length (blob)); - } - - inline void fini (void) - { - accel.fini (); - hb_blob_destroy (this->post_blob); - } - - inline bool get_glyph_name (hb_codepoint_t glyph, - char *name, unsigned int size) const - { - return this->accel.get_glyph_name (glyph, name, size); - } - - inline bool get_glyph_from_name (const char *name, int len, - hb_codepoint_t *glyph) const - { - if (unlikely (!len)) - return false; - - return this->accel.get_glyph_from_name (name, len, glyph); - } -}; - typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph); @@ -470,7 +437,7 @@ struct hb_ot_font_t hb_ot_face_metrics_accelerator_t v_metrics; OT::hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf; OT::hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt; - OT::hb_lazy_loader_t<hb_ot_face_post_accelerator_t> post; + OT::hb_lazy_loader_t<OT::post::accelerator_t> post; OT::hb_lazy_loader_t<OT::kern::accelerator_t> kern; }; diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh index 01d626bf..0c1aaed9 100644 --- a/src/hb-ot-post-table.hh +++ b/src/hb-ot-post-table.hh @@ -84,8 +84,12 @@ struct post struct accelerator_t { - inline void init (const post *table, unsigned int post_len) + inline void init (hb_face_t *face) { + blob = Sanitizer<post>::sanitize (face->reference_table (HB_OT_TAG_post)); + const post *table = Sanitizer<post>::lock_instance (blob); + unsigned int table_length = hb_blob_get_length (blob); + version = table->version.to_int (); index_to_offset.init (); if (version != 0x00020000) @@ -96,7 +100,7 @@ struct post glyphNameIndex = &v2.glyphNameIndex; pool = &StructAfter<uint8_t> (v2.glyphNameIndex); - const uint8_t *end = (uint8_t *) table + post_len; + const uint8_t *end = (uint8_t *) table + table_length; for (const uint8_t *data = pool; data < end && data + *data <= end; data += 1 + *data) { uint32_t *offset = index_to_offset.push (); @@ -227,6 +231,7 @@ struct post return hb_string_t ((const char *) data, name_length); } + hb_blob_t *blob; uint32_t version; const ArrayOf<USHORT> *glyphNameIndex; hb_prealloced_array_t<uint32_t, 1> index_to_offset; commit 702d86ba6b4a2e41cbee46fea18b3f8eb8986dc9 Author: Behdad Esfahbod <[email protected]> Date: Tue Nov 14 19:25:38 2017 -0800 [ot] Fold hb_ot_face_kern_accelerator_t diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 47416012..8d8d68b1 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -335,27 +335,6 @@ struct hb_ot_face_post_accelerator_t } }; -struct hb_ot_face_kern_accelerator_t -{ - hb_blob_t *kern_blob; - OT::kern::accelerator_t accel; - - inline void init (hb_face_t *face) - { - hb_blob_t *blob = this->kern_blob = OT::Sanitizer<OT::kern>::sanitize (face->reference_table (HB_OT_TAG_kern)); - accel.init (OT::Sanitizer<OT::kern>::lock_instance (blob), hb_blob_get_length (blob)); - } - - inline void fini (void) - { - accel.fini (); - hb_blob_destroy (this->kern_blob); - } - - inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return accel.get_h_kerning (left, right); } -}; - typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph); @@ -492,7 +471,7 @@ struct hb_ot_font_t OT::hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf; OT::hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt; OT::hb_lazy_loader_t<hb_ot_face_post_accelerator_t> post; - OT::hb_lazy_loader_t<hb_ot_face_kern_accelerator_t> kern; + OT::hb_lazy_loader_t<OT::kern::accelerator_t> kern; }; diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 5fd2e20e..aa293b8d 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -358,17 +358,22 @@ struct kern struct accelerator_t { - inline void init (const kern *table_, unsigned int table_length_) + inline void init (hb_face_t *face) { - table = table_; - table_length = table_length_; + blob = Sanitizer<kern>::sanitize (face->reference_table (HB_OT_TAG_kern)); + table = Sanitizer<kern>::lock_instance (blob); + table_length = hb_blob_get_length (blob); + } + inline void fini (void) + { + hb_blob_destroy (blob); } - inline void fini (void) {} inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const { return table->get_h_kerning (left, right, table_length); } private: + hb_blob_t *blob; const kern *table; unsigned int table_length; }; commit 909de95a112ffe4d05ddcfed97a235763e8af068 Author: Behdad Esfahbod <[email protected]> Date: Tue Nov 14 16:22:52 2017 -0800 Minor build fix diff --git a/src/Makefile.am b/src/Makefile.am index df99afee..4140cbce 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -99,6 +99,9 @@ SUBDIRS += hb-ucdn HBCFLAGS += -I$(srcdir)/hb-ucdn HBLIBS += hb-ucdn/libhb-ucdn.la HBSOURCES += $(HB_UCDN_sources) +hb-ucdn/libhb-ucdn.la: ucdn +ucdn: + @$(MAKE) $(AM_MAKEFLAGS) -C hb-ucdn endif DIST_SUBDIRS += hb-ucdn _______________________________________________ HarfBuzz mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/harfbuzz
