[HarfBuzz] harfbuzz: Branch 'master' - 6 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Thu Sep 25 14:20:15 PDT 2014
src/hb-ot-font.cc | 208 +++++++++++++++++++++++++++++-----------------
src/hb-ot-hhea-table.hh | 63 +++++++------
src/hb-ot-hmtx-table.hh | 35 ++++---
util/helper-cairo-ansi.cc | 4
4 files changed, 189 insertions(+), 121 deletions(-)
New commits:
commit 80f77282264afb1356351024b1f062b2824bba3b
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Sep 25 17:59:46 2014 +0300
[util] Fix ansi output when surface is empty
diff --git a/util/helper-cairo-ansi.cc b/util/helper-cairo-ansi.cc
index 376bf2b..50f9eb4 100644
--- a/util/helper-cairo-ansi.cc
+++ b/util/helper-cairo-ansi.cc
@@ -63,10 +63,10 @@ helper_cairo_surface_write_to_ansi_stream (cairo_surface_t *surface,
* Find the tight image top/bottom and only print in between. */
/* Use corner color as background color. */
- uint32_t bg_color = * (uint32_t *) data;
+ uint32_t bg_color = data ? * (uint32_t *) data : 0;
/* Drop first row while empty */
- while (height)
+ while (height)
{
unsigned int i;
for (i = 0; i < width; i++)
commit 156852991e18e5ac256ee4d6b2916931cc274977
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Sep 25 17:45:49 2014 +0300
[ot-font] Add hb_ot_face_cmap_accelerator_t
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index 91df5ca..2af2f54 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -91,14 +91,72 @@ struct hb_ot_face_metrics_accelerator_t
}
};
+struct hb_ot_face_cmap_accelerator_t
+{
+ const OT::CmapSubtable *table;
+ const OT::CmapSubtable *uvs_table;
+ hb_blob_t *blob;
+
+ inline void init (hb_face_t *face)
+ {
+ this->blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap));
+ const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob);
+ const OT::CmapSubtable *subtable = NULL;
+ const OT::CmapSubtable *subtable_uvs = NULL;
+
+ /* 32-bit subtables. */
+ if (!subtable) subtable = cmap->find_subtable (3, 10);
+ if (!subtable) subtable = cmap->find_subtable (0, 6);
+ if (!subtable) subtable = cmap->find_subtable (0, 4);
+ /* 16-bit subtables. */
+ if (!subtable) subtable = cmap->find_subtable (3, 1);
+ if (!subtable) subtable = cmap->find_subtable (0, 3);
+ if (!subtable) subtable = cmap->find_subtable (0, 2);
+ if (!subtable) subtable = cmap->find_subtable (0, 1);
+ if (!subtable) subtable = cmap->find_subtable (0, 0);
+ /* Meh. */
+ if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
+
+ /* UVS subtable. */
+ if (!subtable_uvs) subtable_uvs = cmap->find_subtable (0, 5);
+ /* Meh. */
+ if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtable);
+
+ this->table = subtable;
+ this->uvs_table = subtable_uvs;
+ }
+
+ inline void fini (void)
+ {
+ hb_blob_destroy (this->blob);
+ }
+
+ inline bool get_glyph (hb_codepoint_t unicode,
+ hb_codepoint_t variation_selector,
+ hb_codepoint_t *glyph) const
+ {
+ if (unlikely (variation_selector))
+ {
+ switch (this->uvs_table->get_glyph_variant (unicode,
+ variation_selector,
+ glyph))
+ {
+ case OT::GLYPH_VARIANT_NOT_FOUND: return false;
+ case OT::GLYPH_VARIANT_FOUND: return true;
+ case OT::GLYPH_VARIANT_USE_DEFAULT: break;
+ }
+ }
+
+ return this->table->get_glyph (unicode, glyph);
+ }
+};
+
+
struct hb_ot_font_t
{
+ hb_ot_face_cmap_accelerator_t cmap;
hb_ot_face_metrics_accelerator_t h_metrics;
hb_ot_face_metrics_accelerator_t v_metrics;
-
- const OT::CmapSubtable *cmap;
- const OT::CmapSubtable *cmap_uvs;
- hb_blob_t *cmap_blob;
};
@@ -113,35 +171,9 @@ _hb_ot_font_create (hb_font_t *font)
unsigned int upem = face->get_upem ();
+ ot_font->cmap.init (face);
ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, upem>>1);
- /* TODO Can we do this lazily? */
- ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, upem);
-
- ot_font->cmap_blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap));
- const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (ot_font->cmap_blob);
- const OT::CmapSubtable *subtable = NULL;
- const OT::CmapSubtable *subtable_uvs = NULL;
-
- /* 32-bit subtables. */
- if (!subtable) subtable = cmap->find_subtable (3, 10);
- if (!subtable) subtable = cmap->find_subtable (0, 6);
- if (!subtable) subtable = cmap->find_subtable (0, 4);
- /* 16-bit subtables. */
- if (!subtable) subtable = cmap->find_subtable (3, 1);
- if (!subtable) subtable = cmap->find_subtable (0, 3);
- if (!subtable) subtable = cmap->find_subtable (0, 2);
- if (!subtable) subtable = cmap->find_subtable (0, 1);
- if (!subtable) subtable = cmap->find_subtable (0, 0);
- /* Meh. */
- if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
-
- /* UVS subtable. */
- if (!subtable_uvs) subtable_uvs = cmap->find_subtable (0, 5);
- /* Meh. */
- if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtable);
-
- ot_font->cmap = subtable;
- ot_font->cmap_uvs = subtable_uvs;
+ ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, upem); /* TODO Can we do this lazily? */
return ot_font;
}
@@ -149,7 +181,7 @@ _hb_ot_font_create (hb_font_t *font)
static void
_hb_ot_font_destroy (hb_ot_font_t *ot_font)
{
- hb_blob_destroy (ot_font->cmap_blob);
+ ot_font->cmap.fini ();
ot_font->h_metrics.fini ();
ot_font->v_metrics.fini ();
@@ -167,20 +199,7 @@ hb_ot_get_glyph (hb_font_t *font HB_UNUSED,
{
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
-
- if (unlikely (variation_selector))
- {
- switch (ot_font->cmap_uvs->get_glyph_variant (unicode,
- variation_selector,
- glyph))
- {
- case OT::GLYPH_VARIANT_NOT_FOUND: return false;
- case OT::GLYPH_VARIANT_FOUND: return true;
- case OT::GLYPH_VARIANT_USE_DEFAULT: break;
- }
- }
-
- return ot_font->cmap->get_glyph (unicode, glyph);
+ return ot_font->cmap.get_glyph (unicode, variation_selector, glyph);
}
static hb_position_t
commit d088ccaf11d9475fe0d269ce130b1793b8a1ffbf
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Sep 25 17:26:56 2014 +0300
[ot-font] Minor
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index 24de830..91df5ca 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -35,7 +35,7 @@
#include "hb-ot-hmtx-table.hh"
-struct metrics_accel_t
+struct hb_ot_face_metrics_accelerator_t
{
unsigned int num_metrics;
unsigned int num_advances;
@@ -43,19 +43,19 @@ struct metrics_accel_t
const OT::_mtx *table;
hb_blob_t *blob;
- inline void init (hb_font_t *font,
+ inline void init (hb_face_t *face,
hb_tag_t _hea_tag, hb_tag_t _mtx_tag,
unsigned int default_advance)
{
this->default_advance = default_advance;
- this->num_metrics = font->face->get_num_glyphs ();
+ this->num_metrics = face->get_num_glyphs ();
- hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (font->face->reference_table (_hea_tag));
+ hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_table (_hea_tag));
const OT::_hea *_hea = OT::Sanitizer<OT::_hea>::lock_instance (_hea_blob);
this->num_advances = _hea->numberOfLongMetrics;
hb_blob_destroy (_hea_blob);
- this->blob = OT::Sanitizer<OT::_mtx>::sanitize (font->face->reference_table (_mtx_tag));
+ this->blob = OT::Sanitizer<OT::_mtx>::sanitize (face->reference_table (_mtx_tag));
if (unlikely (!this->num_advances ||
2 * (this->num_advances + this->num_metrics) < hb_blob_get_length (this->blob)))
{
@@ -93,8 +93,8 @@ struct metrics_accel_t
struct hb_ot_font_t
{
- metrics_accel_t h_metrics;
- metrics_accel_t v_metrics;
+ hb_ot_face_metrics_accelerator_t h_metrics;
+ hb_ot_face_metrics_accelerator_t v_metrics;
const OT::CmapSubtable *cmap;
const OT::CmapSubtable *cmap_uvs;
@@ -106,17 +106,18 @@ static hb_ot_font_t *
_hb_ot_font_create (hb_font_t *font)
{
hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t));
+ hb_face_t *face = font->face;
if (unlikely (!ot_font))
return NULL;
- unsigned int upem = font->face->get_upem ();
+ unsigned int upem = face->get_upem ();
- ot_font->h_metrics.init (font, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, upem>>1);
+ ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, upem>>1);
/* TODO Can we do this lazily? */
- ot_font->v_metrics.init (font, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, upem);
+ ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, upem);
- ot_font->cmap_blob = OT::Sanitizer<OT::cmap>::sanitize (font->face->reference_table (HB_OT_TAG_cmap));
+ ot_font->cmap_blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap));
const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (ot_font->cmap_blob);
const OT::CmapSubtable *subtable = NULL;
const OT::CmapSubtable *subtable_uvs = NULL;
commit d7c160a1530adabbcf33725b105072293115a34c
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Sep 25 17:15:35 2014 +0300
[ot-font] Handle missing vertical metrics tables
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index d629c41..24de830 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -39,11 +39,15 @@ struct metrics_accel_t
{
unsigned int num_metrics;
unsigned int num_advances;
+ unsigned int default_advance;
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)
+ inline void init (hb_font_t *font,
+ hb_tag_t _hea_tag, hb_tag_t _mtx_tag,
+ unsigned int default_advance)
{
+ this->default_advance = default_advance;
this->num_metrics = font->face->get_num_glyphs ();
hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (font->face->reference_table (_hea_tag));
@@ -55,6 +59,7 @@ struct metrics_accel_t
if (unlikely (!this->num_advances ||
2 * (this->num_advances + this->num_metrics) < hb_blob_get_length (this->blob)))
{
+ this->num_metrics = this->num_advances = 0;
hb_blob_destroy (this->blob);
this->blob = hb_blob_get_empty ();
}
@@ -69,7 +74,15 @@ struct metrics_accel_t
inline unsigned int get_advance (hb_codepoint_t glyph) const
{
if (unlikely (glyph >= this->num_metrics))
- return 0;
+ {
+ /* If this->num_metrics is zero, it means we don't have the metrics table
+ * for this direction: return one EM. Otherwise, it means that the glyph
+ * index is out of bound: return zero. */
+ if (this->num_metrics)
+ return 0;
+ else
+ return this->default_advance;
+ }
if (glyph >= this->num_advances)
glyph = this->num_advances - 1;
@@ -80,8 +93,6 @@ struct metrics_accel_t
struct hb_ot_font_t
{
- unsigned int num_glyphs;
-
metrics_accel_t h_metrics;
metrics_accel_t v_metrics;
@@ -99,11 +110,11 @@ _hb_ot_font_create (hb_font_t *font)
if (unlikely (!ot_font))
return NULL;
- ot_font->num_glyphs = font->face->get_num_glyphs ();
+ unsigned int upem = font->face->get_upem ();
- ot_font->h_metrics.init (font, HB_OT_TAG_hhea, HB_OT_TAG_hmtx);
+ ot_font->h_metrics.init (font, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, upem>>1);
/* TODO Can we do this lazily? */
- ot_font->v_metrics.init (font, HB_OT_TAG_vhea, HB_OT_TAG_vmtx);
+ ot_font->v_metrics.init (font, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, upem);
ot_font->cmap_blob = OT::Sanitizer<OT::cmap>::sanitize (font->face->reference_table (HB_OT_TAG_cmap));
const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (ot_font->cmap_blob);
@@ -233,6 +244,7 @@ hb_ot_get_glyph_v_kerning (hb_font_t *font HB_UNUSED,
hb_codepoint_t bottom_glyph HB_UNUSED,
void *user_data HB_UNUSED)
{
+ /* OpenType doesn't have vertical-kerning other than GPOS. */
return 0;
}
commit be1cca270257bfdfee3fbe821175269713acf408
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Sep 25 16:53:24 2014 +0300
[ot-font] Add metrics_accel_t
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index 25fe511..d629c41 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<OT::_hea>::sanitize (font->face->reference_table (_hea_tag));
+ const OT::_hea *_hea = OT::Sanitizer<OT::_hea>::lock_instance (_hea_blob);
+ this->num_advances = _hea->numberOfLongMetrics;
+ hb_blob_destroy (_hea_blob);
+
+ this->blob = OT::Sanitizer<OT::_mtx>::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<OT::_mtx>::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<OT::hhea>::sanitize (font->face->reference_table (HB_OT_TAG_hhea));
- const OT::hhea *hhea = OT::Sanitizer<OT::hhea>::lock_instance (hhea_blob);
- ot_font->num_hmetrics = hhea->numberOfMetrics;
- hb_blob_destroy (hhea_blob);
-
- ot_font->hmtx_blob = OT::Sanitizer<OT::hmtx>::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<OT::hmtx>::lock_instance (ot_font->hmtx_blob);
- }
-
- /* Setup vertical metrics. */
- {
- hb_blob_t *vhea_blob = OT::Sanitizer<OT::vhea>::sanitize (font->face->reference_table (HB_OT_TAG_vhea));
- const OT::vhea *vhea = OT::Sanitizer<OT::vhea>::lock_instance (vhea_blob);
- ot_font->num_vmetrics = vhea->numberOfMetrics;
- hb_blob_destroy (vhea_blob);
-
- ot_font->vmtx_blob = OT::Sanitizer<OT::vmtx>::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<OT::vmtx>::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<OT::cmap>::sanitize (font->face->reference_table (HB_OT_TAG_cmap));
const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::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 9999bca..6bf6d5f 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 642c636..932f973 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 {
commit d41b809e9d21e655129a97c600d28f278fd7e62c
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Sep 25 13:04:08 2014 +0300
[ot-font] Start adding vertical support
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index 3514fcc..25fe511 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<OT::hhea>::sanitize (font->face->reference_table (HB_OT_TAG_hhea));
const OT::hhea *hhea = OT::Sanitizer<OT::hhea>::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<OT::hmtx>::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<OT::hmtx>::lock_instance (ot_font->hmtx_blob);
}
- ot_font->hmtx_blob = OT::Sanitizer<OT::hmtx>::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<OT::vhea>::sanitize (font->face->reference_table (HB_OT_TAG_vhea));
+ const OT::vhea *vhea = OT::Sanitizer<OT::vhea>::lock_instance (vhea_blob);
+ ot_font->num_vmetrics = vhea->numberOfMetrics;
+ hb_blob_destroy (vhea_blob);
+
+ ot_font->vmtx_blob = OT::Sanitizer<OT::vmtx>::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<OT::vmtx>::lock_instance (ot_font->vmtx_blob);
}
- ot_font->hmtx = OT::Sanitizer<OT::hmtx>::lock_instance (ot_font->hmtx_blob);
ot_font->cmap_blob = OT::Sanitizer<OT::cmap>::sanitize (font->face->reference_table (HB_OT_TAG_cmap));
const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::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 d433200..9999bca 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. <a
- * href="http://developer.apple.com/fonts/TTRefMan/RM06/Chap6hhea.html">
- * (Distance from baseline of highest
- * ascender)</a> */
- FWORD descender; /* Typographic descent. <a
- * href="http://developer.apple.com/fonts/TTRefMan/RM06/Chap6hhea.html">
- * (Distance from baseline of lowest
- * descender)</a> */
- 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 e918e3b..642c636 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 */
More information about the HarfBuzz
mailing list