diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 9472af4f1..fccfcb0ed 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -479,7 +479,9 @@ HB_OT_TAG_GSUB HB_OT_TAG_JSTF hb_ot_layout_collect_lookups hb_ot_layout_collect_features +hb_ot_layout_feature_get_characters hb_ot_layout_feature_get_lookups +hb_ot_layout_feature_get_name_ids hb_ot_layout_feature_with_variations_get_lookups hb_ot_layout_get_attach_points hb_ot_layout_get_glyph_class diff --git a/src/Makefile.sources b/src/Makefile.sources index 94d826735..619715217 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -184,6 +184,7 @@ HB_OT_headers = \ hb-ot-font.h \ hb-ot-layout.h \ hb-ot-math.h \ + hb-ot-name.h \ hb-ot-shape.h \ hb-ot-tag.h \ hb-ot-var.h \ diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index cd1129128..52923a8da 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -226,15 +226,14 @@ struct KerxSubTableFormat1 struct KerxSubTableFormat2 { inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, - unsigned int num_glyphs) const + hb_aat_apply_context_t *c) const { + unsigned int num_glyphs = c->sanitizer.get_num_glyphs (); unsigned int l = (this+leftClassTable).get_value_or_null (left, num_glyphs); unsigned int r = (this+rightClassTable).get_value_or_null (right, num_glyphs); unsigned int offset = l + r; const FWORD *v = &StructAtOffset (&(this+array), offset); - if (unlikely ((const char *) v < (const char *) &array || - (const char *) v + v->static_size - (const char *) this > header.length)) - return 0; + if (unlikely (!v->sanitize (&c->sanitizer))) return 0; return *v; } @@ -245,8 +244,7 @@ struct KerxSubTableFormat2 if (!c->plan->requested_kerning) return false; - accelerator_t accel (*this, - c->face->get_num_glyphs ()); + accelerator_t accel (*this, c); hb_kern_machine_t machine (accel); machine.kern (c->font, c->buffer, c->plan->kern_mask); @@ -258,22 +256,21 @@ struct KerxSubTableFormat2 TRACE_SANITIZE (this); return_trace (likely (rowWidth.sanitize (c) && leftClassTable.sanitize (c, this) && - rightClassTable.sanitize (c, this))); + rightClassTable.sanitize (c, this) && + c->check_range (this, array))); } struct accelerator_t { const KerxSubTableFormat2 &table; - unsigned int num_glyphs; + hb_aat_apply_context_t *c; inline accelerator_t (const KerxSubTableFormat2 &table_, - unsigned int num_glyphs_) - : table (table_), num_glyphs (num_glyphs_) {} + hb_aat_apply_context_t *c_) : + table (table_), c (c_) {} inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { - return table.get_kerning (left, right, num_glyphs); - } + { return table.get_kerning (left, right, c); } }; protected: @@ -383,11 +380,11 @@ struct KerxSubTableFormat4 unsigned int currAnchorPoint = *data++; const Anchor markAnchor = c->ankr_table.get_anchor (c->buffer->info[mark].codepoint, markAnchorPoint, - c->face->get_num_glyphs (), + c->sanitizer.get_num_glyphs (), c->ankr_end); const Anchor currAnchor = c->ankr_table.get_anchor (c->buffer->cur ().codepoint, currAnchorPoint, - c->face->get_num_glyphs (), + c->sanitizer.get_num_glyphs (), c->ankr_end); o.x_offset = c->font->em_scale_x (markAnchor.xCoordinate) - c->font->em_scale_x (currAnchor.xCoordinate); @@ -472,18 +469,19 @@ struct KerxSubTableFormat6 inline bool is_long (void) const { return flags & ValuesAreLong; } inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, - unsigned int num_glyphs) const + hb_aat_apply_context_t *c) const { + unsigned int num_glyphs = c->sanitizer.get_num_glyphs (); if (is_long ()) { const U::Long &t = u.l; unsigned int l = (this+t.rowIndexTable).get_value_or_null (left, num_glyphs); unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs); unsigned int offset = l + r; + if (unlikely (offset < l)) return 0; /* Addition overflow. */ + if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0; const FWORD32 *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD32)); - if (unlikely ((const char *) v < (const char *) &t.array || - (const char *) v + v->static_size - (const char *) this > header.length)) - return 0; + if (unlikely (!v->sanitize (&c->sanitizer))) return 0; return *v; } else @@ -493,9 +491,7 @@ struct KerxSubTableFormat6 unsigned int r = (this+t.columnIndexTable).get_value_or_null (right, num_glyphs); unsigned int offset = l + r; const FWORD *v = &StructAtOffset (&(this+t.array), offset * sizeof (FWORD)); - if (unlikely ((const char *) v < (const char *) &t.array || - (const char *) v + v->static_size - (const char *) this > header.length)) - return 0; + if (unlikely (!v->sanitize (&c->sanitizer))) return 0; return *v; } } @@ -507,8 +503,7 @@ struct KerxSubTableFormat6 if (!c->plan->requested_kerning) return false; - accelerator_t accel (*this, - c->face->get_num_glyphs ()); + accelerator_t accel (*this, c); hb_kern_machine_t machine (accel); machine.kern (c->font, c->buffer, c->plan->kern_mask); @@ -522,26 +517,26 @@ struct KerxSubTableFormat6 is_long () ? ( u.l.rowIndexTable.sanitize (c, this) && - u.l.columnIndexTable.sanitize (c, this) + u.l.columnIndexTable.sanitize (c, this) && + c->check_range (this, u.l.array) ) : ( u.s.rowIndexTable.sanitize (c, this) && - u.s.columnIndexTable.sanitize (c, this) + u.s.columnIndexTable.sanitize (c, this) && + c->check_range (this, u.s.array) ))); } struct accelerator_t { const KerxSubTableFormat6 &table; - unsigned int num_glyphs; + hb_aat_apply_context_t *c; inline accelerator_t (const KerxSubTableFormat6 &table_, - unsigned int num_glyphs_) - : table (table_), num_glyphs (num_glyphs_) {} + hb_aat_apply_context_t *c_) : + table (table_), c (c_) {} inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { - return table.get_kerning (left, right, num_glyphs); - } + { return table.get_kerning (left, right, c); } }; protected: diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 2b86ba8c7..e9da850b3 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -36,6 +36,99 @@ #include "hb-aat-layout-trak-table.hh" #include "hb-aat-ltag-table.hh" // Just so we compile it; unused otherwise. + +/* Table data courtesy of Apple. Converted from mnemonics to integers + * when moving to this file. */ +static const hb_aat_feature_mapping_t feature_mappings[] = +{ + {HB_TAG ('c','2','p','c'), 38/*kUpperCaseType*/, 2/*kUpperCasePetiteCapsSelector*/, 0/*kDefaultUpperCaseSelector*/}, + {HB_TAG ('c','2','s','c'), 38/*kUpperCaseType*/, 1/*kUpperCaseSmallCapsSelector*/, 0/*kDefaultUpperCaseSelector*/}, + {HB_TAG ('c','a','l','t'), 36/*kContextualAlternatesType*/, 0/*kContextualAlternatesOnSelector*/, 1/*kContextualAlternatesOffSelector*/}, + {HB_TAG ('c','a','s','e'), 33/*kCaseSensitiveLayoutType*/, 0/*kCaseSensitiveLayoutOnSelector*/, 1/*kCaseSensitiveLayoutOffSelector*/}, + {HB_TAG ('c','l','i','g'), 1/*kLigaturesType*/, 18/*kContextualLigaturesOnSelector*/, 19/*kContextualLigaturesOffSelector*/}, + {HB_TAG ('c','p','s','p'), 33/*kCaseSensitiveLayoutType*/, 2/*kCaseSensitiveSpacingOnSelector*/, 3/*kCaseSensitiveSpacingOffSelector*/}, + {HB_TAG ('c','s','w','h'), 36/*kContextualAlternatesType*/, 4/*kContextualSwashAlternatesOnSelector*/, 5/*kContextualSwashAlternatesOffSelector*/}, + {HB_TAG ('d','l','i','g'), 1/*kLigaturesType*/, 4/*kRareLigaturesOnSelector*/, 5/*kRareLigaturesOffSelector*/}, + {HB_TAG ('e','x','p','t'), 20/*kCharacterShapeType*/, 10/*kExpertCharactersSelector*/, 16}, + {HB_TAG ('f','r','a','c'), 11/*kFractionsType*/, 2/*kDiagonalFractionsSelector*/, 0/*kNoFractionsSelector*/}, + {HB_TAG ('f','w','i','d'), 22/*kTextSpacingType*/, 1/*kMonospacedTextSelector*/, 7}, + {HB_TAG ('h','a','l','t'), 22/*kTextSpacingType*/, 6/*kAltHalfWidthTextSelector*/, 7}, + {HB_TAG ('h','i','s','t'), 1/*kLigaturesType*/, 20/*kHistoricalLigaturesOnSelector*/, 21/*kHistoricalLigaturesOffSelector*/}, + {HB_TAG ('h','k','n','a'), 34/*kAlternateKanaType*/, 0/*kAlternateHorizKanaOnSelector*/, 1/*kAlternateHorizKanaOffSelector*/, }, + {HB_TAG ('h','l','i','g'), 1/*kLigaturesType*/, 20/*kHistoricalLigaturesOnSelector*/, 21/*kHistoricalLigaturesOffSelector*/}, + {HB_TAG ('h','n','g','l'), 23/*kTransliterationType*/, 1/*kHanjaToHangulSelector*/, 0/*kNoTransliterationSelector*/}, + {HB_TAG ('h','o','j','o'), 20/*kCharacterShapeType*/, 12/*kHojoCharactersSelector*/, 16}, + {HB_TAG ('h','w','i','d'), 22/*kTextSpacingType*/, 2/*kHalfWidthTextSelector*/, 7}, + {HB_TAG ('i','t','a','l'), 32/*kItalicCJKRomanType*/, 2/*kCJKItalicRomanOnSelector*/, 3/*kCJKItalicRomanOffSelector*/}, + {HB_TAG ('j','p','0','4'), 20/*kCharacterShapeType*/, 11/*kJIS2004CharactersSelector*/, 16}, + {HB_TAG ('j','p','7','8'), 20/*kCharacterShapeType*/, 2/*kJIS1978CharactersSelector*/, 16}, + {HB_TAG ('j','p','8','3'), 20/*kCharacterShapeType*/, 3/*kJIS1983CharactersSelector*/, 16}, + {HB_TAG ('j','p','9','0'), 20/*kCharacterShapeType*/, 4/*kJIS1990CharactersSelector*/, 16}, + {HB_TAG ('l','i','g','a'), 1/*kLigaturesType*/, 2/*kCommonLigaturesOnSelector*/, 3/*kCommonLigaturesOffSelector*/}, + {HB_TAG ('l','n','u','m'), 21/*kNumberCaseType*/, 1/*kUpperCaseNumbersSelector*/, 2}, + {HB_TAG ('m','g','r','k'), 15/*kMathematicalExtrasType*/, 10/*kMathematicalGreekOnSelector*/, 11/*kMathematicalGreekOffSelector*/}, + {HB_TAG ('n','l','c','k'), 20/*kCharacterShapeType*/, 13/*kNLCCharactersSelector*/, 16}, + {HB_TAG ('o','n','u','m'), 21/*kNumberCaseType*/, 0/*kLowerCaseNumbersSelector*/, 2}, + {HB_TAG ('o','r','d','n'), 10/*kVerticalPositionType*/, 3/*kOrdinalsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('p','a','l','t'), 22/*kTextSpacingType*/, 5/*kAltProportionalTextSelector*/, 7}, + {HB_TAG ('p','c','a','p'), 37/*kLowerCaseType*/, 2/*kLowerCasePetiteCapsSelector*/, 0/*kDefaultLowerCaseSelector*/}, + {HB_TAG ('p','k','n','a'), 22/*kTextSpacingType*/, 0/*kProportionalTextSelector*/, 7}, + {HB_TAG ('p','n','u','m'), 6/*kNumberSpacingType*/, 1/*kProportionalNumbersSelector*/, 4}, + {HB_TAG ('p','w','i','d'), 22/*kTextSpacingType*/, 0/*kProportionalTextSelector*/, 7}, + {HB_TAG ('q','w','i','d'), 22/*kTextSpacingType*/, 4/*kQuarterWidthTextSelector*/, 7}, + {HB_TAG ('r','u','b','y'), 28/*kRubyKanaType*/, 2/*kRubyKanaOnSelector*/, 3/*kRubyKanaOffSelector*/}, + {HB_TAG ('s','i','n','f'), 10/*kVerticalPositionType*/, 4/*kScientificInferiorsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('s','m','c','p'), 37/*kLowerCaseType*/, 1/*kLowerCaseSmallCapsSelector*/, 0/*kDefaultLowerCaseSelector*/}, + {HB_TAG ('s','m','p','l'), 20/*kCharacterShapeType*/, 1/*kSimplifiedCharactersSelector*/, 16}, + {HB_TAG ('s','s','0','1'), 35/*kStylisticAlternativesType*/, 2/*kStylisticAltOneOnSelector*/, 3/*kStylisticAltOneOffSelector*/}, + {HB_TAG ('s','s','0','2'), 35/*kStylisticAlternativesType*/, 4/*kStylisticAltTwoOnSelector*/, 5/*kStylisticAltTwoOffSelector*/}, + {HB_TAG ('s','s','0','3'), 35/*kStylisticAlternativesType*/, 6/*kStylisticAltThreeOnSelector*/, 7/*kStylisticAltThreeOffSelector*/}, + {HB_TAG ('s','s','0','4'), 35/*kStylisticAlternativesType*/, 8/*kStylisticAltFourOnSelector*/, 9/*kStylisticAltFourOffSelector*/}, + {HB_TAG ('s','s','0','5'), 35/*kStylisticAlternativesType*/, 10/*kStylisticAltFiveOnSelector*/, 11/*kStylisticAltFiveOffSelector*/}, + {HB_TAG ('s','s','0','6'), 35/*kStylisticAlternativesType*/, 12/*kStylisticAltSixOnSelector*/, 13/*kStylisticAltSixOffSelector*/}, + {HB_TAG ('s','s','0','7'), 35/*kStylisticAlternativesType*/, 14/*kStylisticAltSevenOnSelector*/, 15/*kStylisticAltSevenOffSelector*/}, + {HB_TAG ('s','s','0','8'), 35/*kStylisticAlternativesType*/, 16/*kStylisticAltEightOnSelector*/, 17/*kStylisticAltEightOffSelector*/}, + {HB_TAG ('s','s','0','9'), 35/*kStylisticAlternativesType*/, 18/*kStylisticAltNineOnSelector*/, 19/*kStylisticAltNineOffSelector*/}, + {HB_TAG ('s','s','1','0'), 35/*kStylisticAlternativesType*/, 20/*kStylisticAltTenOnSelector*/, 21/*kStylisticAltTenOffSelector*/}, + {HB_TAG ('s','s','1','1'), 35/*kStylisticAlternativesType*/, 22/*kStylisticAltElevenOnSelector*/, 23/*kStylisticAltElevenOffSelector*/}, + {HB_TAG ('s','s','1','2'), 35/*kStylisticAlternativesType*/, 24/*kStylisticAltTwelveOnSelector*/, 25/*kStylisticAltTwelveOffSelector*/}, + {HB_TAG ('s','s','1','3'), 35/*kStylisticAlternativesType*/, 26/*kStylisticAltThirteenOnSelector*/, 27/*kStylisticAltThirteenOffSelector*/}, + {HB_TAG ('s','s','1','4'), 35/*kStylisticAlternativesType*/, 28/*kStylisticAltFourteenOnSelector*/, 29/*kStylisticAltFourteenOffSelector*/}, + {HB_TAG ('s','s','1','5'), 35/*kStylisticAlternativesType*/, 30/*kStylisticAltFifteenOnSelector*/, 31/*kStylisticAltFifteenOffSelector*/}, + {HB_TAG ('s','s','1','6'), 35/*kStylisticAlternativesType*/, 32/*kStylisticAltSixteenOnSelector*/, 33/*kStylisticAltSixteenOffSelector*/}, + {HB_TAG ('s','s','1','7'), 35/*kStylisticAlternativesType*/, 34/*kStylisticAltSeventeenOnSelector*/, 35/*kStylisticAltSeventeenOffSelector*/}, + {HB_TAG ('s','s','1','8'), 35/*kStylisticAlternativesType*/, 36/*kStylisticAltEighteenOnSelector*/, 37/*kStylisticAltEighteenOffSelector*/}, + {HB_TAG ('s','s','1','9'), 35/*kStylisticAlternativesType*/, 38/*kStylisticAltNineteenOnSelector*/, 39/*kStylisticAltNineteenOffSelector*/}, + {HB_TAG ('s','s','2','0'), 35/*kStylisticAlternativesType*/, 40/*kStylisticAltTwentyOnSelector*/, 41/*kStylisticAltTwentyOffSelector*/}, + {HB_TAG ('s','u','b','s'), 10/*kVerticalPositionType*/, 2/*kInferiorsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('s','u','p','s'), 10/*kVerticalPositionType*/, 1/*kSuperiorsSelector*/, 0/*kNormalPositionSelector*/}, + {HB_TAG ('s','w','s','h'), 36/*kContextualAlternatesType*/, 2/*kSwashAlternatesOnSelector*/, 3/*kSwashAlternatesOffSelector*/}, + {HB_TAG ('t','i','t','l'), 19/*kStyleOptionsType*/, 4/*kTitlingCapsSelector*/, 0/*kNoStyleOptionsSelector*/}, + {HB_TAG ('t','n','a','m'), 20/*kCharacterShapeType*/, 14/*kTraditionalNamesCharactersSelector*/, 16}, + {HB_TAG ('t','n','u','m'), 6/*kNumberSpacingType*/, 0/*kMonospacedNumbersSelector*/, 4}, + {HB_TAG ('t','r','a','d'), 20/*kCharacterShapeType*/, 0/*kTraditionalCharactersSelector*/, 16}, + {HB_TAG ('t','w','i','d'), 22/*kTextSpacingType*/, 3/*kThirdWidthTextSelector*/, 7}, + {HB_TAG ('u','n','i','c'), 3/*kLetterCaseType*/, 14, 15}, + {HB_TAG ('v','a','l','t'), 22/*kTextSpacingType*/, 5/*kAltProportionalTextSelector*/, 7}, + {HB_TAG ('v','e','r','t'), 4/*kVerticalSubstitutionType*/, 0/*kSubstituteVerticalFormsOnSelector*/, 1/*kSubstituteVerticalFormsOffSelector*/}, + {HB_TAG ('v','h','a','l'), 22/*kTextSpacingType*/, 6/*kAltHalfWidthTextSelector*/, 7}, + {HB_TAG ('v','k','n','a'), 34/*kAlternateKanaType*/, 2/*kAlternateVertKanaOnSelector*/, 3/*kAlternateVertKanaOffSelector*/}, + {HB_TAG ('v','p','a','l'), 22/*kTextSpacingType*/, 5/*kAltProportionalTextSelector*/, 7}, + {HB_TAG ('v','r','t','2'), 4/*kVerticalSubstitutionType*/, 0/*kSubstituteVerticalFormsOnSelector*/, 1/*kSubstituteVerticalFormsOffSelector*/}, + {HB_TAG ('z','e','r','o'), 14/*kTypographicExtrasType*/, 4/*kSlashedZeroOnSelector*/, 5/*kSlashedZeroOffSelector*/}, +}; + +const hb_aat_feature_mapping_t * +hb_aat_layout_find_feature_mapping (hb_tag_t tag) +{ + return (const hb_aat_feature_mapping_t *) bsearch (&tag, + feature_mappings, + ARRAY_LENGTH (feature_mappings), + sizeof (feature_mappings[0]), + hb_aat_feature_mapping_t::cmp); +} + + /* * morx/kerx/trak */ diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index 897c26aa0..d0eb0190d 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -31,6 +31,28 @@ #include "hb-ot-shape.hh" + +struct hb_aat_feature_mapping_t +{ + hb_tag_t otFeatureTag; + uint16_t aatFeatureType; + uint16_t selectorToEnable; + uint16_t selectorToDisable; + + static inline int cmp (const void *key_, const void *entry_) + { + hb_tag_t key = * (unsigned int *) key_; + const hb_aat_feature_mapping_t * entry = (const hb_aat_feature_mapping_t *) entry_; + return key < entry->otFeatureTag ? -1 : + key > entry->otFeatureTag ? 1 : + 0; + } +}; + +HB_INTERNAL const hb_aat_feature_mapping_t * +hb_aat_layout_find_feature_mapping (hb_tag_t tag); + + HB_INTERNAL hb_bool_t hb_aat_layout_has_substitution (hb_face_t *face); diff --git a/src/hb-buffer-serialize.cc b/src/hb-buffer-serialize.cc index 1b6d14731..c1d82ab8d 100644 --- a/src/hb-buffer-serialize.cc +++ b/src/hb-buffer-serialize.cc @@ -440,8 +440,8 @@ hb_bool_t hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, const char *buf, int buf_len, /* -1 means nul-terminated */ - const char **end_ptr, /* May be nullptr */ - hb_font_t *font, /* May be nullptr */ + const char **end_ptr, /* May be NULL */ + hb_font_t *font, /* May be NULL */ hb_buffer_serialize_format_t format) { const char *end; diff --git a/src/hb-common.h b/src/hb-common.h index 4f91a1761..c601b1f66 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -71,6 +71,14 @@ typedef unsigned __int64 uint64_t; #define HB_DEPRECATED #endif +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#define HB_DEPRECATED_FOR(f) __attribute__((__deprecated__("Use '" #f "' instead"))) +#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320) +#define HB_DEPRECATED_FOR(f) __declspec(deprecated("is deprecated. Use '" #f "' instead")) +#else +#define HB_DEPRECATED_FOR(f) HB_DEPRECATED +#endif + HB_BEGIN_DECLS diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index 9bebb2be6..aa3921a3f 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -32,6 +32,7 @@ #include "hb-shaper-impl.hh" #include "hb-coretext.h" +#include "hb-aat-layout.hh" #include /* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ @@ -431,185 +432,6 @@ struct range_record_t { }; -/* The following enum members are added in OS X 10.8. */ -#define kAltHalfWidthTextSelector 6 -#define kAltProportionalTextSelector 5 -#define kAlternateHorizKanaOffSelector 1 -#define kAlternateHorizKanaOnSelector 0 -#define kAlternateKanaType 34 -#define kAlternateVertKanaOffSelector 3 -#define kAlternateVertKanaOnSelector 2 -#define kCaseSensitiveLayoutOffSelector 1 -#define kCaseSensitiveLayoutOnSelector 0 -#define kCaseSensitiveLayoutType 33 -#define kCaseSensitiveSpacingOffSelector 3 -#define kCaseSensitiveSpacingOnSelector 2 -#define kContextualAlternatesOffSelector 1 -#define kContextualAlternatesOnSelector 0 -#define kContextualAlternatesType 36 -#define kContextualLigaturesOffSelector 19 -#define kContextualLigaturesOnSelector 18 -#define kContextualSwashAlternatesOffSelector 5 -#define kContextualSwashAlternatesOnSelector 4 -#define kDefaultLowerCaseSelector 0 -#define kDefaultUpperCaseSelector 0 -#define kHistoricalLigaturesOffSelector 21 -#define kHistoricalLigaturesOnSelector 20 -#define kHojoCharactersSelector 12 -#define kJIS2004CharactersSelector 11 -#define kLowerCasePetiteCapsSelector 2 -#define kLowerCaseSmallCapsSelector 1 -#define kLowerCaseType 37 -#define kMathematicalGreekOffSelector 11 -#define kMathematicalGreekOnSelector 10 -#define kNLCCharactersSelector 13 -#define kQuarterWidthTextSelector 4 -#define kScientificInferiorsSelector 4 -#define kStylisticAltEightOffSelector 17 -#define kStylisticAltEightOnSelector 16 -#define kStylisticAltEighteenOffSelector 37 -#define kStylisticAltEighteenOnSelector 36 -#define kStylisticAltElevenOffSelector 23 -#define kStylisticAltElevenOnSelector 22 -#define kStylisticAltFifteenOffSelector 31 -#define kStylisticAltFifteenOnSelector 30 -#define kStylisticAltFiveOffSelector 11 -#define kStylisticAltFiveOnSelector 10 -#define kStylisticAltFourOffSelector 9 -#define kStylisticAltFourOnSelector 8 -#define kStylisticAltFourteenOffSelector 29 -#define kStylisticAltFourteenOnSelector 28 -#define kStylisticAltNineOffSelector 19 -#define kStylisticAltNineOnSelector 18 -#define kStylisticAltNineteenOffSelector 39 -#define kStylisticAltNineteenOnSelector 38 -#define kStylisticAltOneOffSelector 3 -#define kStylisticAltOneOnSelector 2 -#define kStylisticAltSevenOffSelector 15 -#define kStylisticAltSevenOnSelector 14 -#define kStylisticAltSeventeenOffSelector 35 -#define kStylisticAltSeventeenOnSelector 34 -#define kStylisticAltSixOffSelector 13 -#define kStylisticAltSixOnSelector 12 -#define kStylisticAltSixteenOffSelector 33 -#define kStylisticAltSixteenOnSelector 32 -#define kStylisticAltTenOffSelector 21 -#define kStylisticAltTenOnSelector 20 -#define kStylisticAltThirteenOffSelector 27 -#define kStylisticAltThirteenOnSelector 26 -#define kStylisticAltThreeOffSelector 7 -#define kStylisticAltThreeOnSelector 6 -#define kStylisticAltTwelveOffSelector 25 -#define kStylisticAltTwelveOnSelector 24 -#define kStylisticAltTwentyOffSelector 41 -#define kStylisticAltTwentyOnSelector 40 -#define kStylisticAltTwoOffSelector 5 -#define kStylisticAltTwoOnSelector 4 -#define kStylisticAlternativesType 35 -#define kSwashAlternatesOffSelector 3 -#define kSwashAlternatesOnSelector 2 -#define kThirdWidthTextSelector 3 -#define kTraditionalNamesCharactersSelector 14 -#define kUpperCasePetiteCapsSelector 2 -#define kUpperCaseSmallCapsSelector 1 -#define kUpperCaseType 38 - -/* Table data courtesy of Apple. */ -static const struct feature_mapping_t -{ - hb_tag_t otFeatureTag; - uint16_t aatFeatureType; - uint16_t selectorToEnable; - uint16_t selectorToDisable; -} feature_mappings[] = -{ - { 'c2pc', kUpperCaseType, kUpperCasePetiteCapsSelector, kDefaultUpperCaseSelector }, - { 'c2sc', kUpperCaseType, kUpperCaseSmallCapsSelector, kDefaultUpperCaseSelector }, - { 'calt', kContextualAlternatesType, kContextualAlternatesOnSelector, kContextualAlternatesOffSelector }, - { 'case', kCaseSensitiveLayoutType, kCaseSensitiveLayoutOnSelector, kCaseSensitiveLayoutOffSelector }, - { 'clig', kLigaturesType, kContextualLigaturesOnSelector, kContextualLigaturesOffSelector }, - { 'cpsp', kCaseSensitiveLayoutType, kCaseSensitiveSpacingOnSelector, kCaseSensitiveSpacingOffSelector }, - { 'cswh', kContextualAlternatesType, kContextualSwashAlternatesOnSelector, kContextualSwashAlternatesOffSelector }, - { 'dlig', kLigaturesType, kRareLigaturesOnSelector, kRareLigaturesOffSelector }, - { 'expt', kCharacterShapeType, kExpertCharactersSelector, 16 }, - { 'frac', kFractionsType, kDiagonalFractionsSelector, kNoFractionsSelector }, - { 'fwid', kTextSpacingType, kMonospacedTextSelector, 7 }, - { 'halt', kTextSpacingType, kAltHalfWidthTextSelector, 7 }, - { 'hist', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector }, - { 'hkna', kAlternateKanaType, kAlternateHorizKanaOnSelector, kAlternateHorizKanaOffSelector, }, - { 'hlig', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector }, - { 'hngl', kTransliterationType, kHanjaToHangulSelector, kNoTransliterationSelector }, - { 'hojo', kCharacterShapeType, kHojoCharactersSelector, 16 }, - { 'hwid', kTextSpacingType, kHalfWidthTextSelector, 7 }, - { 'ital', kItalicCJKRomanType, kCJKItalicRomanOnSelector, kCJKItalicRomanOffSelector }, - { 'jp04', kCharacterShapeType, kJIS2004CharactersSelector, 16 }, - { 'jp78', kCharacterShapeType, kJIS1978CharactersSelector, 16 }, - { 'jp83', kCharacterShapeType, kJIS1983CharactersSelector, 16 }, - { 'jp90', kCharacterShapeType, kJIS1990CharactersSelector, 16 }, - { 'liga', kLigaturesType, kCommonLigaturesOnSelector, kCommonLigaturesOffSelector }, - { 'lnum', kNumberCaseType, kUpperCaseNumbersSelector, 2 }, - { 'mgrk', kMathematicalExtrasType, kMathematicalGreekOnSelector, kMathematicalGreekOffSelector }, - { 'nlck', kCharacterShapeType, kNLCCharactersSelector, 16 }, - { 'onum', kNumberCaseType, kLowerCaseNumbersSelector, 2 }, - { 'ordn', kVerticalPositionType, kOrdinalsSelector, kNormalPositionSelector }, - { 'palt', kTextSpacingType, kAltProportionalTextSelector, 7 }, - { 'pcap', kLowerCaseType, kLowerCasePetiteCapsSelector, kDefaultLowerCaseSelector }, - { 'pkna', kTextSpacingType, kProportionalTextSelector, 7 }, - { 'pnum', kNumberSpacingType, kProportionalNumbersSelector, 4 }, - { 'pwid', kTextSpacingType, kProportionalTextSelector, 7 }, - { 'qwid', kTextSpacingType, kQuarterWidthTextSelector, 7 }, - { 'ruby', kRubyKanaType, kRubyKanaOnSelector, kRubyKanaOffSelector }, - { 'sinf', kVerticalPositionType, kScientificInferiorsSelector, kNormalPositionSelector }, - { 'smcp', kLowerCaseType, kLowerCaseSmallCapsSelector, kDefaultLowerCaseSelector }, - { 'smpl', kCharacterShapeType, kSimplifiedCharactersSelector, 16 }, - { 'ss01', kStylisticAlternativesType, kStylisticAltOneOnSelector, kStylisticAltOneOffSelector }, - { 'ss02', kStylisticAlternativesType, kStylisticAltTwoOnSelector, kStylisticAltTwoOffSelector }, - { 'ss03', kStylisticAlternativesType, kStylisticAltThreeOnSelector, kStylisticAltThreeOffSelector }, - { 'ss04', kStylisticAlternativesType, kStylisticAltFourOnSelector, kStylisticAltFourOffSelector }, - { 'ss05', kStylisticAlternativesType, kStylisticAltFiveOnSelector, kStylisticAltFiveOffSelector }, - { 'ss06', kStylisticAlternativesType, kStylisticAltSixOnSelector, kStylisticAltSixOffSelector }, - { 'ss07', kStylisticAlternativesType, kStylisticAltSevenOnSelector, kStylisticAltSevenOffSelector }, - { 'ss08', kStylisticAlternativesType, kStylisticAltEightOnSelector, kStylisticAltEightOffSelector }, - { 'ss09', kStylisticAlternativesType, kStylisticAltNineOnSelector, kStylisticAltNineOffSelector }, - { 'ss10', kStylisticAlternativesType, kStylisticAltTenOnSelector, kStylisticAltTenOffSelector }, - { 'ss11', kStylisticAlternativesType, kStylisticAltElevenOnSelector, kStylisticAltElevenOffSelector }, - { 'ss12', kStylisticAlternativesType, kStylisticAltTwelveOnSelector, kStylisticAltTwelveOffSelector }, - { 'ss13', kStylisticAlternativesType, kStylisticAltThirteenOnSelector, kStylisticAltThirteenOffSelector }, - { 'ss14', kStylisticAlternativesType, kStylisticAltFourteenOnSelector, kStylisticAltFourteenOffSelector }, - { 'ss15', kStylisticAlternativesType, kStylisticAltFifteenOnSelector, kStylisticAltFifteenOffSelector }, - { 'ss16', kStylisticAlternativesType, kStylisticAltSixteenOnSelector, kStylisticAltSixteenOffSelector }, - { 'ss17', kStylisticAlternativesType, kStylisticAltSeventeenOnSelector, kStylisticAltSeventeenOffSelector }, - { 'ss18', kStylisticAlternativesType, kStylisticAltEighteenOnSelector, kStylisticAltEighteenOffSelector }, - { 'ss19', kStylisticAlternativesType, kStylisticAltNineteenOnSelector, kStylisticAltNineteenOffSelector }, - { 'ss20', kStylisticAlternativesType, kStylisticAltTwentyOnSelector, kStylisticAltTwentyOffSelector }, - { 'subs', kVerticalPositionType, kInferiorsSelector, kNormalPositionSelector }, - { 'sups', kVerticalPositionType, kSuperiorsSelector, kNormalPositionSelector }, - { 'swsh', kContextualAlternatesType, kSwashAlternatesOnSelector, kSwashAlternatesOffSelector }, - { 'titl', kStyleOptionsType, kTitlingCapsSelector, kNoStyleOptionsSelector }, - { 'tnam', kCharacterShapeType, kTraditionalNamesCharactersSelector, 16 }, - { 'tnum', kNumberSpacingType, kMonospacedNumbersSelector, 4 }, - { 'trad', kCharacterShapeType, kTraditionalCharactersSelector, 16 }, - { 'twid', kTextSpacingType, kThirdWidthTextSelector, 7 }, - { 'unic', kLetterCaseType, 14, 15 }, - { 'valt', kTextSpacingType, kAltProportionalTextSelector, 7 }, - { 'vert', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector }, - { 'vhal', kTextSpacingType, kAltHalfWidthTextSelector, 7 }, - { 'vkna', kAlternateKanaType, kAlternateVertKanaOnSelector, kAlternateVertKanaOffSelector }, - { 'vpal', kTextSpacingType, kAltProportionalTextSelector, 7 }, - { 'vrt2', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector }, - { 'zero', kTypographicExtrasType, kSlashedZeroOnSelector, kSlashedZeroOffSelector }, -}; - -static int -_hb_feature_mapping_cmp (const void *key_, const void *entry_) -{ - hb_tag_t key = * (unsigned int *) key_; - const feature_mapping_t * entry = (const feature_mapping_t *) entry_; - return key < entry->otFeatureTag ? -1 : - key > entry->otFeatureTag ? 1 : - 0; -} - hb_bool_t _hb_coretext_shape (hb_shape_plan_t *shape_plan, hb_font_t *font, @@ -655,11 +477,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, hb_auto_t > feature_events; for (unsigned int i = 0; i < num_features; i++) { - const feature_mapping_t * mapping = (const feature_mapping_t *) bsearch (&features[i].tag, - feature_mappings, - ARRAY_LENGTH (feature_mappings), - sizeof (feature_mappings[0]), - _hb_feature_mapping_cmp); + const hb_aat_feature_mapping_t * mapping = hb_aat_layout_find_feature_mapping (features[i].tag); if (!mapping) continue; diff --git a/src/hb-deprecated.h b/src/hb-deprecated.h index 46590731b..52ee49e2b 100644 --- a/src/hb-deprecated.h +++ b/src/hb-deprecated.h @@ -50,7 +50,7 @@ typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t *glyph, void *user_data); -HB_EXTERN HB_DEPRECATED void +HB_EXTERN HB_DEPRECATED_FOR(hb_font_funcs_set_nominal_glyph_func or hb_font_funcs_set_variation_glyph_func) void hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -212,26 +212,26 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font, hb_position_t *x, hb_position_t *y); /* Like hb_ot_layout_table_find_script, but takes zero-terminated array of scripts to test */ -HB_EXTERN HB_DEPRECATED hb_bool_t +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_layout_table_select_script) hb_bool_t hb_ot_layout_table_choose_script (hb_face_t *face, hb_tag_t table_tag, const hb_tag_t *script_tags, unsigned int *script_index, hb_tag_t *chosen_script); -HB_EXTERN HB_DEPRECATED hb_bool_t +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_layout_script_select_language) hb_bool_t hb_ot_layout_script_find_language (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, hb_tag_t language_tag, unsigned int *language_index); -HB_EXTERN HB_DEPRECATED void +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) void hb_ot_tags_from_script (hb_script_t script, hb_tag_t *script_tag_1, hb_tag_t *script_tag_2); -HB_EXTERN HB_DEPRECATED hb_tag_t +HB_EXTERN HB_DEPRECATED_FOR (hb_ot_tags_from_script_and_language) hb_tag_t hb_ot_tag_from_language (hb_language_t language); diff --git a/src/hb-font.cc b/src/hb-font.cc index fd0e097a8..c9656cee7 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1910,8 +1910,6 @@ hb_font_get_var_coords_normalized (hb_font_t *font, } -#ifndef HB_DISABLE_DEPRECATED - /* * Deprecated get_glyph_func(): */ @@ -2034,5 +2032,3 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, trampoline, trampoline_destroy); } - -#endif /* HB_DISABLE_DEPRECATED */ diff --git a/src/hb-graphite2.h b/src/hb-graphite2.h index 05c55debe..1720191b4 100644 --- a/src/hb-graphite2.h +++ b/src/hb-graphite2.h @@ -41,7 +41,7 @@ hb_graphite2_face_get_gr_face (hb_face_t *face); #ifndef HB_DISABLE_DEPRECATED -HB_EXTERN gr_font * +HB_EXTERN HB_DEPRECATED_FOR (hb_graphite2_face_get_gr_face) gr_font * hb_graphite2_font_get_gr_font (hb_font_t *font); #endif diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 56914beae..a6ff6e7b9 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -302,10 +302,10 @@ struct hb_sanitize_context_t : inline bool check_range (const void *base, unsigned int len) const { const char *p = (const char *) base; - bool ok = this->max_ops-- > 0 && - this->start <= p && + bool ok = this->start <= p && p <= this->end && - (unsigned int) (this->end - p) >= len; + (unsigned int) (this->end - p) >= len && + this->max_ops-- > 0; DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, "check_range [%p..%p] (%d bytes) in [%p..%p] -> %s", diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index 52b4db6a9..e5793c387 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -709,9 +709,9 @@ struct VariationSelectorRecord HBUINT24 varSelector; /* Variation selector. */ LOffsetTo - defaultUVS; /* Offset to Default UVS Table. May be 0. */ + defaultUVS; /* Offset to Default UVS Table. May be 0. */ LOffsetTo - nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */ + nonDefaultUVS; /* Offset to Non-Default UVS Table. May be 0. */ public: DEFINE_SIZE_STATIC (11); }; diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index fb98c318e..cf686a7ee 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -400,7 +400,7 @@ struct FeatureParamsSize * same subfamily value. If this value is * zero, the remaining fields in the array * will be ignored. */ - HBUINT16 subfamilyNameID;/* If the preceding value is non-zero, this + NameID subfamilyNameID;/* If the preceding value is non-zero, this * value must be set in the range 256 - 32767 * (inclusive). It records the value of a * field in the name table, which must @@ -473,7 +473,7 @@ struct FeatureParamsCharacterVariants * specifies a string (or strings, * for multiple languages) for a * user-interface label for this - * feature. (May be nullptr.) */ + * feature. (May be NULL.) */ NameID featUITooltipTextNameID;/* The ‘name’ table name ID that * specifies a string (or strings, * for multiple languages) that an @@ -483,7 +483,7 @@ struct FeatureParamsCharacterVariants NameID sampleTextNameID; /* The ‘name’ table name ID that * specifies sample text that * illustrates the effect of this - * feature. (May be nullptr.) */ + * feature. (May be NULL.) */ HBUINT16 numNamedParameters; /* Number of named parameters. (May * be zero.) */ NameID firstParamUILabelNameID;/* The first ‘name’ table name ID @@ -521,6 +521,20 @@ struct FeatureParams return Null(FeatureParamsSize); } + inline const FeatureParamsStylisticSet& get_stylistic_set_params (hb_tag_t tag) const + { + if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */ + return u.stylisticSet; + return Null(FeatureParamsStylisticSet); + } + + inline const FeatureParamsCharacterVariants& get_character_variants_params (hb_tag_t tag) const + { + if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */ + return u.characterVariants; + return Null(FeatureParamsCharacterVariants); + } + private: union { FeatureParamsSize size; diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 3a09803ee..695a5df99 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -214,10 +214,10 @@ struct hb_collect_glyphs_context_t : unsigned int debug_depth; hb_collect_glyphs_context_t (hb_face_t *face_, - hb_set_t *glyphs_before, /* OUT. May be nullptr */ - hb_set_t *glyphs_input, /* OUT. May be nullptr */ - hb_set_t *glyphs_after, /* OUT. May be nullptr */ - hb_set_t *glyphs_output, /* OUT. May be nullptr */ + hb_set_t *glyphs_before, /* OUT. May be NULL */ + hb_set_t *glyphs_input, /* OUT. May be NULL */ + hb_set_t *glyphs_after, /* OUT. May be NULL */ + hb_set_t *glyphs_output, /* OUT. May be NULL */ unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), before (glyphs_before ? glyphs_before : hb_set_get_empty ()), diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index aa36954d0..d279b868d 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -322,7 +322,7 @@ hb_ot_layout_table_get_script_tags (hb_face_t *face, hb_tag_t table_tag, unsigned int start_offset, unsigned int *script_count /* IN/OUT */, - hb_tag_t *script_tags /* OUT */) + hb_tag_t *script_tags /* OUT */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); @@ -383,7 +383,7 @@ hb_ot_layout_table_select_script (hb_face_t *face, hb_tag_t table_tag, unsigned int script_count, const hb_tag_t *script_tags, - unsigned int *script_index /* OUT */, + unsigned int *script_index /* OUT */, hb_tag_t *chosen_script /* OUT */) { static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX), ""); @@ -433,7 +433,7 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face, hb_tag_t table_tag, unsigned int start_offset, unsigned int *feature_count /* IN/OUT */, - hb_tag_t *feature_tags /* OUT */) + hb_tag_t *feature_tags /* OUT */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); @@ -469,7 +469,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face, unsigned int script_index, unsigned int start_offset, unsigned int *language_count /* IN/OUT */, - hb_tag_t *language_tags /* OUT */) + hb_tag_t *language_tags /* OUT */) { const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index); @@ -574,7 +574,7 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t *face, unsigned int script_index, unsigned int language_index, unsigned int start_offset, - unsigned int *feature_count /* IN/OUT */, + unsigned int *feature_count /* IN/OUT */, unsigned int *feature_indexes /* OUT */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); @@ -590,7 +590,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face, unsigned int language_index, unsigned int start_offset, unsigned int *feature_count /* IN/OUT */, - hb_tag_t *feature_tags /* OUT */) + hb_tag_t *feature_tags /* OUT */) { const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index); @@ -644,7 +644,7 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face, hb_tag_t table_tag, unsigned int feature_index, unsigned int start_offset, - unsigned int *lookup_count /* IN/OUT */, + unsigned int *lookup_count /* IN/OUT */, unsigned int *lookup_indexes /* OUT */) { return hb_ot_layout_feature_with_variations_get_lookups (face, @@ -872,10 +872,10 @@ void hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, hb_tag_t table_tag, unsigned int lookup_index, - hb_set_t *glyphs_before, /* OUT. May be nullptr */ - hb_set_t *glyphs_input, /* OUT. May be nullptr */ - hb_set_t *glyphs_after, /* OUT. May be nullptr */ - hb_set_t *glyphs_output /* OUT. May be nullptr */) + hb_set_t *glyphs_before, /* OUT. May be NULL */ + hb_set_t *glyphs_input, /* OUT. May be NULL */ + hb_set_t *glyphs_after, /* OUT. May be NULL */ + hb_set_t *glyphs_output /* OUT. May be NULL */) { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return; @@ -1073,11 +1073,11 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) **/ hb_bool_t hb_ot_layout_get_size_params (hb_face_t *face, - unsigned int *design_size, /* OUT. May be nullptr */ - unsigned int *subfamily_id, /* OUT. May be nullptr */ - unsigned int *subfamily_name_id, /* OUT. May be nullptr */ - unsigned int *range_start, /* OUT. May be nullptr */ - unsigned int *range_end /* OUT. May be nullptr */) + unsigned int *design_size, /* OUT. May be NULL */ + unsigned int *subfamily_id, /* OUT. May be NULL */ + unsigned int *subfamily_name_id, /* OUT. May be NULL */ + unsigned int *range_start, /* OUT. May be NULL */ + unsigned int *range_end /* OUT. May be NULL */) { const OT::GPOS &gpos = _get_gpos (face); const hb_tag_t tag = HB_TAG ('s','i','z','e'); @@ -1092,30 +1092,152 @@ hb_ot_layout_get_size_params (hb_face_t *face, if (params.designSize) { -#define PARAM(a, A) if (a) *a = params.A - PARAM (design_size, designSize); - PARAM (subfamily_id, subfamilyID); - PARAM (subfamily_name_id, subfamilyNameID); - PARAM (range_start, rangeStart); - PARAM (range_end, rangeEnd); -#undef PARAM + if (design_size) *design_size = params.designSize; + if (subfamily_id) *subfamily_id = params.subfamilyID; + if (subfamily_name_id) *subfamily_name_id = params.subfamilyNameID; + if (range_start) *range_start = params.rangeStart; + if (range_end) *range_end = params.rangeEnd; return true; } } } -#define PARAM(a, A) if (a) *a = 0 - PARAM (design_size, designSize); - PARAM (subfamily_id, subfamilyID); - PARAM (subfamily_name_id, subfamilyNameID); - PARAM (range_start, rangeStart); - PARAM (range_end, rangeEnd); -#undef PARAM + if (design_size) *design_size = 0; + if (subfamily_id) *subfamily_id = 0; + if (subfamily_name_id) *subfamily_name_id = 0; + if (range_start) *range_start = 0; + if (range_end) *range_end = 0; return false; } +/** + * hb_ot_layout_feature_get_name_ids: + * @face: #hb_face_t to work upon + * @table_tag: + * @feature_index: + * @label_id: (out) (allow-none): The ‘name’ table name ID that specifies a string + * for a user-interface label for this feature. (May be NULL.) + * @tooltip_id: (out) (allow-none): The ‘name’ table name ID that specifies a string + * that an application can use for tooltip text for this + * feature. (May be NULL.) + * @sample_id: (out) (allow-none): The ‘name’ table name ID that specifies sample text + * that illustrates the effect of this feature. (May be NULL.) + * @num_named_parameters: (out) (allow-none): Number of named parameters. (May be zero.) + * @first_param_id: (out) (allow-none): The first ‘name’ table name ID used to specify + * strings for user-interface labels for the feature + * parameters. (Must be zero if numParameters is zero.) + * + * Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or + * "Character Variant" ('cvXX') features. + * + * Return value: true if data found, false otherwise + * + * Since: REPLACEME + **/ +hb_bool_t +hb_ot_layout_feature_get_name_ids (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + hb_name_id_t *label_id, /* OUT. May be NULL */ + hb_name_id_t *tooltip_id, /* OUT. May be NULL */ + hb_name_id_t *sample_id, /* OUT. May be NULL */ + unsigned int *num_named_parameters, /* OUT. May be NULL */ + hb_name_id_t *first_param_id /* OUT. May be NULL */) +{ + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + + hb_tag_t feature_tag = g.get_feature_tag (feature_index); + const OT::Feature &f = g.get_feature (feature_index); + + const OT::FeatureParams &feature_params = f.get_feature_params (); + if (&feature_params != &Null (OT::FeatureParams)) + { + const OT::FeatureParamsStylisticSet& ss_params = + feature_params.get_stylistic_set_params (feature_tag); + if (&ss_params != &Null (OT::FeatureParamsStylisticSet)) /* ssXX */ + { + if (label_id) *label_id = ss_params.uiNameID; + // ssXX features don't have the rest + if (tooltip_id) *tooltip_id = HB_NAME_ID_INVALID; + if (sample_id) *sample_id = HB_NAME_ID_INVALID; + if (num_named_parameters) *num_named_parameters = 0; + if (first_param_id) *first_param_id = HB_NAME_ID_INVALID; + return true; + } + const OT::FeatureParamsCharacterVariants& cv_params = + feature_params.get_character_variants_params (feature_tag); + if (&cv_params != &Null (OT::FeatureParamsCharacterVariants)) /* cvXX */ + { + if (label_id) *label_id = cv_params.featUILableNameID; + if (tooltip_id) *tooltip_id = cv_params.featUITooltipTextNameID; + if (sample_id) *sample_id = cv_params.sampleTextNameID; + if (num_named_parameters) *num_named_parameters = cv_params.numNamedParameters; + if (first_param_id) *first_param_id = cv_params.firstParamUILabelNameID; + return true; + } + } + + if (label_id) *label_id = HB_NAME_ID_INVALID; + if (tooltip_id) *tooltip_id = HB_NAME_ID_INVALID; + if (sample_id) *sample_id = HB_NAME_ID_INVALID; + if (num_named_parameters) *num_named_parameters = 0; + if (first_param_id) *first_param_id = HB_NAME_ID_INVALID; + return false; +} + +/** + * hb_ot_layout_feature_get_characters:: + * @face: #hb_face_t to work upon + * @table_tag: + * @feature_index: + * @start_offset: In case the resulting char_count was equal to its input value, there + * is a chance there were more characters on the tag so this API can be + * called with an offset till resulting char_count gets to a number + * lower than input buffer (or consider using just a bigger buffer for + * one shot copying). + * @char_count: (in/out) (allow-none): The count of characters for which this feature + * provides glyph variants. (May be zero.) + * @characters: (out) (allow-none): A buffer pointer. The Unicode Scalar Value + * of the characters for which this feature provides glyph variants. + * + * Fetches characters listed by designer under feature parameters for "Character + * Variant" ("cvXX") features. + * + * Return value: Number of total sample characters in the cvXX feature. + * + * Since: REPLACEME + **/ +unsigned int +hb_ot_layout_feature_get_characters (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + unsigned int start_offset, + unsigned int *char_count, /* IN/OUT. May be NULL */ + hb_codepoint_t *characters /* OUT. May be NULL */) +{ + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + + hb_tag_t feature_tag = g.get_feature_tag (feature_index); + const OT::Feature &f = g.get_feature (feature_index); + + const OT::FeatureParams &feature_params = f.get_feature_params (); + + const OT::FeatureParamsCharacterVariants& cv_params = + feature_params.get_character_variants_params(feature_tag); + + unsigned int len = 0; + if (char_count && characters && start_offset < cv_params.characters.len) + { + len = MIN (cv_params.characters.len - start_offset, *char_count); + for (unsigned int i = 0; i < len; ++i) + characters[i] = cv_params.characters[start_offset + i]; + } + if (char_count) *char_count = len; + return cv_params.characters.len; +} + /* * Parts of different types are implemented here such that they have direct diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index eb0df8936..9bd18c8af 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -34,6 +34,7 @@ #include "hb.h" #include "hb-ot-tag.h" +#include "hb-ot-name.h" HB_BEGIN_DECLS @@ -215,10 +216,10 @@ HB_EXTERN void hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, hb_tag_t table_tag, unsigned int lookup_index, - hb_set_t *glyphs_before, /* OUT. May be NULL */ - hb_set_t *glyphs_input, /* OUT. May be NULL */ - hb_set_t *glyphs_after, /* OUT. May be NULL */ - hb_set_t *glyphs_output /* OUT. May be NULL */); + hb_set_t *glyphs_before, /* OUT. May be NULL */ + hb_set_t *glyphs_input, /* OUT. May be NULL */ + hb_set_t *glyphs_after, /* OUT. May be NULL */ + hb_set_t *glyphs_output /* OUT. May be NULL */); #ifdef HB_NOT_IMPLEMENTED typedef struct @@ -326,11 +327,30 @@ HB_EXTERN hb_bool_t hb_ot_layout_get_size_params (hb_face_t *face, unsigned int *design_size, /* OUT. May be NULL */ unsigned int *subfamily_id, /* OUT. May be NULL */ - unsigned int *subfamily_name_id, /* OUT. May be NULL */ + hb_name_id_t *subfamily_name_id, /* OUT. May be NULL */ unsigned int *range_start, /* OUT. May be NULL */ unsigned int *range_end /* OUT. May be NULL */); +HB_EXTERN hb_bool_t +hb_ot_layout_feature_get_name_ids (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + hb_name_id_t *label_id /* OUT. May be NULL */, + hb_name_id_t *tooltip_id /* OUT. May be NULL */, + hb_name_id_t *sample_id /* OUT. May be NULL */, + unsigned int *num_named_parameters /* OUT. May be NULL */, + hb_name_id_t *first_param_id /* OUT. May be NULL */); + + +HB_EXTERN unsigned int +hb_ot_layout_feature_get_characters (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + unsigned int start_offset, + unsigned int *char_count /* IN/OUT. May be NULL */, + hb_codepoint_t *characters /* OUT. May be NULL */); + /* * BASE */ diff --git a/src/hb-ot-math-table.hh b/src/hb-ot-math-table.hh index 87ebdc7d7..2f871124c 100644 --- a/src/hb-ot-math-table.hh +++ b/src/hb-ot-math-table.hh @@ -50,7 +50,7 @@ struct MathValueRecord protected: HBINT16 value; /* The X or Y value in design units */ OffsetTo deviceTable; /* Offset to the device table - from the - * beginning of parent table. May be nullptr. + * beginning of parent table. May be NULL. * Suggested format for device table is 1. */ public: @@ -318,7 +318,7 @@ struct MathKernInfoRecord protected: /* Offset to MathKern table for each corner - - * from the beginning of MathKernInfo table. May be nullptr. */ + * from the beginning of MathKernInfo table. May be NULL. */ OffsetTo mathKern[4]; public: @@ -401,7 +401,7 @@ struct MathGlyphInfo * from the beginning of MathGlyphInfo table. When the left or right glyph of * a box is an extended shape variant, the (ink) box (and not the default * position defined by values in MathConstants table) should be used for - * vertical positioning purposes. May be nullptr.. */ + * vertical positioning purposes. May be NULL.. */ OffsetTo extendedShapeCoverage; /* Offset to MathKernInfo table - @@ -570,7 +570,7 @@ struct MathGlyphConstruction protected: /* Offset to MathGlyphAssembly table for this shape - from the beginning of - MathGlyphConstruction table. May be nullptr. */ + MathGlyphConstruction table. May be NULL. */ OffsetTo glyphAssembly; /* MathGlyphVariantRecords for alternative variants of the glyphs. */ diff --git a/src/hb-ot-name.h b/src/hb-ot-name.h new file mode 100644 index 000000000..0fdd63bbd --- /dev/null +++ b/src/hb-ot-name.h @@ -0,0 +1,53 @@ +/* + * Copyright © 2018 Ebrahim Byagowi. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_OT_H_IN +#error "Include instead." +#endif + +#ifndef HB_OT_NAME_H +#define HB_OT_NAME_H + +#include "hb.h" + +HB_BEGIN_DECLS + + +/** + * hb_name_id_t: + * + * Since: REPLACEME + */ +typedef unsigned int hb_name_id_t; + +/** + * HB_NAME_ID_INVALID + * + * Since: REPLACEME + **/ +#define HB_NAME_ID_INVALID 0xFFFF + +HB_END_DECLS + +#endif /* HB_OT_NAME_H */ diff --git a/src/hb-ot-shape-complex-hangul.cc b/src/hb-ot-shape-complex-hangul.cc index 0e7abadbe..959540258 100644 --- a/src/hb-ot-shape-complex-hangul.cc +++ b/src/hb-ot-shape-complex-hangul.cc @@ -345,13 +345,6 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, { unsigned int s_len = tindex ? 3 : 2; buffer->replace_glyphs (1, s_len, decomposed); - if (unlikely (!buffer->successful)) - return; - - /* We decomposed S: apply jamo features to the individual glyphs - * that are now in buffer->out_info. - */ - hb_glyph_info_t *info = buffer->out_info; /* If we decomposed an LV because of a non-combining T following, * we want to include this T in the syllable. @@ -361,6 +354,14 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, buffer->next_glyph (); s_len++; } + + if (unlikely (!buffer->successful)) + return; + + /* We decomposed S: apply jamo features to the individual glyphs + * that are now in buffer->out_info. + */ + hb_glyph_info_t *info = buffer->out_info; end = start + s_len; unsigned int i = start; @@ -368,6 +369,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, info[i++].hangul_shaping_feature() = VJMO; if (i < end) info[i++].hangul_shaping_feature() = TJMO; + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) buffer->merge_out_clusters (start, end); continue; diff --git a/src/hb-ot-shape-complex.hh b/src/hb-ot-shape-complex.hh index 216966d2e..2944d745c 100644 --- a/src/hb-ot-shape-complex.hh +++ b/src/hb-ot-shape-complex.hh @@ -69,7 +69,7 @@ struct hb_ot_complex_shaper_t /* collect_features() * Called during shape_plan(). * Shapers should use plan->map to add their features and callbacks. - * May be nullptr. + * May be NULL. */ void (*collect_features) (hb_ot_shape_planner_t *plan); @@ -77,7 +77,7 @@ struct hb_ot_complex_shaper_t * Called during shape_plan(). * Shapers should use plan->map to override features and add callbacks after * common features are added. - * May be nullptr. + * May be NULL. */ void (*override_features) (hb_ot_shape_planner_t *plan); @@ -93,7 +93,7 @@ struct hb_ot_complex_shaper_t * Called when the shape_plan is being destroyed. * plan->data is passed here for destruction. * If nullptr is returned, means a plan failure. - * May be nullptr. + * May be NULL. */ void (*data_destroy) (void *data); @@ -101,7 +101,7 @@ struct hb_ot_complex_shaper_t /* preprocess_text() * Called during shape(). * Shapers can use to modify text before shaping starts. - * May be nullptr. + * May be NULL. */ void (*preprocess_text) (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, @@ -110,7 +110,7 @@ struct hb_ot_complex_shaper_t /* postprocess_glyphs() * Called during shape(). * Shapers can use to modify glyphs after shaping ends. - * May be nullptr. + * May be NULL. */ void (*postprocess_glyphs) (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, @@ -121,7 +121,7 @@ struct hb_ot_complex_shaper_t /* decompose() * Called during shape()'s normalization. - * May be nullptr. + * May be NULL. */ bool (*decompose) (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t ab, @@ -130,7 +130,7 @@ struct hb_ot_complex_shaper_t /* compose() * Called during shape()'s normalization. - * May be nullptr. + * May be NULL. */ bool (*compose) (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t a, @@ -141,7 +141,7 @@ struct hb_ot_complex_shaper_t * Called during shape(). * Shapers should use map to get feature masks and set on buffer. * Shapers may NOT modify characters. - * May be nullptr. + * May be NULL. */ void (*setup_masks) (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, @@ -156,7 +156,7 @@ struct hb_ot_complex_shaper_t /* reorder_marks() * Called during shape(). * Shapers can use to modify ordering of combining marks. - * May be nullptr. + * May be NULL. */ void (*reorder_marks) (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, diff --git a/src/hb-ot.h b/src/hb-ot.h index 2120a3efa..4b6e3cf74 100644 --- a/src/hb-ot.h +++ b/src/hb-ot.h @@ -33,6 +33,7 @@ #include "hb-ot-font.h" #include "hb-ot-layout.h" #include "hb-ot-math.h" +#include "hb-ot-name.h" #include "hb-ot-tag.h" #include "hb-ot-shape.h" #include "hb-ot-var.h" diff --git a/test/api/CMakeLists.txt b/test/api/CMakeLists.txt index b540eb505..77cb35771 100644 --- a/test/api/CMakeLists.txt +++ b/test/api/CMakeLists.txt @@ -3,6 +3,8 @@ if (HB_HAVE_GLIB) extract_make_variable (TEST_PROGS ${MAKEFILEAM}) list (APPEND TEST_PROGS + test-ot-color + test-ot-nameid test-ot-tag test-c test-cplusplus diff --git a/test/api/Makefile.am b/test/api/Makefile.am index 03cf815ca..4572336ef 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -75,6 +75,7 @@ endif TEST_PROGS += \ test-ot-color \ + test-ot-nameid \ test-ot-tag \ test-ot-extents-cff \ $(NULL) diff --git a/test/api/fonts/cv01.otf b/test/api/fonts/cv01.otf new file mode 100644 index 000000000..01dbf01f3 Binary files /dev/null and b/test/api/fonts/cv01.otf differ diff --git a/test/api/test-ot-nameid.c b/test/api/test-ot-nameid.c new file mode 100644 index 000000000..1205190d2 --- /dev/null +++ b/test/api/test-ot-nameid.c @@ -0,0 +1,100 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + */ + +#include +#include +#include + +static const char *font_path = "fonts/cv01.otf"; + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + +#if GLIB_CHECK_VERSION(2,37,2) + gchar *default_path = g_test_build_filename (G_TEST_DIST, font_path, NULL); +#else + gchar *default_path = g_strdup (font_path); +#endif + + hb_blob_t *blob; + hb_face_t *face; + hb_font_t *font; + + char *path = argc > 1 && *argv[1] ? argv[1] : (char *) default_path; + blob = hb_blob_create_from_file (path); + if (hb_blob_get_length (blob) == 0) + g_error ("Font not found."); + + face = hb_face_create (blob, 0); + font = hb_font_create (face); + + hb_tag_t cv01 = HB_TAG ('c','v','0','1'); + unsigned int feature_index; + if (!hb_ot_layout_language_find_feature (face, + HB_OT_TAG_GSUB, + 0, + HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, + cv01, + &feature_index)) + g_error ("Failed to find feature index"); + + hb_name_id_t label_id; + hb_name_id_t tooltip_id; + hb_name_id_t sample_id; + unsigned int num_named_parameters; + hb_name_id_t first_param_id; + if (!hb_ot_layout_feature_get_name_ids (face, HB_OT_TAG_GSUB, feature_index, + &label_id, &tooltip_id, &sample_id, + &num_named_parameters, &first_param_id)) + g_error ("Failed to get name ids"); + + g_assert (label_id == 256); + g_assert (tooltip_id == 257); + g_assert (sample_id == 258); + g_assert (num_named_parameters == 2); + g_assert (first_param_id == 259); + + hb_codepoint_t characters[100]; + unsigned int char_count = 100; + + unsigned int all_chars; + all_chars = hb_ot_layout_feature_get_characters (face, HB_OT_TAG_GSUB, feature_index, + 0, &char_count, characters); + + g_assert (all_chars == 2); + g_assert (char_count == 2); + g_assert (characters[0] == 10); + g_assert (characters[1] == 24030); + + hb_font_destroy (font); + hb_face_destroy (face); + hb_blob_destroy (blob); + + g_free (default_path); + + return 0; +}