summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-12-15 13:00:39 +0100
committerLars Knoll <lars.knoll@qt.io>2017-12-30 15:17:28 +0000
commit809200a83e366141d543336503635cf57c626434 (patch)
treefc3aa70aa67f69ea2247a7ef30819ff4e98ead1b /src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
parent89b0364cded81457eaa264c1634af5d082da3c21 (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.hh123
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 */