From be1cca270257bfdfee3fbe821175269713acf408 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 25 Sep 2014 16:53:24 +0300 Subject: [PATCH] [ot-font] Add metrics_accel_t --- src/hb-ot-font.cc | 111 ++++++++++++++++++---------------------- src/hb-ot-hhea-table.hh | 2 +- src/hb-ot-hmtx-table.hh | 4 +- 3 files changed, 54 insertions(+), 63 deletions(-) diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 25fe51192..d629c4100 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -35,18 +35,55 @@ #include "hb-ot-hmtx-table.hh" +struct metrics_accel_t +{ + unsigned int num_metrics; + unsigned int num_advances; + const OT::_mtx *table; + hb_blob_t *blob; + + inline void init (hb_font_t *font, hb_tag_t _hea_tag, hb_tag_t _mtx_tag) + { + this->num_metrics = font->face->get_num_glyphs (); + + hb_blob_t *_hea_blob = OT::Sanitizer::sanitize (font->face->reference_table (_hea_tag)); + const OT::_hea *_hea = OT::Sanitizer::lock_instance (_hea_blob); + this->num_advances = _hea->numberOfLongMetrics; + hb_blob_destroy (_hea_blob); + + this->blob = OT::Sanitizer::sanitize (font->face->reference_table (_mtx_tag)); + if (unlikely (!this->num_advances || + 2 * (this->num_advances + this->num_metrics) < hb_blob_get_length (this->blob))) + { + hb_blob_destroy (this->blob); + this->blob = hb_blob_get_empty (); + } + this->table = OT::Sanitizer::lock_instance (this->blob); + } + + inline void fini (void) + { + hb_blob_destroy (this->blob); + } + + inline unsigned int get_advance (hb_codepoint_t glyph) const + { + if (unlikely (glyph >= this->num_metrics)) + return 0; + + if (glyph >= this->num_advances) + glyph = this->num_advances - 1; + + return this->table->longMetric[glyph].advance; + } +}; struct hb_ot_font_t { unsigned int num_glyphs; - unsigned int num_hmetrics; - const OT::hmtx *hmtx; - hb_blob_t *hmtx_blob; - - unsigned int num_vmetrics; - const OT::vmtx *vmtx; - hb_blob_t *vmtx_blob; + metrics_accel_t h_metrics; + metrics_accel_t v_metrics; const OT::CmapSubtable *cmap; const OT::CmapSubtable *cmap_uvs; @@ -64,41 +101,9 @@ _hb_ot_font_create (hb_font_t *font) ot_font->num_glyphs = font->face->get_num_glyphs (); - /* Setup horizontal metrics. */ - { - hb_blob_t *hhea_blob = OT::Sanitizer::sanitize (font->face->reference_table (HB_OT_TAG_hhea)); - const OT::hhea *hhea = OT::Sanitizer::lock_instance (hhea_blob); - ot_font->num_hmetrics = hhea->numberOfMetrics; - hb_blob_destroy (hhea_blob); - - ot_font->hmtx_blob = OT::Sanitizer::sanitize (font->face->reference_table (HB_OT_TAG_hmtx)); - if (unlikely (!ot_font->num_hmetrics || - 2 * (ot_font->num_hmetrics + ot_font->num_glyphs) < hb_blob_get_length (ot_font->hmtx_blob))) - { - hb_blob_destroy (ot_font->hmtx_blob); - free (ot_font); - return NULL; - } - ot_font->hmtx = OT::Sanitizer::lock_instance (ot_font->hmtx_blob); - } - - /* Setup vertical metrics. */ - { - hb_blob_t *vhea_blob = OT::Sanitizer::sanitize (font->face->reference_table (HB_OT_TAG_vhea)); - const OT::vhea *vhea = OT::Sanitizer::lock_instance (vhea_blob); - ot_font->num_vmetrics = vhea->numberOfMetrics; - hb_blob_destroy (vhea_blob); - - ot_font->vmtx_blob = OT::Sanitizer::sanitize (font->face->reference_table (HB_TAG('v','m','t','x'))); - if (unlikely (!ot_font->num_vmetrics || - 2 * (ot_font->num_vmetrics + ot_font->num_glyphs) < hb_blob_get_length (ot_font->vmtx_blob))) - { - hb_blob_destroy (ot_font->vmtx_blob); - free (ot_font); - return NULL; - } - ot_font->vmtx = OT::Sanitizer::lock_instance (ot_font->vmtx_blob); - } + ot_font->h_metrics.init (font, HB_OT_TAG_hhea, HB_OT_TAG_hmtx); + /* TODO Can we do this lazily? */ + ot_font->v_metrics.init (font, HB_OT_TAG_vhea, HB_OT_TAG_vmtx); ot_font->cmap_blob = OT::Sanitizer::sanitize (font->face->reference_table (HB_OT_TAG_cmap)); const OT::cmap *cmap = OT::Sanitizer::lock_instance (ot_font->cmap_blob); @@ -133,8 +138,8 @@ static void _hb_ot_font_destroy (hb_ot_font_t *ot_font) { hb_blob_destroy (ot_font->cmap_blob); - hb_blob_destroy (ot_font->hmtx_blob); - hb_blob_destroy (ot_font->vmtx_blob); + ot_font->h_metrics.fini (); + ot_font->v_metrics.fini (); free (ot_font); } @@ -173,14 +178,7 @@ hb_ot_get_glyph_h_advance (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; - - if (unlikely (glyph >= ot_font->num_glyphs)) - return 0; - - if (glyph >= ot_font->num_hmetrics) - glyph = ot_font->num_hmetrics - 1; - - return font->em_scale_x (ot_font->hmtx->longHorMetric[glyph].advance); + return font->em_scale_x (ot_font->h_metrics.get_advance (glyph)); } static hb_position_t @@ -190,14 +188,7 @@ hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; - - if (unlikely (glyph >= ot_font->num_glyphs)) - return 0; - - if (glyph >= ot_font->num_vmetrics) - glyph = ot_font->num_vmetrics - 1; - - return font->em_scale_y (-ot_font->vmtx->longHorMetric[glyph].advance); + return font->em_scale_y (-ot_font->v_metrics.get_advance (glyph)); } static hb_bool_t diff --git a/src/hb-ot-hhea-table.hh b/src/hb-ot-hhea-table.hh index 9999bcab4..6bf6d5f5f 100644 --- a/src/hb-ot-hhea-table.hh +++ b/src/hb-ot-hhea-table.hh @@ -80,7 +80,7 @@ struct _hea SHORT reserved3; /* Set to 0. */ SHORT reserved4; /* Set to 0. */ SHORT metricDataFormat; /* 0 for current format. */ - USHORT numberOfMetrics; /* Number of LongMetric entries in metric + USHORT numberOfLongMetrics; /* Number of LongMetric entries in metric * table. */ public: DEFINE_SIZE_STATIC (36); diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index 642c63680..932f97301 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -63,7 +63,7 @@ struct _mtx } public: - LongMetric longHorMetric[VAR]; /* Paired advance width and leading + LongMetric longMetric[VAR]; /* Paired advance width and leading * bearing values for each glyph. The * value numOfHMetrics comes from * the 'hhea' table. If the font is @@ -85,7 +85,7 @@ struct _mtx * font to vary the side bearing * values for each glyph. */ public: - DEFINE_SIZE_ARRAY2 (0, longHorMetric, leadingBearingX); + DEFINE_SIZE_ARRAY2 (0, longMetric, leadingBearingX); }; struct hmtx : _mtx {