diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index 4be248d30..91d7cfa24 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -600,6 +600,15 @@ hb_ot_math_get_min_connector_overlap
hb_ot_math_get_glyph_assembly
+
+hb-ot-metrics
+hb_ot_metrics_t
+hb_ot_metrics_get_position
+hb_ot_metrics_get_variation
+hb_ot_metrics_get_x_variation
+hb_ot_metrics_get_y_variation
+
+
hb-ot-shape
hb_ot_shape_glyphs_closure
diff --git a/src/Makefile.sources b/src/Makefile.sources
index 6f42ba3dc..d30c489a1 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -88,6 +88,9 @@ HB_BASE_sources = \
hb-ot-math-table.hh \
hb-ot-math.cc \
hb-ot-maxp-table.hh \
+ hb-ot-metrics-internal.cc \
+ hb-ot-metrics.cc \
+ hb-ot-metrics.hh \
hb-ot-name-language-static.hh \
hb-ot-name-language.hh \
hb-ot-name-table.hh \
@@ -191,6 +194,7 @@ HB_BASE_headers = \
hb-ot-font.h \
hb-ot-layout.h \
hb-ot-math.h \
+ hb-ot-metrics.h \
hb-ot-name.h \
hb-ot-shape.h \
hb-ot-var.h \
@@ -233,6 +237,8 @@ HB_ICU_headers = hb-icu.h
HB_SUBSET_sources = \
hb-ot-cff1-table.cc \
hb-ot-cff2-table.cc \
+ hb-ot-metrics-internal.cc \
+ hb-ot-metrics.hh \
hb-static.cc \
hb-subset-cff-common.cc \
hb-subset-cff-common.hh \
diff --git a/src/hb-ot-face-table-list.hh b/src/hb-ot-face-table-list.hh
index ac7052751..09e000d04 100644
--- a/src/hb-ot-face-table-list.hh
+++ b/src/hb-ot-face-table-list.hh
@@ -50,6 +50,7 @@ HB_OT_TABLE (OT, head)
#if !defined(HB_NO_FACE_COLLECT_UNICODES) || !defined(HB_NO_OT_FONT)
HB_OT_ACCELERATOR (OT, cmap)
#endif
+HB_OT_TABLE (OT, hhea)
HB_OT_ACCELERATOR (OT, hmtx)
HB_OT_TABLE (OT, OS2)
#ifndef HB_NO_OT_FONT_GLYPH_NAMES
@@ -63,6 +64,7 @@ HB_OT_TABLE (OT, STAT)
#endif
/* Vertical layout. */
+HB_OT_TABLE (OT, vhea)
HB_OT_ACCELERATOR (OT, vmtx)
/* TrueType outlines. */
diff --git a/src/hb-ot-hhea-table.hh b/src/hb-ot-hhea-table.hh
index c3155b79e..778b6c513 100644
--- a/src/hb-ot-hhea-table.hh
+++ b/src/hb-ot-hhea-table.hh
@@ -45,6 +45,8 @@ namespace OT {
template
struct _hea
{
+ bool has_data () const { return version.major; }
+
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh
index 754a37628..09df44a93 100644
--- a/src/hb-ot-hmtx-table.hh
+++ b/src/hb-ot-hmtx-table.hh
@@ -31,6 +31,7 @@
#include "hb-ot-hhea-table.hh"
#include "hb-ot-os2-table.hh"
#include "hb-ot-var-hvar-table.hh"
+#include "hb-ot-metrics.hh"
/*
* hmtx -- Horizontal Metrics
@@ -88,22 +89,22 @@ struct hmtxvmtx
template
- void serialize (hb_serialize_context_t *c,
- Iterator it,
+ void serialize (hb_serialize_context_t *c,
+ Iterator it,
unsigned num_advances)
{
unsigned idx = 0;
+ it
| hb_apply ([c, &idx, num_advances] (const hb_item_type& _)
{
- if (idx < num_advances)
+ if (idx < num_advances)
{
LongMetric lm;
lm.advance = _.first;
lm.sb = _.second;
if (unlikely (!c->embed (&lm))) return;
- }
- else
+ }
+ else
{
FWORD *sb = c->allocate_size (FWORD::static_size);
if (unlikely (!sb)) return;
@@ -120,12 +121,12 @@ struct hmtxvmtx
T *table_prime = c->serializer->start_embed ();
if (unlikely (!table_prime)) return_trace (false);
-
+
accelerator_t _mtx;
_mtx.init (c->plan->source);
unsigned num_advances = _mtx.num_advances_for_subset (c->plan);
-
- auto it =
+
+ auto it =
+ hb_range (c->plan->num_output_glyphs ())
| hb_map ([c, &_mtx] (unsigned _)
{
@@ -161,29 +162,16 @@ struct hmtxvmtx
unsigned int default_advance_ = 0)
{
default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face);
+ ascender = 0; descender = 0; line_gap = 0;
- bool got_font_extents = false;
- if (T::os2Tag != HB_TAG_NONE && face->table.OS2->is_typo_metrics ())
- {
- ascender = abs (face->table.OS2->sTypoAscender);
- descender = -abs (face->table.OS2->sTypoDescender);
- line_gap = face->table.OS2->sTypoLineGap;
- got_font_extents = (ascender | descender) != 0;
- }
+ hb_ot_metrics_get_position_internal (face, (hb_ot_metrics_t) T::ascenderTag, &ascender);
+ hb_ot_metrics_get_position_internal (face, (hb_ot_metrics_t) T::descenderTag, &descender);
+ hb_ot_metrics_get_position_internal (face, (hb_ot_metrics_t) T::lineGapTag, &line_gap);
+ ascender = fabs (ascender);
+ descender = -fabs (descender);
+ has_font_extents = ascender != 0 || descender != 0;
- hb_blob_t *_hea_blob = hb_sanitize_context_t().reference_table (face);
- const H *_hea_table = _hea_blob->as ();
- num_advances = _hea_table->numberOfLongMetrics;
- if (!got_font_extents)
- {
- ascender = abs (_hea_table->ascender);
- descender = -abs (_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;
+ num_advances = T::is_horizontal ? face->table.hhea->numberOfLongMetrics : face->table.vhea->numberOfLongMetrics;
table = hb_sanitize_context_t().reference_table (face, T::tableTag);
@@ -279,9 +267,9 @@ struct hmtxvmtx
public:
bool has_font_extents;
- int ascender;
- int descender;
- int line_gap;
+ float ascender;
+ float descender;
+ float line_gap;
protected:
unsigned int num_metrics;
@@ -322,12 +310,18 @@ struct hmtxvmtx
struct hmtx : hmtxvmtx {
static constexpr hb_tag_t tableTag = HB_OT_TAG_hmtx;
static constexpr hb_tag_t variationsTag = HB_OT_TAG_HVAR;
- static constexpr hb_tag_t os2Tag = HB_OT_TAG_OS2;
+ static constexpr hb_tag_t ascenderTag = HB_OT_METRICS_HORIZONTAL_ASCENDER;
+ static constexpr hb_tag_t descenderTag = HB_OT_METRICS_HORIZONTAL_DESCENDER;
+ static constexpr hb_tag_t lineGapTag = HB_OT_METRICS_HORIZONTAL_LINE_GAP;
+ static constexpr bool is_horizontal = true;
};
struct vmtx : hmtxvmtx {
static constexpr hb_tag_t tableTag = HB_OT_TAG_vmtx;
static constexpr hb_tag_t variationsTag = HB_OT_TAG_VVAR;
- static constexpr hb_tag_t os2Tag = HB_TAG_NONE;
+ static constexpr hb_tag_t ascenderTag = HB_OT_METRICS_VERTICAL_ASCENDER;
+ static constexpr hb_tag_t descenderTag = HB_OT_METRICS_VERTICAL_DESCENDER;
+ static constexpr hb_tag_t lineGapTag = HB_OT_METRICS_VERTICAL_LINE_GAP;
+ static constexpr bool is_horizontal = false;
};
struct hmtx_accelerator_t : hmtx::accelerator_t {};
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 98cd10923..c67cd0cbf 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -43,7 +43,6 @@
#include "hb-map.hh"
#include "hb-ot-kern-table.hh"
-#include "hb-ot-gasp-table.hh" // Just so we compile it; unused otherwise.
#include "hb-ot-layout-gdef-table.hh"
#include "hb-ot-layout-gsub-table.hh"
#include "hb-ot-layout-gpos-table.hh"
diff --git a/src/hb-ot-metrics-internal.cc b/src/hb-ot-metrics-internal.cc
new file mode 100644
index 000000000..9f0294f66
--- /dev/null
+++ b/src/hb-ot-metrics-internal.cc
@@ -0,0 +1,94 @@
+/*
+ * Copyright © 2018 Ebrahim Byagowi
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include "hb.hh"
+
+#include "hb-ot-gasp-table.hh" // Just so we compile it; unused otherwise.
+#include "hb-ot-os2-table.hh"
+#include "hb-ot-post-table.hh"
+#include "hb-ot-hmtx-table.hh"
+#include "hb-ot-var-mvar-table.hh"
+#include "hb-ot-metrics.hh"
+
+#include "hb-ot-face.hh"
+
+#if 0
+static bool
+_get_gasp (hb_face_t *face, float *result, hb_ot_metrics_t metrics_tag)
+{
+ const OT::GaspRange& range = face->table.gasp->get_gasp_range (metrics_tag - HB_TAG ('g','s','p','0'));
+ if (&range == &Null (OT::GaspRange)) return false;
+ if (result) *result = range.rangeMaxPPEM + face->table.MVAR->get_var (metrics_tag, nullptr, 0);
+ return true;
+}
+#endif
+
+bool
+hb_ot_metrics_get_position_internal (hb_face_t *face,
+ hb_ot_metrics_t metrics_tag,
+ float *position /* OUT. May be NULL. */)
+{
+ switch (metrics_tag)
+ {
+#define GET_METRIC(TABLE, ATTR) \
+ (face->table.TABLE->has_data () && \
+ (position && (*position = face->table.TABLE->ATTR + face->table.MVAR->get_var (metrics_tag, nullptr, 0)), true))
+ case HB_OT_METRICS_HORIZONTAL_ASCENDER:
+ return (face->table.OS2->is_typo_metrics () ^ GET_METRIC (hhea, ascender)) ||
+ GET_METRIC (OS2, sTypoAscender);
+ case HB_OT_METRICS_HORIZONTAL_DESCENDER:
+ return (face->table.OS2->is_typo_metrics () ^ GET_METRIC (hhea, descender)) ||
+ GET_METRIC (OS2, sTypoDescender);
+ case HB_OT_METRICS_HORIZONTAL_LINE_GAP:
+ return (face->table.OS2->is_typo_metrics () ^ GET_METRIC (hhea, lineGap)) ||
+ GET_METRIC (OS2, sTypoLineGap);
+ case HB_OT_METRICS_HORIZONTAL_CLIPPING_ASCENT: return GET_METRIC (OS2, usWinAscent);
+ case HB_OT_METRICS_HORIZONTAL_CLIPPING_DESCENT: return GET_METRIC (OS2, usWinDescent);
+ case HB_OT_METRICS_VERTICAL_ASCENDER: return GET_METRIC (vhea, ascender);
+ case HB_OT_METRICS_VERTICAL_DESCENDER: return GET_METRIC (vhea, descender);
+ case HB_OT_METRICS_VERTICAL_LINE_GAP: return GET_METRIC (vhea, lineGap);
+ case HB_OT_METRICS_HORIZONTAL_CARET_RISE: return GET_METRIC (hhea, caretSlopeRise);
+ case HB_OT_METRICS_HORIZONTAL_CARET_RUN: return GET_METRIC (hhea, caretSlopeRun);
+ case HB_OT_METRICS_HORIZONTAL_CARET_OFFSET: return GET_METRIC (hhea, caretOffset);
+ case HB_OT_METRICS_VERTICAL_CARET_RISE: return GET_METRIC (vhea, caretSlopeRise);
+ case HB_OT_METRICS_VERTICAL_CARET_RUN: return GET_METRIC (vhea, caretSlopeRun);
+ case HB_OT_METRICS_VERTICAL_CARET_OFFSET: return GET_METRIC (vhea, caretOffset);
+ case HB_OT_METRICS_X_HEIGHT: return GET_METRIC (OS2->v2 (), sxHeight);
+ case HB_OT_METRICS_CAP_HEIGHT: return GET_METRIC (OS2->v2 (), sCapHeight);
+ case HB_OT_METRICS_SUBSCRIPT_EM_X_SIZE: return GET_METRIC (OS2, ySubscriptXSize);
+ case HB_OT_METRICS_SUBSCRIPT_EM_Y_SIZE: return GET_METRIC (OS2, ySubscriptYSize);
+ case HB_OT_METRICS_SUBSCRIPT_EM_X_OFFSET: return GET_METRIC (OS2, ySubscriptXOffset);
+ case HB_OT_METRICS_SUBSCRIPT_EM_Y_OFFSET: return GET_METRIC (OS2, ySubscriptYOffset);
+ case HB_OT_METRICS_SUPERSCRIPT_EM_X_SIZE: return GET_METRIC (OS2, ySuperscriptXSize);
+ case HB_OT_METRICS_SUPERSCRIPT_EM_Y_SIZE: return GET_METRIC (OS2, ySuperscriptYSize);
+ case HB_OT_METRICS_SUPERSCRIPT_EM_X_OFFSET: return GET_METRIC (OS2, ySuperscriptXOffset);
+ case HB_OT_METRICS_SUPERSCRIPT_EM_Y_OFFSET: return GET_METRIC (OS2, ySuperscriptYOffset);
+ case HB_OT_METRICS_STRIKEOUT_SIZE: return GET_METRIC (OS2, yStrikeoutSize);
+ case HB_OT_METRICS_STRIKEOUT_OFFSET: return GET_METRIC (OS2, yStrikeoutPosition);
+ case HB_OT_METRICS_UNDERLINE_SIZE: return GET_METRIC (post->table, underlineThickness);
+ case HB_OT_METRICS_UNDERLINE_OFFSET: return GET_METRIC (post->table, underlinePosition);
+#undef GET_METRIC
+ default: return false;
+ }
+}
diff --git a/src/hb-ot-metrics.cc b/src/hb-ot-metrics.cc
new file mode 100644
index 000000000..d6672c685
--- /dev/null
+++ b/src/hb-ot-metrics.cc
@@ -0,0 +1,135 @@
+/*
+ * Copyright © 2018 Ebrahim Byagowi
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include "hb.hh"
+
+#include "hb-ot-metrics.hh"
+#include "hb-ot-var-mvar-table.hh"
+#include "hb-ot-face.hh"
+
+
+/**
+ * hb_ot_metrics_get_position:
+ * @font:
+ * @metrics_tag:
+ * @position: (out) (optional):
+ *
+ * Returns: Whether found the requested metrics
+ *
+ * Since: REPLACEME
+ **/
+hb_bool_t
+hb_ot_metrics_get_position (hb_font_t *font,
+ hb_ot_metrics_t metrics_tag,
+ hb_position_t *position /* OUT. May be NULL. */)
+{
+ switch (metrics_tag)
+ {
+ case HB_OT_METRICS_HORIZONTAL_ASCENDER:
+ case HB_OT_METRICS_HORIZONTAL_DESCENDER:
+ case HB_OT_METRICS_HORIZONTAL_LINE_GAP:
+ case HB_OT_METRICS_HORIZONTAL_CLIPPING_ASCENT:
+ case HB_OT_METRICS_HORIZONTAL_CLIPPING_DESCENT:
+ case HB_OT_METRICS_HORIZONTAL_CARET_RISE:
+ case HB_OT_METRICS_VERTICAL_CARET_RUN:
+ case HB_OT_METRICS_VERTICAL_CARET_OFFSET:
+ case HB_OT_METRICS_X_HEIGHT:
+ case HB_OT_METRICS_CAP_HEIGHT:
+ case HB_OT_METRICS_SUBSCRIPT_EM_Y_SIZE:
+ case HB_OT_METRICS_SUBSCRIPT_EM_Y_OFFSET:
+ case HB_OT_METRICS_SUPERSCRIPT_EM_Y_SIZE:
+ case HB_OT_METRICS_SUPERSCRIPT_EM_Y_OFFSET:
+ case HB_OT_METRICS_STRIKEOUT_SIZE:
+ case HB_OT_METRICS_STRIKEOUT_OFFSET:
+ case HB_OT_METRICS_UNDERLINE_SIZE:
+ case HB_OT_METRICS_UNDERLINE_OFFSET: {
+ float value;
+ bool result = hb_ot_metrics_get_position_internal (font->face, metrics_tag, &value);
+ if (result && position) *position = font->em_scalef_y (value);
+ return result;
+ }
+ case HB_OT_METRICS_VERTICAL_ASCENDER:
+ case HB_OT_METRICS_VERTICAL_DESCENDER:
+ case HB_OT_METRICS_VERTICAL_LINE_GAP:
+ case HB_OT_METRICS_HORIZONTAL_CARET_RUN:
+ case HB_OT_METRICS_HORIZONTAL_CARET_OFFSET:
+ case HB_OT_METRICS_VERTICAL_CARET_RISE:
+ case HB_OT_METRICS_SUBSCRIPT_EM_X_SIZE:
+ case HB_OT_METRICS_SUBSCRIPT_EM_X_OFFSET:
+ case HB_OT_METRICS_SUPERSCRIPT_EM_X_SIZE:
+ case HB_OT_METRICS_SUPERSCRIPT_EM_X_OFFSET: {
+ float value;
+ bool result = hb_ot_metrics_get_position_internal (font->face, metrics_tag, &value);
+ if (result && position) *position = font->em_scalef_x (value);
+ return result;
+ }
+ default:
+ return false;
+ }
+}
+
+/**
+ * hb_ot_metrics_get_variation:
+ * @face:
+ * @metrics_tag:
+ *
+ * Returns:
+ *
+ * Since: REPLACEME
+ **/
+float
+hb_ot_metrics_get_variation (hb_face_t *face, hb_ot_metrics_t metrics_tag)
+{
+ return face->table.MVAR->get_var (metrics_tag, nullptr, 0);
+}
+
+/**
+ * hb_ot_metrics_get_x_variation:
+ * @font:
+ * @metrics_tag:
+ *
+ * Returns:
+ *
+ * Since: REPLACEME
+ **/
+hb_position_t
+hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_t metrics_tag)
+{
+ return font->em_scalef_x (hb_ot_metrics_get_variation (font->face, metrics_tag));
+}
+
+/**
+ * hb_ot_metrics_get_y_variation:
+ * @font:
+ * @metrics_tag:
+ *
+ * Returns:
+ *
+ * Since: REPLACEME
+ **/
+hb_position_t
+hb_ot_metrics_get_y_variation (hb_font_t *font, hb_ot_metrics_t metrics_tag)
+{
+ return font->em_scalef_y (hb_ot_metrics_get_variation (font->face, metrics_tag));
+}
diff --git a/src/hb-ot-metrics.h b/src/hb-ot-metrics.h
new file mode 100644
index 000000000..611222f26
--- /dev/null
+++ b/src/hb-ot-metrics.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright © 2018 Ebrahim Byagowi
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_OT_H_IN
+#error "Include instead."
+#endif
+
+#ifndef HB_OT_METRICS_H
+#define HB_OT_METRICS_H
+
+#include "hb.h"
+#include "hb-ot-name.h"
+
+HB_BEGIN_DECLS
+
+
+/**
+ * hb_ot_metrics_t:
+ *
+ * From https://docs.microsoft.com/en-us/typography/opentype/spec/mvar#value-tags
+ *
+ * Since: REPLACEME
+ **/
+typedef enum {
+ HB_OT_METRICS_HORIZONTAL_ASCENDER = HB_TAG ('h','a','s','c'),
+ HB_OT_METRICS_HORIZONTAL_DESCENDER = HB_TAG ('h','d','s','c'),
+ HB_OT_METRICS_HORIZONTAL_LINE_GAP = HB_TAG ('h','l','g','p'),
+ HB_OT_METRICS_HORIZONTAL_CLIPPING_ASCENT = HB_TAG ('h','c','l','a'),
+ HB_OT_METRICS_HORIZONTAL_CLIPPING_DESCENT = HB_TAG ('h','c','l','d'),
+ HB_OT_METRICS_VERTICAL_ASCENDER = HB_TAG ('v','a','s','c'),
+ HB_OT_METRICS_VERTICAL_DESCENDER = HB_TAG ('v','d','s','c'),
+ HB_OT_METRICS_VERTICAL_LINE_GAP = HB_TAG ('v','l','g','p'),
+ HB_OT_METRICS_HORIZONTAL_CARET_RISE = HB_TAG ('h','c','r','s'),
+ HB_OT_METRICS_HORIZONTAL_CARET_RUN = HB_TAG ('h','c','r','n'),
+ HB_OT_METRICS_HORIZONTAL_CARET_OFFSET = HB_TAG ('h','c','o','f'),
+ HB_OT_METRICS_VERTICAL_CARET_RISE = HB_TAG ('v','c','r','s'),
+ HB_OT_METRICS_VERTICAL_CARET_RUN = HB_TAG ('v','c','r','n'),
+ HB_OT_METRICS_VERTICAL_CARET_OFFSET = HB_TAG ('v','c','o','f'),
+ HB_OT_METRICS_X_HEIGHT = HB_TAG ('x','h','g','t'),
+ HB_OT_METRICS_CAP_HEIGHT = HB_TAG ('c','p','h','t'),
+ HB_OT_METRICS_SUBSCRIPT_EM_X_SIZE = HB_TAG ('s','b','x','s'),
+ HB_OT_METRICS_SUBSCRIPT_EM_Y_SIZE = HB_TAG ('s','b','y','s'),
+ HB_OT_METRICS_SUBSCRIPT_EM_X_OFFSET = HB_TAG ('s','b','x','o'),
+ HB_OT_METRICS_SUBSCRIPT_EM_Y_OFFSET = HB_TAG ('s','b','y','o'),
+ HB_OT_METRICS_SUPERSCRIPT_EM_X_SIZE = HB_TAG ('s','p','x','s'),
+ HB_OT_METRICS_SUPERSCRIPT_EM_Y_SIZE = HB_TAG ('s','p','y','s'),
+ HB_OT_METRICS_SUPERSCRIPT_EM_X_OFFSET = HB_TAG ('s','p','x','o'),
+ HB_OT_METRICS_SUPERSCRIPT_EM_Y_OFFSET = HB_TAG ('s','p','y','o'),
+ HB_OT_METRICS_STRIKEOUT_SIZE = HB_TAG ('s','t','r','s'),
+ HB_OT_METRICS_STRIKEOUT_OFFSET = HB_TAG ('s','t','r','o'),
+ HB_OT_METRICS_UNDERLINE_SIZE = HB_TAG ('u','n','d','s'),
+ HB_OT_METRICS_UNDERLINE_OFFSET = HB_TAG ('u','n','d','o')
+} hb_ot_metrics_t;
+
+HB_EXTERN hb_bool_t
+hb_ot_metrics_get_position (hb_font_t *font,
+ hb_ot_metrics_t metrics_tag,
+ hb_position_t *position /* OUT. May be NULL. */);
+
+HB_EXTERN float
+hb_ot_metrics_get_variation (hb_face_t *face, hb_ot_metrics_t metrics_tag);
+
+HB_EXTERN hb_position_t
+hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_t metrics_tag);
+
+HB_EXTERN hb_position_t
+hb_ot_metrics_get_y_variation (hb_font_t *font, hb_ot_metrics_t metrics_tag);
+
+HB_END_DECLS
+
+#endif /* HB_OT_METRICS_H */
diff --git a/src/hb-ot-metrics.hh b/src/hb-ot-metrics.hh
new file mode 100644
index 000000000..e813f463f
--- /dev/null
+++ b/src/hb-ot-metrics.hh
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2018 Ebrahim Byagowi
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_OT_METRICS_HH
+#define HB_OT_METRICS_HH
+
+#include "hb.hh"
+
+HB_INTERNAL bool
+hb_ot_metrics_get_position_internal (hb_face_t *face,
+ hb_ot_metrics_t metrics_tag,
+ float *position /* OUT. May be NULL. */);
+
+#endif /* HB_OT_METRICS_HH */
diff --git a/src/hb-ot-os2-table.hh b/src/hb-ot-os2-table.hh
index 16e29caf3..bfe8ef9d2 100644
--- a/src/hb-ot-os2-table.hh
+++ b/src/hb-ot-os2-table.hh
@@ -59,6 +59,10 @@ struct OS2V1Tail
struct OS2V2Tail
{
+ bool has_data () const { return this != &Null (OS2V2Tail); }
+
+ const OS2V2Tail * operator -> () const { return this; }
+
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh
index 720e03bac..fb826cd35 100644
--- a/src/hb-ot-post-table.hh
+++ b/src/hb-ot-post-table.hh
@@ -178,6 +178,8 @@ struct post
return false;
}
+ hb_blob_ptr_t table;
+
protected:
unsigned int get_glyph_count () const
@@ -237,7 +239,6 @@ struct post
}
private:
- hb_blob_ptr_t table;
uint32_t version;
const ArrayOf *glyphNameIndex;
hb_vector_t index_to_offset;
@@ -245,6 +246,8 @@ struct post
hb_atomic_ptr_t gids_sorted_by_name;
};
+ bool has_data () const { return version.to_int (); }
+
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
diff --git a/src/hb-ot.h b/src/hb-ot.h
index db784694c..d00ee80ae 100644
--- a/src/hb-ot.h
+++ b/src/hb-ot.h
@@ -35,6 +35,7 @@
#include "hb-ot-font.h"
#include "hb-ot-layout.h"
#include "hb-ot-math.h"
+#include "hb-ot-metrics.h"
#include "hb-ot-name.h"
#include "hb-ot-shape.h"
#include "hb-ot-var.h"
diff --git a/test/api/Makefile.am b/test/api/Makefile.am
index b9d4d7928..63c7195fa 100644
--- a/test/api/Makefile.am
+++ b/test/api/Makefile.am
@@ -84,6 +84,7 @@ TEST_PROGS += \
test-ot-color \
test-ot-ligature-carets \
test-ot-name \
+ test-ot-metrics \
test-ot-tag \
test-ot-extents-cff \
$(NULL)
diff --git a/test/api/test-ot-metrics.c b/test/api/test-ot-metrics.c
new file mode 100644
index 000000000..270de8828
--- /dev/null
+++ b/test/api/test-ot-metrics.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright © 2018 Ebrahim Byagowi
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include "hb-test.h"
+
+#include
+
+#include
+
+/* Unit tests for hb-ot-metrics.h */
+
+static void
+test_ot_metrics_get (void)
+{
+ hb_face_t *face = hb_test_open_font_file ("fonts/cpal-v0.ttf");
+ hb_font_t *font = hb_font_create (face);
+ hb_position_t value;
+ g_assert (hb_ot_metrics_get_position (font, HB_OT_METRICS_HORIZONTAL_ASCENDER, &value));
+ g_assert_cmpint (value, ==, 1000);
+ g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
+ g_assert_cmpint (hb_ot_metrics_get_y_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
+ // g_assert_cmpint ((int) hb_ot_metrics_get_variation (face, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
+ hb_font_destroy (font);
+ hb_face_destroy (face);
+}
+
+int
+main (int argc, char **argv)
+{
+ hb_test_init (&argc, &argv);
+ hb_test_add (test_ot_metrics_get);
+ return hb_test_run ();
+}