diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 3514fcc27..25fe51192 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -39,10 +39,15 @@ 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; + const OT::CmapSubtable *cmap; const OT::CmapSubtable *cmap_uvs; hb_blob_t *cmap_blob; @@ -59,21 +64,41 @@ _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->numberOfHMetrics; + 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); } - 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))) + + /* Setup vertical metrics. */ { - hb_blob_destroy (ot_font->hmtx_blob); - free (ot_font); - return NULL; + 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->hmtx = OT::Sanitizer::lock_instance (ot_font->hmtx_blob); 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); @@ -109,6 +134,7 @@ _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); free (ot_font); } @@ -149,12 +175,12 @@ hb_ot_get_glyph_h_advance (hb_font_t *font 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; /* Maybe better to return notdef's advance instead? */ + return 0; if (glyph >= ot_font->num_hmetrics) glyph = ot_font->num_hmetrics - 1; - return font->em_scale_x (ot_font->hmtx->longHorMetric[glyph].advanceWidth); + return font->em_scale_x (ot_font->hmtx->longHorMetric[glyph].advance); } static hb_position_t @@ -163,8 +189,15 @@ hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED, hb_codepoint_t glyph, void *user_data HB_UNUSED) { - /* TODO */ - return 0; + 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); } static hb_bool_t diff --git a/src/hb-ot-hhea-table.hh b/src/hb-ot-hhea-table.hh index d43320016..9999bcab4 100644 --- a/src/hb-ot-hhea-table.hh +++ b/src/hb-ot-hhea-table.hh @@ -35,14 +35,17 @@ namespace OT { /* * hhea -- The Horizontal Header Table + * vhea -- The Vertical Header Table */ #define HB_OT_TAG_hhea HB_TAG('h','h','e','a') +#define HB_OT_TAG_vhea HB_TAG('v','h','e','a') -struct hhea +struct _hea { - static const hb_tag_t tableTag = HB_OT_TAG_hhea; + static const hb_tag_t hheaTag = HB_OT_TAG_hhea; + static const hb_tag_t vheaTag = HB_OT_TAG_vhea; inline bool sanitize (hb_sanitize_context_t *c) { TRACE_SANITIZE (this); @@ -51,45 +54,45 @@ struct hhea public: FixedVersion version; /* 0x00010000u for version 1.0. */ - FWORD ascender; /* Typographic ascent. - * (Distance from baseline of highest - * ascender) */ - FWORD descender; /* Typographic descent. - * (Distance from baseline of lowest - * descender) */ - FWORD lineGap; /* Typographic line gap. Negative - * LineGap values are treated as zero - * in Windows 3.1, System 6, and - * System 7. */ - UFWORD advanceWidthMax; /* Maximum advance width value in - * 'hmtx' table. */ - FWORD minLeftSideBearing; /* Minimum left sidebearing value in - * 'hmtx' table. */ - FWORD minRightSideBearing; /* Minimum right sidebearing value; + FWORD ascender; /* Typographic ascent. */ + FWORD descender; /* Typographic descent. */ + FWORD lineGap; /* Typographic line gap. */ + UFWORD advanceMax; /* Maximum advance width/height value in + * metrics table. */ + FWORD minLeadingBearing; /* Minimum left/top sidebearing value in + * metrics table. */ + FWORD minTrailingBearing; /* Minimum right/bottom sidebearing value; * calculated as Min(aw - lsb - - * (xMax - xMin)). */ - FWORD xMaxExtent; /* Max(lsb + (xMax - xMin)). */ + * (xMax - xMin)) for horizontal. */ + FWORD maxExtent; /* horizontal: Max(lsb + (xMax - xMin)), + * vertical: minLeadingBearing+(yMax-yMin). */ SHORT caretSlopeRise; /* Used to calculate the slope of the - * cursor (rise/run); 1 for vertical. */ - SHORT caretSlopeRun; /* 0 for vertical. */ + * cursor (rise/run); 1 for vertical caret, + * 0 for horizontal.*/ + SHORT caretSlopeRun; /* 0 for vertical caret, 1 for horizontal. */ SHORT caretOffset; /* The amount by which a slanted * highlight on a glyph needs * to be shifted to produce the * best appearance. Set to 0 for - * non--slanted fonts */ - SHORT reserved1; /* set to 0 */ - SHORT reserved2; /* set to 0 */ - SHORT reserved3; /* set to 0 */ - SHORT reserved4; /* set to 0 */ + * non-slanted fonts. */ + SHORT reserved1; /* Set to 0. */ + SHORT reserved2; /* Set to 0. */ + SHORT reserved3; /* Set to 0. */ + SHORT reserved4; /* Set to 0. */ SHORT metricDataFormat; /* 0 for current format. */ - USHORT numberOfHMetrics; /* Number of hMetric entries in 'hmtx' - * table */ + USHORT numberOfMetrics; /* Number of LongMetric entries in metric + * table. */ public: DEFINE_SIZE_STATIC (36); }; +struct hhea : _hea { + static const hb_tag_t tableTag = HB_OT_TAG_hhea; +}; +struct vhea : _hea { + static const hb_tag_t tableTag = HB_OT_TAG_vhea; +}; + } /* namespace OT */ diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index e918e3b3f..642c63680 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -35,22 +35,25 @@ namespace OT { /* * hmtx -- The Horizontal Metrics Table + * vmtx -- The Vertical Metrics Table */ #define HB_OT_TAG_hmtx HB_TAG('h','m','t','x') +#define HB_OT_TAG_vmtx HB_TAG('v','m','t','x') -struct LongHorMetric +struct LongMetric { - USHORT advanceWidth; - SHORT lsb; + USHORT advance; /* Advance width/height. */ + SHORT lsb; /* Leading (left/top) side bearing. */ public: DEFINE_SIZE_STATIC (4); }; -struct hmtx +struct _mtx { - static const hb_tag_t tableTag = HB_OT_TAG_hmtx; + 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) { TRACE_SANITIZE (this); @@ -60,7 +63,7 @@ struct hmtx } public: - LongHorMetric longHorMetric[VAR]; /* Paired advance width and left side + LongMetric longHorMetric[VAR]; /* Paired advance width and leading * bearing values for each glyph. The * value numOfHMetrics comes from * the 'hhea' table. If the font is @@ -68,23 +71,29 @@ struct hmtx * be in the array, but that entry is * required. The last entry applies to * all subsequent glyphs. */ - SHORT leftSideBearingX[VAR]; /* Here the advanceWidth is assumed - * to be the same as the advanceWidth + SHORT leadingBearingX[VAR]; /* Here the advance is assumed + * to be the same as the advance * for the last entry above. The * number of entries in this array is * derived from numGlyphs (from 'maxp' - * table) minus numberOfHMetrics. This - * generally is used with a run of - * monospaced glyphs (e.g., Kanji + * table) minus numberOfLongMetrics. + * This generally is used with a run + * of monospaced glyphs (e.g., Kanji * fonts or Courier fonts). Only one * run is allowed and it must be at * the end. This allows a monospaced - * font to vary the left side bearing + * font to vary the side bearing * values for each glyph. */ public: - DEFINE_SIZE_ARRAY2 (0, longHorMetric, leftSideBearingX); + DEFINE_SIZE_ARRAY2 (0, longHorMetric, leadingBearingX); }; +struct hmtx : _mtx { + static const hb_tag_t tableTag = HB_OT_TAG_hmtx; +}; +struct vmtx : _mtx { + static const hb_tag_t tableTag = HB_OT_TAG_vmtx; +}; } /* namespace OT */