Implement hmtx/vmtx metrics read from hvar/vvar
diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index 6b2cc86..cf1f3b4 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh
@@ -53,6 +53,18 @@ DEFINE_SIZE_STATIC (4); }; +struct hmtxvmtx_accelerator_base_t +{ + static int get_side_bearing_var_tt (hb_font_t *font HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + bool is_vertical HB_UNUSED) + { return 0; } /* Not implemented yet */ + static unsigned int get_advance_var_tt (hb_font_t *font HB_UNUSED, + hb_codepoint_t glyph HB_UNUSED, + bool is_vertical HB_UNUSED) + { return 0; } /* Not implemented yet */ +}; + template <typename T, typename H> struct hmtxvmtx { @@ -133,7 +145,7 @@ if (c->plan->old_gid_for_new_gid (_, &old_gid)) return hb_pair (_mtx.get_advance (old_gid), _mtx.get_side_bearing (old_gid)); else - return hb_pair (0u, 0u); + return hb_pair (0u, 0); }) ; @@ -153,13 +165,14 @@ return_trace (true); } - struct accelerator_t + struct accelerator_t : hmtxvmtx_accelerator_base_t { friend struct hmtxvmtx; void init (hb_face_t *face, unsigned int default_advance_ = 0) { + memset (this, 0, sizeof (*this)); default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face); num_advances = T::is_horizontal ? face->table.hhea->numberOfLongMetrics : face->table.vhea->numberOfLongMetrics; @@ -190,8 +203,9 @@ var_table.destroy (); } - /* TODO Add variations version. */ - unsigned int get_side_bearing (hb_codepoint_t glyph) const + bool has_data () const { return table.get () != nullptr; } + + int get_side_bearing (hb_codepoint_t glyph) const { if (glyph < num_advances) return table->longMetricZ[glyph].sb; @@ -203,6 +217,22 @@ return bearings[glyph - num_advances]; } + int get_side_bearing (hb_font_t *font, hb_codepoint_t glyph) const + { + int side_bearing = get_side_bearing (glyph); + if (likely (glyph < num_metrics)) + { + if (font->num_coords) + { + if (var_table.get_blob () != hb_blob_get_empty ()) + side_bearing += var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?! + else + side_bearing = get_side_bearing_var_tt (font, glyph, T::tableTag==HB_OT_TAG_vmtx); + } + } + return side_bearing; + } + unsigned int get_advance (hb_codepoint_t glyph) const { if (unlikely (glyph >= num_metrics)) @@ -225,7 +255,13 @@ unsigned int advance = get_advance (glyph); if (likely (glyph < num_metrics)) { - advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?! + if (font->num_coords) + { + if (var_table.get_blob () != hb_blob_get_empty ()) + advance += roundf (var_table->get_advance_var (glyph, font->coords, font->num_coords)); // TODO Optimize?! + else + advance = get_advance_var_tt (font, glyph, T::tableTag==HB_OT_TAG_vmtx); + } } return advance; }
diff --git a/src/hb-ot-var-hvar-table.hh b/src/hb-ot-var-hvar-table.hh index a8d9fe3..628a600 100644 --- a/src/hb-ot-var-hvar-table.hh +++ b/src/hb-ot-var-hvar-table.hh
@@ -63,7 +63,7 @@ } { /* Repack it. */ - unsigned int n = get_inner_bitcount (); + unsigned int n = get_inner_bit_count (); unsigned int outer = u >> n; unsigned int inner = u & ((1 << n) - 1); u = (outer<<16) | inner; @@ -72,10 +72,9 @@ return u; } - protected: - unsigned int get_width () const { return ((format >> 4) & 3) + 1; } - - unsigned int get_inner_bitcount () const { return (format & 0xF) + 1; } + unsigned int get_map_count () const { return mapCount; } + unsigned int get_width () const { return ((format >> 4) & 3) + 1; } + unsigned int get_inner_bit_count () const { return (format & 0xF) + 1; } protected: HBUINT16 format; /* A packed field that describes the compressed @@ -121,7 +120,15 @@ return (this+varStore).get_delta (varidx, coords, coord_count); } - bool has_sidebearing_deltas () const { return lsbMap && rsbMap; } + float get_side_bearing_var (hb_codepoint_t glyph, + const int *coords, unsigned int coord_count) const + { + if (!has_side_bearing_deltas ()) return 0.f; + unsigned int varidx = (this+lsbMap).map (glyph); + return (this+varStore).get_delta (varidx, coords, coord_count); + } + + bool has_side_bearing_deltas () const { return lsbMap && rsbMap; } protected: FixedVersion<>version; /* Version of the metrics variation table