diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 455e4f50a..2ee14a964 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -156,6 +156,21 @@ HB_SCRIPT_CANADIAN_ABORIGINAL hb_font_funcs_set_glyph_func hb_font_get_glyph_func_t hb_set_invert +hb_unicode_eastasian_width_func_t +hb_unicode_eastasian_width +hb_unicode_funcs_set_eastasian_width_func +HB_UNICODE_MAX_DECOMPOSITION_LEN +hb_unicode_decompose_compatibility_func_t +hb_unicode_decompose_compatibility +hb_unicode_funcs_set_decompose_compatibility_func +hb_font_funcs_set_glyph_h_kerning_func +hb_font_funcs_set_glyph_v_kerning_func +hb_font_get_glyph_h_kerning +hb_font_get_glyph_h_kerning_func_t +hb_font_get_glyph_kerning_for_direction +hb_font_get_glyph_kerning_func_t +hb_font_get_glyph_v_kerning +hb_font_get_glyph_v_kerning_func_t
@@ -216,12 +231,10 @@ hb_font_funcs_set_glyph_extents_func hb_font_funcs_set_glyph_from_name_func hb_font_funcs_set_glyph_h_advance_func hb_font_funcs_set_glyph_h_advances_func -hb_font_funcs_set_glyph_h_kerning_func hb_font_funcs_set_glyph_h_origin_func hb_font_funcs_set_glyph_name_func hb_font_funcs_set_glyph_v_advance_func hb_font_funcs_set_glyph_v_advances_func -hb_font_funcs_set_glyph_v_kerning_func hb_font_funcs_set_glyph_v_origin_func hb_font_funcs_set_nominal_glyph_func hb_font_funcs_set_user_data @@ -246,12 +259,8 @@ hb_font_get_glyph_h_advance hb_font_get_glyph_h_advance_func_t hb_font_get_glyph_h_advances hb_font_get_glyph_h_advances_func_t -hb_font_get_glyph_h_kerning -hb_font_get_glyph_h_kerning_func_t hb_font_get_glyph_h_origin hb_font_get_glyph_h_origin_func_t -hb_font_get_glyph_kerning_for_direction -hb_font_get_glyph_kerning_func_t hb_font_get_glyph_name hb_font_get_glyph_name_func_t hb_font_get_glyph_origin_for_direction @@ -260,8 +269,6 @@ hb_font_get_glyph_v_advance hb_font_get_glyph_v_advance_func_t hb_font_get_glyph_v_advances hb_font_get_glyph_v_advances_func_t -hb_font_get_glyph_v_kerning -hb_font_get_glyph_v_kerning_func_t hb_font_get_glyph_v_origin hb_font_get_glyph_v_origin_func_t hb_font_get_nominal_glyph @@ -613,16 +620,13 @@ hb_shape_plan_t
hb-unicode HB_UNICODE_MAX -HB_UNICODE_MAX_DECOMPOSITION_LEN hb_unicode_combining_class hb_unicode_combining_class_func_t hb_unicode_combining_class_t hb_unicode_compose hb_unicode_compose_func_t hb_unicode_decompose -hb_unicode_decompose_compatibility hb_unicode_decompose_func_t -hb_unicode_eastasian_width hb_unicode_funcs_create hb_unicode_funcs_destroy hb_unicode_funcs_get_default @@ -634,9 +638,7 @@ hb_unicode_funcs_make_immutable hb_unicode_funcs_reference hb_unicode_funcs_set_combining_class_func hb_unicode_funcs_set_compose_func -hb_unicode_funcs_set_decompose_compatibility_func hb_unicode_funcs_set_decompose_func -hb_unicode_funcs_set_eastasian_width_func hb_unicode_funcs_set_general_category_func hb_unicode_funcs_set_mirroring_func hb_unicode_funcs_set_script_func diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 97866919a..d6e597a40 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -35,111 +35,6 @@ namespace AAT { using namespace OT; -/* - * Binary Searching Tables - */ - -struct BinSearchHeader -{ - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - HBUINT16 unitSize; /* Size of a lookup unit for this search in bytes. */ - HBUINT16 nUnits; /* Number of units of the preceding size to be searched. */ - HBUINT16 searchRange; /* The value of unitSize times the largest power of 2 - * that is less than or equal to the value of nUnits. */ - HBUINT16 entrySelector; /* The log base 2 of the largest power of 2 less than - * or equal to the value of nUnits. */ - HBUINT16 rangeShift; /* The value of unitSize times the difference of the - * value of nUnits minus the largest power of 2 less - * than or equal to the value of nUnits. */ - public: - DEFINE_SIZE_STATIC (10); -}; - -template -struct BinSearchArrayOf -{ - inline const Type& operator [] (unsigned int i) const - { - if (unlikely (i >= header.nUnits)) return Null(Type); - return StructAtOffset (&bytesZ, i * header.unitSize); - } - inline Type& operator [] (unsigned int i) - { - return StructAtOffset (&bytesZ, i * header.unitSize); - } - inline unsigned int get_size (void) const - { return header.static_size + header.nUnits * header.unitSize; } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return_trace (false); - - /* Note: for structs that do not reference other structs, - * we do not need to call their sanitize() as we already did - * a bound check on the aggregate array size. We just include - * a small unreachable expression to make sure the structs - * pointed to do have a simple sanitize(), ie. they do not - * reference other structs via offsets. - */ - (void) (false && StructAtOffset (&bytesZ, 0).sanitize (c)); - - return_trace (true); - } - inline bool sanitize (hb_sanitize_context_t *c, const void *base) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return_trace (false); - unsigned int count = header.nUnits; - for (unsigned int i = 0; i < count; i++) - if (unlikely (!(*this)[i].sanitize (c, base))) - return_trace (false); - return_trace (true); - } - - template - inline const Type *bsearch (const T &key) const - { - unsigned int size = header.unitSize; - int min = 0, max = (int) header.nUnits - 1; - while (min <= max) - { - int mid = (min + max) / 2; - const Type *p = (const Type *) (((const char *) &bytesZ) + (mid * size)); - int c = p->cmp (key); - if (c < 0) - max = mid - 1; - else if (c > 0) - min = mid + 1; - else - return p; - } - return nullptr; - } - - private: - inline bool sanitize_shallow (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (header.sanitize (c) && - Type::static_size >= header.unitSize && - c->check_array (bytesZ.arrayZ, header.nUnits, header.unitSize)); - } - - protected: - BinSearchHeader header; - UnsizedArrayOf bytesZ; - public: - DEFINE_SIZE_ARRAY (10, bytesZ); -}; - - /* * Lookup Table */ @@ -213,7 +108,7 @@ struct LookupFormat2 protected: HBUINT16 format; /* Format identifier--format = 2 */ - BinSearchArrayOf > + VarSizedBinSearchArrayOf > segments; /* The actual segments. These must already be sorted, * according to the first word in each one (the last * glyph in each segment). */ @@ -270,7 +165,7 @@ struct LookupFormat4 protected: HBUINT16 format; /* Format identifier--format = 2 */ - BinSearchArrayOf > + VarSizedBinSearchArrayOf > segments; /* The actual segments. These must already be sorted, * according to the first word in each one (the last * glyph in each segment). */ @@ -315,7 +210,7 @@ struct LookupFormat6 protected: HBUINT16 format; /* Format identifier--format = 6 */ - BinSearchArrayOf > + VarSizedBinSearchArrayOf > entries; /* The actual entries, sorted by glyph index. */ public: DEFINE_SIZE_ARRAY (8, entries); diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 21fd26b4f..6a793a3e4 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -30,6 +30,7 @@ #include "hb-open-type.hh" #include "hb-aat-layout-common.hh" +#include "hb-ot-kern-table.hh" /* * kerx -- Extended Kerning @@ -43,33 +44,17 @@ namespace AAT { using namespace OT; -struct KerxFormat0Records -{ - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); - } - - protected: - GlyphID left; - GlyphID right; - FWORD value; - public: - DEFINE_SIZE_STATIC (6); -}; - struct KerxSubTableFormat0 { - // TODO(ebraminio) Enable when we got suitable BinSearchArrayOf - // inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - // { - // hb_glyph_pair_t pair = {left, right}; - // int i = pairs.bsearch (pair); - // if (i == -1) - // return 0; - // return pairs[i].get_kerning (); - // } + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const + { + hb_glyph_pair_t pair = {left, right}; + int i = pairs.bsearch (pair); + if (i == -1) + return 0; + return pairs[i].get_kerning (); + } + inline bool apply (hb_aat_apply_context_t *c) const { TRACE_APPLY (this); @@ -82,23 +67,14 @@ struct KerxSubTableFormat0 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - recordsZ.sanitize (c, nPairs))); + return_trace (likely (pairs.sanitize (c))); } protected: - // TODO(ebraminio): A custom version of "BinSearchArrayOf pairs;" is - // needed here to use HBUINT32 instead - HBUINT32 nPairs; /* The number of kerning pairs in this subtable */ - HBUINT32 searchRange; /* The largest power of two less than or equal to the value of nPairs, - * multiplied by the size in bytes of an entry in the subtable. */ - HBUINT32 entrySelector; /* This is calculated as log2 of the largest power of two less - * than or equal to the value of nPairs. */ - HBUINT32 rangeShift; /* The value of nPairs minus the largest power of two less than or equal to nPairs. */ - UnsizedArrayOf - recordsZ; /* VAR=nPairs */ + BinSearchArrayOf + pairs; /* Sorted kern records. */ public: - DEFINE_SIZE_ARRAY (16, recordsZ); + DEFINE_SIZE_ARRAY (16, pairs); }; struct KerxSubTableFormat1 @@ -126,32 +102,14 @@ struct KerxSubTableFormat1 DEFINE_SIZE_STATIC (20); }; -// TODO(ebraminio): Maybe this can be replaced with Lookup? -struct KerxClassTable -{ - inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (firstGlyph.sanitize (c) && - classes.sanitize (c))); - } - - protected: - HBUINT16 firstGlyph; /* First glyph in class range. */ - ArrayOf classes; /* Glyph classes. */ - public: - DEFINE_SIZE_ARRAY (4, classes); -}; - struct KerxSubTableFormat2 { - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, + const char *end, unsigned int num_glyphs) const { - unsigned int l = (this+leftClassTable).get_class (left); - unsigned int r = (this+leftClassTable).get_class (left); - unsigned int offset = l * rowWidth + r * sizeof (FWORD); + unsigned int l = *(this+leftClassTable).get_value (left, num_glyphs); + unsigned int r = *(this+rightClassTable).get_value (right, num_glyphs); + unsigned int offset = l + r; const FWORD *arr = &(this+array); if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end)) return 0; @@ -182,10 +140,10 @@ struct KerxSubTableFormat2 protected: HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */ - LOffsetTo + LOffsetTo > leftClassTable; /* Offset from beginning of this subtable to * left-hand class table. */ - LOffsetTo + LOffsetTo > rightClassTable;/* Offset from beginning of this subtable to * right-hand class table. */ LOffsetTo @@ -209,26 +167,14 @@ struct KerxSubTableFormat4 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - rowWidth.sanitize (c) && - leftClassTable.sanitize (c, this) && - rightClassTable.sanitize (c, this) && - array.sanitize (c, this))); + + /* TODO */ + return_trace (likely (c->check_struct (this))); } protected: - HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */ - LOffsetTo - leftClassTable; /* Offset from beginning of this subtable to - * left-hand class table. */ - LOffsetTo - rightClassTable;/* Offset from beginning of this subtable to - * right-hand class table. */ - LOffsetTo - array; /* Offset from beginning of this subtable to - * the start of the kerning array. */ public: - DEFINE_SIZE_STATIC (16); + DEFINE_SIZE_STATIC (1); }; struct KerxSubTableFormat6 @@ -266,6 +212,8 @@ struct KerxSubTableFormat6 struct KerxTable { + friend kerx; + inline unsigned int get_size (void) const { return length; } inline unsigned int get_type (void) const { return coverage & SubtableType; } @@ -358,7 +306,33 @@ struct kerx unsigned int count = tableCount; for (unsigned int i = 0; i < count; i++) { + bool reverse; + + if (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != + bool (table->coverage & KerxTable::Vertical)) + goto skip; + + if (table->coverage & KerxTable::CrossStream) + goto skip; /* We do NOT handle cross-stream kerning. */ + + reverse = bool (table->coverage & KerxTable::ProcessDirection) != + HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); + + if (!c->buffer->message (c->font, "start kerx subtable %d", c->lookup_index)) + goto skip; + + if (reverse) + c->buffer->reverse (); + + /* XXX Reverse-kern is not working yet... */ table->dispatch (c); + + if (reverse) + c->buffer->reverse (); + + (void) c->buffer->message (c->font, "end kerx subtable %d", c->lookup_index); + + skip: table = &StructAfter (*table); } } diff --git a/src/hb-common.h b/src/hb-common.h index 6101d72fe..4f91a1761 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -63,6 +63,15 @@ typedef unsigned __int64 uint64_t; # include #endif +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +#define HB_DEPRECATED __attribute__((__deprecated__)) +#elif defined(_MSC_VER) && (_MSC_VER >= 1300) +#define HB_DEPRECATED __declspec(deprecated) +#else +#define HB_DEPRECATED +#endif + + HB_BEGIN_DECLS diff --git a/src/hb-deprecated.h b/src/hb-deprecated.h index eac7efb42..2deb249ae 100644 --- a/src/hb-deprecated.h +++ b/src/hb-deprecated.h @@ -50,14 +50,168 @@ 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 void +HB_EXTERN HB_DEPRECATED 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); -HB_EXTERN void +HB_EXTERN HB_DEPRECATED void hb_set_invert (hb_set_t *set); +/** + * hb_unicode_eastasian_width_func_t: + * + * Deprecated: REPLACEME + */ +typedef unsigned int (*hb_unicode_eastasian_width_func_t) (hb_unicode_funcs_t *ufuncs, + hb_codepoint_t unicode, + void *user_data); + +/** + * hb_unicode_funcs_set_eastasian_width_func: + * @ufuncs: a Unicode function structure + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 0.9.2 + * Deprecated: REPLACEME + **/ +HB_EXTERN HB_DEPRECATED void +hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs, + hb_unicode_eastasian_width_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** + * hb_unicode_eastasian_width: + * + * Since: 0.9.2 + * Deprecated: REPLACEME + **/ +HB_EXTERN HB_DEPRECATED unsigned int +hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs, + hb_codepoint_t unicode); + + +/** + * hb_unicode_decompose_compatibility_func_t: + * @ufuncs: a Unicode function structure + * @u: codepoint to decompose + * @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into + * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func() + * + * Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed. + * The complete length of the decomposition will be returned. + * + * If @u has no compatibility decomposition, zero should be returned. + * + * The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any + * compatibility decomposition plus an terminating value of 0. Consequently, @decompose must be allocated by the caller to be at least this length. Implementations + * of this function type must ensure that they do not write past the provided array. + * + * Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available. + * + * Deprecated: REPLACEME + */ +typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_funcs_t *ufuncs, + hb_codepoint_t u, + hb_codepoint_t *decomposed, + void *user_data); + +/** + * HB_UNICODE_MAX_DECOMPOSITION_LEN: + * + * See Unicode 6.1 for details on the maximum decomposition length. + * + * Deprecated: REPLACEME + */ +#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */ + +/** + * hb_unicode_funcs_set_decompose_compatibility_func: + * @ufuncs: a Unicode function structure + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 0.9.2 + * Deprecated: REPLACEME + **/ +HB_EXTERN HB_DEPRECATED void +hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs, + hb_unicode_decompose_compatibility_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** + * hb_unicode_decompose_compatibility: + * + * + * Deprecated: REPLACEME + **/ +HB_EXTERN HB_DEPRECATED unsigned int +hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, + hb_codepoint_t u, + hb_codepoint_t *decomposed); + + +typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, + void *user_data); +typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t; +typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t; + +/** + * hb_font_funcs_set_glyph_h_kerning_func: + * @ffuncs: font functions. + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 0.9.2 + * Deprecated: REPLACEME + **/ +HB_EXTERN void +hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_h_kerning_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** + * hb_font_funcs_set_glyph_v_kerning_func: + * @ffuncs: font functions. + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 0.9.2 + * Deprecated: REPLACEME + **/ +HB_EXTERN void +hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_v_kerning_func_t func, + void *user_data, hb_destroy_func_t destroy); + +HB_EXTERN hb_position_t +hb_font_get_glyph_h_kerning (hb_font_t *font, + hb_codepoint_t left_glyph, hb_codepoint_t right_glyph); +HB_EXTERN hb_position_t +hb_font_get_glyph_v_kerning (hb_font_t *font, + hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph); + +HB_EXTERN void +hb_font_get_glyph_kerning_for_direction (hb_font_t *font, + hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, + hb_direction_t direction, + hb_position_t *x, hb_position_t *y); + + #endif HB_END_DECLS diff --git a/src/hb-font.cc b/src/hb-font.cc index 5c259dca2..f4f2df7c7 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -887,6 +887,7 @@ hb_font_get_glyph_v_origin (hb_font_t *font, * Return value: * * Since: 0.9.2 + * Deprecated: REPLACEME **/ hb_position_t hb_font_get_glyph_h_kerning (hb_font_t *font, @@ -906,6 +907,7 @@ hb_font_get_glyph_h_kerning (hb_font_t *font, * Return value: * * Since: 0.9.2 + * Deprecated: REPLACEME **/ hb_position_t hb_font_get_glyph_v_kerning (hb_font_t *font, @@ -1134,6 +1136,7 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, * * * Since: 0.9.2 + * Deprecated: REPLACEME **/ void hb_font_get_glyph_kerning_for_direction (hb_font_t *font, diff --git a/src/hb-font.h b/src/hb-font.h index 6cd486979..e13b0916a 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -149,12 +149,6 @@ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *fon typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t; typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t; -typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data, - hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, - void *user_data); -typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t; -typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t; - typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data, hb_codepoint_t glyph, @@ -338,38 +332,6 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_v_origin_func_t func, void *user_data, hb_destroy_func_t destroy); -/** - * hb_font_funcs_set_glyph_h_kerning_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * - * - * - * Since: 0.9.2 - **/ -HB_EXTERN void -hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_h_kerning_func_t func, - void *user_data, hb_destroy_func_t destroy); - -/** - * hb_font_funcs_set_glyph_v_kerning_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * - * - * - * Since: 0.9.2 - **/ -HB_EXTERN void -hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_v_kerning_func_t func, - void *user_data, hb_destroy_func_t destroy); - /** * hb_font_funcs_set_glyph_extents_func: * @ffuncs: font functions. @@ -483,13 +445,6 @@ hb_font_get_glyph_v_origin (hb_font_t *font, hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y); -HB_EXTERN hb_position_t -hb_font_get_glyph_h_kerning (hb_font_t *font, - hb_codepoint_t left_glyph, hb_codepoint_t right_glyph); -HB_EXTERN hb_position_t -hb_font_get_glyph_v_kerning (hb_font_t *font, - hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph); - HB_EXTERN hb_bool_t hb_font_get_glyph_extents (hb_font_t *font, hb_codepoint_t glyph, @@ -552,12 +507,6 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, hb_direction_t direction, hb_position_t *x, hb_position_t *y); -HB_EXTERN void -hb_font_get_glyph_kerning_for_direction (hb_font_t *font, - hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y); - HB_EXTERN hb_bool_t hb_font_get_glyph_extents_for_origin (hb_font_t *font, hb_codepoint_t glyph, diff --git a/src/hb-font.hh b/src/hb-font.hh index 4c8d0aeec..8b19dd715 100644 --- a/src/hb-font.hh +++ b/src/hb-font.hh @@ -502,8 +502,8 @@ struct hb_font_t hb_position_t *x, hb_position_t *y) { if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { - *x = get_glyph_h_kerning (first_glyph, second_glyph); *y = 0; + *x = get_glyph_h_kerning (first_glyph, second_glyph); } else { *x = 0; *y = get_glyph_v_kerning (first_glyph, second_glyph); diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 6da31fc29..fcd87a078 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -305,23 +305,6 @@ hb_ft_get_glyph_v_origin (hb_font_t *font, return true; } -static hb_position_t -hb_ft_get_glyph_h_kerning (hb_font_t *font, - void *font_data, - hb_codepoint_t left_glyph, - hb_codepoint_t right_glyph, - void *user_data HB_UNUSED) -{ - const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - FT_Vector kerningv; - - FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED; - if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv)) - return 0; - - return kerningv.x; -} - static hb_bool_t hb_ft_get_glyph_extents (hb_font_t *font, void *font_data, @@ -466,8 +449,6 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t= 2.29.12 we have to perform - * a round trip to UTF-8 and the associated memory management dance. */ - gchar utf8[6]; - gchar *utf8_decomposed, *c; - gsize utf8_len, utf8_decomposed_len, i; - - /* Convert @u to UTF-8 and normalise it in NFKD mode. This performs the compatibility decomposition. */ - utf8_len = g_unichar_to_utf8 (u, utf8); - utf8_decomposed = g_utf8_normalize (utf8, utf8_len, G_NORMALIZE_NFKD); - utf8_decomposed_len = g_utf8_strlen (utf8_decomposed, -1); - - assert (utf8_decomposed_len <= HB_UNICODE_MAX_DECOMPOSITION_LEN); - - for (i = 0, c = utf8_decomposed; i < utf8_decomposed_len; i++, c = g_utf8_next_char (c)) - *decomposed++ = g_utf8_get_char (c); - - g_free (utf8_decomposed); - - return utf8_decomposed_len; -} +#define hb_glib_unicode_decompose_compatibility nullptr #ifdef HB_USE_ATEXIT diff --git a/src/hb-icu.cc b/src/hb-icu.cc index 564f71fe2..8dbeaddd6 100644 --- a/src/hb-icu.cc +++ b/src/hb-icu.cc @@ -73,24 +73,7 @@ hb_icu_unicode_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED, return (hb_unicode_combining_class_t) u_getCombiningClass (unicode); } -static unsigned int -hb_icu_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs HB_UNUSED, - hb_codepoint_t unicode, - void *user_data HB_UNUSED) -{ - switch (u_getIntPropertyValue(unicode, UCHAR_EAST_ASIAN_WIDTH)) - { - case U_EA_WIDE: - case U_EA_FULLWIDTH: - return 2; - case U_EA_NEUTRAL: - case U_EA_AMBIGUOUS: - case U_EA_HALFWIDTH: - case U_EA_NARROW: - return 1; - } - return 1; -} +#define hb_icu_unicode_eastasian_width nullptr static hb_unicode_general_category_t hb_icu_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED, @@ -309,39 +292,8 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED, return ret; } -static unsigned int -hb_icu_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED, - hb_codepoint_t u, - hb_codepoint_t *decomposed, - void *user_data HB_UNUSED) -{ - UChar utf16[2], normalized[2 * HB_UNICODE_MAX_DECOMPOSITION_LEN + 1]; - unsigned int len; - int32_t utf32_len; - hb_bool_t err; - UErrorCode icu_err; +#define hb_icu_unicode_decompose_compatibility nullptr - /* Copy @u into a UTF-16 array to be passed to ICU. */ - len = 0; - err = false; - U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), u, err); - if (err) - return 0; - - /* Normalise the codepoint using NFKD mode. */ - icu_err = U_ZERO_ERROR; - len = unorm2_normalize (unorm2_getNFKDInstance (&icu_err), utf16, len, normalized, ARRAY_LENGTH (normalized), &icu_err); - if (U_FAILURE (icu_err)) - return 0; - - /* Convert the decomposed form from UTF-16 to UTF-32. */ - icu_err = U_ZERO_ERROR; - u_strToUTF32 ((UChar32*) decomposed, HB_UNICODE_MAX_DECOMPOSITION_LEN, &utf32_len, normalized, len, &icu_err); - if (U_FAILURE (icu_err)) - return 0; - - return utf32_len; -} #ifdef HB_USE_ATEXIT static void free_static_icu_funcs (void); diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index ae7cdfaf6..9a0873369 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -702,7 +702,11 @@ struct SortedArrayOf : ArrayOf } }; -/* Binary-search arrays */ +/* + * Binary-search arrays + */ + +template struct BinSearchHeader { inline operator uint32_t (void) const { return len; } @@ -725,17 +729,117 @@ struct BinSearchHeader } protected: - HBUINT16 len; - HBUINT16 searchRange; - HBUINT16 entrySelector; - HBUINT16 rangeShift; + LenType len; + LenType searchRange; + LenType entrySelector; + LenType rangeShift; public: DEFINE_SIZE_STATIC (8); }; +template +struct BinSearchArrayOf : SortedArrayOf > {}; + +struct VarSizedBinSearchHeader +{ + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + HBUINT16 unitSize; /* Size of a lookup unit for this search in bytes. */ + HBUINT16 nUnits; /* Number of units of the preceding size to be searched. */ + HBUINT16 searchRange; /* The value of unitSize times the largest power of 2 + * that is less than or equal to the value of nUnits. */ + HBUINT16 entrySelector; /* The log base 2 of the largest power of 2 less than + * or equal to the value of nUnits. */ + HBUINT16 rangeShift; /* The value of unitSize times the difference of the + * value of nUnits minus the largest power of 2 less + * than or equal to the value of nUnits. */ + public: + DEFINE_SIZE_STATIC (10); +}; + template -struct BinSearchArrayOf : SortedArrayOf {}; +struct VarSizedBinSearchArrayOf +{ + inline const Type& operator [] (unsigned int i) const + { + if (unlikely (i >= header.nUnits)) return Null(Type); + return StructAtOffset (&bytesZ, i * header.unitSize); + } + inline Type& operator [] (unsigned int i) + { + return StructAtOffset (&bytesZ, i * header.unitSize); + } + inline unsigned int get_size (void) const + { return header.static_size + header.nUnits * header.unitSize; } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (unlikely (!sanitize_shallow (c))) return_trace (false); + + /* Note: for structs that do not reference other structs, + * we do not need to call their sanitize() as we already did + * a bound check on the aggregate array size. We just include + * a small unreachable expression to make sure the structs + * pointed to do have a simple sanitize(), ie. they do not + * reference other structs via offsets. + */ + (void) (false && StructAtOffset (&bytesZ, 0).sanitize (c)); + + return_trace (true); + } + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + if (unlikely (!sanitize_shallow (c))) return_trace (false); + unsigned int count = header.nUnits; + for (unsigned int i = 0; i < count; i++) + if (unlikely (!(*this)[i].sanitize (c, base))) + return_trace (false); + return_trace (true); + } + + template + inline const Type *bsearch (const T &key) const + { + unsigned int size = header.unitSize; + int min = 0, max = (int) header.nUnits - 1; + while (min <= max) + { + int mid = (min + max) / 2; + const Type *p = (const Type *) (((const char *) &bytesZ) + (mid * size)); + int c = p->cmp (key); + if (c < 0) + max = mid - 1; + else if (c > 0) + min = mid + 1; + else + return p; + } + return nullptr; + } + + private: + inline bool sanitize_shallow (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (header.sanitize (c) && + Type::static_size >= header.unitSize && + c->check_array (bytesZ.arrayZ, header.nUnits, header.unitSize)); + } + + protected: + VarSizedBinSearchHeader header; + UnsizedArrayOf bytesZ; + public: + DEFINE_SIZE_ARRAY (10, bytesZ); +}; } /* namespace OT */ diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 74e1554a8..f2d12c1b3 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -105,17 +105,6 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, } } -static hb_position_t -hb_ot_get_glyph_h_kerning (hb_font_t *font, - void *font_data, - hb_codepoint_t left_glyph, - hb_codepoint_t right_glyph, - void *user_data HB_UNUSED) -{ - const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; - return font->em_scale_x (ot_face->kern->get_h_kerning (left_glyph, right_glyph)); -} - static hb_bool_t hb_ot_get_glyph_extents (hb_font_t *font, void *font_data, @@ -211,8 +200,6 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t +struct hb_kern_machine_t +{ + hb_kern_machine_t (const Driver &driver_) : driver (driver_) {} + + inline void kern (hb_font_t *font, + hb_buffer_t *buffer, + hb_mask_t kern_mask) const + { + OT::hb_ot_apply_context_t c (1, font, buffer); + c.set_lookup_mask (kern_mask); + c.set_lookup_props (OT::LookupFlag::IgnoreMarks); + OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input; + skippy_iter.init (&c); + + bool horizontal = HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction); + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + for (unsigned int idx = 0; idx < count;) + { + if (!(info[idx].mask & kern_mask)) + { + idx++; + continue; + } + + skippy_iter.reset (idx, 1); + if (!skippy_iter.next ()) + { + idx++; + continue; + } + + unsigned int i = idx; + unsigned int j = skippy_iter.idx; + hb_position_t kern1, kern2; + + hb_position_t kern = driver.get_kerning (info[i].codepoint, + info[j].codepoint); + + + if (likely (!kern)) + goto skip; + + kern1 = kern >> 1; + kern2 = kern - kern1; + + if (horizontal) + { + pos[i].x_advance += kern1; + pos[j].x_advance += kern2; + pos[j].x_offset += kern2; + } + else + { + pos[i].y_advance += kern1; + pos[j].y_advance += kern2; + pos[j].y_offset += kern2; + } + + buffer->unsafe_to_break (i, j + 1); + + skip: + idx = skippy_iter.idx; + } + } + + const Driver &driver; +}; + /* * kern -- Kerning @@ -118,7 +193,7 @@ struct KernSubTableFormat2 { unsigned int l = (this+leftClassTable).get_class (left); unsigned int r = (this+rightClassTable).get_class (right); - unsigned int offset = l * rowWidth + r * sizeof (FWORD); + unsigned int offset = l + r; const FWORD *arr = &(this+array); if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end)) return 0; @@ -190,10 +265,10 @@ struct KernSubTableWrapper inline const T* thiz (void) const { return static_cast (this); } inline bool is_horizontal (void) const - { return (thiz()->coverage & T::COVERAGE_CHECK_FLAGS) == T::COVERAGE_CHECK_HORIZONTAL; } + { return (thiz()->coverage & T::CheckFlags) == T::CheckHorizontal; } inline bool is_override (void) const - { return bool (thiz()->coverage & T::COVERAGE_OVERRIDE_FLAG); } + { return bool (thiz()->coverage & T::Override); } inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const { return thiz()->subtable.get_kerning (left, right, end, thiz()->format); } @@ -264,16 +339,17 @@ struct KernOT : KernTable { friend struct KernSubTableWrapper; - enum coverage_flags_t { - COVERAGE_DIRECTION_FLAG = 0x01u, - COVERAGE_MINIMUM_FLAG = 0x02u, - COVERAGE_CROSSSTREAM_FLAG = 0x04u, - COVERAGE_OVERRIDE_FLAG = 0x08u, + enum Coverage + { + Direction = 0x01u, + Minimum = 0x02u, + CrossStream = 0x04u, + Override = 0x08u, - COVERAGE_VARIATION_FLAG = 0x00u, /* Not supported. */ + Variation = 0x00u, /* Not supported. */ - COVERAGE_CHECK_FLAGS = 0x07u, - COVERAGE_CHECK_HORIZONTAL = 0x01u + CheckFlags = 0x07u, + CheckHorizontal = 0x01u }; protected: @@ -304,15 +380,16 @@ struct KernAAT : KernTable { friend struct KernSubTableWrapper; - enum coverage_flags_t { - COVERAGE_DIRECTION_FLAG = 0x80u, - COVERAGE_CROSSSTREAM_FLAG = 0x40u, - COVERAGE_VARIATION_FLAG = 0x20u, + enum Coverage + { + Direction = 0x80u, + CrossStream = 0x40u, + Variation = 0x20u, - COVERAGE_OVERRIDE_FLAG = 0x00u, /* Not supported. */ + Override = 0x00u, /* Not supported. */ - COVERAGE_CHECK_FLAGS = 0xE0u, - COVERAGE_CHECK_HORIZONTAL = 0x00u + CheckFlags = 0xE0u, + CheckHorizontal = 0x00u }; protected: @@ -338,6 +415,9 @@ struct kern { static const hb_tag_t tableTag = HB_OT_TAG_kern; + inline bool has_data (void) const + { return u.version32 != 0; } + inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const { switch (u.major) { @@ -371,9 +451,27 @@ struct kern hb_blob_destroy (blob); } + inline bool has_data (void) const + { return table->has_data (); } + inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const { return table->get_h_kerning (left, right, table_length); } + inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const + { return get_h_kerning (first, second); } + + inline void apply (hb_font_t *font, + hb_buffer_t *buffer, + hb_mask_t kern_mask) const + { + if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + return; + + hb_kern_machine_t machine (*this); + + machine.kern (font, buffer, kern_mask); + } + private: hb_blob_t *blob; const kern *table; @@ -383,6 +481,7 @@ struct kern protected: union { HBUINT16 major; + HBUINT32 version32; KernOT ot; KernAAT aat; } u; diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 51c119858..975b7f8d4 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -45,17 +45,15 @@ #include "hb-ot-color-cpal-table.hh" #include "hb-ot-color-sbix-table.hh" #include "hb-ot-color-svg-table.hh" +#include "hb-ot-kern-table.hh" #include "hb-ot-name-table.hh" -// static inline const OT::BASE& -// _get_base (hb_face_t *face) -// { -// if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::BASE); -// hb_ot_face_data_t *data = hb_ot_face_data (face); -// return *(data->base.get ()); -// } - +static const OT::kern::accelerator_t& _get_kern (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern::accelerator_t); + return *hb_ot_face_data (face)->kern; +} const OT::GDEF& _get_gdef (hb_face_t *face) { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GDEF); @@ -91,6 +89,25 @@ const OT::GPOS& _get_gpos_relaxed (hb_face_t *face) } +/* + * kern + */ + +hb_bool_t +hb_ot_layout_has_kerning (hb_face_t *face) +{ + return _get_kern (face).has_data (); +} + +void +hb_ot_layout_kern (hb_font_t *font, + hb_buffer_t *buffer, + hb_mask_t kern_mask) +{ + _get_kern (font->face).apply (font, buffer, kern_mask); +} + + /* * GDEF */ @@ -1306,27 +1323,3 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, { apply_string (c, lookup, accel); } - - - - -/* - * OT::BASE - */ - -// /** -// * hb_ot_base_has_data: -// * @face: #hb_face_t to test -// * -// * This function allows to verify the presence of an OpenType BASE table on the -// * face. -// * -// * Return value: true if face has a BASE table, false otherwise -// * -// * Since: XXX -// **/ -// hb_bool_t -// hb_ot_base_has_data (hb_face_t *face) -// { -// return _get_base (face).has_data (); -// } diff --git a/src/hb-ot-layout.hh b/src/hb-ot-layout.hh index ac55459b6..f5ffe3112 100644 --- a/src/hb-ot-layout.hh +++ b/src/hb-ot-layout.hh @@ -49,6 +49,19 @@ HB_INTERNAL const OT::GSUB& _get_gsub_relaxed (hb_face_t *face); HB_INTERNAL const OT::GPOS& _get_gpos_relaxed (hb_face_t *face); +/* + * kern + */ + +HB_INTERNAL hb_bool_t +hb_ot_layout_has_kerning (hb_face_t *face); + +HB_INTERNAL void +hb_ot_layout_kern (hb_font_t *font, + hb_buffer_t *buffer, + hb_mask_t kern_mask); + + /* Private API corresponding to hb-ot-layout.h: */ HB_INTERNAL hb_bool_t diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc index 6673abd14..bf1fc8fbb 100644 --- a/src/hb-ot-shape-fallback.cc +++ b/src/hb-ot-shape-fallback.cc @@ -25,7 +25,7 @@ */ #include "hb-ot-shape-fallback.hh" -#include "hb-ot-layout-gsubgpos.hh" +#include "hb-ot-kern-table.hh" static unsigned int recategorize_combining_class (hb_codepoint_t u, @@ -162,9 +162,9 @@ recategorize_combining_class (hb_codepoint_t u, } void -_hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font HB_UNUSED, - hb_buffer_t *buffer) +_hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) { unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; @@ -417,9 +417,9 @@ position_cluster (const hb_ot_shape_plan_t *plan, } void -_hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer) +_hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) { _hb_buffer_assert_gsubgpos_vars (buffer); @@ -435,67 +435,34 @@ _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan, } -/* Performs old-style TrueType kerning. */ +/* Performs font-assisted kerning. */ void _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, hb_font_t *font, - hb_buffer_t *buffer) + hb_buffer_t *buffer) { - if (!plan->kerning_requested) return; - - OT::hb_ot_apply_context_t c (1, font, buffer); - hb_mask_t kern_mask = plan->kern_mask; - c.set_lookup_mask (kern_mask); - c.set_lookup_props (OT::LookupFlag::IgnoreMarks); - OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input; - skippy_iter.init (&c); - - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - hb_glyph_position_t *pos = buffer->pos; - for (unsigned int idx = 0; idx < count;) + struct driver_t { - if (!(info[idx].mask & kern_mask)) + driver_t (hb_font_t *font_, + hb_buffer_t *buffer) : + font (font_), direction (buffer->props.direction) {} + + hb_position_t get_kerning (hb_codepoint_t first, hb_codepoint_t second) const { - idx++; - continue; + hb_position_t kern = 0; + font->get_glyph_kerning_for_direction (first, second, + direction, + &kern, &kern); + return kern; } - skippy_iter.reset (idx, 1); - if (!skippy_iter.next ()) - { - idx++; - continue; - } + hb_font_t *font; + hb_direction_t direction; + } driver (font, buffer); - hb_position_t x_kern, y_kern; - font->get_glyph_kerning_for_direction (info[idx].codepoint, - info[skippy_iter.idx].codepoint, - buffer->props.direction, - &x_kern, &y_kern); + hb_kern_machine_t machine (driver); - if (x_kern) - { - hb_position_t kern1 = x_kern >> 1; - hb_position_t kern2 = x_kern - kern1; - pos[idx].x_advance += kern1; - pos[skippy_iter.idx].x_advance += kern2; - pos[skippy_iter.idx].x_offset += kern2; - buffer->unsafe_to_break (idx, skippy_iter.idx + 1); - } - - if (y_kern) - { - hb_position_t kern1 = y_kern >> 1; - hb_position_t kern2 = y_kern - kern1; - pos[idx].y_advance += kern1; - pos[skippy_iter.idx].y_advance += kern2; - pos[skippy_iter.idx].y_offset += kern2; - buffer->unsafe_to_break (idx, skippy_iter.idx + 1); - } - - idx = skippy_iter.idx; - } + machine.kern (font, buffer, plan->kern_mask); } diff --git a/src/hb-ot-shape-fallback.hh b/src/hb-ot-shape-fallback.hh index 730e7f280..12f18ed12 100644 --- a/src/hb-ot-shape-fallback.hh +++ b/src/hb-ot-shape-fallback.hh @@ -32,13 +32,13 @@ #include "hb-ot-shape.hh" -HB_INTERNAL void _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); +HB_INTERNAL void _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); -HB_INTERNAL void _hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); +HB_INTERNAL void _hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); HB_INTERNAL void _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, diff --git a/src/hb-ot-shape-normalize.hh b/src/hb-ot-shape-normalize.hh index 80755f775..04f1a8009 100644 --- a/src/hb-ot-shape-normalize.hh +++ b/src/hb-ot-shape-normalize.hh @@ -41,7 +41,7 @@ enum hb_ot_shape_normalization_mode_t { HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* Never composes base-to-base */ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* Always fully decomposes and then recompose back */ - HB_OT_SHAPE_NORMALIZATION_MODE_AUTO, /* Choose decomposed if GPOS mark feature available, compose otherwise. */ + HB_OT_SHAPE_NORMALIZATION_MODE_AUTO, /* See hb-ot-shape-normalize.cc for logic. */ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_AUTO }; diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 4e5bd4e9b..a9c0844e8 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -69,8 +69,9 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, bool disable_gpos = plan.shaper->gpos_tag && plan.shaper->gpos_tag != plan.map.chosen_script[1]; plan.apply_gpos = !disable_gpos && hb_ot_layout_has_positioning (face); - - plan.fallback_positioning = !plan.apply_gpos; + plan.apply_kern = !plan.apply_gpos && hb_ot_layout_has_kerning (face); + plan.fallback_kerning = !plan.apply_gpos && !plan.apply_kern; + plan.fallback_mark_positioning = !plan.apply_gpos; plan.fallback_glyph_classes = !hb_ot_layout_has_glyph_classes (face); } @@ -404,7 +405,7 @@ hb_ensure_native_direction (hb_buffer_t *buffer) /* Substitute */ static inline void -hb_ot_mirror_chars (hb_ot_shape_context_t *c) +hb_ot_mirror_chars (const hb_ot_shape_context_t *c) { if (HB_DIRECTION_IS_FORWARD (c->target_direction)) return; @@ -425,7 +426,7 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c) } static inline void -hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c) +hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c) { if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) || !c->plan->has_frac) @@ -475,7 +476,7 @@ hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c) } static inline void -hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c) +hb_ot_shape_initialize_masks (const hb_ot_shape_context_t *c) { hb_ot_map_t *map = &c->plan->map; hb_buffer_t *buffer = c->buffer; @@ -485,7 +486,7 @@ hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c) } static inline void -hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) +hb_ot_shape_setup_masks (const hb_ot_shape_context_t *c) { hb_ot_map_t *map = &c->plan->map; hb_buffer_t *buffer = c->buffer; @@ -507,7 +508,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) } static void -hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c) +hb_ot_zero_width_default_ignorables (const hb_ot_shape_context_t *c) { hb_buffer_t *buffer = c->buffer; @@ -526,7 +527,7 @@ hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c) } static void -hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) +hb_ot_hide_default_ignorables (const hb_ot_shape_context_t *c) { hb_buffer_t *buffer = c->buffer; @@ -609,7 +610,7 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer) } static inline void -hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) +hb_synthesize_glyph_classes (const hb_ot_shape_context_t *c) { unsigned int count = c->buffer->len; hb_glyph_info_t *info = c->buffer->info; @@ -635,7 +636,7 @@ hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) } static inline void -hb_ot_substitute_default (hb_ot_shape_context_t *c) +hb_ot_substitute_default (const hb_ot_shape_context_t *c) { hb_buffer_t *buffer = c->buffer; @@ -648,8 +649,8 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c) hb_ot_shape_setup_masks (c); /* This is unfortunate to go here, but necessary... */ - if (c->plan->fallback_positioning) - _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer); + if (c->plan->fallback_mark_positioning) + _hb_ot_shape_fallback_mark_position_recategorize_marks (c->plan, c->font, buffer); hb_ot_map_glyphs_fast (buffer); @@ -657,7 +658,7 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c) } static inline void -hb_ot_substitute_complex (hb_ot_shape_context_t *c) +hb_ot_substitute_complex (const hb_ot_shape_context_t *c) { hb_buffer_t *buffer = c->buffer; @@ -673,7 +674,7 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c) } static inline void -hb_ot_substitute (hb_ot_shape_context_t *c) +hb_ot_substitute (const hb_ot_shape_context_t *c) { hb_ot_substitute_default (c); @@ -713,7 +714,7 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets) } static inline void -hb_ot_position_default (hb_ot_shape_context_t *c) +hb_ot_position_default (const hb_ot_shape_context_t *c) { hb_direction_t direction = c->buffer->props.direction; unsigned int count = c->buffer->len; @@ -747,7 +748,7 @@ hb_ot_position_default (hb_ot_shape_context_t *c) } static inline void -hb_ot_position_complex (hb_ot_shape_context_t *c) +hb_ot_position_complex (const hb_ot_shape_context_t *c) { unsigned int count = c->buffer->len; hb_glyph_info_t *info = c->buffer->info; @@ -762,7 +763,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c) * If fallback positinoing happens or GPOS is present, we don't * care. */ - bool adjust_offsets_when_zeroing = c->plan->fallback_positioning && + bool adjust_offsets_when_zeroing = c->plan->fallback_mark_positioning && !c->plan->shaper->fallback_position && HB_DIRECTION_IS_FORWARD (c->buffer->props.direction); @@ -818,7 +819,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c) } static inline void -hb_ot_position (hb_ot_shape_context_t *c) +hb_ot_position (const hb_ot_shape_context_t *c) { c->buffer->clear_positions (); @@ -826,15 +827,19 @@ hb_ot_position (hb_ot_shape_context_t *c) hb_ot_position_complex (c); - if (c->plan->fallback_positioning && c->plan->shaper->fallback_position) - _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer); + if (c->plan->fallback_mark_positioning && c->plan->shaper->fallback_position) + _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer); if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)) hb_buffer_reverse (c->buffer); /* Visual fallback goes here. */ - if (c->plan->fallback_positioning) + if (!c->plan->kerning_requested) + ; + else if (c->plan->apply_kern) + hb_ot_layout_kern (c->font, c->buffer, c->plan->kern_mask); + else if (c->plan->fallback_kerning) _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); _hb_buffer_deallocate_gsubgpos_vars (c->buffer); diff --git a/src/hb-ot-shape.hh b/src/hb-ot-shape.hh index 23c385aa1..43852d8ff 100644 --- a/src/hb-ot-shape.hh +++ b/src/hb-ot-shape.hh @@ -46,11 +46,12 @@ struct hb_ot_shape_plan_t bool has_frac : 1; bool kerning_requested : 1; bool has_gpos_mark : 1; - bool fallback_positioning : 1; bool fallback_glyph_classes : 1; + bool fallback_kerning : 1; + bool fallback_mark_positioning : 1; bool apply_morx : 1; - + bool apply_kern : 1; bool apply_gpos : 1; diff --git a/src/hb-ucdn.cc b/src/hb-ucdn.cc index 41be586c8..3edd17eaa 100644 --- a/src/hb-ucdn.cc +++ b/src/hb-ucdn.cc @@ -182,14 +182,7 @@ hb_ucdn_combining_class(hb_unicode_funcs_t *ufuncs HB_UNUSED, return (hb_unicode_combining_class_t) ucdn_get_combining_class(unicode); } -static unsigned int -hb_ucdn_eastasian_width(hb_unicode_funcs_t *ufuncs HB_UNUSED, - hb_codepoint_t unicode, - void *user_data HB_UNUSED) -{ - int w = ucdn_get_east_asian_width(unicode); - return (w == UCDN_EAST_ASIAN_F || w == UCDN_EAST_ASIAN_W) ? 2 : 1; -} +#define hb_ucdn_eastasian_width nullptr static hb_unicode_general_category_t hb_ucdn_general_category(hb_unicode_funcs_t *ufuncs HB_UNUSED, @@ -231,13 +224,7 @@ hb_ucdn_decompose(hb_unicode_funcs_t *ufuncs HB_UNUSED, return ucdn_decompose(ab, a, b); } -static unsigned int -hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs HB_UNUSED, - hb_codepoint_t u, hb_codepoint_t *decomposed, - void *user_data HB_UNUSED) -{ - return ucdn_compat_decompose(u, decomposed); -} +#define hb_ucdn_decompose_compatibility nullptr #ifdef HB_USE_ATEXIT diff --git a/src/hb-unicode.h b/src/hb-unicode.h index c8d87e4d1..62b58803a 100644 --- a/src/hb-unicode.h +++ b/src/hb-unicode.h @@ -230,9 +230,6 @@ hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs); typedef hb_unicode_combining_class_t (*hb_unicode_combining_class_func_t) (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode, void *user_data); -typedef unsigned int (*hb_unicode_eastasian_width_func_t) (hb_unicode_funcs_t *ufuncs, - hb_codepoint_t unicode, - void *user_data); typedef hb_unicode_general_category_t (*hb_unicode_general_category_func_t) (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode, void *user_data); @@ -254,32 +251,6 @@ typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs, hb_codepoint_t *b, void *user_data); -/** - * hb_unicode_decompose_compatibility_func_t: - * @ufuncs: a Unicode function structure - * @u: codepoint to decompose - * @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into - * @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func() - * - * Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed. - * The complete length of the decomposition will be returned. - * - * If @u has no compatibility decomposition, zero should be returned. - * - * The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any - * compatibility decomposition plus an terminating value of 0. Consequently, @decompose must be allocated by the caller to be at least this length. Implementations - * of this function type must ensure that they do not write past the provided array. - * - * Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available. - */ -typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_funcs_t *ufuncs, - hb_codepoint_t u, - hb_codepoint_t *decomposed, - void *user_data); - -/* See Unicode 6.1 for details on the maximum decomposition length. */ -#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */ - /* setters */ /** @@ -298,22 +269,6 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs, hb_unicode_combining_class_func_t func, void *user_data, hb_destroy_func_t destroy); -/** - * hb_unicode_funcs_set_eastasian_width_func: - * @ufuncs: a Unicode function structure - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * - * - * - * Since: 0.9.2 - **/ -HB_EXTERN void -hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs, - hb_unicode_eastasian_width_func_t func, - void *user_data, hb_destroy_func_t destroy); - /** * hb_unicode_funcs_set_general_category_func: * @ufuncs: a Unicode function structure @@ -394,22 +349,6 @@ hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs, hb_unicode_decompose_func_t func, void *user_data, hb_destroy_func_t destroy); -/** - * hb_unicode_funcs_set_decompose_compatibility_func: - * @ufuncs: a Unicode function structure - * @func: (closure user_data) (destroy destroy) (scope notified): - * @user_data: - * @destroy: - * - * - * - * Since: 0.9.2 - **/ -HB_EXTERN void -hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs, - hb_unicode_decompose_compatibility_func_t func, - void *user_data, hb_destroy_func_t destroy); - /* accessors */ /** @@ -421,15 +360,6 @@ HB_EXTERN hb_unicode_combining_class_t hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); -/** - * hb_unicode_eastasian_width: - * - * Since: 0.9.2 - **/ -HB_EXTERN unsigned int -hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs, - hb_codepoint_t unicode); - /** * hb_unicode_general_category: * @@ -469,11 +399,6 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, hb_codepoint_t *a, hb_codepoint_t *b); -HB_EXTERN unsigned int -hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, - hb_codepoint_t u, - hb_codepoint_t *decomposed); - HB_END_DECLS #endif /* HB_UNICODE_H */ diff --git a/test/api/test-unicode.c b/test/api/test-unicode.c index 4238ca992..6195bb286 100644 --- a/test/api/test-unicode.c +++ b/test/api/test-unicode.c @@ -160,69 +160,6 @@ static const test_pair_t combining_class_tests_more[] = { 0x111111, 0 } }; -static const test_pair_t eastasian_width_tests[] = -{ - /* Neutral */ - { 0x0000, 1 }, - { 0x0483, 1 }, - { 0x0641, 1 }, - { 0xFFFC, 1 }, - { 0x10000, 1 }, - { 0xE0001, 1 }, - - /* Narrow */ - { 0x0020, 1 }, - { 0x0041, 1 }, - { 0x27E6, 1 }, - - /* Halfwidth */ - { 0x20A9, 1 }, - { 0xFF61, 1 }, - { 0xFF69, 1 }, - { 0xFFEE, 1 }, - - /* Ambiguous */ - { 0x00A1, 1 }, - { 0x00D8, 1 }, - { 0x02DD, 1 }, - { 0xE0100, 1 }, - { 0x100000, 1 }, - - /* Fullwidth */ - { 0x3000, 2 }, - { 0xFF60, 2 }, - - /* Wide */ - { 0x2329, 2 }, - { 0x3001, 2 }, - { 0xFE69, 2 }, - { 0x30000, 2 }, - { 0x3FFFD, 2 }, - - { 0x111111, 1 } -}; -static const test_pair_t eastasian_width_tests_more[] = -{ - /* Default Wide blocks */ - { 0x4DBF, 2 }, - { 0x9FFF, 2 }, - { 0xFAFF, 2 }, - { 0x2A6DF, 2 }, - { 0x2B73F, 2 }, - { 0x2B81F, 2 }, - { 0x2FA1F, 2 }, - - /* Uniode-5.2 character additions */ - /* Wide */ - { 0x115F, 2 }, - - /* Uniode-6.0 character additions */ - /* Wide */ - { 0x2B740, 2 }, - { 0x1B000, 2 }, - - { 0x111111, 1 } -}; static const test_pair_t general_category_tests[] = { @@ -469,7 +406,6 @@ typedef struct { static const property_t properties[] = { PROPERTY (combining_class, 0), - PROPERTY (eastasian_width, 1), PROPERTY (general_category, (unsigned int) HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER), PROPERTY (mirroring, RETURNS_UNICODE_ITSELF), PROPERTY (script, (unsigned int) HB_SCRIPT_UNKNOWN) @@ -786,7 +722,6 @@ test_unicode_normalization (gconstpointer user_data) { hb_unicode_funcs_t *uf = (hb_unicode_funcs_t *) user_data; gunichar a, b, ab; - hb_codepoint_t decomposed[HB_UNICODE_MAX_DECOMPOSITION_LEN]; /* Test compose() */ @@ -849,56 +784,6 @@ test_unicode_normalization (gconstpointer user_data) g_assert (hb_unicode_decompose (uf, 0xD4CC, &a, &b) && a == 0x1111 && b == 0x1171); g_assert (hb_unicode_decompose (uf, 0xCE31, &a, &b) && a == 0xCE20 && b == 0x11B8); g_assert (hb_unicode_decompose (uf, 0xCE20, &a, &b) && a == 0x110E && b == 0x1173); - - - /* Test decompose_compatibility() */ - - /* Not decomposable */ - g_assert (hb_unicode_decompose_compatibility (uf, 0x0041, decomposed) == 0); - g_assert (hb_unicode_decompose_compatibility (uf, 0x1F632, decomposed) == 0); - - /* Singletons */ - g_assert (hb_unicode_decompose_compatibility (uf, 0x00B5, decomposed) == 1 && decomposed[0] == 0x03BC); - g_assert (hb_unicode_decompose_compatibility (uf, 0x03D6, decomposed) == 1 && decomposed[0] == 0x03C0); - - /* Arabic compatibility */ - g_assert (hb_unicode_decompose_compatibility (uf, 0xFB54, decomposed) == 1 && decomposed[0] == 0x067B); - - /* Longest decomposition ever */ - g_assert (18 <= HB_UNICODE_MAX_DECOMPOSITION_LEN); - g_assert (hb_unicode_decompose_compatibility (uf, 0xFDFA, decomposed) == 18 && decomposed[17] == 0x0645); - - /* Note: we deliberately don't test characters that have canonical decompositions but no - * compatibility decomposition against the decompose_compatibility() function as that we - * leave up to implementations (for now). */ - - /* Spaces */ - g_assert (hb_unicode_decompose_compatibility (uf, 0x2002, decomposed) == 1 && decomposed[0] == 0x0020); - g_assert (hb_unicode_decompose_compatibility (uf, 0x2003, decomposed) == 1 && decomposed[0] == 0x0020); - g_assert (hb_unicode_decompose_compatibility (uf, 0x2004, decomposed) == 1 && decomposed[0] == 0x0020); - g_assert (hb_unicode_decompose_compatibility (uf, 0x2005, decomposed) == 1 && decomposed[0] == 0x0020); - g_assert (hb_unicode_decompose_compatibility (uf, 0x2006, decomposed) == 1 && decomposed[0] == 0x0020); - g_assert (hb_unicode_decompose_compatibility (uf, 0x2008, decomposed) == 1 && decomposed[0] == 0x0020); - g_assert (hb_unicode_decompose_compatibility (uf, 0x2009, decomposed) == 1 && decomposed[0] == 0x0020); - g_assert (hb_unicode_decompose_compatibility (uf, 0x200A, decomposed) == 1 && decomposed[0] == 0x0020); - - /* Pairs */ - g_assert (hb_unicode_decompose_compatibility (uf, 0x0587, decomposed) == 2 && - decomposed[0] == 0x0565 && decomposed[1] == 0x0582); - g_assert (hb_unicode_decompose_compatibility (uf, 0x2017, decomposed) == 2 && - decomposed[0] == 0x0020 && decomposed[1] == 0x0333); - g_assert (hb_unicode_decompose_compatibility (uf, 0x2025, decomposed) == 2 && - decomposed[0] == 0x002E && decomposed[1] == 0x002E); - g_assert (hb_unicode_decompose_compatibility (uf, 0x2033, decomposed) == 2 && - decomposed[0] == 0x2032 && decomposed[1] == 0x2032); - - /* Triples */ - g_assert (hb_unicode_decompose_compatibility (uf, 0x2026, decomposed) == 3 && - decomposed[0] == 0x002E && decomposed[1] == 0x002E && decomposed[2] == 0x002E); - g_assert (hb_unicode_decompose_compatibility (uf, 0x2034, decomposed) == 3 && - decomposed[0] == 0x2032 && decomposed[1] == 0x2032 && decomposed[2] == 0x2032); - g_assert (hb_unicode_decompose_compatibility (uf, 0x213B, decomposed) == 3 && - decomposed[0] == 0x0046 && decomposed[1] == 0x0041 && decomposed[2] == 0x0058); } diff --git a/test/shaping/data/text-rendering-tests/DISABLED b/test/shaping/data/text-rendering-tests/DISABLED index 4e8b1cf24..8539c0ee1 100644 --- a/test/shaping/data/text-rendering-tests/DISABLED +++ b/test/shaping/data/text-rendering-tests/DISABLED @@ -1,6 +1,3 @@ -# https://github.com/harfbuzz/harfbuzz/issues/1224 -tests/MORX-35.tests - # Non-Unicode cmap tests/CMAP-3.tests diff --git a/test/shaping/data/text-rendering-tests/Makefile.sources b/test/shaping/data/text-rendering-tests/Makefile.sources index 5a3d20a6c..c7f487600 100644 --- a/test/shaping/data/text-rendering-tests/Makefile.sources +++ b/test/shaping/data/text-rendering-tests/Makefile.sources @@ -55,6 +55,7 @@ TESTS = \ tests/MORX-32.tests \ tests/MORX-33.tests \ tests/MORX-34.tests \ + tests/MORX-35.tests \ tests/MORX-36.tests \ tests/MORX-37.tests \ tests/MORX-38.tests \ @@ -73,7 +74,6 @@ TESTS = \ DISBALED_TESTS = \ tests/CMAP-3.tests \ - tests/MORX-35.tests \ tests/SHARAN-1.tests \ tests/SHBALI-1.tests \ tests/SHBALI-2.tests \ diff --git a/test/shaping/data/text-rendering-tests/tests/MORX-35.tests b/test/shaping/data/text-rendering-tests/tests/MORX-35.tests index 616b2f9b8..a0331852e 100644 --- a/test/shaping/data/text-rendering-tests/tests/MORX-35.tests +++ b/test/shaping/data/text-rendering-tests/tests/MORX-35.tests @@ -1,2 +1,2 @@ -../fonts/TestMORXThirtyfive.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0041:[A|B@639,0|E@1265,0|C@1821,0|E@2417,0] -../fonts/TestMORXThirtyfive.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0041,U+0059:[X|A@586,0|B@1225,0|E@1851,0|C@2407,0|E@3003,0|Y@3559,0] +../fonts/TestMORXThirtyfive.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0041:[A|B@639,0|C@1265,0|E@1861,0] +../fonts/TestMORXThirtyfive.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0041,U+0059:[X|A@586,0|B@1225,0|C@1851,0|E@2447,0|Y@3003,0]