diff --git a/CMakeLists.txt b/CMakeLists.txt
index ac857ef8f..66e4a8388 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -142,8 +142,8 @@ endif ()
## Extract variables from Makefile files
function (extract_make_variable variable makefile_source)
- string(REGEX MATCH "${variable} = ([^$]+)\\$" temp ${makefile_source})
- string(REGEX MATCHALL "[^ \n\t\\]+" listVar ${CMAKE_MATCH_1})
+ string(REGEX MATCH "${variable} = ([^$]+)\\$" temp "${makefile_source}")
+ string(REGEX MATCHALL "[^ \n\t\\]+" listVar "${CMAKE_MATCH_1}")
set (${variable} ${listVar} PARENT_SCOPE)
endfunction ()
diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt
index 43fd76115..99916ebe2 100644
--- a/docs/harfbuzz-sections.txt
+++ b/docs/harfbuzz-sections.txt
@@ -607,6 +607,13 @@ hb_ot_math_get_min_connector_overlap
hb_ot_math_get_glyph_assembly
+
+hb-ot-meta
+hb_ot_meta_t
+hb_ot_meta_get_entries
+hb_ot_meta_reference_entry
+
+
hb-ot-metrics
hb_ot_metrics_t
diff --git a/src/Makefile.am b/src/Makefile.am
index 54e4a02cf..7173f4b7d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -332,6 +332,7 @@ noinst_PROGRAMS = \
main \
test \
test-buffer-serialize \
+ test-ot-meta \
test-ot-name \
test-gpos-size-params \
test-gsub-would-substitute \
@@ -350,6 +351,10 @@ test_buffer_serialize_SOURCES = test-buffer-serialize.cc
test_buffer_serialize_CPPFLAGS = $(HBCFLAGS)
test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS)
+test_ot_meta_SOURCES = test-ot-meta.cc
+test_ot_meta_CPPFLAGS = $(HBCFLAGS)
+test_ot_meta_LDADD = libharfbuzz.la $(HBLIBS)
+
test_ot_name_SOURCES = test-ot-name.cc
test_ot_name_CPPFLAGS = $(HBCFLAGS)
test_ot_name_LDADD = libharfbuzz.la $(HBLIBS)
diff --git a/src/Makefile.sources b/src/Makefile.sources
index 985301af2..38197a82b 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -90,6 +90,7 @@ HB_BASE_sources = \
hb-ot-math.cc \
hb-ot-maxp-table.hh \
hb-ot-meta-table.hh \
+ hb-ot-meta.cc \
hb-ot-metrics.cc \
hb-ot-metrics.hh \
hb-ot-name-language-static.hh \
@@ -196,6 +197,7 @@ HB_BASE_headers = \
hb-ot-font.h \
hb-ot-layout.h \
hb-ot-math.h \
+ hb-ot-meta.h \
hb-ot-metrics.h \
hb-ot-name.h \
hb-ot-shape.h \
diff --git a/src/harfbuzz.cc b/src/harfbuzz.cc
index 0701b7024..20940cde0 100644
--- a/src/harfbuzz.cc
+++ b/src/harfbuzz.cc
@@ -17,6 +17,7 @@
#include "hb-ot-layout.cc"
#include "hb-ot-map.cc"
#include "hb-ot-math.cc"
+#include "hb-ot-meta.cc"
#include "hb-ot-metrics.cc"
#include "hb-ot-name.cc"
#include "hb-ot-shape-complex-arabic.cc"
diff --git a/src/hb-aat-layout-feat-table.hh b/src/hb-aat-layout-feat-table.hh
index a20ef8640..2345f2198 100644
--- a/src/hb-aat-layout-feat-table.hh
+++ b/src/hb-aat-layout-feat-table.hh
@@ -174,9 +174,7 @@ struct feat
}
const FeatureName& get_feature (hb_aat_layout_feature_type_t feature_type) const
- {
- return namesZ.bsearch (featureNameCount, feature_type);
- }
+ { return namesZ.bsearch (featureNameCount, feature_type); }
hb_ot_name_id_t get_feature_name_id (hb_aat_layout_feature_type_t feature) const
{ return get_feature (feature).get_feature_name_id (); }
diff --git a/src/hb-aat-layout.h b/src/hb-aat-layout.h
index 760aaae40..b617e8b70 100644
--- a/src/hb-aat-layout.h
+++ b/src/hb-aat-layout.h
@@ -85,7 +85,7 @@ typedef enum
HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE = 39,
HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE = 103,
- _HB_AAT_LAYOUT_FEATURE_TYPE_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/
+ _HB_AAT_LAYOUT_FEATURE_TYPE_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
} hb_aat_layout_feature_type_t;
/**
@@ -424,7 +424,7 @@ typedef enum
HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN = 2,
HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN = 3,
- _HB_AAT_LAYOUT_FEATURE_SELECTOR_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/
+ _HB_AAT_LAYOUT_FEATURE_SELECTOR_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
} hb_aat_layout_feature_selector_t;
HB_EXTERN unsigned int
diff --git a/src/hb-config.hh b/src/hb-config.hh
index bd440050e..b6db206a3 100644
--- a/src/hb-config.hh
+++ b/src/hb-config.hh
@@ -66,6 +66,7 @@
#define HB_NO_LAYOUT_COLLECT_GLYPHS
#define HB_NO_LAYOUT_UNUSED
#define HB_NO_MATH
+#define HB_NO_META
#define HB_NO_METRICS
#define HB_NO_MMAP
#define HB_NO_NAME
diff --git a/src/hb-iter.hh b/src/hb-iter.hh
index c820c8fb4..8d2ff80c2 100644
--- a/src/hb-iter.hh
+++ b/src/hb-iter.hh
@@ -480,7 +480,7 @@ struct hb_reduce_t
template >
+ typename AccuT = hb_decay>
AccuT
operator () (Iter it)
{
diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
index e235a97c3..ad995750b 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
@@ -576,13 +576,13 @@ struct ArrayOf
operator writer_t () { return writer (); }
hb_array_t sub_array (unsigned int start_offset, unsigned int count) const
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_array_t sub_array (unsigned int start_offset, unsigned int count)
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
bool serialize (hb_serialize_context_t *c, unsigned int items_len)
{
@@ -826,13 +826,13 @@ struct SortedArrayOf : ArrayOf
operator writer_t () { return writer (); }
hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int count) const
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int count)
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
bool serialize (hb_serialize_context_t *c, unsigned int items_len)
{
diff --git a/src/hb-ot-face-table-list.hh b/src/hb-ot-face-table-list.hh
index 4ec622c57..97fb765a2 100644
--- a/src/hb-ot-face-table-list.hh
+++ b/src/hb-ot-face-table-list.hh
@@ -62,7 +62,9 @@ HB_OT_ACCELERATOR (OT, name)
#ifndef HB_NO_STAT
HB_OT_TABLE (OT, STAT)
#endif
-//HB_OT_TABLE (OT, meta)
+#ifndef HB_NO_META
+HB_OT_ACCELERATOR (OT, meta)
+#endif
/* Vertical layout. */
HB_OT_TABLE (OT, vhea)
diff --git a/src/hb-ot-face.cc b/src/hb-ot-face.cc
index f54d0b639..5ef8df43c 100644
--- a/src/hb-ot-face.cc
+++ b/src/hb-ot-face.cc
@@ -32,6 +32,7 @@
#include "hb-ot-cff2-table.hh"
#include "hb-ot-hmtx-table.hh"
#include "hb-ot-kern-table.hh"
+#include "hb-ot-meta-table.hh"
#include "hb-ot-name-table.hh"
#include "hb-ot-post-table.hh"
#include "hb-ot-color-cbdt-table.hh"
diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh
index 091236294..12cc163ce 100644
--- a/src/hb-ot-layout-base-table.hh
+++ b/src/hb-ot-layout-base-table.hh
@@ -1,7 +1,7 @@
/*
- * Copyright © 2016 Elie Roux
+ * Copyright © 2016 Elie Roux
* Copyright © 2018 Google, Inc.
- * Copyright © 2018 Ebrahim Byagowi
+ * Copyright © 2018-2019 Ebrahim Byagowi
*
* This is part of HarfBuzz, a text shaping library.
*
@@ -116,6 +116,8 @@ struct BaseCoordFormat3
struct BaseCoord
{
+ bool has_data () const { return u.format; }
+
hb_position_t get_coord (hb_font_t *font,
const VariationStore &var_store,
hb_direction_t direction) const
@@ -142,10 +144,10 @@ struct BaseCoord
protected:
union {
- HBUINT16 format;
- BaseCoordFormat1 format1;
- BaseCoordFormat2 format2;
- BaseCoordFormat3 format3;
+ HBUINT16 format;
+ BaseCoordFormat1 format1;
+ BaseCoordFormat2 format2;
+ BaseCoordFormat3 format3;
} u;
public:
DEFINE_SIZE_UNION (2, format);
@@ -153,14 +155,9 @@ struct BaseCoord
struct FeatMinMaxRecord
{
- HB_INTERNAL static int cmp (const void *key_, const void *entry_)
- {
- hb_tag_t key = * (hb_tag_t *) key_;
- const FeatMinMaxRecord &entry = * (const FeatMinMaxRecord *) entry_;
- return key < (unsigned int) entry.tag ? -1 :
- key > (unsigned int) entry.tag ? 1 :
- 0;
- }
+ int cmp (hb_tag_t key) const { return tag.cmp (key); }
+
+ bool has_data () const { return tag; }
void get_min_max (const BaseCoord **min, const BaseCoord **max) const
{
@@ -195,17 +192,12 @@ struct FeatMinMaxRecord
struct MinMax
{
void get_min_max (hb_tag_t feature_tag,
- const BaseCoord **min,
- const BaseCoord **max) const
+ const BaseCoord **min,
+ const BaseCoord **max) const
{
- /* TODO Replace hb_bsearch() with .bsearch(). */
- const FeatMinMaxRecord *minMaxCoord = (const FeatMinMaxRecord *)
- hb_bsearch (&feature_tag, featMinMaxRecords.arrayZ,
- featMinMaxRecords.len,
- FeatMinMaxRecord::static_size,
- FeatMinMaxRecord::cmp);
- if (minMaxCoord)
- minMaxCoord->get_min_max (min, max);
+ const FeatMinMaxRecord &minMaxCoord = featMinMaxRecords.bsearch (feature_tag);
+ if (minMaxCoord.has_data ())
+ minMaxCoord.get_min_max (min, max);
else
{
if (likely (min)) *min = &(this+minCoord);
@@ -271,17 +263,11 @@ struct BaseValues
struct BaseLangSysRecord
{
- HB_INTERNAL static int cmp (const void *key_, const void *entry_)
- {
- hb_tag_t key = * (hb_tag_t *) key_;
- const BaseLangSysRecord &entry = * (const BaseLangSysRecord *) entry_;
- return key < (unsigned int) entry.baseLangSysTag ? -1 :
- key > (unsigned int) entry.baseLangSysTag ? 1 :
- 0;
- }
+ int cmp (hb_tag_t key) const { return baseLangSysTag.cmp (key); }
- const MinMax &get_min_max () const
- { return this+minMax; }
+ bool has_data () const { return baseLangSysTag; }
+
+ const MinMax &get_min_max () const { return this+minMax; }
bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
@@ -303,19 +289,14 @@ struct BaseScript
{
const MinMax &get_min_max (hb_tag_t language_tag) const
{
- /* TODO Replace hb_bsearch() with .bsearch(). */
- const BaseLangSysRecord* record = (const BaseLangSysRecord *)
- hb_bsearch (&language_tag, baseLangSysRecords.arrayZ,
- baseLangSysRecords.len,
- BaseLangSysRecord::static_size,
- BaseLangSysRecord::cmp);
- return record ? record->get_min_max () : this+defaultMinMax;
+ const BaseLangSysRecord& record = baseLangSysRecords.bsearch (language_tag);
+ return record.has_data () ? record.get_min_max () : this+defaultMinMax;
}
const BaseCoord &get_base_coord (int baseline_tag_index) const
{ return (this+baseValues).get_base_coord (baseline_tag_index); }
- bool is_empty () const { return !baseValues; }
+ bool has_data () const { return baseValues; }
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -345,14 +326,9 @@ struct BaseScript
struct BaseScriptList;
struct BaseScriptRecord
{
- HB_INTERNAL static int cmp (const void *key_, const void *entry_)
- {
- hb_tag_t key = * (hb_tag_t *) key_;
- const BaseScriptRecord &entry = * (const BaseScriptRecord *) entry_;
- return key < (unsigned int) entry.baseScriptTag ? -1 :
- key > (unsigned int) entry.baseScriptTag ? 1 :
- 0;
- }
+ int cmp (hb_tag_t key) const { return baseScriptTag.cmp (key); }
+
+ bool has_data () const { return baseScriptTag; }
const BaseScript &get_base_script (const BaseScriptList *list) const
{ return list+baseScript; }
@@ -376,22 +352,11 @@ struct BaseScriptRecord
struct BaseScriptList
{
- const BaseScriptRecord *find_record (hb_tag_t script) const
- {
- /* TODO Replace hb_bsearch() with .bsearch(). */
- return (const BaseScriptRecord *) hb_bsearch (&script, baseScriptRecords.arrayZ,
- baseScriptRecords.len,
- BaseScriptRecord::static_size,
- BaseScriptRecord::cmp);
- }
-
- /* TODO: Or client should handle fallback? */
const BaseScript &get_base_script (hb_tag_t script) const
{
- const BaseScriptRecord *record = find_record (script);
- if (!record) record = find_record ((hb_script_t) HB_TAG ('D','F','L','T'));
-
- return record ? record->get_base_script (this) : Null (BaseScript);
+ const BaseScriptRecord *record = &baseScriptRecords.bsearch (script);
+ if (!record->has_data ()) record = &baseScriptRecords.bsearch (HB_TAG ('D','F','L','T'));
+ return record->has_data () ? record->get_base_script (this) : Null (BaseScript);
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -412,14 +377,19 @@ struct BaseScriptList
struct Axis
{
bool get_baseline (hb_ot_layout_baseline_t baseline,
- hb_tag_t script_tag,
- hb_tag_t language_tag,
- const BaseCoord **coord) const
+ hb_tag_t script_tag,
+ hb_tag_t language_tag,
+ const BaseCoord **coord) const
{
const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
- if (base_script.is_empty ()) return false;
+ if (!base_script.has_data ()) return false;
- if (likely (coord)) *coord = &base_script.get_base_coord ((this+baseTagList).bsearch (baseline));
+ if (likely (coord))
+ {
+ unsigned int tag_index = 0;
+ (this+baseTagList).bfind (baseline, &tag_index);
+ *coord = &base_script.get_base_coord (tag_index);
+ }
return true;
}
@@ -431,7 +401,7 @@ struct Axis
const BaseCoord **max_coord) const
{
const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
- if (base_script.is_empty ()) return false;
+ if (!base_script.has_data ()) return false;
base_script.get_min_max (language_tag).get_min_max (feature_tag, min_coord, max_coord);
@@ -479,13 +449,14 @@ struct BASE
hb_tag_t language_tag,
hb_position_t *base) const
{
- const BaseCoord *base_coord;
- if (!get_axis (direction).get_baseline (baseline, script_tag, language_tag, &base_coord))
+ const BaseCoord *base_coord = nullptr;
+ if (unlikely (!get_axis (direction).get_baseline (baseline, script_tag, language_tag, &base_coord) ||
+ !base_coord || !base_coord->has_data ()))
return false;
- if (likely (base && base_coord)) *base = base_coord->get_coord (font,
- get_var_store (),
- direction);
+ if (likely (base))
+ *base = base_coord->get_coord (font, get_var_store (), direction);
+
return true;
}
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index a6cc1a230..84e1b1578 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -248,7 +248,7 @@ struct SingleSubst
if (unlikely (!c->extend_min (u.format))) return_trace (false);
unsigned format = 2;
unsigned delta = 0;
- if (glyphs.len ())
+ if (glyphs)
{
format = 1;
auto get_delta = [=] (hb_codepoint_pair_t _) {
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index f493005bc..4cd65b4a9 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -48,7 +48,6 @@
#include "hb-ot-layout-gpos-table.hh"
#include "hb-ot-layout-base-table.hh" // Just so we compile it; unused otherwise.
#include "hb-ot-layout-jstf-table.hh" // Just so we compile it; unused otherwise.
-#include "hb-ot-meta-table.hh" // Just so we compile it; unused otherwise.
#include "hb-ot-name-table.hh"
#include "hb-ot-os2-table.hh"
@@ -1980,7 +1979,9 @@ typedef enum {
HB_OT_LAYOUT_BASELINE_IDEO = HB_TAG('i','d','e','o'),
HB_OT_LAYOUT_BASELINE_IDTB = HB_TAG('i','d','t','b'),
HB_OT_LAYOUT_BASELINE_MATH = HB_TAG('m','a','t','h'),
- HB_OT_LAYOUT_BASELINE_ROMN = HB_TAG('r','o','m','n')
+ HB_OT_LAYOUT_BASELINE_ROMN = HB_TAG('r','o','m','n'),
+
+ _HB_OT_LAYOUT_BASELINE_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
} hb_ot_layout_baseline_t;
diff --git a/src/hb-ot-meta-table.hh b/src/hb-ot-meta-table.hh
index dac55e47f..f0842e4ef 100644
--- a/src/hb-ot-meta-table.hh
+++ b/src/hb-ot-meta-table.hh
@@ -32,7 +32,7 @@
* https://docs.microsoft.com/en-us/typography/opentype/spec/meta
* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6meta.html
*/
-#define HB_OT_TAG_meta HB_TAG('m','e','t','a')
+#define HB_OT_TAG_meta HB_TAG ('m','e','t','a')
namespace OT {
@@ -40,6 +40,13 @@ namespace OT {
struct DataMap
{
+ int cmp (hb_tag_t a) const { return tag.cmp (a); }
+
+ hb_tag_t get_tag () const { return tag; }
+
+ hb_blob_t *reference_entry (hb_blob_t *meta_blob) const
+ { return hb_blob_create_sub_blob (meta_blob, dataZ, dataLength); }
+
bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
@@ -62,6 +69,32 @@ struct meta
{
static constexpr hb_tag_t tableTag = HB_OT_TAG_meta;
+ struct accelerator_t
+ {
+ void init (hb_face_t *face)
+ { table = hb_sanitize_context_t ().reference_table (face); }
+ void fini () { table.destroy (); }
+
+ hb_blob_t *reference_entry (hb_tag_t tag) const
+ { return table->dataMaps.lsearch (tag).reference_entry (table.get_blob ()); }
+
+ unsigned int get_entries (unsigned int start_offset,
+ unsigned int *count,
+ hb_ot_meta_tag_t *entries) const
+ {
+ if (count)
+ {
+ hb_array_t arr = table->dataMaps.sub_array (start_offset, count);
+ for (unsigned int i = 0; i < arr.length; i++)
+ entries[i] = (hb_ot_meta_tag_t) arr[i].get_tag ();
+ }
+ return table->dataMaps.len;
+ }
+
+ private:
+ hb_blob_ptr_t table;
+ };
+
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -83,6 +116,8 @@ struct meta
DEFINE_SIZE_ARRAY (16, dataMaps);
};
+struct meta_accelerator_t : meta::accelerator_t {};
+
} /* namespace OT */
diff --git a/src/hb-ot-meta.cc b/src/hb-ot-meta.cc
new file mode 100644
index 000000000..a5ce14876
--- /dev/null
+++ b/src/hb-ot-meta.cc
@@ -0,0 +1,77 @@
+/*
+ * 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_META
+
+#include "hb-ot-meta-table.hh"
+
+/**
+ * SECTION:hb-ot-meta
+ * @title: hb-ot-meta
+ * @short_description: OpenType Metadata
+ * @include: hb-ot.h
+ *
+ * Functions for fetching metadata from fonts.
+ **/
+
+/**
+ * hb_ot_meta_reference_entry:
+ * @face: a face object
+ * @start_offset: iteration's start offset
+ * @entries_count:(inout) (allow-none): buffer size as input, filled size as output
+ * @entries: (out caller-allocates) (array length=entries_count): entries tags buffer
+ *
+ * Return value: Number of all available feature types.
+ *
+ * Since: REPLACEME
+ **/
+unsigned int
+hb_ot_meta_get_entries (hb_face_t *face,
+ unsigned int start_offset,
+ unsigned int *entries_count, /* IN/OUT. May be NULL. */
+ hb_ot_meta_tag_t *entries /* OUT. May be NULL. */)
+{
+ return face->table.meta->get_entries (start_offset, entries_count, entries);
+}
+
+/**
+ * hb_ot_meta_reference_entry:
+ * @face: a #hb_face_t object.
+ * @meta_tag: tag of metadata you like to have.
+ *
+ * It fetches metadata entry of a given tag from a font.
+ *
+ * Returns: (transfer full): A blob containing the blob.
+ *
+ * Since: REPLACEME
+ **/
+hb_blob_t *
+hb_ot_meta_reference_entry (hb_face_t *face, hb_ot_meta_tag_t meta_tag)
+{
+ return face->table.meta->reference_entry (meta_tag);
+}
+
+#endif
diff --git a/src/hb-ot-meta.h b/src/hb-ot-meta.h
new file mode 100644
index 000000000..5267728ea
--- /dev/null
+++ b/src/hb-ot-meta.h
@@ -0,0 +1,65 @@
+/*
+ * 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_OT_H_IN
+#error "Include instead."
+#endif
+
+#ifndef HB_OT_META_H
+#define HB_OT_META_H
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+
+/**
+ * hb_ot_meta_tag_t:
+ *
+ * From https://docs.microsoft.com/en-us/typography/opentype/spec/meta
+ *
+ * Since: REPLACEME
+ **/
+typedef enum {
+/*
+ HB_OT_META_APPL = HB_TAG ('a','p','p','l'),
+ HB_OT_META_BILD = HB_TAG ('b','i','l','d'),
+*/
+ HB_OT_META_DESIGN_LANGUAGES = HB_TAG ('d','l','n','g'),
+ HB_OT_META_SUPPORTED_LANGUAGES= HB_TAG ('s','l','n','g'),
+
+ _HB_OT_META_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
+} hb_ot_meta_tag_t;
+
+HB_EXTERN unsigned int
+hb_ot_meta_get_entries (hb_face_t *face,
+ unsigned int start_offset,
+ unsigned int *entries_count, /* IN/OUT. May be NULL. */
+ hb_ot_meta_tag_t *entries /* OUT. May be NULL. */);
+
+HB_EXTERN hb_blob_t *
+hb_ot_meta_reference_entry (hb_face_t *face, hb_ot_meta_tag_t meta_tag);
+
+HB_END_DECLS
+
+#endif /* HB_OT_META_H */
diff --git a/src/hb-ot-metrics.cc b/src/hb-ot-metrics.cc
index 910d826b9..d211d7e68 100644
--- a/src/hb-ot-metrics.cc
+++ b/src/hb-ot-metrics.cc
@@ -34,7 +34,7 @@
static float
-_fix_ascender_descender (float value, hb_ot_metrics_t metrics_tag)
+_fix_ascender_descender (float value, hb_ot_metrics_tag_t metrics_tag)
{
if (metrics_tag == HB_OT_METRICS_HORIZONTAL_ASCENDER ||
metrics_tag == HB_OT_METRICS_VERTICAL_ASCENDER)
@@ -48,12 +48,12 @@ _fix_ascender_descender (float value, hb_ot_metrics_t metrics_tag)
/* The common part of _get_position logic needed on hb-ot-font and here
to be able to have slim builds without the not always needed parts */
bool
-_hb_ot_metrics_get_position_common (hb_font_t *font,
- hb_ot_metrics_t metrics_tag,
- hb_position_t *position /* OUT. May be NULL. */)
+_hb_ot_metrics_get_position_common (hb_font_t *font,
+ hb_ot_metrics_tag_t metrics_tag,
+ hb_position_t *position /* OUT. May be NULL. */)
{
hb_face_t *face = font->face;
- switch ((unsigned int) metrics_tag)
+ switch ((unsigned) metrics_tag)
{
#ifndef HB_NO_VAR
#define GET_VAR face->table.MVAR->get_var (metrics_tag, font->coords, font->num_coords)
@@ -91,7 +91,7 @@ _hb_ot_metrics_get_position_common (hb_font_t *font,
#if 0
static bool
-_get_gasp (hb_face_t *face, float *result, hb_ot_metrics_t metrics_tag)
+_get_gasp (hb_face_t *face, float *result, hb_ot_metrics_tag_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;
@@ -100,6 +100,14 @@ _get_gasp (hb_face_t *face, float *result, hb_ot_metrics_t metrics_tag)
}
#endif
+/* Private tags for https://github.com/harfbuzz/harfbuzz/issues/1866 */
+#define _HB_OT_METRICS_HORIZONTAL_ASCENDER_OS2 HB_TAG ('O','a','s','c')
+#define _HB_OT_METRICS_HORIZONTAL_ASCENDER_HHEA HB_TAG ('H','a','s','c')
+#define _HB_OT_METRICS_HORIZONTAL_DESCENDER_OS2 HB_TAG ('O','d','s','c')
+#define _HB_OT_METRICS_HORIZONTAL_DESCENDER_HHEA HB_TAG ('H','d','s','c')
+#define _HB_OT_METRICS_HORIZONTAL_LINE_GAP_OS2 HB_TAG ('O','l','g','p')
+#define _HB_OT_METRICS_HORIZONTAL_LINE_GAP_HHEA HB_TAG ('H','l','g','p')
+
/**
* hb_ot_metrics_get_position:
* @font: a #hb_font_t object.
@@ -112,12 +120,12 @@ _get_gasp (hb_face_t *face, float *result, hb_ot_metrics_t metrics_tag)
* 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. */)
+hb_ot_metrics_get_position (hb_font_t *font,
+ hb_ot_metrics_tag_t metrics_tag,
+ hb_position_t *position /* OUT. May be NULL. */)
{
hb_face_t *face = font->face;
- switch (metrics_tag)
+ switch ((unsigned) metrics_tag)
{
case HB_OT_METRICS_HORIZONTAL_ASCENDER:
case HB_OT_METRICS_HORIZONTAL_DESCENDER:
@@ -158,6 +166,14 @@ hb_ot_metrics_get_position (hb_font_t *font,
case HB_OT_METRICS_STRIKEOUT_OFFSET: return GET_METRIC_Y (OS2, yStrikeoutPosition);
case HB_OT_METRICS_UNDERLINE_SIZE: return GET_METRIC_Y (post->table, underlineThickness);
case HB_OT_METRICS_UNDERLINE_OFFSET: return GET_METRIC_Y (post->table, underlinePosition);
+
+ /* Private tags */
+ case _HB_OT_METRICS_HORIZONTAL_ASCENDER_OS2: return GET_METRIC_Y (OS2, sTypoAscender);
+ case _HB_OT_METRICS_HORIZONTAL_ASCENDER_HHEA: return GET_METRIC_Y (hhea, ascender);
+ case _HB_OT_METRICS_HORIZONTAL_DESCENDER_OS2: return GET_METRIC_Y (OS2, sTypoDescender);
+ case _HB_OT_METRICS_HORIZONTAL_DESCENDER_HHEA: return GET_METRIC_Y (hhea, descender);
+ case _HB_OT_METRICS_HORIZONTAL_LINE_GAP_OS2: return GET_METRIC_Y (OS2, sTypoLineGap);
+ case _HB_OT_METRICS_HORIZONTAL_LINE_GAP_HHEA: return GET_METRIC_Y (hhea, lineGap);
#undef GET_METRIC_Y
#undef GET_METRIC_X
#undef GET_VAR
@@ -176,7 +192,7 @@ hb_ot_metrics_get_position (hb_font_t *font,
* Since: REPLACEME
**/
float
-hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_t metrics_tag)
+hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
{
return font->face->table.MVAR->get_var (metrics_tag, font->coords, font->num_coords);
}
@@ -191,7 +207,7 @@ hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_t metrics_tag)
* Since: REPLACEME
**/
hb_position_t
-hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_t metrics_tag)
+hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
{
return font->em_scalef_x (hb_ot_metrics_get_variation (font, metrics_tag));
}
@@ -206,7 +222,7 @@ hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_t metrics_tag)
* Since: REPLACEME
**/
hb_position_t
-hb_ot_metrics_get_y_variation (hb_font_t *font, hb_ot_metrics_t metrics_tag)
+hb_ot_metrics_get_y_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
{
return font->em_scalef_y (hb_ot_metrics_get_variation (font, metrics_tag));
}
diff --git a/src/hb-ot-metrics.h b/src/hb-ot-metrics.h
index 4d22837f2..6b2747b96 100644
--- a/src/hb-ot-metrics.h
+++ b/src/hb-ot-metrics.h
@@ -36,7 +36,7 @@ HB_BEGIN_DECLS
/**
- * hb_ot_metrics_t:
+ * hb_ot_metrics_tag_t:
*
* From https://docs.microsoft.com/en-us/typography/opentype/spec/mvar#value-tags
*
@@ -70,22 +70,24 @@ typedef enum {
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_OT_METRICS_UNDERLINE_OFFSET = HB_TAG ('u','n','d','o'),
+
+ _HB_OT_METRICS_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
+} hb_ot_metrics_tag_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_ot_metrics_get_position (hb_font_t *font,
+ hb_ot_metrics_tag_t metrics_tag,
+ hb_position_t *position /* OUT. May be NULL. */);
HB_EXTERN float
-hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_t metrics_tag);
+hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_tag_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_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_tag_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_ot_metrics_get_y_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag);
HB_END_DECLS
diff --git a/src/hb-ot-metrics.hh b/src/hb-ot-metrics.hh
index f9ae46fc9..19a5e9ed4 100644
--- a/src/hb-ot-metrics.hh
+++ b/src/hb-ot-metrics.hh
@@ -28,8 +28,8 @@
#include "hb.hh"
HB_INTERNAL bool
-_hb_ot_metrics_get_position_common (hb_font_t *font,
- hb_ot_metrics_t metrics_tag,
- hb_position_t *position /* OUT. May be NULL. */);
+_hb_ot_metrics_get_position_common (hb_font_t *font,
+ hb_ot_metrics_tag_t metrics_tag,
+ hb_position_t *position /* OUT. May be NULL. */);
#endif /* HB_OT_METRICS_HH */
diff --git a/src/hb-ot-var.h b/src/hb-ot-var.h
index cf6f0c950..df89bc5a2 100644
--- a/src/hb-ot-var.h
+++ b/src/hb-ot-var.h
@@ -68,7 +68,7 @@ hb_ot_var_get_axis_count (hb_face_t *face);
typedef enum { /*< flags >*/
HB_OT_VAR_AXIS_FLAG_HIDDEN = 0x00000001u,
- _HB_OT_VAR_AXIS_FLAG_MAX_VALUE= 0x7FFFFFFFu /*< skip >*/
+ _HB_OT_VAR_AXIS_FLAG_MAX_VALUE= HB_TAG_MAX_SIGNED /*< skip >*/
} hb_ot_var_axis_flags_t;
/**
diff --git a/src/hb-ot-vorg-table.hh b/src/hb-ot-vorg-table.hh
index 19e08ebb5..d9002f3d6 100644
--- a/src/hb-ot-vorg-table.hh
+++ b/src/hb-ot-vorg-table.hh
@@ -85,7 +85,7 @@ struct VORG
this->vertYOrigins.len = it.len ();
+ it
- | hb_apply ([c] (const VertOriginMetric& _) { c->copy (_);})
+ | hb_apply ([c] (const VertOriginMetric& _) { c->copy (_); })
;
}
diff --git a/src/hb-ot.h b/src/hb-ot.h
index d00ee80ae..f2dbaa1b3 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-meta.h"
#include "hb-ot-metrics.h"
#include "hb-ot-name.h"
#include "hb-ot-shape.h"
diff --git a/src/hb-vector.hh b/src/hb-vector.hh
index de16c97dd..035c6d0a8 100644
--- a/src/hb-vector.hh
+++ b/src/hb-vector.hh
@@ -143,13 +143,13 @@ struct hb_vector_t
operator writer_t () { return writer (); }
hb_array_t sub_array (unsigned int start_offset, unsigned int count) const
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_array_t sub_array (unsigned int start_offset, unsigned int count)
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
- { return as_array ().sub_array (start_offset, count);}
+ { return as_array ().sub_array (start_offset, count); }
hb_sorted_array_t as_sorted_array ()
{ return hb_sorted_array (arrayZ, length); }
diff --git a/src/test-ot-meta.cc b/src/test-ot-meta.cc
new file mode 100644
index 000000000..512df5a78
--- /dev/null
+++ b/src/test-ot-meta.cc
@@ -0,0 +1,70 @@
+/*
+ * 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"
+#include "hb-ot.h"
+
+#include
+#include
+
+#ifdef HB_NO_OPEN
+#define hb_blob_create_from_file(x) hb_blob_get_empty ()
+#endif
+
+int
+main (int argc, char **argv)
+{
+ if (argc != 2) {
+ fprintf (stderr, "usage: %s font-file\n", argv[0]);
+ exit (1);
+ }
+
+ hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
+ hb_face_t *face = hb_face_create (blob, 0 /* first face */);
+ hb_blob_destroy (blob);
+ blob = nullptr;
+
+ unsigned int count = 0;
+
+#ifndef HB_NO_META
+ count = hb_ot_meta_get_entries (face, 0, nullptr, nullptr);
+
+ hb_ot_meta_tag_t *tags = (hb_ot_meta_tag_t *)
+ malloc (sizeof (hb_ot_meta_tag_t) * count);
+ hb_ot_meta_get_entries (face, 0, &count, tags);
+ for (unsigned i = 0; i < count; ++i)
+ {
+ hb_blob_t *entry = hb_ot_meta_reference_entry (face, tags[i]);
+ printf ("%c%c%c%c, size: %d: %.*s\n",
+ HB_UNTAG (tags[i]), hb_blob_get_length (entry),
+ hb_blob_get_length (entry), hb_blob_get_data (entry, nullptr));
+ hb_blob_destroy (entry);
+ }
+ free (tags);
+#endif
+
+ hb_face_destroy (face);
+
+ return !count;
+}
diff --git a/test/api/Makefile.am b/test/api/Makefile.am
index b95d8c9ac..33b5fdf64 100644
--- a/test/api/Makefile.am
+++ b/test/api/Makefile.am
@@ -90,6 +90,7 @@ TEST_PROGS += \
test-ot-color \
test-ot-ligature-carets \
test-ot-name \
+ test-ot-meta \
test-ot-metrics \
test-ot-tag \
test-ot-extents-cff \
diff --git a/test/api/fonts/TestCFF2VF.otf b/test/api/fonts/TestCFF2VF.otf
new file mode 100644
index 000000000..a9e48e396
Binary files /dev/null and b/test/api/fonts/TestCFF2VF.otf differ
diff --git a/test/api/fonts/meta.ttf b/test/api/fonts/meta.ttf
new file mode 100644
index 000000000..414d7e671
Binary files /dev/null and b/test/api/fonts/meta.ttf differ
diff --git a/test/api/test-ot-meta.c b/test/api/test-ot-meta.c
new file mode 100644
index 000000000..b8be5a30d
--- /dev/null
+++ b/test/api/test-ot-meta.c
@@ -0,0 +1,84 @@
+/*
+ * 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-ot-meta.h */
+
+static void
+test_ot_meta_get_entries (void)
+{
+ hb_face_t *face = hb_test_open_font_file ("fonts/meta.ttf");
+ hb_ot_meta_tag_t entries[2];
+
+ unsigned int entries_count = 2;
+ g_assert_cmpint (hb_ot_meta_get_entries (face, 0, &entries_count, entries), ==, 5);
+ g_assert_cmpint (entries_count, ==, 2);
+ g_assert_cmpint (entries[0], ==, HB_TAG ('a','p','p','l'));
+ g_assert_cmpint (entries[1], ==, HB_TAG ('b','i','l','d'));
+
+ entries_count = 1;
+ g_assert_cmpint (hb_ot_meta_get_entries (face, 2, &entries_count, entries), ==, 5);
+ g_assert_cmpint (entries_count, ==, 1);
+ g_assert_cmpint (entries[0], ==, HB_TAG ('d','l','n','g'));
+
+ entries_count = 2;
+ g_assert_cmpint (hb_ot_meta_get_entries (face, 4, &entries_count, entries), ==, 5);
+ g_assert_cmpint (entries_count, ==, 1);
+ g_assert_cmpint (entries[0], ==, HB_TAG ('s','l','n','g'));
+
+ hb_face_destroy (face);
+}
+
+static void
+test_ot_meta_reference_entry (void)
+{
+ hb_face_t *face = hb_test_open_font_file ("fonts/meta.ttf");
+ hb_blob_t *dlng = hb_ot_meta_reference_entry (face, HB_OT_META_DESIGN_LANGUAGES);
+ g_assert_cmpint (hb_blob_get_length (dlng), ==, 8);
+ g_assert_cmpmem (hb_blob_get_data (dlng, NULL), 8, "ar,de,fa", 8);
+ hb_blob_destroy (dlng);
+ hb_blob_t *fslf = hb_ot_meta_reference_entry (face, (hb_ot_meta_tag_t) HB_TAG ('f','s','l','f'));
+ g_assert_cmpint (hb_blob_get_length (fslf), ==, 12);
+ hb_blob_destroy (fslf);
+ hb_blob_t *nacl = hb_ot_meta_reference_entry (face, (hb_ot_meta_tag_t) HB_TAG ('n','a','c','l'));
+ g_assert_cmpint (hb_blob_get_length (nacl), ==, 0);
+ hb_blob_destroy (nacl);
+ hb_blob_t *slng = hb_ot_meta_reference_entry (face, HB_OT_META_SUPPORTED_LANGUAGES);
+ g_assert_cmpint (hb_blob_get_length (slng), ==, 11);
+ g_assert_cmpmem (hb_blob_get_data (slng, NULL), 11, "ar,de,en,fa", 11);
+ hb_blob_destroy (slng);
+ hb_face_destroy (face);
+}
+
+int
+main (int argc, char **argv)
+{
+ hb_test_init (&argc, &argv);
+ hb_test_add (test_ot_meta_get_entries);
+ hb_test_add (test_ot_meta_reference_entry);
+ return hb_test_run ();
+}
diff --git a/test/api/test-ot-metrics.c b/test/api/test-ot-metrics.c
index 91dd7f5e1..9712c932a 100644
--- a/test/api/test-ot-metrics.c
+++ b/test/api/test-ot-metrics.c
@@ -31,7 +31,7 @@
/* Unit tests for hb-ot-metrics.h */
static void
-test_ot_metrics_get (void)
+test_ot_metrics_get_no_var (void)
{
hb_face_t *face = hb_test_open_font_file ("fonts/cpal-v0.ttf");
hb_font_t *font = hb_font_create (face);
@@ -40,15 +40,39 @@ test_ot_metrics_get (void)
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 (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_X_HEIGHT), ==, 0);
// g_assert_cmpint ((int) hb_ot_metrics_get_variation (font, HB_OT_METRICS_HORIZONTAL_ASCENDER), ==, 0);
hb_font_destroy (font);
hb_face_destroy (face);
}
+static void
+test_ot_metrics_get_var (void)
+{
+ hb_face_t *face = hb_test_open_font_file ("fonts/TestCFF2VF.otf");
+ hb_font_t *font = hb_font_create (face);
+ hb_position_t value;
+ g_assert (hb_ot_metrics_get_position (font, HB_OT_METRICS_X_HEIGHT, &value));
+ g_assert_cmpint (value, ==, 486);
+ 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 (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_X_HEIGHT), ==, 0);
+ float coords[] = {100.f};
+ hb_font_set_var_coords_design (font, coords, 1);
+ g_assert (hb_ot_metrics_get_position (font, HB_OT_METRICS_X_HEIGHT, &value));
+ g_assert_cmpint (value, ==, 478);
+ 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 (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_X_HEIGHT), ==, -8);
+ 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);
+ hb_test_add (test_ot_metrics_get_no_var);
+ hb_test_add (test_ot_metrics_get_var);
return hb_test_run ();
}
diff --git a/test/fuzzing/run-subset-fuzzer-tests.py b/test/fuzzing/run-subset-fuzzer-tests.py
index d431e10a3..f94c13ffe 100755
--- a/test/fuzzing/run-subset-fuzzer-tests.py
+++ b/test/fuzzing/run-subset-fuzzer-tests.py
@@ -33,7 +33,7 @@ def cmd(command):
def timeout(p, is_killed):
is_killed['value'] = True
p.kill()
- timer = threading.Timer (6, timeout, [p, is_killed])
+ timer = threading.Timer (8, timeout, [p, is_killed])
try:
timer.start()
diff --git a/util/options.cc b/util/options.cc
index 42dfa956a..f71a5a34d 100644
--- a/util/options.cc
+++ b/util/options.cc
@@ -370,6 +370,7 @@ parse_unicodes (const char *name G_GNUC_UNUSED,
hb_codepoint_t u = strtoul (s, &p, 16);
if (errno || s == p)
{
+ g_string_free (gs, TRUE);
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
"Failed parsing Unicode values at: '%s'", s);
return false;