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;