diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-12-15 13:00:39 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-12-30 15:17:28 +0000 |
commit | 809200a83e366141d543336503635cf57c626434 (patch) | |
tree | fc3aa70aa67f69ea2247a7ef30819ff4e98ead1b /src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh | |
parent | 89b0364cded81457eaa264c1634af5d082da3c21 (diff) |
Update bundled HarfBuzz-NG copy to 1.7.4
This is the latest released version, fixing a large amount
of bugs and adding Unicode 10 support.
[ChangeLog] Bundled HarfBuzz-NG copy updated to 1.7.4
Change-Id: Idc8092dfc4e593d64fff2fd51ff9e1b3d84049a7
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh')
-rw-r--r-- | src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh | 123 |
1 files changed, 114 insertions, 9 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh index a9606b3d27..e710aee42e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh @@ -28,6 +28,9 @@ #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" namespace OT { @@ -50,13 +53,9 @@ struct LongMetric DEFINE_SIZE_STATIC (4); }; -struct _mtx +template <typename T> +struct hmtxvmtx { - static const hb_tag_t tableTag = HB_TAG('_','m','t','x'); - - 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); @@ -65,7 +64,107 @@ struct _mtx return_trace (true); } - public: + struct accelerator_t + { + inline void init (hb_face_t *face, + unsigned int default_advance_ = 0) + { + default_advance = default_advance_ ? default_advance_ : face->get_upem (); + + bool got_font_extents = false; + if (T::os2Tag) + { + 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)) + { + 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 (T::headerTag)); + const _hea *_hea_table = Sanitizer<_hea>::lock_instance (_hea_blob); + num_advances = _hea_table->numberOfLongMetrics; + if (!got_font_extents) + { + ascender = _hea_table->ascender; + descender = _hea_table->descender; + line_gap = _hea_table->lineGap; + got_font_extents = (ascender | descender) != 0; + } + hb_blob_destroy (_hea_blob); + + has_font_extents = got_font_extents; + + 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); + 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 (!num_advances)) + { + num_metrics = num_advances = 0; + hb_blob_destroy (blob); + blob = hb_blob_get_empty (); + } + table = Sanitizer<hmtxvmtx>::lock_instance (blob); + + var_blob = Sanitizer<HVARVVAR>::sanitize (face->reference_table (T::variationsTag)); + var_table = Sanitizer<HVARVVAR>::lock_instance (var_blob); + } + + inline void fini (void) + { + 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 >= num_metrics)) + { + /* 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 (num_metrics) + return 0; + else + return default_advance; + } + + 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: + 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; + + const hmtxvmtx *table; + hb_blob_t *blob; + const HVARVVAR *var_table; + hb_blob_t *var_blob; + }; + + protected: LongMetric longMetric[VAR]; /* Paired advance width and leading * bearing values for each glyph. The * value numOfHMetrics comes from @@ -91,11 +190,17 @@ struct _mtx DEFINE_SIZE_ARRAY2 (0, longMetric, leadingBearingX); }; -struct hmtx : _mtx { +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 : _mtx { +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 */ |