diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index bcad37a77..3549ea406 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -714,6 +714,12 @@ hb_shape_plan_set_user_data
hb_shape_plan_t
+
+hb-style
+hb_style_tag_t
+hb_style_get_value
+
+
hb-unicode
HB_UNICODE_MAX
diff --git a/src/Makefile.sources b/src/Makefile.sources
index 81b5cde7a..d8fe508be 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -159,6 +159,7 @@ HB_BASE_sources = \
hb-shaper.hh \
hb-static.cc \
hb-string-array.hh \
+ hb-style.cc \
hb-ucd-table.hh \
hb-ucd.cc \
hb-unicode-emoji-table.hh \
@@ -213,6 +214,7 @@ HB_BASE_headers = \
hb-set.h \
hb-shape-plan.h \
hb-shape.h \
+ hb-style.h \
hb-unicode.h \
hb-version.h \
hb.h \
diff --git a/src/harfbuzz.cc b/src/harfbuzz.cc
index 6a07a9e0d..226d013d2 100644
--- a/src/harfbuzz.cc
+++ b/src/harfbuzz.cc
@@ -43,6 +43,7 @@
#include "hb-shape.cc"
#include "hb-shaper.cc"
#include "hb-static.cc"
+#include "hb-style.cc"
#include "hb-ucd.cc"
#include "hb-unicode.cc"
#include "hb-glib.cc"
diff --git a/src/hb-config.hh b/src/hb-config.hh
index 07659fad1..fc8d424bf 100644
--- a/src/hb-config.hh
+++ b/src/hb-config.hh
@@ -76,7 +76,7 @@
#define HB_NO_SETLOCALE
#define HB_NO_OT_FONT_GLYPH_NAMES
#define HB_NO_OT_SHAPE_FRACTIONS
-#define HB_NO_STAT
+#define HB_NO_STYLE
#define HB_NO_SUBSET_LAYOUT
#define HB_NO_VAR
#endif
diff --git a/src/hb-ot-face-table-list.hh b/src/hb-ot-face-table-list.hh
index 6fa9baf13..5519d4fdf 100644
--- a/src/hb-ot-face-table-list.hh
+++ b/src/hb-ot-face-table-list.hh
@@ -53,13 +53,14 @@ HB_OT_ACCELERATOR (OT, cmap)
HB_OT_TABLE (OT, hhea)
HB_OT_ACCELERATOR (OT, hmtx)
HB_OT_TABLE (OT, OS2)
-#if !defined(HB_NO_OT_FONT_GLYPH_NAMES) || !defined(HB_NO_METRICS)
+#if !defined(HB_NO_OT_FONT_GLYPH_NAMES) || !defined(HB_NO_METRICS) || !defined(HB_NO_STYLE)
HB_OT_ACCELERATOR (OT, post)
#endif
#ifndef HB_NO_NAME
HB_OT_ACCELERATOR (OT, name)
#endif
-#ifndef HB_NO_STAT
+#ifndef HB_NO_STYLE
+HB_OT_TABLE (AAT, fdsc)
HB_OT_TABLE (OT, STAT)
#endif
#ifndef HB_NO_META
diff --git a/src/hb-ot-stat-table.hh b/src/hb-ot-stat-table.hh
index 88135234d..655064bdf 100644
--- a/src/hb-ot-stat-table.hh
+++ b/src/hb-ot-stat-table.hh
@@ -59,6 +59,9 @@ enum
struct AxisValueFormat1
{
+ unsigned int get_axis_index () const { return axisIndex; }
+ float get_value () const { return value.to_float (); }
+
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
bool sanitize (hb_sanitize_context_t *c) const
@@ -84,6 +87,9 @@ struct AxisValueFormat1
struct AxisValueFormat2
{
+ unsigned int get_axis_index () const { return axisIndex; }
+ float get_value () const { return nominalValue.to_float (); }
+
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
bool sanitize (hb_sanitize_context_t *c) const
@@ -113,6 +119,9 @@ struct AxisValueFormat2
struct AxisValueFormat3
{
+ unsigned int get_axis_index () const { return axisIndex; }
+ float get_value () const { return value.to_float (); }
+
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
bool sanitize (hb_sanitize_context_t *c) const
@@ -140,6 +149,9 @@ struct AxisValueFormat3
struct AxisValueRecord
{
+ unsigned int get_axis_index () const { return axisIndex; }
+ float get_value () const { return value.to_float (); }
+
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -157,6 +169,9 @@ struct AxisValueRecord
struct AxisValueFormat4
{
+ const AxisValueRecord &get_axis_record (unsigned int axis_index) const
+ { return axisValues.as_array (axisCount)[axis_index]; }
+
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
bool sanitize (hb_sanitize_context_t *c) const
@@ -183,6 +198,30 @@ struct AxisValueFormat4
struct AxisValue
{
+ bool get_value (unsigned int axis_index) const
+ {
+ switch (u.format)
+ {
+ case 1: return u.format1.get_value ();
+ case 2: return u.format2.get_value ();
+ case 3: return u.format3.get_value ();
+ case 4: return u.format4.get_axis_record (axis_index).get_value ();
+ default:return 0;
+ }
+ }
+
+ unsigned int get_axis_index () const
+ {
+ switch (u.format)
+ {
+ case 1: return u.format1.get_axis_index ();
+ case 2: return u.format2.get_axis_index ();
+ case 3: return u.format3.get_axis_index ();
+ /* case 4: Makes more sense for variable fonts which are handled by fvar in hb-style */
+ default:return -1;
+ }
+ }
+
hb_ot_name_id_t get_value_name_id () const
{
switch (u.format)
@@ -226,6 +265,8 @@ struct AxisValue
struct StatAxisRecord
{
+ int cmp (hb_tag_t key) const { return tag.cmp (key); }
+
hb_ot_name_id_t get_name_id () const { return nameID; }
bool sanitize (hb_sanitize_context_t *c) const
@@ -251,6 +292,38 @@ struct STAT
bool has_data () const { return version.to_int (); }
+ bool find_axis_index (hb_tag_t tag, unsigned int *axis_index) const
+ {
+ hb_array_t axes = get_design_axes ();
+ /* TODO: add lfind in hb_array_t and use it in here and fvar's find_axis_info */
+ for (unsigned int i = 0; i < axes.length; i++)
+ if (!axes[i].cmp (tag))
+ {
+ *axis_index = i;
+ return true;
+ }
+ return false;
+ }
+
+ bool get_value (hb_tag_t tag, float *value) const
+ {
+ unsigned int axis_index;
+ if (!find_axis_index (tag, &axis_index)) return false;
+
+ hb_array_t> axis_values = get_axis_value_offsets ();
+ for (unsigned int i = 0; i < axis_values.length; i++)
+ {
+ const AxisValue& axis_value = (this + axis_values[i]);
+ if (axis_value.get_axis_index () == axis_index)
+ {
+ if (value)
+ *value = axis_value.get_value (axis_index);
+ return true;
+ }
+ }
+ return false;
+ }
+
unsigned get_design_axis_count () const { return designAxisCount; }
hb_ot_name_id_t get_axis_record_name_id (unsigned axis_record_index) const
diff --git a/src/hb-style.cc b/src/hb-style.cc
new file mode 100644
index 000000000..dd54fdd9d
--- /dev/null
+++ b/src/hb-style.cc
@@ -0,0 +1,110 @@
+/*
+ * Copyright © 2019 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"
+
+#ifndef HB_NO_STYLE
+
+#include "hb-aat-fdsc-table.hh"
+#include "hb-ot-var-avar-table.hh"
+#include "hb-ot-var-fvar-table.hh"
+#include "hb-ot-stat-table.hh"
+#include "hb-ot-os2-table.hh"
+#include "hb-ot-head-table.hh"
+#include "hb-ot-post-table.hh"
+#include "hb-ot-face.hh"
+
+/**
+ * hb_style_get_value:
+ * @font: a #hb_font_t object.
+ * @style_tag: a style tag.
+ *
+ * Searches variation axes of a hb_font_t object for a specific axis first,
+ * if not set, then tries to get default style values from different
+ * tables of the font.
+ *
+ * Returns: Corresponding axis or default value to a style tag.
+ *
+ * Since: REPLACEME
+ **/
+float
+hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag)
+{
+ hb_face_t *face = font->face;
+
+#ifndef HB_NO_VAR
+ hb_ot_var_axis_info_t axis;
+ if (hb_ot_var_find_axis_info (face, style_tag, &axis))
+ {
+ if (axis.axis_index < font->num_coords) return font->design_coords[axis.axis_index];
+ /* If a face is variable, fvar's default_value is better than STAT records */
+ return axis.default_value;
+ }
+#endif
+
+ /* STAT */
+ float value;
+ if (face->table.STAT->get_value (style_tag, &value))
+ return value;
+
+ /* Check Apple's fdsc as OS2 table is optional in AAT */
+ const AAT::FontDescriptor &descriptor = face->table.fdsc->get_descriptor (style_tag);
+ if (descriptor.has_data ())
+ {
+ float value = descriptor.get_value ();
+ /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6fdsc.html */
+ /* Percent weight relative to regular weight. */
+ if (style_tag == HB_STYLE_TAG_WEIGHT) value *= 400.f;
+ /* Percent width relative to regular width. */
+ if (style_tag == HB_STYLE_TAG_WIDTH) value *= 100.f;
+ return value;
+ }
+
+ switch ((unsigned) style_tag)
+ {
+ case HB_STYLE_TAG_ITALIC:
+ return face->table.OS2->is_italic () || face->table.head->is_italic () ? 1 : 0;
+ case HB_STYLE_TAG_OPTICAL_SIZE:
+ {
+ unsigned int lower, upper;
+ return face->table.OS2->v5 ().get_optical_size (&lower, &upper)
+ ? (float) (lower + upper) / 2.f
+ : 12.f;
+ }
+ case HB_STYLE_TAG_SLANT:
+ return face->table.post->table->italicAngle.to_float ();
+ case HB_STYLE_TAG_WIDTH:
+ return face->table.OS2->has_data ()
+ ? face->table.OS2->get_width ()
+ : (face->table.head->is_condensed () ? 75 : 100);
+ case HB_STYLE_TAG_WEIGHT:
+ return face->table.OS2->has_data ()
+ ? face->table.OS2->usWeightClass
+ : (face->table.head->is_bold () ? 700 : 400);
+ default:
+ return 0;
+ }
+}
+
+#endif
diff --git a/src/hb-style.h b/src/hb-style.h
new file mode 100644
index 000000000..ee84b7232
--- /dev/null
+++ b/src/hb-style.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright © 2019 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_H_IN
+#error "Include instead."
+#endif
+
+#ifndef HB_STYLE_H
+#define HB_STYLE_H
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+
+
+/**
+ * hb_style_tag_t:
+ * @HB_STYLE_TAG_ITALIC: Used to vary between non-italic and italic.
+ * A value of 0 can be interpreted as "Roman" (non-italic); a value of 1 can
+ * be interpreted as (fully) italic.
+ * @HB_STYLE_TAG_OPTICAL_SIZE: Used to vary design to suit different text sizes.
+ * Non-zero. Values can be interpreted as text size, in points.
+ * @HB_STYLE_TAG_SLANT: Used to vary between upright and slanted text. Values
+ * must be greater than -90 and less than +90. Values can be interpreted as
+ * the angle, in counter-clockwise degrees, of oblique slant from whatever the
+ * designer considers to be upright for that font design.
+ * @HB_STYLE_TAG_WIDTH: Used to vary width of text from narrower to wider.
+ * Non-zero. Values can be interpreted as a percentage of whatever the font
+ * designer considers “normal width” for that font design.
+ * @HB_STYLE_TAG_WEIGHT: Used to vary stroke thicknesses or other design details
+ * to give variation from lighter to blacker. Values can be interpreted in direct
+ * comparison to values for usWeightClass in the OS/2 table,
+ * or the CSS font-weight property.
+ *
+ * Defined by https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg
+ *
+ * Since: REPLACEME
+ **/
+typedef enum {
+ HB_STYLE_TAG_ITALIC = HB_TAG ('i','t','a','l'),
+ HB_STYLE_TAG_OPTICAL_SIZE = HB_TAG ('o','p','s','z'),
+ HB_STYLE_TAG_SLANT = HB_TAG ('s','l','n','t'),
+ HB_STYLE_TAG_WIDTH = HB_TAG ('w','d','t','h'),
+ HB_STYLE_TAG_WEIGHT = HB_TAG ('w','g','h','t'),
+
+ _HB_STYLE_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
+} hb_style_tag_t;
+
+HB_EXTERN float
+hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag);
+
+HB_END_DECLS
+
+#endif /* HB_STYLE_H */
diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc
index 232131c59..9a5d74b64 100644
--- a/src/hb-subset-plan.cc
+++ b/src/hb-subset-plan.cc
@@ -301,7 +301,7 @@ static void
_nameid_closure (hb_face_t *face,
hb_set_t *nameids)
{
-#ifndef HB_NO_STAT
+#ifndef HB_NO_STYLE
face->table.STAT->collect_name_ids (nameids);
#endif
#ifndef HB_NO_VAR
diff --git a/src/hb.h b/src/hb.h
index b0cc06c9e..360686ca6 100644
--- a/src/hb.h
+++ b/src/hb.h
@@ -39,6 +39,7 @@
#include "hb-set.h"
#include "hb-shape.h"
#include "hb-shape-plan.h"
+#include "hb-style.h"
#include "hb-unicode.h"
#include "hb-version.h"
diff --git a/test/api/Makefile.am b/test/api/Makefile.am
index 0170b6807..01e12c570 100644
--- a/test/api/Makefile.am
+++ b/test/api/Makefile.am
@@ -52,6 +52,7 @@ TEST_PROGS = \
test-ot-metrics-tt-var \
test-set \
test-shape \
+ test-style \
test-subset \
test-subset-cmap \
test-subset-drop-tables \
diff --git a/test/api/fonts/aat-fdsc.ttf b/test/api/fonts/aat-fdsc.ttf
new file mode 100644
index 000000000..3f82869ea
Binary files /dev/null and b/test/api/fonts/aat-fdsc.ttf differ
diff --git a/test/api/test-ot-face.c b/test/api/test-ot-face.c
index 0e86123a8..155d1ff14 100644
--- a/test/api/test-ot-face.c
+++ b/test/api/test-ot-face.c
@@ -131,6 +131,12 @@ test_font (hb_font_t *font, hb_codepoint_t cp)
hb_ot_name_get_utf16 (face, cp, NULL, NULL, NULL);
hb_ot_name_get_utf32 (face, cp, NULL, NULL, NULL);
+ hb_style_get_value (font, HB_STYLE_TAG_ITALIC);
+ hb_style_get_value (font, HB_STYLE_TAG_OPTICAL_SIZE);
+ hb_style_get_value (font, HB_STYLE_TAG_SLANT);
+ hb_style_get_value (font, HB_STYLE_TAG_WIDTH);
+ hb_style_get_value (font, HB_STYLE_TAG_WEIGHT);
+
hb_ot_var_get_axis_count (face);
hb_ot_var_get_axis_infos (face, 0, NULL, NULL);
hb_ot_var_normalize_variations (face, NULL, 0, NULL, 0);
diff --git a/test/api/test-style.c b/test/api/test-style.c
new file mode 100644
index 000000000..23d2e41da
--- /dev/null
+++ b/test/api/test-style.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright © 2019 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
+
+/* Unit tests for hb-style.h */
+
+#define assert_cmpfloat(n1, n2) g_assert_cmpint ((int) (n1 * 100.f), ==, (int) (n2 * 100.f))
+
+static void
+test_empty_face (void)
+{
+ hb_font_t *empty = hb_font_get_empty ();
+
+ assert_cmpfloat (hb_style_get_value (empty, HB_STYLE_TAG_ITALIC), 0);
+ assert_cmpfloat (hb_style_get_value (empty, HB_STYLE_TAG_OPTICAL_SIZE), 12);
+ assert_cmpfloat (hb_style_get_value (empty, HB_STYLE_TAG_SLANT), 0);
+ assert_cmpfloat (hb_style_get_value (empty, HB_STYLE_TAG_WIDTH), 100);
+ assert_cmpfloat (hb_style_get_value (empty, HB_STYLE_TAG_WEIGHT), 400);
+}
+
+static void
+test_regular_face (void)
+{
+ hb_face_t *face = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf");
+ hb_font_t *font = hb_font_create (face);
+
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_ITALIC), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_OPTICAL_SIZE), 12);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_SLANT), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WIDTH), 100);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WEIGHT), 400);
+
+ hb_font_destroy (font);
+ hb_face_destroy (face);
+}
+
+static void
+test_face_fdsc (void)
+{
+ hb_face_t *face = hb_test_open_font_file ("fonts/aat-fdsc.ttf");
+ hb_font_t *font = hb_font_create (face);
+
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_ITALIC), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_OPTICAL_SIZE), 24);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_SLANT), 6.33f);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WIDTH), 100);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WEIGHT), 400);
+
+ hb_font_destroy (font);
+ hb_face_destroy (face);
+}
+
+static void
+test_face_user_setting (void)
+{
+ hb_face_t *face = hb_test_open_font_file ("fonts/AdobeVFPrototype_vsindex.otf");
+ hb_font_t *font = hb_font_create (face);
+
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_ITALIC), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_OPTICAL_SIZE), 12);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_SLANT), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WIDTH), 100);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WEIGHT), 389.34f); /* its default weight */
+ assert_cmpfloat (hb_style_get_value (font, (hb_style_tag_t) HB_TAG ('C','N','T','R')), 0);
+
+ hb_font_set_var_named_instance (font, 0);
+
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_ITALIC), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_OPTICAL_SIZE), 12);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_SLANT), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WIDTH), 100);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WEIGHT), 200);
+ assert_cmpfloat (hb_style_get_value (font, (hb_style_tag_t) HB_TAG ('C','N','T','R')), 0);
+
+ hb_font_set_var_named_instance (font, 1);
+
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_ITALIC), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_OPTICAL_SIZE), 12);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_SLANT), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WIDTH), 100);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WEIGHT), 300);
+ assert_cmpfloat (hb_style_get_value (font, (hb_style_tag_t) HB_TAG ('C','N','T','R')), 0);
+
+ hb_font_set_var_named_instance (font, 2);
+
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_ITALIC), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_OPTICAL_SIZE), 12);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_SLANT), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WIDTH), 100);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WEIGHT), 400);
+ assert_cmpfloat (hb_style_get_value (font, (hb_style_tag_t) HB_TAG ('C','N','T','R')), 0);
+
+ hb_font_set_var_named_instance (font, 3);
+
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_ITALIC), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_OPTICAL_SIZE), 12);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_SLANT), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WIDTH), 100);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WEIGHT),600);
+ assert_cmpfloat (hb_style_get_value (font, (hb_style_tag_t) HB_TAG ('C','N','T','R')), 0);
+
+ hb_font_set_var_named_instance (font, 4);
+
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_ITALIC), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_OPTICAL_SIZE), 12);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_SLANT), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WIDTH), 100);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WEIGHT), 700);
+ assert_cmpfloat (hb_style_get_value (font, (hb_style_tag_t) HB_TAG ('C','N','T','R')), 0);
+
+ hb_font_set_var_named_instance (font, 5);
+
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_ITALIC), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_OPTICAL_SIZE), 12);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_SLANT), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WIDTH), 100);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WEIGHT), 900);
+ assert_cmpfloat (hb_style_get_value (font, (hb_style_tag_t) HB_TAG ('C','N','T','R')), 0);
+
+ hb_font_set_var_named_instance (font, 6);
+
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_ITALIC), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_OPTICAL_SIZE), 12);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_SLANT), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WIDTH), 100);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WEIGHT), 900);
+ assert_cmpfloat (hb_style_get_value (font, (hb_style_tag_t) HB_TAG ('C','N','T','R')), 50);
+
+ hb_font_set_var_named_instance (font, 7);
+
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_ITALIC), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_OPTICAL_SIZE), 12);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_SLANT), 0);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WIDTH), 100);
+ assert_cmpfloat (hb_style_get_value (font, HB_STYLE_TAG_WEIGHT), 900);
+ assert_cmpfloat (hb_style_get_value (font, (hb_style_tag_t) HB_TAG ('C','N','T','R')), 100);
+
+ hb_font_destroy (font);
+ hb_face_destroy (face);
+}
+
+int
+main (int argc, char **argv)
+{
+ hb_test_init (&argc, &argv);
+
+ hb_test_add (test_empty_face);
+ hb_test_add (test_regular_face);
+ hb_test_add (test_face_fdsc);
+ hb_test_add (test_face_user_setting);
+
+ return hb_test_run ();
+}