diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2018-11-19 04:05:47 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2018-11-19 04:05:47 +0000 |
commit | a0f9dd8213083d3021d12beceb451325ee8fce30 (patch) | |
tree | c3de2c62a20cf8b71dbe6d968f463e8c5b76fc26 /Build/source/libs/harfbuzz/harfbuzz-src/src | |
parent | a34ffc9669bd1c626c01adc0292ee625b3ad16de (diff) |
harfbuzz-2.1.3
git-svn-id: svn://tug.org/texlive/trunk@49193 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src')
90 files changed, 3480 insertions, 3033 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am index fbd8f60237c..b3cc42f3f84 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.am @@ -15,7 +15,6 @@ check_PROGRAMS = # Convenience targets: lib: $(BUILT_SOURCES) libharfbuzz.la libs: $(BUILT_SOURCES) $(lib_LTLIBRARIES) -fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la lib_LTLIBRARIES = libharfbuzz.la @@ -169,36 +168,6 @@ pkginclude_HEADERS += $(HB_SUBSET_headers) pkgconfig_DATA += harfbuzz-subset.pc EXTRA_DIST += harfbuzz-subset.pc.in -FUZZING_CPPFLAGS = \ - -DHB_MAX_NESTING_LEVEL=3 \ - -DHB_SANITIZE_MAX_EDITS=3 \ - -DHB_SANITIZE_MAX_OPS_FACTOR=3 \ - -DHB_SANITIZE_MAX_OPS_MIN=128 \ - -DHB_BUFFER_MAX_LEN_FACTOR=3 \ - -DHB_BUFFER_MAX_LEN_MIN=8 \ - -DHB_BUFFER_MAX_LEN_DEFAULT=128 \ - -DHB_BUFFER_MAX_OPS_FACTOR=8 \ - -DHB_BUFFER_MAX_OPS_MIN=64 \ - -DHB_BUFFER_MAX_OPS_DEFAULT=1024 \ - $(NULL) -EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la - -libharfbuzz_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_fuzzing_la_LDFLAGS) -libharfbuzz_fuzzing_la_SOURCES = $(libharfbuzz_la_SOURCES) -libharfbuzz_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS) -libharfbuzz_fuzzing_la_LDFLAGS = $(AM_LDFLAGS) -libharfbuzz_fuzzing_la_LIBADD = $(libharfbuzz_la_LIBADD) -EXTRA_libharfbuzz_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_la_DEPENDENCIES) -CLEANFILES += libharfbuzz-fuzzing.la - -libharfbuzz_subset_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_subset_fuzzing_la_LDFLAGS) -libharfbuzz_subset_fuzzing_la_SOURCES = $(libharfbuzz_subset_la_SOURCES) -libharfbuzz_subset_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS) -libharfbuzz_subset_fuzzing_la_LDFLAGS = $(AM_LDFLAGS) -libharfbuzz_subset_fuzzing_la_LIBADD = $(libharfbuzz_subset_la_LIBADD) -EXTRA_libharfbuzz_subset_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_subset_la_DEPENDENCIES) -CLEANFILES += libharfbuzz-subset-fuzzing.la - if HAVE_ICU if HAVE_ICU_BUILTIN HBCFLAGS += $(ICU_CFLAGS) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources index 561fbed6d36..3dcd771f4b5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/Makefile.sources @@ -16,6 +16,7 @@ HB_BASE_sources = \ hb-font.hh \ hb-font.cc \ hb-iter.hh \ + hb-kern.hh \ hb-map.hh \ hb-map.cc \ hb-machinery.hh \ @@ -99,7 +100,9 @@ HB_OT_sources = \ hb-aat-layout-ankr-table.hh \ hb-aat-layout-bsln-table.hh \ hb-aat-layout-feat-table.hh \ + hb-aat-layout-just-table.hh \ hb-aat-layout-kerx-table.hh \ + hb-aat-layout-lcar-table.hh \ hb-aat-layout-morx-table.hh \ hb-aat-layout-trak-table.hh \ hb-aat-layout.hh \ @@ -155,6 +158,7 @@ HB_OT_sources = \ hb-ot-shape-fallback.hh \ hb-ot-shape-fallback.cc \ hb-ot-shape.hh \ + hb-ot-stat-table.hh \ hb-ot-var.cc \ hb-ot-var-avar-table.hh \ hb-ot-var-fvar-table.hh \ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py index ebfae6fab8f..a8a7a23261b 100755 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/gen-use-table.py @@ -200,7 +200,8 @@ def is_HALANT(U, UISC, UGC): return UISC in [Virama, Invisible_Stacker] and not is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UGC) def is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UGC): # https://github.com/harfbuzz/harfbuzz/issues/1102 - return U == 0x11046 + # https://github.com/harfbuzz/harfbuzz/issues/1379 + return U in [0x11046, 0x1134D] def is_HALANT_NUM(U, UISC, UGC): return UISC == Number_Joiner def is_ZWNJ(U, UISC, UGC): diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh index ee2136ed972..6572b26d86f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-common.hh @@ -58,6 +58,11 @@ struct LookupFormat0 TRACE_SANITIZE (this); return_trace (arrayZ.sanitize (c, c->get_num_glyphs ())); } + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (arrayZ.sanitize (c, c->get_num_glyphs (), base)); + } protected: HBUINT16 format; /* Format identifier--format = 0 */ @@ -80,6 +85,11 @@ struct LookupSegmentSingle TRACE_SANITIZE (this); return_trace (c->check_struct (this) && value.sanitize (c)); } + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && value.sanitize (c, base)); + } GlyphID last; /* Last GlyphID in this segment */ GlyphID first; /* First GlyphID in this segment */ @@ -105,6 +115,11 @@ struct LookupFormat2 TRACE_SANITIZE (this); return_trace (segments.sanitize (c)); } + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (segments.sanitize (c, base)); + } protected: HBUINT16 format; /* Format identifier--format = 2 */ @@ -135,6 +150,14 @@ struct LookupSegmentArray first <= last && valuesZ.sanitize (c, base, last - first + 1)); } + template <typename T2> + inline bool sanitize (hb_sanitize_context_t *c, const void *base, T2 user_data) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + first <= last && + valuesZ.sanitize (c, base, last - first + 1, user_data)); + } GlyphID last; /* Last GlyphID in this segment */ GlyphID first; /* First GlyphID in this segment */ @@ -162,6 +185,11 @@ struct LookupFormat4 TRACE_SANITIZE (this); return_trace (segments.sanitize (c, this)); } + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (segments.sanitize (c, this, base)); + } protected: HBUINT16 format; /* Format identifier--format = 4 */ @@ -183,6 +211,11 @@ struct LookupSingle TRACE_SANITIZE (this); return_trace (c->check_struct (this) && value.sanitize (c)); } + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && value.sanitize (c, base)); + } GlyphID glyph; /* Last GlyphID */ T value; /* The lookup value (only one) */ @@ -207,6 +240,11 @@ struct LookupFormat6 TRACE_SANITIZE (this); return_trace (entries.sanitize (c)); } + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (entries.sanitize (c, base)); + } protected: HBUINT16 format; /* Format identifier--format = 6 */ @@ -233,6 +271,11 @@ struct LookupFormat8 TRACE_SANITIZE (this); return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount)); } + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount, base)); + } protected: HBUINT16 format; /* Format identifier--format = 8 */ @@ -328,6 +371,20 @@ struct Lookup default:return_trace (true); } } + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + if (!u.format.sanitize (c)) return_trace (false); + switch (u.format) { + case 0: return_trace (u.format0.sanitize (c, base)); + case 2: return_trace (u.format2.sanitize (c, base)); + case 4: return_trace (u.format4.sanitize (c, base)); + case 6: return_trace (u.format6.sanitize (c, base)); + case 8: return_trace (u.format8.sanitize (c, base)); + case 10: return_trace (false); /* No need to support format10 apparently */ + default:return_trace (true); + } + } protected: union { @@ -365,7 +422,7 @@ namespace AAT { enum { DELETED_GLYPH = 0xFFFF }; /* - * Extended State Table + * (Extended) State Table */ template <typename T> @@ -430,13 +487,13 @@ struct StateTable CLASS_END_OF_LINE = 3, }; - inline unsigned int new_state (unsigned int newState) const - { return Types::extended ? newState : (newState - stateArrayTable) / nClasses; } + inline int new_state (unsigned int newState) const + { return Types::extended ? newState : ((int) newState - (int) stateArrayTable) / nClasses; } inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const { if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH; - return (this+classTable).get_class (glyph_id, num_glyphs); + return (this+classTable).get_class (glyph_id, num_glyphs, 1); } inline const Entry<Extra> *get_entries () const @@ -444,7 +501,7 @@ struct StateTable return (this+entryTable).arrayZ; } - inline const Entry<Extra> *get_entryZ (unsigned int state, unsigned int klass) const + inline const Entry<Extra> *get_entryZ (int state, unsigned int klass) const { if (unlikely (klass >= nClasses)) return nullptr; @@ -452,6 +509,7 @@ struct StateTable const Entry<Extra> *entries = (this+entryTable).arrayZ; unsigned int entry = states[state * nClasses + klass]; + DEBUG_MSG (APPLY, nullptr, "e%u", entry); return &entries[entry]; } @@ -467,28 +525,73 @@ struct StateTable const Entry<Extra> *entries = (this+entryTable).arrayZ; unsigned int num_classes = nClasses; + if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size))) + return_trace (false); + unsigned int row_stride = num_classes * states[0].static_size; - unsigned int num_states = 1; + /* Apple 'kern' table has this peculiarity: + * + * "Because the stateTableOffset in the state table header is (strictly + * speaking) redundant, some 'kern' tables use it to record an initial + * state where that should not be StartOfText. To determine if this is + * done, calculate what the stateTableOffset should be. If it's different + * from the actual stateTableOffset, use it as the initial state." + * + * We implement this by calling the initial state zero, but allow *negative* + * states if the start state indeed was not the first state. Since the code + * is shared, this will also apply to 'mort' table. The 'kerx' / 'morx' + * tables are not affected since those address states by index, not offset. + */ + + int min_state = 0; + int max_state = 0; unsigned int num_entries = 0; - unsigned int state = 0; + int state_pos = 0; + int state_neg = 0; unsigned int entry = 0; - while (state < num_states) + while (min_state < state_neg || state_pos <= max_state) { - if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size))) - return_trace (false); + if (min_state < state_neg) + { + /* Negative states. */ + if (unlikely (hb_unsigned_mul_overflows (min_state, num_classes))) + return_trace (false); + if (unlikely (!c->check_range (&states[min_state * num_classes], + -min_state, + row_stride))) + return_trace (false); + if ((c->max_ops -= state_neg - min_state) < 0) + return_trace (false); + { /* Sweep new states. */ + const HBUSHORT *stop = &states[min_state * num_classes]; + if (unlikely (stop > states)) + return_trace (false); + for (const HBUSHORT *p = states; stop < p; p--) + num_entries = MAX<unsigned int> (num_entries, *(p - 1) + 1); + state_neg = min_state; + } + } - if (unlikely (!c->check_array (states, - num_states, - num_classes * states[0].static_size))) - return_trace (false); - if ((c->max_ops -= num_states - state) < 0) - return_trace (false); - { /* Sweep new states. */ - const HBUSHORT *stop = &states[num_states * num_classes]; - for (const HBUSHORT *p = &states[state * num_classes]; p < stop; p++) - num_entries = MAX<unsigned int> (num_entries, *p + 1); - state = num_states; + if (state_pos <= max_state) + { + /* Positive states. */ + if (unlikely (!c->check_range (states, + max_state + 1, + row_stride))) + return_trace (false); + if ((c->max_ops -= max_state - state_pos + 1) < 0) + return_trace (false); + { /* Sweep new states. */ + if (unlikely (hb_unsigned_mul_overflows ((max_state + 1), num_classes))) + return_trace (false); + const HBUSHORT *stop = &states[(max_state + 1) * num_classes]; + if (unlikely (stop < states)) + return_trace (false); + for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++) + num_entries = MAX<unsigned int> (num_entries, *p + 1); + state_pos = max_state + 1; + } } if (unlikely (!c->check_array (entries, num_entries))) @@ -499,8 +602,9 @@ struct StateTable const Entry<Extra> *stop = &entries[num_entries]; for (const Entry<Extra> *p = &entries[entry]; p < stop; p++) { - unsigned int newState = new_state (p->newState); - num_states = MAX<unsigned int> (num_states, newState + 1); + int newState = new_state (p->newState); + min_state = MIN (min_state, newState); + max_state = MAX (max_state, newState); } entry = num_entries; } @@ -528,36 +632,36 @@ struct StateTable struct ClassTable { - inline unsigned int get_class (hb_codepoint_t glyph_id) const + inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int outOfRange) const { - return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ? classArrayZ[glyph_id - firstGlyph] : 1; + unsigned int i = glyph_id - firstGlyph; + return i >= classArray.len ? outOfRange : classArray.arrayZ[i]; } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && classArrayZ.sanitize (c, glyphCount)); + return_trace (c->check_struct (this) && classArray.sanitize (c)); } protected: - GlyphID firstGlyph; /* First glyph index included in the trimmed array. */ - HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last - * glyph minus the value of firstGlyph plus 1). */ - UnsizedArrayOf<HBUINT8> - classArrayZ; /* The class codes (indexed by glyph index minus - * firstGlyph). */ + GlyphID firstGlyph; /* First glyph index included in the trimmed array. */ + ArrayOf<HBUINT8> classArray; /* The class codes (indexed by glyph index minus + * firstGlyph). */ public: - DEFINE_SIZE_ARRAY (4, classArrayZ); + DEFINE_SIZE_ARRAY (4, classArray); }; -struct MortTypes +struct ObsoleteTypes { static const bool extended = false; typedef HBUINT16 HBUINT; typedef HBUINT8 HBUSHORT; struct ClassType : ClassTable { - inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs HB_UNUSED) const + inline unsigned int get_class (hb_codepoint_t glyph_id, + unsigned int num_glyphs HB_UNUSED, + unsigned int outOfRange) const { - return ClassTable::get_class (glyph_id); + return ClassTable::get_class (glyph_id, outOfRange); } }; template <typename T> @@ -575,17 +679,19 @@ struct MortTypes return offsetToIndex (2 * offset, base, array); } }; -struct MorxTypes +struct ExtendedTypes { static const bool extended = true; typedef HBUINT32 HBUINT; typedef HBUINT16 HBUSHORT; struct ClassType : Lookup<HBUINT16> { - inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const + inline unsigned int get_class (hb_codepoint_t glyph_id, + unsigned int num_glyphs, + unsigned int outOfRange) const { const HBUINT16 *v = get_value (glyph_id, num_glyphs); - return v ? *v : 1; + return v ? *v : outOfRange; } }; template <typename T> @@ -620,13 +726,14 @@ struct StateTableDriver if (!c->in_place) buffer->clear_output (); - unsigned int state = StateTable<Types, EntryData>::STATE_START_OF_TEXT; + int state = StateTable<Types, EntryData>::STATE_START_OF_TEXT; bool last_was_dont_advance = false; for (buffer->idx = 0; buffer->successful;) { unsigned int klass = buffer->idx < buffer->len ? machine.get_class (buffer->info[buffer->idx].codepoint, num_glyphs) : (unsigned) StateTable<Types, EntryData>::CLASS_END_OF_TEXT; + DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx); const Entry<EntryData> *entry = machine.get_entryZ (state, klass); if (unlikely (!entry)) break; @@ -659,6 +766,7 @@ struct StateTableDriver last_was_dont_advance = (entry->flags & context_t::DontAdvance) && buffer->max_ops-- > 0; state = machine.new_state (entry->newState); + DEBUG_MSG (APPLY, nullptr, "s%d", state); if (buffer->idx == buffer->len) break; @@ -693,7 +801,7 @@ struct hb_aat_apply_context_t : static return_t default_return_value (void) { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } - hb_ot_shape_plan_t *plan; + const hb_ot_shape_plan_t *plan; hb_font_t *font; hb_face_t *face; hb_buffer_t *buffer; @@ -705,7 +813,7 @@ struct hb_aat_apply_context_t : unsigned int lookup_index; unsigned int debug_depth; - HB_INTERNAL hb_aat_apply_context_t (hb_ot_shape_plan_t *plan_, + HB_INTERNAL hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_, hb_font_t *font_, hb_buffer_t *buffer_, hb_blob_t *blob = const_cast<hb_blob_t *> (&Null(hb_blob_t))); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh index b670caab83b..87ab4abd3f0 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-feat-table.hh @@ -54,13 +54,6 @@ struct SettingName struct FeatureName { - inline bool sanitize (hb_sanitize_context_t *c, const void *base) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - (base+settingTable).sanitize (c, nSettings))); - } - enum { Exclusive = 0x8000, /* If set, the feature settings are mutually exclusive. */ NotDefault = 0x4000, /* If clear, then the setting with an index of 0 in @@ -75,6 +68,13 @@ struct FeatureName * as the default. */ }; + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + (base+settingTable).sanitize (c, nSettings))); + } + protected: HBUINT16 feature; /* Feature type. */ HBUINT16 nSettings; /* The number of records in the setting name array. */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh new file mode 100644 index 00000000000..92ca6603e16 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-just-table.hh @@ -0,0 +1,417 @@ +/* + * 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_AAT_LAYOUT_JUST_TABLE_HH +#define HB_AAT_LAYOUT_JUST_TABLE_HH + +#include "hb-aat-layout-common.hh" +#include "hb-ot-layout.hh" +#include "hb-open-type.hh" + +#include "hb-aat-layout-morx-table.hh" + +/* + * just -- Justification + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6just.html + */ +#define HB_AAT_TAG_just HB_TAG('j','u','s','t') + + +namespace AAT { + +using namespace OT; + + +struct ActionSubrecordHeader +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + HBUINT16 actionClass; /* The JustClass value associated with this + * ActionSubrecord. */ + HBUINT16 actionType; /* The type of postcompensation action. */ + HBUINT16 actionLength; /* Length of this ActionSubrecord record, which + * must be a multiple of 4. */ + public: + DEFINE_SIZE_STATIC (6); +}; + +struct DecompositionAction +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + ActionSubrecordHeader + header; + Fixed lowerLimit; /* If the distance factor is less than this value, + * then the ligature is decomposed. */ + Fixed upperLimit; /* If the distance factor is greater than this value, + * then the ligature is decomposed. */ + HBUINT16 order; /* Numerical order in which this ligature will + * be decomposed; you may want infrequent ligatures + * to decompose before more frequent ones. The ligatures + * on the line of text will decompose in increasing + * value of this field. */ + ArrayOf<HBUINT16> + decomposedglyphs; + /* Number of 16-bit glyph indexes that follow; + * the ligature will be decomposed into these glyphs. + * + * Array of decomposed glyphs. */ + public: + DEFINE_SIZE_ARRAY (18, decomposedglyphs); +}; + +struct UnconditionalAddGlyphAction +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + ActionSubrecordHeader + header; + GlyphID addGlyph; /* Glyph that should be added if the distance factor + * is growing. */ + + public: + DEFINE_SIZE_STATIC (8); +}; + +struct ConditionalAddGlyphAction +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + protected: + ActionSubrecordHeader + header; + Fixed substThreshold; /* Distance growth factor (in ems) at which + * this glyph is replaced and the growth factor + * recalculated. */ + GlyphID addGlyph; /* Glyph to be added as kashida. If this value is + * 0xFFFF, no extra glyph will be added. Note that + * generally when a glyph is added, justification + * will need to be redone. */ + GlyphID substGlyph; /* Glyph to be substituted for this glyph if the + * growth factor equals or exceeds the value of + * substThreshold. */ + public: + DEFINE_SIZE_STATIC (14); +}; + +struct DuctileGlyphAction +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + protected: + ActionSubrecordHeader + header; + HBUINT32 variationAxis; /* The 4-byte tag identifying the ductile axis. + * This would normally be 0x64756374 ('duct'), + * but you may use any axis the font contains. */ + Fixed minimumLimit; /* The lowest value for the ductility axis tha + * still yields an acceptable appearance. Normally + * this will be 1.0. */ + Fixed noStretchValue; /* This is the default value that corresponds to + * no change in appearance. Normally, this will + * be 1.0. */ + Fixed maximumLimit; /* The highest value for the ductility axis that + * still yields an acceptable appearance. */ + public: + DEFINE_SIZE_STATIC (22); +}; + +struct RepeatedAddGlyphAction +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + protected: + ActionSubrecordHeader + header; + HBUINT16 flags; /* Currently unused; set to 0. */ + GlyphID glyph; /* Glyph that should be added if the distance factor + * is growing. */ + public: + DEFINE_SIZE_STATIC (10); +}; + +struct ActionSubrecord +{ + inline unsigned int get_length (void) const { return u.header.actionLength; } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (unlikely (!c->check_struct (this))) + return_trace (false); + + switch (u.header.actionType) + { + case 0: return_trace (u.decompositionAction.sanitize (c)); + case 1: return_trace (u.unconditionalAddGlyphAction.sanitize (c)); + case 2: return_trace (u.conditionalAddGlyphAction.sanitize (c)); + // case 3: return_trace (u.stretchGlyphAction.sanitize (c)); + case 4: return_trace (u.decompositionAction.sanitize (c)); + case 5: return_trace (u.decompositionAction.sanitize (c)); + default: return_trace (true); + } + } + + protected: + union { + ActionSubrecordHeader header; + DecompositionAction decompositionAction; + UnconditionalAddGlyphAction unconditionalAddGlyphAction; + ConditionalAddGlyphAction conditionalAddGlyphAction; + /* StretchGlyphAction stretchGlyphAction; -- Not supported by CoreText */ + DuctileGlyphAction ductileGlyphAction; + RepeatedAddGlyphAction repeatedAddGlyphAction; + } u; /* Data. The format of this data depends on + * the value of the actionType field. */ + public: + DEFINE_SIZE_UNION (6, header); +}; + +struct PostcompensationActionChain +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (unlikely (!c->check_struct (this))) + return_trace (false); + + unsigned int offset = min_size; + for (unsigned int i = 0; i < count; i++) + { + const ActionSubrecord& subrecord = StructAtOffset<ActionSubrecord> (this, offset); + if (unlikely (!subrecord.sanitize (c))) return_trace (false); + offset += subrecord.get_length (); + } + + return_trace (true); + } + + protected: + HBUINT32 count; + + public: + DEFINE_SIZE_STATIC (4); +}; + +struct JustWidthDeltaEntry +{ + enum Flags + { + Reserved1 =0xE000,/* Reserved. You should set these bits to zero. */ + UnlimiteGap =0x1000,/* The glyph can take unlimited gap. When this + * glyph participates in the justification process, + * it and any other glyphs on the line having this + * bit set absorb all the remaining gap. */ + Reserved2 =0x0FF0,/* Reserved. You should set these bits to zero. */ + Priority =0x000F /* The justification priority of the glyph. */ + }; + + enum Priority + { + Kashida = 0, /* Kashida priority. This is the highest priority + * during justification. */ + Whitespace = 1, /* Whitespace priority. Any whitespace glyphs (as + * identified in the glyph properties table) will + * get this priority. */ + InterCharacter = 2, /* Inter-character priority. Give this to any + * remaining glyphs. */ + NullPriority = 3 /* Null priority. You should set this priority for + * glyphs that only participate in justification + * after the above priorities. Normally all glyphs + * have one of the previous three values. If you + * don't want a glyph to participate in justification, + * and you don't want to set its factors to zero, + * you may instead assign it to the null priority. */ + }; + + protected: + Fixed beforeGrowLimit;/* The ratio by which the advance width of the + * glyph is permitted to grow on the left or top side. */ + Fixed beforeShrinkLimit; + /* The ratio by which the advance width of the + * glyph is permitted to shrink on the left or top side. */ + Fixed afterGrowLimit; /* The ratio by which the advance width of the glyph + * is permitted to shrink on the left or top side. */ + Fixed afterShrinkLimit; + /* The ratio by which the advance width of the glyph + * is at most permitted to shrink on the right or + * bottom side. */ + HBUINT16 growFlags; /* Flags controlling the grow case. */ + HBUINT16 shrinkFlags; /* Flags controlling the shrink case. */ + + public: + DEFINE_SIZE_STATIC (20); +}; + +struct WidthDeltaPair +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + protected: + HBUINT32 justClass; /* The justification category associated + * with the wdRecord field. Only 7 bits of + * this field are used. (The other bits are + * used as padding to guarantee longword + * alignment of the following record). */ + JustWidthDeltaEntry + wdRecord; /* The actual width delta record. */ + + public: + DEFINE_SIZE_STATIC (24); +}; + +typedef OT::LArrayOf<WidthDeltaPair> WidthDeltaCluster; + +struct JustificationCategory +{ + typedef void EntryData; + + enum Flags + { + SetMark =0x8000,/* If set, make the current glyph the marked + * glyph. */ + DontAdvance =0x4000,/* If set, don't advance to the next glyph before + * going to the new state. */ + MarkCategory =0x3F80,/* The justification category for the marked + * glyph if nonzero. */ + CurrentCategory =0x007F /* The justification category for the current + * glyph if nonzero. */ + }; + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + morphHeader.sanitize (c) && + stHeader.sanitize (c))); + } + + protected: + ChainSubtable<ObsoleteTypes> + morphHeader; /* Metamorphosis-style subtable header. */ + StateTable<ObsoleteTypes, EntryData> + stHeader; /* The justification insertion state table header */ + public: + DEFINE_SIZE_STATIC (30); +}; + +struct JustificationHeader +{ + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + justClassTable.sanitize (c, base, base) && + wdcTable.sanitize (c, base) && + pcTable.sanitize (c, base) && + lookupTable.sanitize (c, base))); + } + + protected: + OffsetTo<JustificationCategory> + justClassTable; /* Offset to the justification category state table. */ + OffsetTo<WidthDeltaCluster> + wdcTable; /* Offset from start of justification table to start + * of the subtable containing the width delta factors + * for the glyphs in your font. + * + * The width delta clusters table. */ + OffsetTo<PostcompensationActionChain> + pcTable; /* Offset from start of justification table to start + * of postcompensation subtable (set to zero if none). + * + * The postcompensation subtable, if present in the font. */ + Lookup<OffsetTo<WidthDeltaCluster> > + lookupTable; /* Lookup table associating glyphs with width delta + * clusters. See the description of Width Delta Clusters + * table for details on how to interpret the lookup values. */ + + public: + DEFINE_SIZE_MIN (8); +}; + +struct just +{ + static const hb_tag_t tableTag = HB_AAT_TAG_just; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + + return_trace (likely (c->check_struct (this) && + version.major == 1 && + horizData.sanitize (c, this, this) && + vertData.sanitize (c, this, this))); + } + + protected: + FixedVersion<>version; /* Version of the justification table + * (0x00010000u for version 1.0). */ + HBUINT16 format; /* Format of the justification table (set to 0). */ + OffsetTo<JustificationHeader> + horizData; /* Byte offset from the start of the justification table + * to the header for tables that contain justification + * information for horizontal text. + * If you are not including this information, + * store 0. */ + OffsetTo<JustificationHeader> + vertData; /* ditto, vertical */ + + public: + DEFINE_SIZE_STATIC (10); +}; + +} /* namespace AAT */ + + +#endif /* HB_AAT_LAYOUT_JUST_TABLE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh index d2242c5496e..f075a270a6b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-kerx-table.hh @@ -28,10 +28,8 @@ #ifndef HB_AAT_LAYOUT_KERX_TABLE_HH #define HB_AAT_LAYOUT_KERX_TABLE_HH -#include "hb-open-type.hh" -#include "hb-aat-layout-common.hh" -#include "hb-ot-layout-gpos-table.hh" -#include "hb-ot-kern-table.hh" +#include "hb-kern.hh" +#include "hb-aat-layout-ankr-table.hh" /* * kerx -- Extended Kerning @@ -55,29 +53,54 @@ kerxTupleKern (int value, unsigned int offset = value; const FWORD *pv = &StructAtOffset<FWORD> (base, offset); - if (unlikely (!pv->sanitize (&c->sanitizer))) return 0; + if (unlikely (!c->sanitizer.check_array (pv, tupleCount))) return 0; return *pv; } -struct KerxSubTableHeader +struct hb_glyph_pair_t { + hb_codepoint_t left; + hb_codepoint_t right; +}; + +struct KernPair +{ + inline int get_kerning (void) const + { return value; } + + inline int cmp (const hb_glyph_pair_t &o) const + { + int ret = left.cmp (o.left); + if (ret) return ret; + return right.cmp (o.right); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } + protected: + GlyphID left; + GlyphID right; + FWORD value; public: - HBUINT32 length; - HBUINT32 coverage; - HBUINT32 tupleCount; - public: - DEFINE_SIZE_STATIC (12); + DEFINE_SIZE_STATIC (6); }; +template <typename KernSubTableHeader> struct KerxSubTableFormat0 { + 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, hb_aat_apply_context_t *c) const { @@ -85,7 +108,7 @@ struct KerxSubTableFormat0 int i = pairs.bsearch (pair); if (i == -1) return 0; int v = pairs[i].get_kerning (); - return kerxTupleKern (v, header.tupleCount, this, c); + return kerxTupleKern (v, header.tuple_count (), this, c); } inline bool apply (hb_aat_apply_context_t *c) const @@ -95,8 +118,11 @@ struct KerxSubTableFormat0 if (!c->plan->requested_kerning) return false; + if (header.coverage & header.Backwards) + return false; + accelerator_t accel (*this, c); - hb_kern_machine_t<accelerator_t> machine (accel); + hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream); machine.kern (c->font, c->buffer, c->plan->kern_mask); return_trace (true); @@ -119,20 +145,33 @@ struct KerxSubTableFormat0 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - pairs.sanitize (c))); + return_trace (likely (pairs.sanitize (c))); } protected: - KerxSubTableHeader header; - BinSearchArrayOf<KernPair, HBUINT32> + KernSubTableHeader header; + BinSearchArrayOf<KernPair, typename KernSubTableHeader::Types::HBUINT> pairs; /* Sorted kern records. */ public: - DEFINE_SIZE_ARRAY (28, pairs); + DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 16, pairs); }; -struct KerxSubTableFormat1 + +template <bool extended> +struct Format1Entry; + +template <> +struct Format1Entry<true> { + enum Flags + { + Push = 0x8000, /* If set, push this glyph on the kerning stack. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph + * before going to the new state. */ + Reset = 0x2000, /* If set, reset the kerning data (clear the stack) */ + Reserved = 0x1FFF, /* Not used; set to 0. */ + }; + struct EntryData { HBUINT16 kernActionIndex;/* Index into the kerning value array. If @@ -142,44 +181,78 @@ struct KerxSubTableFormat1 DEFINE_SIZE_STATIC (2); }; + static inline bool performAction (const Entry<EntryData> *entry) + { return entry->data.kernActionIndex != 0xFFFF; } + + static inline unsigned int kernActionIndex (const Entry<EntryData> *entry) + { return entry->data.kernActionIndex; } +}; +template <> +struct Format1Entry<false> +{ + enum Flags + { + Push = 0x8000, /* If set, push this glyph on the kerning stack. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph + * before going to the new state. */ + Offset = 0x3FFF, /* Byte offset from beginning of subtable to the + * value table for the glyphs on the kerning stack. */ + + Reset = 0x0000, /* Not supported? */ + }; + + typedef void EntryData; + + static inline bool performAction (const Entry<EntryData> *entry) + { return entry->flags & Offset; } + + static inline unsigned int kernActionIndex (const Entry<EntryData> *entry) + { return entry->flags & Offset; } +}; + +template <typename KernSubTableHeader> +struct KerxSubTableFormat1 +{ + typedef typename KernSubTableHeader::Types Types; + typedef typename Types::HBUINT HBUINT; + + typedef Format1Entry<Types::extended> Format1EntryT; + typedef typename Format1EntryT::EntryData EntryData; + struct driver_context_t { static const bool in_place = true; - enum Flags + enum { - Push = 0x8000, /* If set, push this glyph on the kerning stack. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph - * before going to the new state. */ - Reset = 0x2000, /* If set, reset the kerning data (clear the stack) */ - Reserved = 0x1FFF, /* Not used; set to 0. */ + DontAdvance = Format1EntryT::DontAdvance, }; - inline driver_context_t (const KerxSubTableFormat1 *table, + inline driver_context_t (const KerxSubTableFormat1 *table_, hb_aat_apply_context_t *c_) : c (c_), + table (table_), /* Apparently the offset kernAction is from the beginning of the state-machine, * similar to offsets in morx table, NOT from beginning of this table, like * other subtables in kerx. Discovered via testing. */ kernAction (&table->machine + table->kernAction), - depth (0) {} + depth (0), + crossStream (table->header.coverage & table->header.CrossStream) {} - inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver HB_UNUSED, + inline bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED, const Entry<EntryData> *entry) { - return entry->data.kernActionIndex != 0xFFFF; + return Format1EntryT::performAction (entry); } - inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver, + inline bool transition (StateTableDriver<Types, EntryData> *driver, const Entry<EntryData> *entry) { hb_buffer_t *buffer = driver->buffer; unsigned int flags = entry->flags; - if (flags & Reset) - { + if (flags & Format1EntryT::Reset) depth = 0; - } - if (flags & Push) + if (flags & Format1EntryT::Push) { if (likely (depth < ARRAY_LENGTH (stack))) stack[depth++] = buffer->idx; @@ -187,41 +260,90 @@ struct KerxSubTableFormat1 depth = 0; /* Probably not what CoreText does, but better? */ } - if (entry->data.kernActionIndex != 0xFFFF) + if (Format1EntryT::performAction (entry) && depth) { - const FWORD *actions = &kernAction[entry->data.kernActionIndex]; - if (!c->sanitizer.check_array (actions, depth)) + unsigned int tuple_count = MAX (1u, table->header.tuple_count ()); + + unsigned int kern_idx = Format1EntryT::kernActionIndex (entry); + kern_idx = Types::offsetToIndex (kern_idx, &table->machine, kernAction.arrayZ); + const FWORD *actions = &kernAction[kern_idx]; + if (!c->sanitizer.check_array (actions, depth, tuple_count)) { depth = 0; return false; } hb_mask_t kern_mask = c->plan->kern_mask; - for (unsigned int i = 0; i < depth; i++) + + /* From Apple 'kern' spec: + * "Each pops one glyph from the kerning stack and applies the kerning value to it. + * The end of the list is marked by an odd value... */ + bool last = false; + while (!last && depth) { - /* Apparently, when spec says "Each pops one glyph from the kerning stack - * and applies the kerning value to it.", it doesn't mean it in that order. - * The deepest item in the stack corresponds to the first item in the action - * list. Discovered by testing. */ - unsigned int idx = stack[i]; - int v = *actions++; - if (idx < buffer->len && buffer->info[idx].mask & kern_mask) + unsigned int idx = stack[--depth]; + int v = *actions; + actions += tuple_count; + if (idx >= buffer->len) continue; + + /* "The end of the list is marked by an odd value..." */ + last = v & 1; + v &= ~1; + + hb_glyph_position_t &o = buffer->pos[idx]; + + /* Testing shows that CoreText only applies kern (cross-stream or not) + * if none has been applied by previous subtables. That is, it does + * NOT seem to accumulate as otherwise implied by specs. */ + + /* The following flag is undocumented in the spec, but described + * in the 'kern' table example. */ + if (v == -0x8000) + { + o.attach_type() = ATTACH_TYPE_NONE; + o.attach_chain() = 0; + o.x_offset = o.y_offset = 0; + } + else if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) { - if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + if (crossStream) { - buffer->pos[idx].x_advance += c->font->em_scale_x (v); - if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) + if (buffer->pos[idx].attach_type() && !buffer->pos[idx].y_offset) + { + o.y_offset = c->font->em_scale_y (v); + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; + } + } + else if (buffer->info[idx].mask & kern_mask) + { + if (!buffer->pos[idx].x_offset) + { + buffer->pos[idx].x_advance += c->font->em_scale_x (v); buffer->pos[idx].x_offset += c->font->em_scale_x (v); + } + } + } + else + { + if (crossStream) + { + /* CoreText doesn't do crossStream kerning in vertical. We do. */ + if (buffer->pos[idx].attach_type() && !buffer->pos[idx].x_offset) + { + o.x_offset = c->font->em_scale_x (v); + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; + } } - else + else if (buffer->info[idx].mask & kern_mask) { - buffer->pos[idx].y_advance += c->font->em_scale_y (v); - if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) + if (!buffer->pos[idx].y_offset) + { + buffer->pos[idx].y_advance += c->font->em_scale_y (v); buffer->pos[idx].y_offset += c->font->em_scale_y (v); + } } } } - depth = 0; } return true; @@ -229,24 +351,24 @@ struct KerxSubTableFormat1 private: hb_aat_apply_context_t *c; + const KerxSubTableFormat1 *table; const UnsizedArrayOf<FWORD> &kernAction; unsigned int stack[8]; unsigned int depth; + bool crossStream; }; inline bool apply (hb_aat_apply_context_t *c) const { TRACE_APPLY (this); - if (!c->plan->requested_kerning) + if (!c->plan->requested_kerning && + !(header.coverage & header.CrossStream)) return false; - if (header.tupleCount) - return_trace (false); /* TODO kerxTupleKern */ - driver_context_t dc (this, c); - StateTableDriver<MorxTypes, EntryData> driver (machine, c->buffer, c->font->face); + StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->font->face); driver.drive (&dc); return_trace (true); @@ -261,25 +383,29 @@ struct KerxSubTableFormat1 } protected: - KerxSubTableHeader header; - StateTable<MorxTypes, EntryData> machine; - LOffsetTo<UnsizedArrayOf<FWORD>, false> kernAction; + KernSubTableHeader header; + StateTable<Types, EntryData> machine; + OffsetTo<UnsizedArrayOf<FWORD>, HBUINT, false>kernAction; public: - DEFINE_SIZE_STATIC (32); + DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 5 * sizeof (HBUINT)); }; +template <typename KernSubTableHeader> struct KerxSubTableFormat2 { + typedef typename KernSubTableHeader::Types Types; + typedef typename Types::HBUINT HBUINT; + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, 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 l = (this+leftClassTable).get_class (left, num_glyphs, 0); + unsigned int r = (this+rightClassTable).get_class (right, num_glyphs, 0); unsigned int offset = l + r; const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; - return kerxTupleKern (*v, header.tupleCount, this, c); + return kerxTupleKern (*v, header.tuple_count (), this, c); } inline bool apply (hb_aat_apply_context_t *c) const @@ -289,8 +415,11 @@ struct KerxSubTableFormat2 if (!c->plan->requested_kerning) return false; + if (header.coverage & header.Backwards) + return false; + accelerator_t accel (*this, c); - hb_kern_machine_t<accelerator_t> machine (accel); + hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream); machine.kern (c->font, c->buffer, c->plan->kern_mask); return_trace (true); @@ -318,24 +447,33 @@ struct KerxSubTableFormat2 c->check_range (this, array))); } + /* Note: + * OT kern table specifies ClassTable as having 16-bit entries, whereas + * AAT kern table specifies them as having 8bit entries. + * I've not seen any fonts with this format in kern table. + * We follow AAT. */ + protected: - KerxSubTableHeader header; - HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */ - LOffsetTo<Lookup<HBUINT16>, false> + KernSubTableHeader header; + HBUINT rowWidth; /* The width, in bytes, of a row in the table. */ + OffsetTo<typename Types::ClassType, HBUINT, false> leftClassTable; /* Offset from beginning of this subtable to * left-hand class table. */ - LOffsetTo<Lookup<HBUINT16>, false> + OffsetTo<typename Types::ClassType, HBUINT, false> rightClassTable;/* Offset from beginning of this subtable to * right-hand class table. */ - LOffsetTo<UnsizedArrayOf<FWORD>, false> + OffsetTo<UnsizedArrayOf<FWORD>, HBUINT, false> array; /* Offset from beginning of this subtable to * the start of the kerning array. */ public: - DEFINE_SIZE_STATIC (28); + DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 4 * sizeof (HBUINT)); }; +template <typename KernSubTableHeader> struct KerxSubTableFormat4 { + typedef ExtendedTypes Types; + struct EntryData { HBUINT16 ankrActionIndex;/* Either 0xFFFF (for no action) or the index of @@ -372,16 +510,15 @@ struct KerxSubTableFormat4 mark_set (false), mark (0) {} - inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver HB_UNUSED, + inline bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED, const Entry<EntryData> *entry) { return entry->data.ankrActionIndex != 0xFFFF; } - inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver, + inline bool transition (StateTableDriver<Types, EntryData> *driver, const Entry<EntryData> *entry) { hb_buffer_t *buffer = driver->buffer; - unsigned int flags = entry->flags; if (mark_set && entry->data.ankrActionIndex != 0xFFFF && buffer->idx < buffer->len) { @@ -457,7 +594,7 @@ struct KerxSubTableFormat4 buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; } - if (flags & Mark) + if (entry->flags & Mark) { mark_set = true; mark = buffer->idx; @@ -480,7 +617,7 @@ struct KerxSubTableFormat4 driver_context_t dc (this, c); - StateTableDriver<MorxTypes, EntryData> driver (machine, c->buffer, c->font->face); + StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->font->face); driver.drive (&dc); return_trace (true); @@ -495,14 +632,14 @@ struct KerxSubTableFormat4 } protected: - KerxSubTableHeader header; - StateTable<MorxTypes, EntryData> - machine; - HBUINT32 flags; + KernSubTableHeader header; + StateTable<Types, EntryData> machine; + HBUINT32 flags; public: - DEFINE_SIZE_STATIC (32); + DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 20); }; +template <typename KernSubTableHeader> struct KerxSubTableFormat6 { enum Flags @@ -518,7 +655,7 @@ struct KerxSubTableFormat6 unsigned int num_glyphs = c->sanitizer.get_num_glyphs (); if (is_long ()) { - const U::Long &t = u.l; + const typename 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; @@ -526,17 +663,17 @@ struct KerxSubTableFormat6 if (unlikely (hb_unsigned_mul_overflows (offset, sizeof (FWORD32)))) return 0; const FWORD32 *v = &StructAtOffset<FWORD32> (&(this+t.array), offset * sizeof (FWORD32)); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; - return kerxTupleKern (*v, header.tupleCount, &(this+vector), c); + return kerxTupleKern (*v, header.tuple_count (), &(this+vector), c); } else { - const U::Short &t = u.s; + const typename U::Short &t = u.s; 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; const FWORD *v = &StructAtOffset<FWORD> (&(this+t.array), offset * sizeof (FWORD)); if (unlikely (!v->sanitize (&c->sanitizer))) return 0; - return kerxTupleKern (*v, header.tupleCount, &(this+vector), c); + return kerxTupleKern (*v, header.tuple_count (), &(this+vector), c); } } @@ -547,8 +684,11 @@ struct KerxSubTableFormat6 if (!c->plan->requested_kerning) return false; + if (header.coverage & header.Backwards) + return false; + accelerator_t accel (*this, c); - hb_kern_machine_t<accelerator_t> machine (accel); + hb_kern_machine_t<accelerator_t> machine (accel, header.coverage & header.CrossStream); machine.kern (c->font, c->buffer, c->plan->kern_mask); return_trace (true); @@ -568,7 +708,7 @@ struct KerxSubTableFormat6 u.s.columnIndexTable.sanitize (c, this) && c->check_range (this, u.s.array) )) && - (header.tupleCount == 0 || + (header.tuple_count () == 0 || c->check_range (this, vector)))); } @@ -586,7 +726,7 @@ struct KerxSubTableFormat6 }; protected: - KerxSubTableHeader header; + KernSubTableHeader header; HBUINT32 flags; HBUINT16 rowCount; HBUINT16 columnCount; @@ -607,42 +747,64 @@ struct KerxSubTableFormat6 } u; LOffsetTo<UnsizedArrayOf<FWORD>, false> vector; public: - DEFINE_SIZE_STATIC (36); + DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 24); }; -struct KerxTable + +struct KerxSubTableHeader { - friend struct kerx; + typedef ExtendedTypes Types; - inline unsigned int get_size (void) const { return u.header.length; } - inline unsigned int get_type (void) const { return u.header.coverage & SubtableType; } + inline unsigned int tuple_count (void) const { return tupleCount; } + inline bool is_horizontal (void) const { return !(coverage & Vertical); } enum Coverage { - Vertical = 0x80000000, /* Set if table has vertical kerning values. */ - CrossStream = 0x40000000, /* Set if table has cross-stream kerning values. */ - Variation = 0x20000000, /* Set if table has variation kerning values. */ - Backwards = 0x10000000, /* If clear, process the glyphs forwards, that - * is, from first to last in the glyph stream. - * If we, process them from last to first. - * This flag only applies to state-table based - * 'kerx' subtables (types 1 and 4). */ - Reserved = 0x0FFFFF00, /* Reserved, set to zero. */ - SubtableType = 0x000000FF, /* Subtable type. */ + Vertical = 0x80000000u, /* Set if table has vertical kerning values. */ + CrossStream = 0x40000000u, /* Set if table has cross-stream kerning values. */ + Variation = 0x20000000u, /* Set if table has variation kerning values. */ + Backwards = 0x10000000u, /* If clear, process the glyphs forwards, that + * is, from first to last in the glyph stream. + * If we, process them from last to first. + * This flag only applies to state-table based + * 'kerx' subtables (types 1 and 4). */ + Reserved = 0x0FFFFF00u, /* Reserved, set to zero. */ + SubtableType= 0x000000FFu, /* Subtable type. */ }; + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + public: + HBUINT32 length; + HBUINT32 coverage; + HBUINT32 tupleCount; + public: + DEFINE_SIZE_STATIC (12); +}; + +struct KerxSubTable +{ + friend struct kerx; + + inline unsigned int get_size (void) const { return u.header.length; } + inline unsigned int get_type (void) const { return u.header.coverage & u.header.SubtableType; } + template <typename context_t> inline typename context_t::return_t dispatch (context_t *c) const { unsigned int subtable_type = get_type (); TRACE_DISPATCH (this, subtable_type); switch (subtable_type) { - case 0 : return_trace (c->dispatch (u.format0)); - case 1 : return_trace (c->dispatch (u.format1)); - case 2 : return_trace (c->dispatch (u.format2)); - case 4 : return_trace (c->dispatch (u.format4)); - case 6 : return_trace (c->dispatch (u.format6)); - default: return_trace (c->default_return_value ()); + case 0: return_trace (c->dispatch (u.format0)); + case 1: return_trace (c->dispatch (u.format1)); + case 2: return_trace (c->dispatch (u.format2)); + case 4: return_trace (c->dispatch (u.format4)); + case 6: return_trace (c->dispatch (u.format6)); + default: return_trace (c->default_return_value ()); } } @@ -656,16 +818,16 @@ struct KerxTable return_trace (dispatch (c)); } -protected: + public: union { - KerxSubTableHeader header; - KerxSubTableFormat0 format0; - KerxSubTableFormat1 format1; - KerxSubTableFormat2 format2; - KerxSubTableFormat4 format4; - KerxSubTableFormat6 format6; + KerxSubTableHeader header; + KerxSubTableFormat0<KerxSubTableHeader> format0; + KerxSubTableFormat1<KerxSubTableHeader> format1; + KerxSubTableFormat2<KerxSubTableHeader> format2; + KerxSubTableFormat4<KerxSubTableHeader> format4; + KerxSubTableFormat6<KerxSubTableHeader> format6; } u; -public: + public: DEFINE_SIZE_MIN (12); }; @@ -674,73 +836,142 @@ public: * The 'kerx' Table */ -struct kerx +template <typename T> +struct KerxTable { - static const hb_tag_t tableTag = HB_AAT_TAG_kerx; + /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ + inline const T* thiz (void) const { return static_cast<const T *> (this); } - inline bool has_data (void) const { return version != 0; } + inline bool has_cross_stream (void) const + { + typedef typename T::SubTable SubTable; + + const SubTable *st = &thiz()->firstSubTable; + unsigned int count = thiz()->tableCount; + for (unsigned int i = 0; i < count; i++) + { + if (st->u.header.coverage & st->u.header.CrossStream) + return true; + st = &StructAfter<SubTable> (*st); + } + return false; + } + + inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const + { + typedef typename T::SubTable SubTable; + + int v = 0; + const SubTable *st = &thiz()->firstSubTable; + unsigned int count = thiz()->tableCount; + for (unsigned int i = 0; i < count; i++) + { + if ((st->u.header.coverage & (st->u.header.Variation | st->u.header.CrossStream)) || + !st->u.header.is_horizontal ()) + continue; + v += st->get_kerning (left, right); + st = &StructAfter<SubTable> (*st); + } + return v; + } - inline void apply (hb_aat_apply_context_t *c) const + inline bool apply (AAT::hb_aat_apply_context_t *c) const { + typedef typename T::SubTable SubTable; + + bool ret = false; + bool seenCrossStream = false; c->set_lookup_index (0); - const KerxTable *table = &firstTable; - unsigned int count = tableCount; + const SubTable *st = &thiz()->firstSubTable; + unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { bool reverse; - if (table->u.header.coverage & (KerxTable::CrossStream)) - goto skip; /* We do NOT handle cross-stream. */ + if (!T::Types::extended && (st->u.header.coverage & st->u.header.Variation)) + goto skip; - if (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) != - bool (table->u.header.coverage & KerxTable::Vertical)) + if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ()) goto skip; - reverse = bool (table->u.header.coverage & KerxTable::Backwards) != + reverse = bool (st->u.header.coverage & st->u.header.Backwards) != HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction); - if (!c->buffer->message (c->font, "start kerx subtable %d", c->lookup_index)) + if (!c->buffer->message (c->font, "start %c%c%c%c subtable %d", HB_UNTAG (thiz()->tableTag), c->lookup_index)) goto skip; + if (!seenCrossStream && + (st->u.header.coverage & st->u.header.CrossStream)) + { + /* Attach all glyphs into a chain. */ + seenCrossStream = true; + hb_glyph_position_t *pos = c->buffer->pos; + unsigned int count = c->buffer->len; + for (unsigned int i = 0; i < count; i++) + { + pos[i].attach_type() = ATTACH_TYPE_CURSIVE; + pos[i].attach_chain() = HB_DIRECTION_IS_FORWARD (c->buffer->props.direction) ? -1 : +1; + /* We intentionally don't set HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT, + * since there needs to be a non-zero attachment for post-positioning to + * be needed. */ + } + } + if (reverse) c->buffer->reverse (); - c->sanitizer.set_object (*table); + c->sanitizer.set_object (*st); - /* XXX Reverse-kern is not working yet... - * hb_kern_machine_t would need to know that it's reverse-kerning. - * Or better yet, make it work in reverse as well, so we don't have - * to reverse and reverse back? */ - table->dispatch (c); + ret |= st->dispatch (c); if (reverse) c->buffer->reverse (); - (void) c->buffer->message (c->font, "end kerx subtable %d", c->lookup_index); + (void) c->buffer->message (c->font, "end %c%c%c%c subtable %d", HB_UNTAG (thiz()->tableTag), c->lookup_index); skip: - table = &StructAfter<KerxTable> (*table); + st = &StructAfter<SubTable> (*st); + c->set_lookup_index (c->lookup_index + 1); } + + return ret; } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!version.sanitize (c) || version < 2 || - !tableCount.sanitize (c)) + if (unlikely (!thiz()->version.sanitize (c) || + thiz()->version < T::minVersion || + !thiz()->tableCount.sanitize (c))) return_trace (false); - const KerxTable *table = &firstTable; - unsigned int count = tableCount; + typedef typename T::SubTable SubTable; + + const SubTable *st = &thiz()->firstSubTable; + unsigned int count = thiz()->tableCount; for (unsigned int i = 0; i < count; i++) { - if (!table->sanitize (c)) + if (unlikely (!st->sanitize (c))) return_trace (false); - table = &StructAfter<KerxTable> (*table); + st = &StructAfter<SubTable> (*st); } return_trace (true); } +}; + +struct kerx : KerxTable<kerx> +{ + friend struct KerxTable<kerx>; + + static const hb_tag_t tableTag = HB_AAT_TAG_kerx; + static const uint16_t minVersion = 2; + + typedef KerxSubTableHeader SubTableHeader; + typedef SubTableHeader::Types Types; + typedef KerxSubTable SubTable; + + inline bool has_data (void) const { return version; } protected: HBUINT16 version; /* The version number of the extended kerning table @@ -748,13 +979,14 @@ struct kerx HBUINT16 unused; /* Set to 0. */ HBUINT32 tableCount; /* The number of subtables included in the extended kerning * table. */ - KerxTable firstTable; /* Subtables. */ + SubTable firstSubTable; /* Subtables. */ /*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */ public: DEFINE_SIZE_MIN (8); }; + } /* namespace AAT */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-lcar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-lcar-table.hh new file mode 100644 index 00000000000..43ac74f9c46 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-lcar-table.hh @@ -0,0 +1,93 @@ +/* + * 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_AAT_LAYOUT_LCAR_TABLE_HH +#define HB_AAT_LAYOUT_LCAR_TABLE_HH + +#include "hb-open-type.hh" +#include "hb-aat-layout-common.hh" + +/* + * lcar -- Ligature caret + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6lcar.html + */ +#define HB_AAT_TAG_lcar HB_TAG('l','c','a','r') + + +namespace AAT { + +typedef ArrayOf<HBINT16> LigCaretClassEntry; + +struct lcar +{ + static const hb_tag_t tableTag = HB_AAT_TAG_lcar; + + inline unsigned int get_lig_carets (hb_font_t *font, + hb_direction_t direction, + hb_codepoint_t glyph, + unsigned int start_offset, + unsigned int *caret_count /* IN/OUT */, + hb_position_t *caret_array /* OUT */) const + { + const OffsetTo<LigCaretClassEntry>* entry_offset = lookup.get_value (glyph, + font->face->get_num_glyphs ()); + const LigCaretClassEntry& array = entry_offset ? this+*entry_offset : Null (LigCaretClassEntry); + if (caret_count && *caret_count) + { + const HBINT16 *arr = array.sub_array (start_offset, caret_count); + unsigned int count = *caret_count; + for (unsigned int i = 0; i < count; ++i) + switch (format) + { + case 0: caret_array[i] = font->em_scale_dir (arr[i], direction); break; + case 1: + hb_position_t x, y; + font->get_glyph_contour_point_for_origin (glyph, arr[i], direction, &x, &y); + caret_array[i] = HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y; + break; + } + } + return array.len; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + version.major == 1 && + lookup.sanitize (c, this))); + } + + protected: + FixedVersion<>version; /* Version number of the ligature caret table */ + HBUINT16 format; /* Format of the ligature caret table. */ + Lookup<OffsetTo<LigCaretClassEntry> > + lookup; /* data Lookup table associating glyphs */ + + public: + DEFINE_SIZE_MIN (8); +}; + +} /* namespace AAT */ + +#endif /* HB_AAT_LAYOUT_LCAR_TABLE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh index 2bc60182e5c..43073270264 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-morx-table.hh @@ -375,21 +375,19 @@ struct LigatureEntry<true> Reserved = 0x1FFF, /* These bits are reserved and should be set to 0. */ }; - typedef struct + struct EntryData { HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry * for processing this group, if indicated * by the flags. */ public: DEFINE_SIZE_STATIC (2); - } EntryData; + }; - template <typename Flags> - static inline bool performAction (Flags flags) - { return flags & PerformAction; } + static inline bool performAction (const Entry<EntryData> *entry) + { return entry->flags & PerformAction; } - template <typename Entry, typename Flags> - static inline unsigned int ligActionIndex (Entry &entry, Flags flags) + static inline unsigned int ligActionIndex (const Entry<EntryData> *entry) { return entry->data.ligActionIndex; } }; template <> @@ -408,13 +406,11 @@ struct LigatureEntry<false> typedef void EntryData; - template <typename Flags> - static inline bool performAction (Flags flags) - { return flags & Offset; } + static inline bool performAction (const Entry<EntryData> *entry) + { return entry->flags & Offset; } - template <typename Entry, typename Flags> - static inline unsigned int ligActionIndex (Entry &entry, Flags flags) - { return flags & 0x3FFF; } + static inline unsigned int ligActionIndex (const Entry<EntryData> *entry) + { return entry->flags & Offset; } }; @@ -428,11 +424,11 @@ struct LigatureSubtable struct driver_context_t { + static const bool in_place = false; enum { DontAdvance = LigatureEntryT::DontAdvance, }; - static const bool in_place = false; enum LigActionFlags { LigActionLast = 0x80000000, /* This is the last action in the list. This also @@ -458,16 +454,15 @@ struct LigatureSubtable inline bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED, const Entry<EntryData> *entry) { - return LigatureEntryT::performAction (entry->flags); + return LigatureEntryT::performAction (entry); } inline bool transition (StateTableDriver<Types, EntryData> *driver, const Entry<EntryData> *entry) { hb_buffer_t *buffer = driver->buffer; - unsigned int flags = entry->flags; - DEBUG_MSG (APPLY, nullptr, "Ligature transition at %d", buffer->idx); - if (flags & LigatureEntryT::SetComponent) + DEBUG_MSG (APPLY, nullptr, "Ligature transition at %u", buffer->idx); + if (entry->flags & LigatureEntryT::SetComponent) { if (unlikely (match_length >= ARRAY_LENGTH (match_positions))) return false; @@ -477,16 +472,13 @@ struct LigatureSubtable match_length--; match_positions[match_length++] = buffer->out_len; - DEBUG_MSG (APPLY, nullptr, "Set component at %d", buffer->out_len); + DEBUG_MSG (APPLY, nullptr, "Set component at %u", buffer->out_len); } - if (LigatureEntryT::performAction (flags)) + if (LigatureEntryT::performAction (entry)) { - DEBUG_MSG (APPLY, nullptr, "Perform action with %d", match_length); + DEBUG_MSG (APPLY, nullptr, "Perform action with %u", match_length); unsigned int end = buffer->out_len; - unsigned int action_idx = LigatureEntryT::ligActionIndex (entry, flags); - unsigned int action; - unsigned int ligature_idx = 0; if (unlikely (!match_length)) return true; @@ -495,8 +487,13 @@ struct LigatureSubtable return false; // TODO Work on previous instead? unsigned int cursor = match_length; + + unsigned int action_idx = LigatureEntryT::ligActionIndex (entry); action_idx = Types::offsetToIndex (action_idx, table, ligAction.arrayZ); const HBUINT32 *actionData = &ligAction[action_idx]; + + unsigned int ligature_idx = 0; + unsigned int action; do { if (unlikely (!cursor)) @@ -507,7 +504,7 @@ struct LigatureSubtable break; } - DEBUG_MSG (APPLY, nullptr, "Moving to stack position %d", cursor - 1); + DEBUG_MSG (APPLY, nullptr, "Moving to stack position %u", cursor - 1); buffer->move_to (match_positions[--cursor]); if (unlikely (!actionData->sanitize (&c->sanitizer))) return false; @@ -523,7 +520,7 @@ struct LigatureSubtable if (unlikely (!componentData.sanitize (&c->sanitizer))) return false; ligature_idx += componentData; - DEBUG_MSG (APPLY, nullptr, "Action store %d last %d", + DEBUG_MSG (APPLY, nullptr, "Action store %u last %u", bool (action & LigActionStore), bool (action & LigActionLast)); if (action & (LigActionStore | LigActionLast)) @@ -533,7 +530,7 @@ struct LigatureSubtable if (unlikely (!ligatureData.sanitize (&c->sanitizer))) return false; hb_codepoint_t lig = ligatureData; - DEBUG_MSG (APPLY, nullptr, "Produced ligature %d", lig); + DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig); buffer->replace_glyph (lig); unsigned int lig_end = match_positions[match_length - 1] + 1; @@ -1109,21 +1106,6 @@ struct mortmorx } } - inline static void remove_deleted_glyphs (hb_buffer_t *buffer) - { - if (unlikely (!buffer->successful)) return; - - buffer->clear_output (); - for (buffer->idx = 0; buffer->idx < buffer->len && buffer->successful;) - { - if (unlikely (buffer->cur().codepoint == DELETED_GLYPH)) - buffer->skip_glyph (); - else - buffer->next_glyph (); - } - buffer->swap_buffers (); - } - inline void apply (hb_aat_apply_context_t *c) const { if (unlikely (!c->buffer->successful)) return; @@ -1136,7 +1118,6 @@ struct mortmorx if (unlikely (!c->buffer->successful)) return; chain = &StructAfter<Chain<Types> > (*chain); } - remove_deleted_glyphs (c->buffer); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -1169,11 +1150,11 @@ struct mortmorx DEFINE_SIZE_MIN (8); }; -struct morx : mortmorx<MorxTypes> +struct morx : mortmorx<ExtendedTypes> { static const hb_tag_t tableTag = HB_AAT_TAG_morx; }; -struct mort : mortmorx<MortTypes> +struct mort : mortmorx<ObsoleteTypes> { static const hb_tag_t tableTag = HB_AAT_TAG_mort; }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh index c579c1193cd..91c0f4562dc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout-trak-table.hh @@ -147,9 +147,9 @@ struct TrackData inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - sizeTable.sanitize (c, base, nSizes) && - trackTable.sanitize (c, nTracks, base, nSizes)); + return_trace (likely (c->check_struct (this) && + sizeTable.sanitize (c, base, nSizes) && + trackTable.sanitize (c, nTracks, base, nSizes))); } protected: @@ -169,16 +169,7 @@ struct trak { static const hb_tag_t tableTag = HB_AAT_TAG_trak; - inline bool has_data (void) const { return version.to_int () != 0; } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - - return_trace (unlikely (c->check_struct (this) && - horizData.sanitize (c, this, this) && - vertData.sanitize (c, this, this))); - } + inline bool has_data (void) const { return version.to_int (); } inline bool apply (hb_aat_apply_context_t *c) const { @@ -221,15 +212,27 @@ struct trak return_trace (true); } + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + + return_trace (likely (c->check_struct (this) && + version.major == 1 && + horizData.sanitize (c, this, this) && + vertData.sanitize (c, this, this))); + } + protected: - FixedVersion<> version; /* Version of the tracking table + FixedVersion<>version; /* Version of the tracking table * (0x00010000u for version 1.0). */ - HBUINT16 format; /* Format of the tracking table (set to 0). */ - OffsetTo<TrackData> horizData; /* Offset from start of tracking table to TrackData - * for horizontal text (or 0 if none). */ - OffsetTo<TrackData> vertData; /* Offset from start of tracking table to TrackData - * for vertical text (or 0 if none). */ - HBUINT16 reserved; /* Reserved. Set to 0. */ + HBUINT16 format; /* Format of the tracking table (set to 0). */ + OffsetTo<TrackData> + horizData; /* Offset from start of tracking table to TrackData + * for horizontal text (or 0 if none). */ + OffsetTo<TrackData> + vertData; /* Offset from start of tracking table to TrackData + * for vertical text (or 0 if none). */ + HBUINT16 reserved; /* Reserved. Set to 0. */ public: DEFINE_SIZE_STATIC (12); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc index 9e0eb92fa78..d9580c15281 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.cc @@ -31,6 +31,7 @@ #include "hb-aat-layout-ankr-table.hh" #include "hb-aat-layout-bsln-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-layout-feat-table.hh" // Just so we compile it; unused otherwise. +#include "hb-aat-layout-just-table.hh" // Just so we compile it; unused otherwise. #include "hb-aat-layout-kerx-table.hh" #include "hb-aat-layout-morx-table.hh" #include "hb-aat-layout-trak-table.hh" @@ -134,7 +135,7 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag) * hb_aat_apply_context_t */ -AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (hb_ot_shape_plan_t *plan_, +AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_, hb_font_t *font_, hb_buffer_t *buffer_, hb_blob_t *blob) : @@ -172,88 +173,19 @@ AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_, * mort/morx/kerx/trak */ -static inline const AAT::mort& -_get_mort (hb_face_t *face, hb_blob_t **blob = nullptr) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) - { - if (blob) - *blob = hb_blob_get_empty (); - return Null(AAT::mort); - } - const AAT::mort& mort = *(hb_ot_face_data (face)->mort); - if (blob) - *blob = hb_ot_face_data (face)->mort.get_blob (); - return mort; -} -static inline const AAT::morx& -_get_morx (hb_face_t *face, hb_blob_t **blob = nullptr) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) - { - if (blob) - *blob = hb_blob_get_empty (); - return Null(AAT::morx); - } - const AAT::morx& morx = *(hb_ot_face_data (face)->morx); - if (blob) - *blob = hb_ot_face_data (face)->morx.get_blob (); - return morx; -} -static inline const AAT::kerx& -_get_kerx (hb_face_t *face, hb_blob_t **blob = nullptr) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) - { - if (blob) - *blob = hb_blob_get_empty (); - return Null(AAT::kerx); - } - const AAT::kerx& kerx = *(hb_ot_face_data (face)->kerx); - if (blob) - *blob = hb_ot_face_data (face)->kerx.get_blob (); - return kerx; -} -static inline const AAT::ankr& -_get_ankr (hb_face_t *face, hb_blob_t **blob = nullptr) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) - { - if (blob) - *blob = hb_blob_get_empty (); - return Null(AAT::ankr); - } - const AAT::ankr& ankr = *(hb_ot_face_data (face)->ankr); - if (blob) - *blob = hb_ot_face_data (face)->ankr.get_blob (); - return ankr; -} -static inline const AAT::trak& -_get_trak (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(AAT::trak); - return *(hb_ot_face_data (face)->trak); -} -static inline const AAT::ltag& -_get_ltag (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(AAT::ltag); - return *(hb_ot_face_data (face)->ltag); -} - void hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, hb_aat_map_t *map) { - const AAT::morx& morx = _get_morx (mapper->face, nullptr); + const AAT::morx& morx = *mapper->face->table.morx; if (morx.has_data ()) { morx.compile_flags (mapper, map); return; } - const AAT::mort& mort = _get_mort (mapper->face, nullptr); + const AAT::mort& mort = *mapper->face->table.mort; if (mort.has_data ()) { mort.compile_flags (mapper, map); @@ -262,80 +194,106 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, } -hb_bool_t +bool hb_aat_layout_has_substitution (hb_face_t *face) { - return _get_morx (face).has_data () || - _get_mort (face).has_data (); + return face->table.morx->has_data () || + face->table.mort->has_data (); } void -hb_aat_layout_substitute (hb_ot_shape_plan_t *plan, +hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - hb_blob_t *blob; - - const AAT::morx& morx = _get_morx (font->face, &blob); + hb_blob_t *morx_blob = font->face->table.morx.get_blob (); + const AAT::morx& morx = *morx_blob->as<AAT::morx> (); if (morx.has_data ()) { - AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); + AAT::hb_aat_apply_context_t c (plan, font, buffer, morx_blob); morx.apply (&c); return; } - const AAT::mort& mort = _get_mort (font->face, &blob); + hb_blob_t *mort_blob = font->face->table.mort.get_blob (); + const AAT::mort& mort = *mort_blob->as<AAT::mort> (); if (mort.has_data ()) { - AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); + AAT::hb_aat_apply_context_t c (plan, font, buffer, mort_blob); mort.apply (&c); return; } } +void +hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer) +{ + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + for (unsigned int i = 0; i < count; i++) + if (unlikely (info[i].codepoint == AAT::DELETED_GLYPH)) + pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; +} + +static bool +is_deleted_glyph (const hb_glyph_info_t *info) +{ + return info->codepoint == AAT::DELETED_GLYPH; +} + +void +hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) +{ + hb_ot_layout_delete_glyphs_inplace (buffer, is_deleted_glyph); +} -hb_bool_t + + +bool hb_aat_layout_has_positioning (hb_face_t *face) { - return _get_kerx (face).has_data (); + return face->table.kerx->has_data (); } void -hb_aat_layout_position (hb_ot_shape_plan_t *plan, +hb_aat_layout_position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - hb_blob_t *blob; - const AAT::kerx& kerx = _get_kerx (font->face, &blob); + hb_blob_t *kerx_blob = font->face->table.kerx.get_blob (); + const AAT::kerx& kerx = *kerx_blob->as<AAT::kerx> (); - hb_blob_t *ankr_blob; - const AAT::ankr& ankr = _get_ankr (font->face, &ankr_blob); + hb_blob_t *ankr_blob = font->face->table.ankr.get_blob ();; + const AAT::ankr& ankr = *font->face->table.ankr; - AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); + AAT::hb_aat_apply_context_t c (plan, font, buffer, kerx_blob); c.set_ankr_table (&ankr, ankr_blob->data + ankr_blob->length); kerx.apply (&c); } -hb_bool_t + +bool hb_aat_layout_has_tracking (hb_face_t *face) { - return _get_trak (face).has_data (); + return face->table.trak->has_data (); } void -hb_aat_layout_track (hb_ot_shape_plan_t *plan, +hb_aat_layout_track (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - const AAT::trak& trak = _get_trak (font->face); + const AAT::trak& trak = *font->face->table.trak; AAT::hb_aat_apply_context_t c (plan, font, buffer); trak.apply (&c); } + hb_language_t _hb_aat_language_get (hb_face_t *face, unsigned int i) { - return _get_ltag (face).get_language (i); + return face->table.ltag->get_language (i); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh index 8a558e6aa73..1d3407971ea 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-layout.hh @@ -56,27 +56,33 @@ HB_INTERNAL void hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, hb_aat_map_t *map); -HB_INTERNAL hb_bool_t +HB_INTERNAL bool hb_aat_layout_has_substitution (hb_face_t *face); HB_INTERNAL void -hb_aat_layout_substitute (hb_ot_shape_plan_t *plan, +hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -HB_INTERNAL hb_bool_t +HB_INTERNAL void +hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer); + +HB_INTERNAL void +hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer); + +HB_INTERNAL bool hb_aat_layout_has_positioning (hb_face_t *face); HB_INTERNAL void -hb_aat_layout_position (hb_ot_shape_plan_t *plan, +hb_aat_layout_position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -HB_INTERNAL hb_bool_t +HB_INTERNAL bool hb_aat_layout_has_tracking (hb_face_t *face); HB_INTERNAL void -hb_aat_layout_track (hb_ot_shape_plan_t *plan, +hb_aat_layout_track (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc index 1ce1b12b05c..8bc1a0c6159 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.cc @@ -51,9 +51,7 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag, } void -hb_aat_map_builder_t::compile (hb_aat_map_t &m, - const int *coords HB_UNUSED, - unsigned int num_coords HB_UNUSED) +hb_aat_map_builder_t::compile (hb_aat_map_t &m) { /* Sort features and merge duplicates */ if (features.len) diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh index 6fd3fa1ea86..07454b2c167 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-aat-map.hh @@ -60,9 +60,7 @@ struct hb_aat_map_builder_t HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value=1); - HB_INTERNAL void compile (hb_aat_map_t &m, - const int *coords, - unsigned int num_coords); + HB_INTERNAL void compile (hb_aat_map_t &m); public: struct feature_info_t diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh index 49c2809e2fa..64ed257bdd2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-atomic.hh @@ -100,7 +100,7 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) #define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)) -#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__)) +#elif !defined(HB_NO_MT) && defined(_WIN32) #include <windows.h> @@ -257,24 +257,24 @@ static_assert ((sizeof (long) == sizeof (void *)), ""); inline void hb_atomic_int_impl_set (int *AI, int v) { _hb_memory_w_barrier (); *AI = v; } #endif #ifndef hb_atomic_int_impl_get -inline int hb_atomic_int_impl_get (int *AI) { int v = *AI; _hb_memory_r_barrier (); return v; } +inline int hb_atomic_int_impl_get (const int *AI) { int v = *AI; _hb_memory_r_barrier (); return v; } #endif #ifndef hb_atomic_ptr_impl_get -inline void *hb_atomic_ptr_impl_get (void **P) { void *v = *P; _hb_memory_r_barrier (); return v; } +inline void *hb_atomic_ptr_impl_get (void ** const P) { void *v = *P; _hb_memory_r_barrier (); return v; } #endif #define HB_ATOMIC_INT_INIT(V) {V} struct hb_atomic_int_t { - inline void set_relaxed (int v_) const { hb_atomic_int_impl_set_relaxed (&v, v_); } - inline void set (int v_) const { hb_atomic_int_impl_set (&v, v_); } + inline void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); } + inline void set (int v_) { hb_atomic_int_impl_set (&v, v_); } inline int get_relaxed (void) const { return hb_atomic_int_impl_get_relaxed (&v); } inline int get (void) const { return hb_atomic_int_impl_get (&v); } inline int inc (void) { return hb_atomic_int_impl_add (&v, 1); } inline int dec (void) { return hb_atomic_int_impl_add (&v, -1); } - mutable int v; + int v; }; @@ -285,7 +285,7 @@ struct hb_atomic_ptr_t typedef typename hb_remove_pointer<P>::value T; inline void init (T* v_ = nullptr) { set_relaxed (v_); } - inline void set_relaxed (T* v_) const { hb_atomic_ptr_impl_set_relaxed (&v, v_); } + inline void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); } inline T *get_relaxed (void) const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); } inline T *get (void) const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); } inline bool cmpexch (const T *old, T *new_) const { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); } @@ -293,7 +293,7 @@ struct hb_atomic_ptr_t inline T * operator -> (void) const { return get (); } template <typename C> inline operator C * (void) const { return get (); } - mutable T *v; + T *v; }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc index 9271200b110..8ebedca7887 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.cc @@ -53,18 +53,6 @@ **/ -DEFINE_NULL_INSTANCE (hb_blob_t) = -{ - HB_OBJECT_HEADER_STATIC, - - nullptr, /* data */ - 0, /* length */ - HB_MEMORY_MODE_READONLY, /* mode */ - - nullptr, /* user_data */ - nullptr /* destroy */ -}; - /** * hb_blob_create: (skip) * @data: Pointer to blob data. @@ -493,7 +481,7 @@ hb_blob_t::try_make_writable (void) # include <fcntl.h> #endif -#if defined(_WIN32) || defined(__CYGWIN__) +#ifdef _WIN32 # include <windows.h> #else # ifndef O_BINARY @@ -509,19 +497,19 @@ struct hb_mapped_file_t { char *contents; unsigned long length; -#if defined(_WIN32) || defined(__CYGWIN__) +#ifdef _WIN32 HANDLE mapping; #endif }; -#if (defined(HAVE_MMAP) || defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_MMAP) +#if (defined(HAVE_MMAP) || defined(_WIN32)) && !defined(HB_NO_MMAP) static void _hb_mapped_file_destroy (void *file_) { hb_mapped_file_t *file = (hb_mapped_file_t *) file_; #ifdef HAVE_MMAP munmap (file->contents, file->length); -#elif defined(_WIN32) || defined(__CYGWIN__) +#elif defined(_WIN32) UnmapViewOfFile (file->contents); CloseHandle (file->mapping); #else @@ -572,7 +560,7 @@ fail: fail_without_close: free (file); -#elif (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_MMAP) +#elif defined(_WIN32) && !defined(HB_NO_MMAP) hb_mapped_file_t *file = (hb_mapped_file_t *) calloc (1, sizeof (hb_mapped_file_t)); if (unlikely (!file)) return hb_blob_get_empty (); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.hh index 1f7499fbf33..802b1f07eb6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-blob.hh @@ -77,7 +77,30 @@ struct hb_blob_t void *user_data; hb_destroy_func_t destroy; }; -DECLARE_NULL_INSTANCE (hb_blob_t); + + +/* + * hb_blob_ptr_t + */ + +template <typename P> +struct hb_blob_ptr_t +{ + typedef typename hb_remove_pointer<P>::value T; + + inline hb_blob_ptr_t (hb_blob_t *b_ = nullptr) : b (b_) {} + inline hb_blob_t * operator = (hb_blob_t *b_) { return b = b_; } + inline const T * operator -> (void) const { return get (); } + inline const T & operator * (void) const { return *get (); } + template <typename C> inline operator const C * (void) const { return get (); } + inline operator const char * (void) const { return (const char *) get (); } + inline const T * get (void) const { return b->as<T> (); } + inline hb_blob_t * get_blob (void) const { return b.get_raw (); } + inline unsigned int get_length (void) const { return b.get ()->length; } + inline void destroy (void) { hb_blob_destroy (b.get ()); b = nullptr; } + + hb_nonnull_ptr_t<hb_blob_t> b; +}; #endif /* HB_BLOB_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc index 893a8761da5..918f649da6c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-coretext.cc @@ -26,8 +26,6 @@ * Google Author(s): Behdad Esfahbod */ -#define HB_SHAPER coretext - #include "hb.hh" #include "hb-shaper-impl.hh" @@ -101,11 +99,6 @@ _hb_cg_font_release (void *data) } -HB_SHAPER_DATA_ENSURE_DEFINE(coretext, face) -HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font, - fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) <= .5 -) - static CTFontDescriptorRef get_last_resort_font_desc (void) { @@ -312,8 +305,7 @@ hb_coretext_face_create (CGFontRef cg_font) CGFontRef hb_coretext_face_get_cg_font (hb_face_t *face) { - if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr; - return (CGFontRef) HB_SHAPER_DATA_GET (face); + return (CGFontRef) (const void *) face->data.coretext; } @@ -321,8 +313,9 @@ hb_coretext_font_data_t * _hb_coretext_shaper_font_data_create (hb_font_t *font) { hb_face_t *face = font->face; - if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr; - CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face); + const hb_coretext_face_data_t *face_data = face->data.coretext; + if (unlikely (!face_data)) return nullptr; + CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext; CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size_from_ptem (font->ptem)); @@ -341,6 +334,38 @@ _hb_coretext_shaper_font_data_destroy (hb_coretext_font_data_t *data) CFRelease ((CTFontRef) data); } +static const hb_coretext_font_data_t * +hb_coretext_font_data_sync (hb_font_t *font) +{ +retry: + const hb_coretext_font_data_t *data = font->data.coretext; + if (unlikely (!data)) return nullptr; + + if (fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) > .5) + { + /* XXX-MT-bug + * Note that evaluating condition above can be dangerous if another thread + * got here first and destructed data. That's, as always, bad use pattern. + * If you modify the font (change font size), other threads must not be + * using it at the same time. However, since this check is delayed to + * when one actually tries to shape something, this is a XXX race condition + * (and the only one we have that I know of) right now. Ie. you modify the + * font size in one thread, then (supposedly safely) try to use it from two + * or more threads and BOOM! I'm not sure how to fix this. We want RCU. + */ + + /* Drop and recreate. */ + /* If someone dropped it in the mean time, throw it away and don't touch it. + * Otherwise, destruct it. */ + if (likely (font->data.coretext.cmpexch (const_cast<hb_coretext_font_data_t *> (data), nullptr))) + _hb_coretext_shaper_font_data_destroy (const_cast<hb_coretext_font_data_t *> (data)); + else + goto retry; + } + return font->data.coretext; +} + + /* * Since: 1.7.2 */ @@ -359,7 +384,7 @@ hb_coretext_font_create (CTFontRef ct_font) hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font))); /* Let there be dragons here... */ - HB_SHAPER_DATA (HB_SHAPER, font).set_relaxed ((hb_coretext_font_data_t *) CFRetain (ct_font)); + font->data.coretext.cmpexch (nullptr, (hb_coretext_font_data_t *) CFRetain (ct_font)); return font; } @@ -367,31 +392,8 @@ hb_coretext_font_create (CTFontRef ct_font) CTFontRef hb_coretext_font_get_ct_font (hb_font_t *font) { - if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return nullptr; - return (CTFontRef) HB_SHAPER_DATA_GET (font); -} - - - -/* - * shaper shape_plan data - */ - -struct hb_coretext_shape_plan_data_t {}; - -hb_coretext_shape_plan_data_t * -_hb_coretext_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, - const hb_feature_t *user_features HB_UNUSED, - unsigned int num_user_features HB_UNUSED, - const int *coords HB_UNUSED, - unsigned int num_coords HB_UNUSED) -{ - return (hb_coretext_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; -} - -void -_hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shape_plan_data_t *data HB_UNUSED) -{ + const hb_coretext_font_data_t *data = hb_coretext_font_data_sync (font); + return data ? (CTFontRef) data : nullptr; } @@ -450,8 +452,8 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, unsigned int num_features) { hb_face_t *face = font->face; - CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face); - CTFontRef ct_font = (CTFontRef) HB_SHAPER_DATA_GET (font); + CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext; + CTFontRef ct_font = (CTFontRef) hb_coretext_font_data_sync (font); CGFloat ct_font_size = CTFontGetSize (ct_font); CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size; @@ -1152,9 +1154,6 @@ fail: * AAT shaper */ -HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, face) -HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, font) - /* * shaper face data */ @@ -1172,7 +1171,7 @@ _hb_coretext_aat_shaper_face_data_create (hb_face_t *face) if (hb_blob_get_length (blob)) { hb_blob_destroy (blob); - return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr; + return face->data.coretext ? (hb_coretext_aat_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr; } hb_blob_destroy (blob); } @@ -1195,7 +1194,7 @@ struct hb_coretext_aat_font_data_t {}; hb_coretext_aat_font_data_t * _hb_coretext_aat_shaper_font_data_create (hb_font_t *font) { - return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr; + return font->data.coretext ? (hb_coretext_aat_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr; } void @@ -1205,28 +1204,6 @@ _hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_font_data_t *data HB_ /* - * shaper shape_plan data - */ - -struct hb_coretext_aat_shape_plan_data_t {}; - -hb_coretext_aat_shape_plan_data_t * -_hb_coretext_aat_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, - const hb_feature_t *user_features HB_UNUSED, - unsigned int num_user_features HB_UNUSED, - const int *coords HB_UNUSED, - unsigned int num_coords HB_UNUSED) -{ - return (hb_coretext_aat_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; -} - -void -_hb_coretext_aat_shaper_shape_plan_data_destroy (hb_coretext_aat_shape_plan_data_t *data HB_UNUSED) -{ -} - - -/* * shaper */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc index 35197c23865..f9b2d261a99 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-directwrite.cc @@ -23,7 +23,6 @@ */ #include "hb.hh" -#define HB_SHAPER directwrite #include "hb-shaper-impl.hh" #include <DWrite_1.h> @@ -31,10 +30,6 @@ #include "hb-directwrite.h" -HB_SHAPER_DATA_ENSURE_DEFINE (directwrite, face) -HB_SHAPER_DATA_ENSURE_DEFINE (directwrite, font) - - /* * hb-directwrite uses new/delete syntatically but as we let users * to override malloc/free, we will redefine new/delete so users @@ -240,8 +235,6 @@ struct hb_directwrite_font_data_t hb_directwrite_font_data_t * _hb_directwrite_shaper_font_data_create (hb_font_t *font) { - if (unlikely (!hb_directwrite_shaper_face_data_ensure (font->face))) return nullptr; - hb_directwrite_font_data_t *data = new hb_directwrite_font_data_t; if (unlikely (!data)) return nullptr; @@ -256,27 +249,6 @@ _hb_directwrite_shaper_font_data_destroy (hb_directwrite_font_data_t *data) } -/* - * shaper shape_plan data - */ - -struct hb_directwrite_shape_plan_data_t {}; - -hb_directwrite_shape_plan_data_t * -_hb_directwrite_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, - const hb_feature_t *user_features HB_UNUSED, - unsigned int num_user_features HB_UNUSED, - const int *coords HB_UNUSED, - unsigned int num_coords HB_UNUSED) -{ - return (hb_directwrite_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; -} - -void -_hb_directwrite_shaper_shape_plan_data_destroy (hb_directwrite_shape_plan_data_t *data HB_UNUSED) -{ -} - // Most of TextAnalysis is originally written by Bas Schouten for Mozilla project // but now is relicensed to MIT for HarfBuzz use class TextAnalysis @@ -555,8 +527,8 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan, float lineWidth) { hb_face_t *face = font->face; - hb_directwrite_face_data_t *face_data = HB_SHAPER_DATA_GET (face); - hb_directwrite_font_data_t *font_data = HB_SHAPER_DATA_GET (font); + const hb_directwrite_face_data_t *face_data = face->data.directwrite; + const hb_directwrite_font_data_t *font_data = font->data.directwrite; IDWriteFactory *dwriteFactory = face_data->dwriteFactory; IDWriteFontFace *fontFace = face_data->fontFace; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh index 9ccd7f25538..7a207f5d24a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-dsalgs.hh @@ -264,6 +264,17 @@ static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; } /* A const version, but does not detect erratically being called on pointers. */ #define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0]))) + +static inline int +hb_memcmp (const void *a, const void *b, unsigned int len) +{ + /* It's illegal to pass NULL to memcmp(), even if len is zero. + * So, wrap it. + * https://sourceware.org/bugzilla/show_bug.cgi?id=23878 */ + if (!len) return 0; + return memcmp (a, b, len); +} + static inline bool hb_unsigned_mul_overflows (unsigned int count, unsigned int size) { @@ -356,7 +367,12 @@ hb_bsearch_r (const void *key, const void *base, } -/* From https://github.com/noporpoise/sort_r */ +/* From https://github.com/noporpoise/sort_r + * With following modifications: + * + * 10 November 2018: + * https://github.com/noporpoise/sort_r/issues/7 + */ /* Isaac Turner 29 April 2014 Public Domain */ @@ -412,7 +428,7 @@ static inline void sort_r_simple(void *base, size_t nel, size_t w, /* Use median of first, middle and last items as pivot */ char *x, *y, *xend, ch; - char *pl, *pr; + char *pl, *pm, *pr; char *last = b+w*(nel-1), *tmp; char *l[3]; l[0] = b; @@ -434,13 +450,15 @@ static inline void sort_r_simple(void *base, size_t nel, size_t w, pr = last; while(pl < pr) { - for(; pl < pr; pl += w) { + pm = pl+((pr-pl+1)>>1); + for(; pl < pm; pl += w) { if(sort_r_cmpswap(pl, pr, w, compar, arg)) { pr -= w; /* pivot now at pl */ break; } } - for(; pl < pr; pr -= w) { + pm = pl+((pr-pl)>>1); + for(; pm < pr; pr -= w) { if(sort_r_cmpswap(pl, pr, w, compar, arg)) { pl += w; /* pivot now at pr */ break; @@ -517,7 +535,10 @@ struct hb_bytes_t inline hb_bytes_t (const char *bytes_, unsigned int len_) : arrayZ (bytes_), len (len_) {} inline hb_bytes_t (const void *bytes_, unsigned int len_) : arrayZ ((const char *) bytes_), len (len_) {} template <typename T> - inline hb_bytes_t (const T& array) : arrayZ ((const char *) array.arrayZ), len (array.len) {} + inline hb_bytes_t (const T& array) : arrayZ ((const char *) array.arrayZ), len (array.len * sizeof (array.arrayZ[0])) {} + + inline operator const void * (void) const { return arrayZ; } + inline operator const char * (void) const { return arrayZ; } inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; } @@ -525,8 +546,7 @@ struct hb_bytes_t { if (len != a.len) return (int) a.len - (int) len; - - return memcmp (a.arrayZ, arrayZ, len); + return hb_memcmp (a.arrayZ, arrayZ, len); } static inline int cmp (const void *pa, const void *pb) { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc index a0f8047f314..e23842fb143 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.cc @@ -87,16 +87,10 @@ DEFINE_NULL_INSTANCE (hb_face_t) = nullptr, /* destroy */ 0, /* index */ - 1000, /* upem */ - 0, /* num_glyphs */ + HB_ATOMIC_INT_INIT (1000), /* upem */ + HB_ATOMIC_INT_INIT (0), /* num_glyphs */ - { -#define HB_SHAPER_IMPLEMENT(shaper) HB_ATOMIC_PTR_INIT (HB_SHAPER_DATA_INVALID), -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT - }, - - HB_ATOMIC_PTR_INIT (nullptr), /* shape_plans */ + /* Zero for the rest is fine. */ }; @@ -129,8 +123,10 @@ hb_face_create_for_tables (hb_reference_table_func_t reference_table_func, face->user_data = user_data; face->destroy = destroy; - face->upem = 0; - face->num_glyphs = (unsigned int) -1; + face->num_glyphs.set_relaxed (-1); + + face->data.init0 (face); + face->table.init0 (face); return face; } @@ -271,9 +267,8 @@ hb_face_destroy (hb_face_t *face) node = next; } -#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face); -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT + face->data.fini (); + face->table.fini (); if (face->destroy) face->destroy (face->user_data); @@ -442,7 +437,7 @@ hb_face_set_upem (hb_face_t *face, if (hb_object_is_immutable (face)) return; - face->upem = upem; + face->upem.set_relaxed (upem); } /** @@ -477,7 +472,7 @@ hb_face_set_glyph_count (hb_face_t *face, if (hb_object_is_immutable (face)) return; - face->num_glyphs = glyph_count; + face->num_glyphs.set_relaxed (glyph_count); } /** @@ -547,8 +542,7 @@ void hb_face_collect_unicodes (hb_face_t *face, hb_set_t *out) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return; - hb_ot_face_data (face)->cmap->collect_unicodes (out); + face->table.cmap->collect_unicodes (out); } /** @@ -564,8 +558,7 @@ void hb_face_collect_variation_selectors (hb_face_t *face, hb_set_t *out) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return; - hb_ot_face_data (face)->cmap->collect_variation_selectors (out); + face->table.cmap->collect_variation_selectors (out); } /** @@ -582,8 +575,7 @@ hb_face_collect_variation_unicodes (hb_face_t *face, hb_codepoint_t variation_selector, hb_set_t *out) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return; - hb_ot_face_data (face)->cmap->collect_variation_unicodes (variation_selector, out); + face->table.cmap->collect_variation_unicodes (variation_selector, out); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh index 520bdfdf81a..0b672336f3e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-face.hh @@ -33,12 +33,17 @@ #include "hb-shaper.hh" #include "hb-shape-plan.hh" +#include "hb-ot-face.hh" /* * hb_face_t */ +#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, face); +#include "hb-shaper-list.hh" +#undef HB_SHAPER_IMPLEMENT + struct hb_face_t { hb_object_header_t header; @@ -48,10 +53,11 @@ struct hb_face_t hb_destroy_func_t destroy; unsigned int index; /* Face index in a collection, zero-based. */ - mutable unsigned int upem; /* Units-per-EM. */ - mutable unsigned int num_glyphs; /* Number of glyphs. */ + mutable hb_atomic_int_t upem; /* Units-per-EM. */ + mutable hb_atomic_int_t num_glyphs; /* Number of glyphs. */ - struct hb_shaper_data_t shaper_data; /* Various shaper data. */ + hb_shaper_object_dataset_t<hb_face_t> data;/* Various shaper data. */ + hb_ot_face_t table; /* All the face's tables. */ /* Cache */ struct plan_node_t @@ -77,29 +83,27 @@ struct hb_face_t inline HB_PURE_FUNC unsigned int get_upem (void) const { - if (unlikely (!upem)) - load_upem (); - return upem; + unsigned int ret = upem.get_relaxed (); + if (unlikely (!ret)) + { + return load_upem (); + } + return ret; } inline unsigned int get_num_glyphs (void) const { - if (unlikely (num_glyphs == (unsigned int) -1)) - load_num_glyphs (); - return num_glyphs; + unsigned int ret = num_glyphs.get_relaxed (); + if (unlikely (ret == (unsigned int) -1)) + return load_num_glyphs (); + return ret; } private: - HB_INTERNAL void load_upem (void) const; - HB_INTERNAL void load_num_glyphs (void) const; + HB_INTERNAL unsigned int load_upem (void) const; + HB_INTERNAL unsigned int load_num_glyphs (void) const; }; DECLARE_NULL_INSTANCE (hb_face_t); -#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS -#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face); -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT -#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS - #endif /* HB_FACE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-fallback-shape.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-fallback-shape.cc index dc8536c8281..09f02900fac 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-fallback-shape.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-fallback-shape.cc @@ -24,14 +24,9 @@ * Google Author(s): Behdad Esfahbod */ -#define HB_SHAPER fallback #include "hb-shaper-impl.hh" -HB_SHAPER_DATA_ENSURE_DEFINE(fallback, face) -HB_SHAPER_DATA_ENSURE_DEFINE(fallback, font) - - /* * shaper face data */ @@ -69,28 +64,6 @@ _hb_fallback_shaper_font_data_destroy (hb_fallback_font_data_t *data HB_UNUSED) /* - * shaper shape_plan data - */ - -struct hb_fallback_shape_plan_data_t {}; - -hb_fallback_shape_plan_data_t * -_hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, - const hb_feature_t *user_features HB_UNUSED, - unsigned int num_user_features HB_UNUSED, - const int *coords HB_UNUSED, - unsigned int num_coords HB_UNUSED) -{ - return (hb_fallback_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; -} - -void -_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shape_plan_data_t *data HB_UNUSED) -{ -} - - -/* * shaper */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc index b24995b12ed..237b2a50929 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.cc @@ -1306,15 +1306,9 @@ DEFINE_NULL_INSTANCE (hb_font_t) = 0, /* num_coords */ nullptr, /* coords */ - const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t), /* klass */ - nullptr, /* user_data */ - nullptr, /* destroy */ + const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t), - { -#define HB_SHAPER_IMPLEMENT(shaper) HB_ATOMIC_PTR_INIT (HB_SHAPER_DATA_INVALID), -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT - } + /* Zero for the rest is fine. */ }; @@ -1332,7 +1326,7 @@ _hb_font_create (hb_face_t *face) font->parent = hb_font_get_empty (); font->face = hb_face_reference (face); font->klass = hb_font_funcs_get_empty (); - + font->data.init0 (font); font->x_scale = font->y_scale = hb_face_get_upem (face); return font; @@ -1448,9 +1442,7 @@ hb_font_destroy (hb_font_t *font) { if (!hb_object_destroy (font)) return; -#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font); -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT + font->data.fini (); if (font->destroy) font->destroy (font->user_data); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh index fb29bcc2289..73733b34bb3 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-font.hh @@ -96,6 +96,10 @@ DECLARE_NULL_INSTANCE (hb_font_funcs_t); * hb_font_t */ +#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, font); +#include "hb-shaper-list.hh" +#undef HB_SHAPER_IMPLEMENT + struct hb_font_t { hb_object_header_t header; @@ -119,7 +123,7 @@ struct hb_font_t void *user_data; hb_destroy_func_t destroy; - struct hb_shaper_data_t shaper_data; + hb_shaper_object_dataset_t<hb_font_t> data; /* Various shaper data. */ /* Convert from font-space to user-space */ @@ -609,11 +613,5 @@ struct hb_font_t }; DECLARE_NULL_INSTANCE (hb_font_t); -#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS -#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font); -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT -#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS - #endif /* HB_FONT_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc index 8b80b960ba3..9b9d787de41 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ft.cc @@ -466,9 +466,9 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; - metrics->ascender = ft_face->size->metrics.ascender; - metrics->descender = ft_face->size->metrics.descender; - metrics->line_gap = ft_face->size->metrics.height - (ft_face->size->metrics.ascender - ft_face->size->metrics.descender); + metrics->ascender = FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale); + metrics->descender = FT_MulFix(ft_face->descender, ft_face->size->metrics.y_scale); + metrics->line_gap = FT_MulFix( ft_face->height, ft_face->size->metrics.y_scale ) - (metrics->ascender - metrics->descender); if (font->y_scale < 0) { metrics->ascender = -metrics->ascender; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc index 24ee3d507ed..a1c602c293d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-graphite2.cc @@ -26,7 +26,6 @@ * Google Author(s): Behdad Esfahbod */ -#define HB_SHAPER graphite2 #include "hb-shaper-impl.hh" #include "hb-graphite2.h" @@ -46,10 +45,6 @@ **/ -HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, face) -HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, font) - - /* * shaper face data */ @@ -185,8 +180,8 @@ _hb_graphite2_shaper_face_data_destroy (hb_graphite2_face_data_t *data) gr_face * hb_graphite2_face_get_gr_face (hb_face_t *face) { - if (unlikely (!hb_graphite2_shaper_face_data_ensure (face))) return nullptr; - return HB_SHAPER_DATA_GET (face)->grface; + const hb_graphite2_face_data_t *data = face->data.graphite2; + return data ? data->grface : nullptr; } @@ -221,28 +216,6 @@ hb_graphite2_font_get_gr_font (hb_font_t *font HB_UNUSED) /* - * shaper shape_plan data - */ - -struct hb_graphite2_shape_plan_data_t {}; - -hb_graphite2_shape_plan_data_t * -_hb_graphite2_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, - const hb_feature_t *user_features HB_UNUSED, - unsigned int num_user_features HB_UNUSED, - const int *coords HB_UNUSED, - unsigned int num_coords HB_UNUSED) -{ - return (hb_graphite2_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; -} - -void -_hb_graphite2_shaper_shape_plan_data_destroy (hb_graphite2_shape_plan_data_t *data HB_UNUSED) -{ -} - - -/* * shaper */ @@ -263,7 +236,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED, unsigned int num_features) { hb_face_t *face = font->face; - gr_face *grface = HB_SHAPER_DATA_GET (face)->grface; + gr_face *grface = face->data.graphite2->grface; const char *lang = hb_language_to_string (hb_buffer_get_language (buffer)); const char *lang_end = lang ? strchr (lang, '-') : nullptr; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-kern.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-kern.hh new file mode 100644 index 00000000000..aa01b470f29 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-kern.hh @@ -0,0 +1,139 @@ +/* + * Copyright © 2017 Google, Inc. + * + * 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. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_KERN_HH +#define HB_KERN_HH + +#include "hb-open-type.hh" +#include "hb-aat-layout-common.hh" +#include "hb-ot-layout-gpos-table.hh" + + +namespace OT { + + +template <typename Driver> +struct hb_kern_machine_t +{ + hb_kern_machine_t (const Driver &driver_, + bool crossStream_ = false) : + driver (driver_), + crossStream (crossStream_) {} + + HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW + inline void kern (hb_font_t *font, + hb_buffer_t *buffer, + hb_mask_t kern_mask, + bool scale = true) 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 kern = driver.get_kerning (info[i].codepoint, + info[j].codepoint); + + + if (likely (!kern)) + goto skip; + + if (horizontal) + { + if (scale) + kern = font->em_scale_x (kern); + if (crossStream) + { + pos[j].y_offset = kern; + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; + } + else + { + hb_position_t kern1 = kern >> 1; + hb_position_t kern2 = kern - kern1; + pos[i].x_advance += kern1; + pos[j].x_advance += kern2; + pos[j].x_offset += kern2; + } + } + else + { + if (scale) + kern = font->em_scale_y (kern); + if (crossStream) + { + pos[j].x_offset = kern; + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; + } + else + { + hb_position_t kern1 = kern >> 1; + hb_position_t kern2 = kern - kern1; + 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; + bool crossStream; +}; + + +} /* namespace OT */ + + +#endif /* HB_KERN_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh index f58050da06a..3c11243f5a1 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-machinery.hh @@ -110,17 +110,17 @@ static inline Type& StructAfter(TObject &X) static const unsigned int min_size = (size) #define DEFINE_SIZE_ARRAY(size, array) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof (array[0])); \ - DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])); \ + DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \ enum { min_size = (size) } #define DEFINE_SIZE_ARRAY_SIZED(size, array) \ - inline unsigned int get_size (void) const { return (size - array.min_size + array.get_size ()); } \ + inline unsigned int get_size (void) const { return (size - (array).min_size + (array).get_size ()); } \ DEFINE_SIZE_ARRAY(size, array) #define DEFINE_SIZE_ARRAY2(size, array1, array2) \ DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \ - DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \ + DEFINE_COMPILES_ASSERTION ((void) (array1)[0].static_size; (void) (array2)[0].static_size) \ static const unsigned int min_size = (size) @@ -298,7 +298,8 @@ struct hb_sanitize_context_t : this->start = this->end = nullptr; } - inline bool check_range (const void *base, unsigned int len) const + inline bool check_range (const void *base, + unsigned int len) const { const char *p = (const char *) base; bool ok = this->start <= p && @@ -316,20 +317,37 @@ struct hb_sanitize_context_t : } template <typename T> - inline bool check_array (const T *base, unsigned int len, unsigned int record_size = T::static_size) const + inline bool check_range (const T *base, + unsigned int a, + unsigned int b) const { - const char *p = (const char *) base; - bool overflows = hb_unsigned_mul_overflows (len, record_size); - unsigned int array_size = record_size * len; - bool ok = !overflows && this->check_range (base, array_size); + return !hb_unsigned_mul_overflows (a, b) && + this->check_range (base, a * b); + } - DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, - "check_array [%p..%p] (%d*%d=%d bytes) in [%p..%p] -> %s", - p, p + (record_size * len), record_size, len, (unsigned int) array_size, - this->start, this->end, - overflows ? "OVERFLOWS" : ok ? "OK" : "OUT-OF-RANGE"); + template <typename T> + inline bool check_range (const T *base, + unsigned int a, + unsigned int b, + unsigned int c) const + { + return !hb_unsigned_mul_overflows (a, b) && + this->check_range (base, a * b, c); + } - return likely (ok); + template <typename T> + inline bool check_array (const T *base, + unsigned int len) const + { + return this->check_range (base, len, T::static_size); + } + + template <typename T> + inline bool check_array (const T *base, + unsigned int a, + unsigned int b) const + { + return this->check_range (base, a, b, T::static_size); } template <typename Type> @@ -734,21 +752,18 @@ struct hb_data_wrapper_t return *(((Data **) (void *) this) - WheresData); } + inline bool is_inert (void) const { return !get_data (); } + template <typename Stored, typename Subclass> - inline Stored * call_create (void) const - { - Data *data = this->get_data (); - return likely (data) ? Subclass::create (data) : nullptr; - } + inline Stored * call_create (void) const { return Subclass::create (get_data ()); } }; template <> struct hb_data_wrapper_t<void, 0> { + inline bool is_inert (void) const { return false; } + template <typename Stored, typename Funcs> - inline Stored * call_create (void) const - { - return Funcs::create (); - } + inline Stored * call_create (void) const { return Funcs::create (); } }; template <typename T1, typename T2> struct hb_non_void_t { typedef T1 value; }; @@ -775,41 +790,37 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> { retry: Stored *p = instance.get (); - if (unlikely (p && !this->instance.cmpexch (p, nullptr))) + if (unlikely (p && !cmpexch (p, nullptr))) goto retry; do_destroy (p); } - inline Stored * do_create (void) const - { - Stored *p = this->template call_create<Stored, Funcs> (); - if (unlikely (!p)) - p = const_cast<Stored *> (Funcs::get_null ()); - return p; - } static inline void do_destroy (Stored *p) { - if (p && p != Funcs::get_null ()) + if (p && p != const_cast<Stored *> (Funcs::get_null ())) Funcs::destroy (p); } inline const Returned * operator -> (void) const { return get (); } inline const Returned & operator * (void) const { return *get (); } + explicit_operator inline operator bool (void) const + { return get_stored () != Funcs::get_null (); } template <typename C> inline operator const C * (void) const { return get (); } - inline Data * get_data (void) const - { - return *(((Data **) this) - WheresData); - } - inline Stored * get_stored (void) const { retry: Stored *p = this->instance.get (); if (unlikely (!p)) { - p = do_create (); - if (unlikely (!this->instance.cmpexch (nullptr, p))) + if (unlikely (this->is_inert ())) + return const_cast<Stored *> (Funcs::get_null ()); + + p = this->template call_create<Stored, Funcs> (); + if (unlikely (!p)) + p = const_cast<Stored *> (Funcs::get_null ()); + + if (unlikely (!cmpexch (nullptr, p))) { do_destroy (p); goto retry; @@ -822,15 +833,10 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> return this->instance.get_relaxed (); } - inline void set_stored (Stored *instance_) + inline bool cmpexch (Stored *current, Stored *value) const { - /* This *must* be called when there are no other threads accessing. - * However, to make TSan, etc, happy, we using cmpexch. */ - retry: - Stored *p = this->instance.get (); - if (unlikely (!this->instance.cmpexch (p, instance_))) - goto retry; - do_destroy (p); + /* This *must* be called when there are no other threads accessing. */ + return this->instance.cmpexch (current, value); } inline const Returned * get (void) const { return Funcs::convert (get_stored ()); } @@ -862,7 +868,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> free (p); } - private: +// private: /* Must only have one pointer. */ hb_atomic_ptr_t<Stored *> instance; }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh index 75b89addb9a..b529091d44a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-mutex.hh @@ -48,7 +48,7 @@ /* Defined externally, i.e. in config.h; must have typedef'ed hb_mutex_impl_t as well. */ -#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__)) +#elif !defined(HB_NO_MT) && defined(_WIN32) #include <windows.h> typedef CRITICAL_SECTION hb_mutex_impl_t; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh index 74340c555a8..cdacf49f4c1 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-object.hh @@ -194,7 +194,7 @@ struct hb_user_data_array_t struct hb_object_header_t { hb_reference_count_t ref_count; - hb_atomic_int_t writable; + mutable hb_atomic_int_t writable; hb_atomic_ptr_t<hb_user_data_array_t> user_data; }; #define HB_OBJECT_HEADER_STATIC \ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh index 0f6efdc6905..b1fcd68777f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh @@ -58,7 +58,7 @@ struct IntType { typedef Type type; inline void set (Type i) { v.set (i); } - inline operator Type(void) const { return v; } + inline operator Type (void) const { return v; } inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; } inline bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); } static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); } @@ -173,7 +173,7 @@ struct Offset : Type } public: - DEFINE_SIZE_STATIC (sizeof(Type)); + DEFINE_SIZE_STATIC (sizeof (Type)); }; typedef Offset<HBUINT16> Offset16; @@ -211,7 +211,7 @@ struct CheckSum : HBUINT32 template <typename FixedType=HBUINT16> struct FixedVersion { - inline uint32_t to_int (void) const { return (major << (sizeof(FixedType) * 8)) + minor; } + inline uint32_t to_int (void) const { return (major << (sizeof (FixedType) * 8)) + minor; } inline bool sanitize (hb_sanitize_context_t *c) const { @@ -222,7 +222,7 @@ struct FixedVersion FixedType major; FixedType minor; public: - DEFINE_SIZE_STATIC (2 * sizeof(FixedType)); + DEFINE_SIZE_STATIC (2 * sizeof (FixedType)); }; @@ -241,12 +241,12 @@ struct OffsetTo : Offset<OffsetType, has_null> inline const Type& operator () (const void *base) const { - if (unlikely (this->is_null ())) return Null(Type); + if (unlikely (this->is_null ())) return Null (Type); return StructAtOffset<const Type> (base, *this); } inline Type& operator () (void *base) const { - if (unlikely (this->is_null ())) return Crap(Type); + if (unlikely (this->is_null ())) return Crap (Type); return StructAtOffset<Type> (base, *this); } @@ -258,7 +258,7 @@ struct OffsetTo : Offset<OffsetType, has_null> template <typename T> inline void serialize_subset (hb_subset_context_t *c, const T &src, const void *base) { - if (&src == &Null(T)) + if (&src == &Null (T)) { this->set (0); return; @@ -319,7 +319,7 @@ struct OffsetTo : Offset<OffsetType, has_null> if (!has_null) return false; return c->try_set (this, 0); } - DEFINE_SIZE_STATIC (sizeof(OffsetType)); + DEFINE_SIZE_STATIC (sizeof (OffsetType)); }; template <typename Type, bool has_null=true> struct LOffsetTo : OffsetTo<Type, HBUINT32, has_null> {}; template <typename Base, typename OffsetType, bool has_null, typename Type> @@ -335,10 +335,22 @@ static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType, has_null> template <typename Type> struct UnsizedArrayOf { + enum { item_size = Type::static_size }; + HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (UnsizedArrayOf, Type); - inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; } - inline Type& operator [] (unsigned int i) { return arrayZ[i]; } + inline const Type& operator [] (unsigned int i) const + { + const Type *p = &arrayZ[i]; + if (unlikely (p < arrayZ)) return Null (Type); /* Overflowed. */ + return *p; + } + inline Type& operator [] (unsigned int i) + { + Type *p = &arrayZ[i]; + if (unlikely (p < arrayZ)) return Crap (Type); /* Overflowed. */ + return *p; + } template <typename T> inline operator T * (void) { return arrayZ; } template <typename T> inline operator const T * (void) const { return arrayZ; } @@ -371,7 +383,7 @@ struct UnsizedArrayOf if (unlikely (!sanitize_shallow (c, count))) return_trace (false); for (unsigned int i = 0; i < count; i++) if (unlikely (!arrayZ[i].sanitize (c, base))) - return_trace (false); + return_trace (false); return_trace (true); } template <typename T> @@ -381,7 +393,7 @@ struct UnsizedArrayOf if (unlikely (!sanitize_shallow (c, count))) return_trace (false); for (unsigned int i = 0; i < count; i++) if (unlikely (!arrayZ[i].sanitize (c, base, user_data))) - return_trace (false); + return_trace (false); return_trace (true); } @@ -427,6 +439,8 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType, has_null> template <typename Type, typename LenType=HBUINT16> struct ArrayOf { + enum { item_size = Type::static_size }; + HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (ArrayOf, Type, LenType); inline const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const @@ -443,12 +457,12 @@ struct ArrayOf inline const Type& operator [] (unsigned int i) const { - if (unlikely (i >= len)) return Null(Type); + if (unlikely (i >= len)) return Null (Type); return arrayZ[i]; } inline Type& operator [] (unsigned int i) { - if (unlikely (i >= len)) return Crap(Type); + if (unlikely (i >= len)) return Crap (Type); return arrayZ[i]; } @@ -499,7 +513,7 @@ struct ArrayOf unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (unlikely (!arrayZ[i].sanitize (c, base))) - return_trace (false); + return_trace (false); return_trace (true); } template <typename T> @@ -510,7 +524,7 @@ struct ArrayOf unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (unlikely (!arrayZ[i].sanitize (c, base, user_data))) - return_trace (false); + return_trace (false); return_trace (true); } @@ -520,7 +534,7 @@ struct ArrayOf unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (!this->arrayZ[i].cmp (x)) - return i; + return i; return -1; } @@ -558,12 +572,12 @@ struct OffsetListOf : OffsetArrayOf<Type> { inline const Type& operator [] (unsigned int i) const { - if (unlikely (i >= this->len)) return Null(Type); + if (unlikely (i >= this->len)) return Null (Type); return this+this->arrayZ[i]; } inline const Type& operator [] (unsigned int i) { - if (unlikely (i >= this->len)) return Crap(Type); + if (unlikely (i >= this->len)) return Crap (Type); return this+this->arrayZ[i]; } @@ -595,16 +609,18 @@ struct OffsetListOf : OffsetArrayOf<Type> template <typename Type, typename LenType=HBUINT16> struct HeadlessArrayOf { + enum { item_size = Type::static_size }; + HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (HeadlessArrayOf, Type, LenType); inline const Type& operator [] (unsigned int i) const { - if (unlikely (i >= lenP1 || !i)) return Null(Type); + if (unlikely (i >= lenP1 || !i)) return Null (Type); return arrayZ[i-1]; } inline Type& operator [] (unsigned int i) { - if (unlikely (i >= lenP1 || !i)) return Crap(Type); + if (unlikely (i >= lenP1 || !i)) return Crap (Type); return arrayZ[i-1]; } inline unsigned int get_size (void) const @@ -665,12 +681,12 @@ struct ArrayOfM1 inline const Type& operator [] (unsigned int i) const { - if (unlikely (i > lenM1)) return Null(Type); + if (unlikely (i > lenM1)) return Null (Type); return arrayZ[i]; } inline Type& operator [] (unsigned int i) { - if (unlikely (i > lenM1)) return Crap(Type); + if (unlikely (i > lenM1)) return Crap (Type); return arrayZ[i]; } inline unsigned int get_size (void) const @@ -684,7 +700,7 @@ struct ArrayOfM1 unsigned int count = lenM1 + 1; for (unsigned int i = 0; i < count; i++) if (unlikely (!arrayZ[i].sanitize (c, base, user_data))) - return_trace (false); + return_trace (false); return_trace (true); } @@ -717,12 +733,9 @@ struct SortedArrayOf : ArrayOf<Type, LenType> { int mid = ((unsigned int) min + (unsigned int) max) / 2; int c = arr[mid].cmp (x); - if (c < 0) - max = mid - 1; - else if (c > 0) - min = mid + 1; - else - return mid; + if (c < 0) max = mid - 1; + else if (c > 0) min = mid + 1; + else return mid; } return -1; } @@ -793,11 +806,13 @@ struct VarSizedBinSearchHeader template <typename Type> struct VarSizedBinSearchArrayOf { + enum { item_size = Type::static_size }; + HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (VarSizedBinSearchArrayOf, Type); inline const Type& operator [] (unsigned int i) const { - if (unlikely (i >= header.nUnits)) return Null(Type); + if (unlikely (i >= header.nUnits)) return Null (Type); return StructAtOffset<Type> (&bytesZ, i * header.unitSize); } inline Type& operator [] (unsigned int i) @@ -830,7 +845,18 @@ struct VarSizedBinSearchArrayOf 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 (false); + return_trace (true); + } + template <typename T> + inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) 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, user_data))) + return_trace (false); return_trace (true); } @@ -844,12 +870,9 @@ struct VarSizedBinSearchArrayOf int mid = ((unsigned int) min + (unsigned int) 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; + if (c < 0) max = mid - 1; + else if (c > 0) min = mid + 1; + else return p; } return nullptr; } @@ -860,7 +883,9 @@ struct VarSizedBinSearchArrayOf TRACE_SANITIZE (this); return_trace (header.sanitize (c) && Type::static_size <= header.unitSize && - c->check_array (bytesZ.arrayZ, header.nUnits, header.unitSize)); + c->check_range (bytesZ.arrayZ, + header.nUnits, + header.unitSize)); } protected: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh index bcb50790e40..b7d17018ac6 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-cmap-table.hh @@ -53,7 +53,7 @@ struct CmapSubtableFormat0 { for (unsigned int i = 0; i < 256; i++) if (glyphIdArray[i]) - out->add (i); + out->add (i); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -82,8 +82,8 @@ struct CmapSubtableFormat4 }; bool serialize (hb_serialize_context_t *c, - const hb_subset_plan_t *plan, - const hb_vector_t<segment_plan> &segments) + const hb_subset_plan_t *plan, + const hb_vector_t<segment_plan> &segments) { TRACE_SERIALIZE (this); @@ -96,8 +96,8 @@ struct CmapSubtableFormat4 this->entrySelector.set (MAX (1u, hb_bit_storage (segments.len)) - 1); this->searchRange.set (2 * (1u << this->entrySelector)); this->rangeShift.set (segments.len * 2 > this->searchRange - ? 2 * segments.len - this->searchRange - : 0); + ? 2 * segments.len - this->searchRange + : 0); HBUINT16 *end_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len); c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding. @@ -114,40 +114,40 @@ struct CmapSubtableFormat4 start_count[i].set (segments[i].start_code); if (segments[i].use_delta) { - hb_codepoint_t cp = segments[i].start_code; - hb_codepoint_t start_gid = 0; - if (unlikely (!plan->new_gid_for_codepoint (cp, &start_gid) && cp != 0xFFFF)) - return_trace (false); - id_delta[i].set (start_gid - segments[i].start_code); + hb_codepoint_t cp = segments[i].start_code; + hb_codepoint_t start_gid = 0; + if (unlikely (!plan->new_gid_for_codepoint (cp, &start_gid) && cp != 0xFFFF)) + return_trace (false); + id_delta[i].set (start_gid - segments[i].start_code); } else { - id_delta[i].set (0); - unsigned int num_codepoints = segments[i].end_code - segments[i].start_code + 1; - HBUINT16 *glyph_id_array = c->allocate_size<HBUINT16> (HBUINT16::static_size * num_codepoints); - if (glyph_id_array == nullptr) - return_trace (false); - // From the cmap spec: - // - // id_range_offset[i]/2 - // + (cp - segments[i].start_code) - // + (id_range_offset + i) - // = - // glyph_id_array + (cp - segments[i].start_code) - // - // So, solve for id_range_offset[i]: - // - // id_range_offset[i] - // = - // 2 * (glyph_id_array - id_range_offset - i) - id_range_offset[i].set (2 * ( - glyph_id_array - id_range_offset - i)); - for (unsigned int j = 0; j < num_codepoints; j++) - { - hb_codepoint_t cp = segments[i].start_code + j; - hb_codepoint_t new_gid; - if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid))) - return_trace (false); - glyph_id_array[j].set (new_gid); - } + id_delta[i].set (0); + unsigned int num_codepoints = segments[i].end_code - segments[i].start_code + 1; + HBUINT16 *glyph_id_array = c->allocate_size<HBUINT16> (HBUINT16::static_size * num_codepoints); + if (glyph_id_array == nullptr) + return_trace (false); + // From the cmap spec: + // + // id_range_offset[i]/2 + // + (cp - segments[i].start_code) + // + (id_range_offset + i) + // = + // glyph_id_array + (cp - segments[i].start_code) + // + // So, solve for id_range_offset[i]: + // + // id_range_offset[i] + // = + // 2 * (glyph_id_array - id_range_offset - i) + id_range_offset[i].set (2 * ( + glyph_id_array - id_range_offset - i)); + for (unsigned int j = 0; j < num_codepoints; j++) + { + hb_codepoint_t cp = segments[i].start_code + j; + hb_codepoint_t new_gid; + if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid))) + return_trace (false); + glyph_id_array[j].set (new_gid); + } } } @@ -161,23 +161,23 @@ struct CmapSubtableFormat4 { // Parallel array entries segment_size += - 2 // end count - + 2 // start count - + 2 // delta - + 2; // range offset + 2 // end count + + 2 // start count + + 2 // delta + + 2; // range offset if (!segments[i].use_delta) - // Add bytes for the glyph index array entries for this segment. - segment_size += (segments[i].end_code - segments[i].start_code + 1) * 2; + // Add bytes for the glyph index array entries for this segment. + segment_size += (segments[i].end_code - segments[i].start_code + 1) * 2; } return min_size - + 2 // Padding - + segment_size; + + 2 // Padding + + segment_size; } static inline bool create_sub_table_plan (const hb_subset_plan_t *plan, - hb_vector_t<segment_plan> *segments) + hb_vector_t<segment_plan> *segments) { segment_plan *segment = nullptr; hb_codepoint_t last_gid = 0; @@ -191,24 +191,22 @@ struct CmapSubtableFormat4 return false; } - if (cp > 0xFFFF) { - // We are now outside of unicode BMP, stop adding to this cmap. - break; - } + /* Stop adding to cmap if we are now outside of unicode BMP. */ + if (cp > 0xFFFF) break; - if (!segment - || cp != segment->end_code + 1u) + if (!segment || + cp != segment->end_code + 1u) { - segment = segments->push (); - segment->start_code.set (cp); - segment->end_code.set (cp); - segment->use_delta = true; + segment = segments->push (); + segment->start_code.set (cp); + segment->end_code.set (cp); + segment->use_delta = true; } else { - segment->end_code.set (cp); - if (last_gid + 1u != new_gid) - // gid's are not consecutive in this segment so delta - // cannot be used. - segment->use_delta = false; + segment->end_code.set (cp); + if (last_gid + 1u != new_gid) + // gid's are not consecutive in this segment so delta + // cannot be used. + segment->use_delta = false; } last_gid = new_gid; @@ -253,7 +251,7 @@ struct CmapSubtableFormat4 unsigned int i; while (min <= max) { - int mid = ((unsigned int) min + (unsigned int) max) / 2; + int mid = ((unsigned int) min + (unsigned int) max) / 2; if (codepoint < startCount[mid]) max = mid - 1; else if (codepoint > endCount[mid]) @@ -296,7 +294,7 @@ struct CmapSubtableFormat4 { unsigned int count = this->segCount; if (count && this->startCount[count - 1] == 0xFFFFu) - count--; /* Skip sentinel segment. */ + count--; /* Skip sentinel segment. */ for (unsigned int i = 0; i < count; i++) { unsigned int rangeOffset = this->idRangeOffset[i]; @@ -438,7 +436,7 @@ struct CmapSubtableTrimmed unsigned int count = glyphIdArray.len; for (unsigned int i = 0; i < count; i++) if (glyphIdArray[i]) - out->add (start + i); + out->add (start + i); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -495,7 +493,7 @@ struct CmapSubtableLongSegmented } inline bool serialize (hb_serialize_context_t *c, - const hb_vector_t<CmapSubtableLongGroup> &group_data) + const hb_vector_t<CmapSubtableLongGroup> &group_data) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); @@ -523,7 +521,7 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> bool serialize (hb_serialize_context_t *c, - const hb_vector_t<CmapSubtableLongGroup> &groups) + const hb_vector_t<CmapSubtableLongGroup> &groups) { if (unlikely (!c->extend_min (*this))) return false; @@ -540,7 +538,7 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> } static inline bool create_sub_table_plan (const hb_subset_plan_t *plan, - hb_vector_t<CmapSubtableLongGroup> *groups) + hb_vector_t<CmapSubtableLongGroup> *groups) { CmapSubtableLongGroup *group = nullptr; @@ -555,14 +553,12 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12> if (!group || !_is_gid_consecutive (group, cp, new_gid)) { - group = groups->push (); - group->startCharCode.set (cp); - group->endCharCode.set (cp); - group->glyphID.set (new_gid); - } else - { - group->endCharCode.set (cp); + group = groups->push (); + group->startCharCode.set (cp); + group->endCharCode.set (cp); + group->glyphID.set (new_gid); } + else group->endCharCode.set (cp); } DEBUG_MSG(SUBSET, nullptr, "cmap"); @@ -636,7 +632,7 @@ struct DefaultUVS : SortedArrayOf<UnicodeValueRange, HBUINT32> } public: - DEFINE_SIZE_ARRAY (4, arrayZ); + DEFINE_SIZE_ARRAY (4, *this); }; struct UVSMapping @@ -668,7 +664,7 @@ struct NonDefaultUVS : SortedArrayOf<UVSMapping, HBUINT32> } public: - DEFINE_SIZE_ARRAY (4, arrayZ); + DEFINE_SIZE_ARRAY (4, *this); }; struct VariationSelectorRecord @@ -855,12 +851,12 @@ struct cmap struct subset_plan { - inline size_t final_size() const + inline size_t final_size () const { return 4 // header - + 8 * 3 // 3 EncodingRecord - + CmapSubtableFormat4::get_sub_table_size (this->format4_segments) - + CmapSubtableFormat12::get_sub_table_size (this->format12_groups); + + 8 * 3 // 3 EncodingRecord + + CmapSubtableFormat4::get_sub_table_size (this->format4_segments) + + CmapSubtableFormat12::get_sub_table_size (this->format12_groups); } hb_vector_t<CmapSubtableFormat4::segment_plan> format4_segments; @@ -876,16 +872,16 @@ struct cmap } inline bool _create_plan (const hb_subset_plan_t *plan, - subset_plan *cmap_plan) const + subset_plan *cmap_plan) const { - if (unlikely( !CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments))) + if (unlikely (!CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments))) return false; return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->format12_groups); } inline bool _subset (const hb_subset_plan_t *plan, - const subset_plan &cmap_subset_plan, + const subset_plan &cmap_subset_plan, size_t dest_sz, void *dest) const { @@ -927,7 +923,7 @@ struct cmap CmapSubtableFormat4 &format4 = subtable.u.format4; if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments))) - return false; + return false; } // Write out format 12 sub table. @@ -937,7 +933,7 @@ struct cmap CmapSubtableFormat12 &format12 = subtable.u.format12; if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups))) - return false; + return false; } c.end_serialize (); @@ -956,7 +952,7 @@ struct cmap } // We now know how big our blob needs to be - size_t dest_sz = cmap_subset_plan.final_size(); + size_t dest_sz = cmap_subset_plan.final_size (); void *dest = malloc (dest_sz); if (unlikely (!dest)) { DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz); @@ -971,11 +967,11 @@ struct cmap } // all done, write the blob into dest - hb_blob_t *cmap_prime = hb_blob_create ((const char *)dest, - dest_sz, - HB_MEMORY_MODE_READONLY, - dest, - free); + hb_blob_t *cmap_prime = hb_blob_create ((const char *) dest, + dest_sz, + HB_MEMORY_MODE_READONLY, + dest, + free); bool result = plan->add_table (HB_OT_TAG_cmap, cmap_prime); hb_blob_destroy (cmap_prime); return result; @@ -1007,32 +1003,29 @@ struct cmap } /* Meh. */ - return &Null(CmapSubtable); + return &Null (CmapSubtable); } struct accelerator_t { inline void init (hb_face_t *face) { - this->blob = hb_sanitize_context_t().reference_table<cmap> (face); - const cmap *table = this->blob->as<cmap> (); + this->table = hb_sanitize_context_t ().reference_table<cmap> (face); bool symbol; - subtableZ = table->find_best_subtable (&symbol); - - /* UVS subtable. */ - subtable_uvsZ = &Null(CmapSubtableFormat14); + this->subtable = table->find_best_subtable (&symbol); + this->subtable_uvs = &Null (CmapSubtableFormat14); { const CmapSubtable *st = table->find_subtable (0, 5); if (st && st->u.format == 14) - subtable_uvsZ = &st->u.format14; + subtable_uvs = &st->u.format14; } - this->get_glyph_data = subtableZ; + this->get_glyph_data = subtable; if (unlikely (symbol)) { this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable>; } else { - switch (subtableZ->u.format) { + switch (subtable->u.format) { /* Accelerate format 4 and format 12. */ default: this->get_glyph_funcZ = get_glyph_from<CmapSubtable>; @@ -1042,7 +1035,7 @@ struct cmap break; case 4: { - this->format4_accel.init (&subtableZ->u.format4); + this->format4_accel.init (&subtable->u.format4); this->get_glyph_data = &this->format4_accel; this->get_glyph_funcZ = this->format4_accel.get_glyph_func; } @@ -1053,7 +1046,7 @@ struct cmap inline void fini (void) { - hb_blob_destroy (this->blob); + this->table.destroy (); } inline bool get_nominal_glyph (hb_codepoint_t unicode, @@ -1062,15 +1055,35 @@ struct cmap if (unlikely (!this->get_glyph_funcZ)) return false; return this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph); } + inline unsigned int get_nominal_glyphs (unsigned int count, + const hb_codepoint_t *first_unicode, + unsigned int unicode_stride, + hb_codepoint_t *first_glyph, + unsigned int glyph_stride) const + { + if (unlikely (!this->get_glyph_funcZ)) return 0; + + hb_cmap_get_glyph_func_t get_glyph_funcZ = this->get_glyph_funcZ; + const void *get_glyph_data = this->get_glyph_data; + + unsigned int done; + for (done = 0; + done < count && get_glyph_funcZ (get_glyph_data, *first_unicode, first_glyph); + done++) + { + first_unicode = &StructAtOffset<hb_codepoint_t> (first_unicode, unicode_stride); + first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride); + } + return done; + } inline bool get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, hb_codepoint_t *glyph) const { - if (unlikely (!this->subtable_uvsZ)) return false; - switch (this->subtable_uvsZ->get_glyph_variant (unicode, - variation_selector, - glyph)) + switch (this->subtable_uvs->get_glyph_variant (unicode, + variation_selector, + glyph)) { case GLYPH_VARIANT_NOT_FOUND: return false; case GLYPH_VARIANT_FOUND: return true; @@ -1082,19 +1095,16 @@ struct cmap inline void collect_unicodes (hb_set_t *out) const { - if (unlikely (!this->subtableZ)) return; - subtableZ->collect_unicodes (out); + subtable->collect_unicodes (out); } inline void collect_variation_selectors (hb_set_t *out) const { - if (unlikely (!this->subtable_uvsZ)) return; - subtable_uvsZ->collect_variation_selectors (out); + subtable_uvs->collect_variation_selectors (out); } inline void collect_variation_unicodes (hb_codepoint_t variation_selector, hb_set_t *out) const { - if (unlikely (!this->subtable_uvsZ)) return; - subtable_uvsZ->collect_variation_unicodes (variation_selector, out); + subtable_uvs->collect_variation_unicodes (variation_selector, out); } protected: @@ -1134,15 +1144,15 @@ struct cmap } private: - const CmapSubtable *subtableZ; - const CmapSubtableFormat14 *subtable_uvsZ; + hb_nonnull_ptr_t<const CmapSubtable> subtable; + hb_nonnull_ptr_t<const CmapSubtableFormat14> subtable_uvs; hb_cmap_get_glyph_func_t get_glyph_funcZ; const void *get_glyph_data; CmapSubtableFormat4::accelerator_t format4_accel; - hb_blob_t *blob; + hb_blob_ptr_t<cmap> table; }; protected: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh index 580dc37690f..47774fd8f0a 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-cbdt-table.hh @@ -384,26 +384,16 @@ struct CBDT { inline void init (hb_face_t *face) { - upem = hb_face_get_upem (face); - - cblc_blob = hb_sanitize_context_t().reference_table<CBLC> (face); - cbdt_blob = hb_sanitize_context_t().reference_table<CBDT> (face); - cbdt_len = hb_blob_get_length (cbdt_blob); - - if (hb_blob_get_length (cblc_blob) == 0) { - cblc = nullptr; - cbdt = nullptr; - return; /* Not a bitmap font. */ - } - cblc = cblc_blob->as<CBLC> (); - cbdt = cbdt_blob->as<CBDT> (); + cblc = hb_sanitize_context_t().reference_table<CBLC> (face); + cbdt = hb_sanitize_context_t().reference_table<CBDT> (face); + upem = hb_face_get_upem (face); } inline void fini (void) { - hb_blob_destroy (this->cblc_blob); - hb_blob_destroy (this->cbdt_blob); + this->cblc.destroy (); + this->cbdt.destroy (); } inline bool get_extents (hb_font_t *font, hb_codepoint_t glyph, @@ -423,6 +413,7 @@ struct CBDT return false; { + unsigned int cbdt_len = cbdt.get_length (); if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length)) return false; @@ -475,6 +466,7 @@ struct CBDT return hb_blob_get_empty (); { + unsigned int cbdt_len = cbdt.get_length (); if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length)) return hb_blob_get_empty (); @@ -485,7 +477,7 @@ struct CBDT return hb_blob_get_empty (); const GlyphBitmapDataFormat17& glyphFormat17 = StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset); - return hb_blob_create_sub_blob (cbdt_blob, + return hb_blob_create_sub_blob (cbdt.get_blob (), image_offset + GlyphBitmapDataFormat17::min_size, glyphFormat17.data.len); } @@ -494,7 +486,7 @@ struct CBDT return hb_blob_get_empty (); const GlyphBitmapDataFormat18& glyphFormat18 = StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset); - return hb_blob_create_sub_blob (cbdt_blob, + return hb_blob_create_sub_blob (cbdt.get_blob (), image_offset + GlyphBitmapDataFormat18::min_size, glyphFormat18.data.len); } @@ -503,7 +495,7 @@ struct CBDT return hb_blob_get_empty (); const GlyphBitmapDataFormat19& glyphFormat19 = StructAtOffset<GlyphBitmapDataFormat19> (this->cbdt, image_offset); - return hb_blob_create_sub_blob (cbdt_blob, + return hb_blob_create_sub_blob (cbdt.get_blob (), image_offset + GlyphBitmapDataFormat19::min_size, glyphFormat19.data.len); } @@ -513,16 +505,12 @@ struct CBDT return hb_blob_get_empty (); } - inline bool has_data () const - { return cbdt_len; } + inline bool has_data () const { return cbdt.get_length (); } private: - hb_blob_t *cblc_blob; - hb_blob_t *cbdt_blob; - hb_nonnull_ptr_t<const CBLC> cblc; - hb_nonnull_ptr_t<const CBDT> cbdt; + hb_blob_ptr_t<CBLC> cblc; + hb_blob_ptr_t<CBDT> cbdt; - unsigned int cbdt_len; unsigned int upem; }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh index b480af51d2c..fa40223b725 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-colr-table.hh @@ -103,7 +103,12 @@ struct COLR unsigned int *count, /* IN/OUT. May be NULL. */ hb_ot_color_layer_t *layers /* OUT. May be NULL. */) const { - const BaseGlyphRecord &record = get_glyph_record (glyph); + const BaseGlyphRecord *rec = (BaseGlyphRecord *) bsearch (&glyph, + &(this+baseGlyphsZ), + numBaseGlyphs, + sizeof (BaseGlyphRecord), + BaseGlyphRecord::cmp); + const BaseGlyphRecord &record = rec ? *rec : Null (BaseGlyphRecord); hb_array_t<const LayerRecord> all_layers ((this+layersZ).arrayZ, numLayers); hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx, @@ -129,17 +134,6 @@ struct COLR (this+layersZ).sanitize (c, numLayers))); } - private: - inline const BaseGlyphRecord &get_glyph_record (hb_codepoint_t glyph_id) const - { - const BaseGlyphRecord *rec = (BaseGlyphRecord *) bsearch (&glyph_id, - &(this+baseGlyphsZ), - numBaseGlyphs, - sizeof (BaseGlyphRecord), - BaseGlyphRecord::cmp); - return rec ? *rec : Null(BaseGlyphRecord); - } - protected: HBUINT16 version; /* Table version number (starts at 0). */ HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records. */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh index 7a01d14ae78..08dee2a0c67 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-sbix-table.hh @@ -140,14 +140,13 @@ struct sbix { inline void init (hb_face_t *face) { - sbix_blob = hb_sanitize_context_t().reference_table<sbix> (face); - table = sbix_blob->as<sbix> (); + table = hb_sanitize_context_t().reference_table<sbix> (face); num_glyphs = face->get_num_glyphs (); } inline void fini (void) { - hb_blob_destroy (sbix_blob); + table.destroy (); } inline bool has_data () const @@ -169,7 +168,7 @@ struct sbix int *y_offset, unsigned int *available_ppem) const { - return choose_strike (font).get_glyph_blob (glyph_id, sbix_blob, + return choose_strike (font).get_glyph_blob (glyph_id, table.get_blob (), HB_TAG ('p','n','g',' '), x_offset, y_offset, num_glyphs, available_ppem); @@ -250,7 +249,7 @@ struct sbix /* Convert to font units. */ if (strike_ppem) { - double scale = font->face->upem / (double) strike_ppem; + double scale = font->face->get_upem () / (double) strike_ppem; extents->x_bearing = round (extents->x_bearing * scale); extents->y_bearing = round (extents->y_bearing * scale); extents->width = round (extents->width * scale); @@ -263,8 +262,7 @@ struct sbix } private: - hb_blob_t *sbix_blob; - hb_nonnull_ptr_t<const sbix> table; + hb_blob_ptr_t<sbix> table; unsigned int num_glyphs; }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh index 069c547889a..bad8ef549bb 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color-svg-table.hh @@ -81,25 +81,24 @@ struct SVG { inline void init (hb_face_t *face) { - svg_blob = hb_sanitize_context_t().reference_table<SVG> (face); - table = svg_blob->as<SVG> (); + table = hb_sanitize_context_t().reference_table<SVG> (face); } inline void fini (void) { - hb_blob_destroy (svg_blob); + table.destroy (); } inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const { - return table->get_glyph_entry (glyph_id).reference_blob (svg_blob, table->svgDocEntries); + return table->get_glyph_entry (glyph_id).reference_blob (table.get_blob (), + table->svgDocEntries); } inline bool has_data () const { return table->has_data (); } private: - hb_blob_t *svg_blob; - hb_nonnull_ptr_t<const SVG> table; + hb_blob_ptr_t<SVG> table; }; inline const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc index 853f65dcf65..791135b100c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-color.cc @@ -50,42 +50,6 @@ **/ -static inline const OT::COLR& -_get_colr (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::COLR); - return *(hb_ot_face_data (face)->COLR); -} - -static inline const OT::CBDT_accelerator_t& -_get_cbdt (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CBDT_accelerator_t); - return *(hb_ot_face_data (face)->CBDT); -} - -static inline const OT::CPAL& -_get_cpal (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CPAL); - return *(hb_ot_face_data (face)->CPAL); -} - -static inline const OT::sbix_accelerator_t& -_get_sbix (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::sbix_accelerator_t); - return *(hb_ot_face_data (face)->sbix); -} - -static inline const OT::SVG_accelerator_t& -_get_svg (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::SVG_accelerator_t); - return *(hb_ot_face_data (face)->SVG); -} - - /* * CPAL */ @@ -102,7 +66,7 @@ _get_svg (hb_face_t *face) hb_bool_t hb_ot_color_has_palettes (hb_face_t *face) { - return _get_cpal (face).has_data (); + return face->table.CPAL->has_data (); } /** @@ -117,7 +81,7 @@ hb_ot_color_has_palettes (hb_face_t *face) unsigned int hb_ot_color_palette_get_count (hb_face_t *face) { - return _get_cpal (face).get_palette_count (); + return face->table.CPAL->get_palette_count (); } /** @@ -137,7 +101,7 @@ hb_ot_name_id_t hb_ot_color_palette_get_name_id (hb_face_t *face, unsigned int palette_index) { - return _get_cpal (face).get_palette_name_id (palette_index); + return face->table.CPAL->get_palette_name_id (palette_index); } /** @@ -153,7 +117,7 @@ hb_ot_name_id_t hb_ot_color_palette_color_get_name_id (hb_face_t *face, unsigned int color_index) { - return _get_cpal (face).get_color_name_id (color_index); + return face->table.CPAL->get_color_name_id (color_index); } /** @@ -169,7 +133,7 @@ hb_ot_color_palette_flags_t hb_ot_color_palette_get_flags (hb_face_t *face, unsigned int palette_index) { - return _get_cpal(face).get_palette_flags (palette_index); + return face->table.CPAL->get_palette_flags (palette_index); } /** @@ -203,7 +167,7 @@ hb_ot_color_palette_get_colors (hb_face_t *face, unsigned int *colors_count /* IN/OUT. May be NULL. */, hb_color_t *colors /* OUT. May be NULL. */) { - return _get_cpal (face).get_palette_colors (palette_index, start_offset, colors_count, colors); + return face->table.CPAL->get_palette_colors (palette_index, start_offset, colors_count, colors); } @@ -222,7 +186,7 @@ hb_ot_color_palette_get_colors (hb_face_t *face, hb_bool_t hb_ot_color_has_layers (hb_face_t *face) { - return _get_colr (face).has_data (); + return face->table.COLR->has_data (); } /** @@ -245,7 +209,7 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, unsigned int *count, /* IN/OUT. May be NULL. */ hb_ot_color_layer_t *layers /* OUT. May be NULL. */) { - return _get_colr (face).get_glyph_layers (glyph, start_offset, count, layers); + return face->table.COLR->get_glyph_layers (glyph, start_offset, count, layers); } @@ -266,7 +230,7 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, hb_bool_t hb_ot_color_has_svg (hb_face_t *face) { - return _get_svg (face).has_data (); + return face->table.SVG->has_data (); } /** @@ -274,7 +238,7 @@ hb_ot_color_has_svg (hb_face_t *face) * @face: a font face. * @glyph: a svg glyph index. * - * Get SVG document for a glyph. + * Get SVG document for a glyph. The blob may be either plain text or gzip-encoded. * * Returns: (transfer full): respective svg blob of the glyph, if available. * @@ -283,7 +247,7 @@ hb_ot_color_has_svg (hb_face_t *face) hb_blob_t * hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph) { - return _get_svg (face).reference_blob_for_glyph (glyph); + return face->table.SVG->reference_blob_for_glyph (glyph); } @@ -304,7 +268,7 @@ hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph) hb_bool_t hb_ot_color_has_png (hb_face_t *face) { - return _get_cbdt (face).has_data () || _get_sbix (face).has_data (); + return face->table.CBDT->has_data () || face->table.sbix->has_data (); } /** @@ -325,11 +289,11 @@ hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph) { hb_blob_t *blob = hb_blob_get_empty (); - if (_get_sbix (font->face).has_data ()) - blob = _get_sbix (font->face).reference_png (font, glyph, nullptr, nullptr, nullptr); + if (font->face->table.sbix->has_data ()) + blob = font->face->table.sbix->reference_png (font, glyph, nullptr, nullptr, nullptr); - if (!blob->length && _get_cbdt (font->face).has_data ()) - blob = _get_cbdt (font->face).reference_png (font, glyph); + if (!blob->length && font->face->table.CBDT->has_data ()) + blob = font->face->table.CBDT->reference_png (font, glyph); return blob; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc index cbceea9b158..c7dafdd4ab9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.cc @@ -40,7 +40,7 @@ #include "hb-ot-layout-gpos-table.hh" -void hb_ot_face_data_t::init0 (hb_face_t *face) +void hb_ot_face_t::init0 (hb_face_t *face) { this->face = face; #define HB_OT_TABLE(Namespace, Type) Type.init0 (); @@ -49,7 +49,7 @@ void hb_ot_face_data_t::init0 (hb_face_t *face) #undef HB_OT_ACCELERATOR #undef HB_OT_TABLE } -void hb_ot_face_data_t::fini (void) +void hb_ot_face_t::fini (void) { #define HB_OT_TABLE(Namespace, Type) Type.fini (); #define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type) @@ -57,23 +57,3 @@ void hb_ot_face_data_t::fini (void) #undef HB_OT_ACCELERATOR #undef HB_OT_TABLE } - -hb_ot_face_data_t * -_hb_ot_face_data_create (hb_face_t *face) -{ - hb_ot_face_data_t *data = (hb_ot_face_data_t *) calloc (1, sizeof (hb_ot_face_data_t)); - if (unlikely (!data)) - return nullptr; - - data->init0 (face); - - return data; -} - -void -_hb_ot_face_data_destroy (hb_ot_face_data_t *data) -{ - data->fini (); - free (data); -} - diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh index caa1d97ef1b..3ca875e7154 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-face.hh @@ -34,44 +34,43 @@ #include "hb-machinery.hh" -#define hb_ot_face_data(face) ((hb_ot_face_data_t *) face->shaper_data.ot.get_relaxed ()) - - /* - * hb_ot_face_data_t + * hb_ot_face_t */ -/* Most of these tables are NOT needed for shaping. But we need to hook them *somewhere*. - * This is as good as any place. */ #define HB_OT_TABLES \ + /* OpenType fundamentals. */ \ + HB_OT_TABLE(OT, head) \ + HB_OT_ACCELERATOR(OT, cmap) \ + HB_OT_ACCELERATOR(OT, hmtx) \ + HB_OT_ACCELERATOR(OT, vmtx) \ + HB_OT_ACCELERATOR(OT, post) \ + HB_OT_TABLE(OT, kern) \ + HB_OT_ACCELERATOR(OT, glyf) \ + HB_OT_TABLE(OT, VORG) \ + HB_OT_ACCELERATOR(OT, name) \ + HB_OT_TABLE(OT, OS2) \ + HB_OT_TABLE(OT, STAT) \ /* OpenType shaping. */ \ HB_OT_ACCELERATOR(OT, GDEF) \ HB_OT_ACCELERATOR(OT, GSUB) \ HB_OT_ACCELERATOR(OT, GPOS) \ - HB_OT_TABLE(OT, JSTF) \ HB_OT_TABLE(OT, BASE) \ + HB_OT_TABLE(OT, JSTF) \ /* AAT shaping. */ \ - HB_OT_TABLE(AAT, morx) \ HB_OT_TABLE(AAT, mort) \ + HB_OT_TABLE(AAT, morx) \ HB_OT_TABLE(AAT, kerx) \ HB_OT_TABLE(AAT, ankr) \ HB_OT_TABLE(AAT, trak) \ + HB_OT_TABLE(AAT, lcar) \ + HB_OT_TABLE(AAT, ltag) \ /* OpenType variations. */ \ HB_OT_TABLE(OT, fvar) \ HB_OT_TABLE(OT, avar) \ HB_OT_TABLE(OT, MVAR) \ /* OpenType math. */ \ HB_OT_TABLE(OT, MATH) \ - /* OpenType fundamentals. */ \ - HB_OT_ACCELERATOR(OT, cmap) \ - HB_OT_ACCELERATOR(OT, hmtx) \ - HB_OT_ACCELERATOR(OT, vmtx) \ - HB_OT_ACCELERATOR(OT, post) \ - HB_OT_TABLE(OT, kern) \ - HB_OT_ACCELERATOR(OT, glyf) \ - HB_OT_TABLE(OT, VORG) \ - HB_OT_ACCELERATOR(OT, name) \ - HB_OT_TABLE(AAT, ltag) \ /* OpenType color fonts. */ \ HB_OT_TABLE(OT, COLR) \ HB_OT_TABLE(OT, CPAL) \ @@ -87,7 +86,7 @@ HB_OT_TABLES #undef HB_OT_ACCELERATOR #undef HB_OT_TABLE -struct hb_ot_face_data_t +struct hb_ot_face_t { HB_INTERNAL void init0 (hb_face_t *face); HB_INTERNAL void fini (void); @@ -115,11 +114,4 @@ struct hb_ot_face_data_t }; -HB_INTERNAL hb_ot_face_data_t * -_hb_ot_face_data_create (hb_face_t *face); - -HB_INTERNAL void -_hb_ot_face_data_destroy (hb_ot_face_data_t *data); - - #endif /* HB_OT_FACE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc index 41bea140523..b19b25a3eed 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-font.cc @@ -33,10 +33,12 @@ #include "hb-ot-face.hh" #include "hb-ot-cmap-table.hh" +#include "hb-ot-glyf-table.hh" #include "hb-ot-hmtx-table.hh" #include "hb-ot-kern-table.hh" +#include "hb-ot-os2-table.hh" #include "hb-ot-post-table.hh" -#include "hb-ot-glyf-table.hh" +#include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise. #include "hb-ot-vorg-table.hh" #include "hb-ot-color-cbdt-table.hh" #include "hb-ot-color-sbix-table.hh" @@ -61,7 +63,7 @@ hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; return ot_face->cmap->get_nominal_glyph (unicode, glyph); } @@ -75,17 +77,10 @@ hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED, unsigned int glyph_stride, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; - const OT::cmap_accelerator_t &cmap = *ot_face->cmap; - unsigned int done; - for (done = 0; - done < count && cmap.get_nominal_glyph (*first_unicode, first_glyph); - done++) - { - first_unicode = &StructAtOffset<hb_codepoint_t> (first_unicode, unicode_stride); - first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride); - } - return done; + const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; + return ot_face->cmap->get_nominal_glyphs (count, + first_unicode, unicode_stride, + first_glyph, glyph_stride); } static hb_bool_t @@ -96,7 +91,7 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; return ot_face->cmap->get_variation_glyph (unicode, variation_selector, glyph); } @@ -109,7 +104,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; for (unsigned int i = 0; i < count; i++) @@ -129,7 +124,7 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, unsigned advance_stride, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; for (unsigned int i = 0; i < count; i++) @@ -148,7 +143,7 @@ hb_ot_get_glyph_v_origin (hb_font_t *font, hb_position_t *y, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; *x = font->get_glyph_h_advance (glyph) / 2; @@ -182,7 +177,7 @@ hb_ot_get_glyph_extents (hb_font_t *font, hb_glyph_extents_t *extents, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; bool ret = ot_face->sbix->get_extents (font, glyph, extents); if (!ret) ret = ot_face->glyf->get_extents (glyph, extents); @@ -203,7 +198,7 @@ hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED, char *name, unsigned int size, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; return ot_face->post->get_glyph_name (glyph, name, size); } @@ -214,7 +209,7 @@ hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED, hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; return ot_face->post->get_glyph_from_name (name, len, glyph); } @@ -224,7 +219,7 @@ hb_ot_get_font_h_extents (hb_font_t *font, hb_font_extents_t *metrics, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; metrics->ascender = font->em_scale_y (hmtx.ascender); metrics->descender = font->em_scale_y (hmtx.descender); @@ -239,7 +234,7 @@ hb_ot_get_font_v_extents (hb_font_t *font, hb_font_extents_t *metrics, void *user_data HB_UNUSED) { - const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; + const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data; const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; metrics->ascender = font->em_scale_x (vmtx.ascender); metrics->descender = font->em_scale_x (vmtx.descender); @@ -305,11 +300,8 @@ _hb_ot_get_font_funcs (void) void hb_ot_font_set_funcs (hb_font_t *font) { - if (unlikely (!hb_ot_shaper_face_data_ensure (font->face))) return; - hb_ot_face_data_t *ot_face = hb_ot_face_data (font->face); - hb_font_set_funcs (font, _hb_ot_get_font_funcs (), - ot_face, + &font->face->table, nullptr); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh index d2a39f2300a..5d9e7a201e7 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-glyf-table.hh @@ -102,7 +102,7 @@ struct glyf static bool _add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca) { - hb_blob_t *head_blob = hb_sanitize_context_t().reference_table<head> (plan->source); + hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<head> (plan->source); hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob); hb_blob_destroy (head_blob); @@ -120,9 +120,9 @@ struct glyf struct GlyphHeader { HBINT16 numberOfContours; /* If the number of contours is - * greater than or equal to zero, - * this is a simple glyph; if negative, - * this is a composite glyph. */ + * greater than or equal to zero, + * this is a simple glyph; if negative, + * this is a composite glyph. */ FWORD xMin; /* Minimum x for coordinate data. */ FWORD yMin; /* Minimum y for coordinate data. */ FWORD xMax; /* Maximum x for coordinate data. */ @@ -149,28 +149,23 @@ struct glyf }; HBUINT16 flags; - HBUINT16 glyphIndex; + GlyphID glyphIndex; inline unsigned int get_size (void) const { unsigned int size = min_size; - if (flags & ARG_1_AND_2_ARE_WORDS) { - // arg1 and 2 are int16 - size += 4; - } else { - // arg1 and 2 are int8 - size += 2; - } - if (flags & WE_HAVE_A_SCALE) { - // One x 16 bit (scale) - size += 2; - } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) { - // Two x 16 bit (xscale, yscale) - size += 4; - } else if (flags & WE_HAVE_A_TWO_BY_TWO) { - // Four x 16 bit (xscale, scale01, scale10, yscale) - size += 8; - } + // arg1 and 2 are int16 + if (flags & ARG_1_AND_2_ARE_WORDS) size += 4; + // arg1 and 2 are int8 + else size += 2; + + // One x 16 bit (scale) + if (flags & WE_HAVE_A_SCALE) size += 2; + // Two x 16 bit (xscale, yscale) + else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) size += 4; + // Four x 16 bit (xscale, scale01, scale10, yscale) + else if (flags & WE_HAVE_A_TWO_BY_TWO) size += 8; + return size; } @@ -198,7 +193,7 @@ struct glyf { return (const char *) composite >= glyph_start && ((const char *) composite + CompositeGlyphHeader::min_size) <= glyph_end - && ((const char *) composite + composite->get_size()) <= glyph_end; + && ((const char *) composite + composite->get_size ()) <= glyph_end; } }; @@ -212,15 +207,15 @@ struct glyf const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph_data, 0); if (glyph_header.numberOfContours < 0) { - const CompositeGlyphHeader *possible = + const CompositeGlyphHeader *possible = &StructAfter<CompositeGlyphHeader, GlyphHeader> (glyph_header); iterator->glyph_start = glyph_data; iterator->glyph_end = (const char *) glyph_data + length; if (!iterator->in_range (possible)) - return false; - iterator->current = possible; - return true; + return false; + iterator->current = possible; + return true; } return false; @@ -235,30 +230,22 @@ struct glyf { memset (this, 0, sizeof (accelerator_t)); - hb_blob_t *head_blob = hb_sanitize_context_t().reference_table<head> (face); - const head *head_table = head_blob->as<head> (); - if (head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0) - { + const OT::head &head = *face->table.head; + if (head.indexToLocFormat > 1 || head.glyphDataFormat != 0) /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ - hb_blob_destroy (head_blob); return; - } - short_offset = 0 == head_table->indexToLocFormat; - hb_blob_destroy (head_blob); + short_offset = 0 == head.indexToLocFormat; - loca_blob = hb_sanitize_context_t().reference_table<loca> (face); - loca_table = loca_blob->as<loca> (); - glyf_blob = hb_sanitize_context_t().reference_table<glyf> (face); - glyf_table = glyf_blob->as<glyf> (); + loca_table = hb_sanitize_context_t ().reference_table<loca> (face); + glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face); - num_glyphs = MAX (1u, hb_blob_get_length (loca_blob) / (short_offset ? 2 : 4)) - 1; - glyf_len = hb_blob_get_length (glyf_blob); + num_glyphs = MAX (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1; } inline void fini (void) { - hb_blob_destroy (loca_blob); - hb_blob_destroy (glyf_blob); + loca_table.destroy (); + glyf_table.destroy (); } /* @@ -274,7 +261,7 @@ struct glyf unsigned int start_offset, end_offset; if (!get_offsets (glyph, &start_offset, &end_offset)) - return false; /* glyph not found */ + return false; /* glyph not found */ return CompositeGlyphHeader::get_iterator ((const char *) this->glyf_table + start_offset, end_offset - start_offset, @@ -290,11 +277,10 @@ struct glyf }; /* based on FontTools _g_l_y_f.py::trim */ - inline bool remove_padding(unsigned int start_offset, - unsigned int *end_offset) const + inline bool remove_padding (unsigned int start_offset, + unsigned int *end_offset) const { - if (*end_offset - start_offset < GlyphHeader::static_size) - return true; + if (*end_offset - start_offset < GlyphHeader::static_size) return true; const char *glyph = ((const char *) glyf_table) + start_offset; const char * const glyph_end = glyph + (*end_offset - start_offset); @@ -302,143 +288,139 @@ struct glyf int16_t num_contours = (int16_t) glyph_header.numberOfContours; if (num_contours < 0) - /* Trimming for composites not implemented. - * If removing hints it falls out of that. */ - return true; + /* Trimming for composites not implemented. + * If removing hints it falls out of that. */ + return true; else if (num_contours > 0) { - /* simple glyph w/contours, possibly trimmable */ - glyph += GlyphHeader::static_size + 2 * num_contours; - - if (unlikely (glyph + 2 >= glyph_end)) return false; - uint16_t nCoordinates = (uint16_t) StructAtOffset<HBUINT16>(glyph - 2, 0) + 1; - uint16_t nInstructions = (uint16_t) StructAtOffset<HBUINT16>(glyph, 0); - - glyph += 2 + nInstructions; - if (unlikely (glyph + 2 >= glyph_end)) return false; - - unsigned int coordBytes = 0; - unsigned int coordsWithFlags = 0; - while (glyph < glyph_end) - { - uint8_t flag = (uint8_t) *glyph; - glyph++; - - unsigned int repeat = 1; - if (flag & FLAG_REPEAT) - { - if (glyph >= glyph_end) - { - DEBUG_MSG(SUBSET, nullptr, "Bad flag"); - return false; - } - repeat = ((uint8_t) *glyph) + 1; - glyph++; - } - - unsigned int xBytes, yBytes; - xBytes = yBytes = 0; - if (flag & FLAG_X_SHORT) - xBytes = 1; - else if ((flag & FLAG_X_SAME) == 0) - xBytes = 2; - - if (flag & FLAG_Y_SHORT) - yBytes = 1; - else if ((flag & FLAG_Y_SAME) == 0) - yBytes = 2; - - coordBytes += (xBytes + yBytes) * repeat; - coordsWithFlags += repeat; - if (coordsWithFlags >= nCoordinates) - break; - } - - if (coordsWithFlags != nCoordinates) - { - DEBUG_MSG(SUBSET, nullptr, "Expect %d coords to have flags, got flags for %d", nCoordinates, coordsWithFlags); - return false; - } - glyph += coordBytes; - - if (glyph < glyph_end) - *end_offset -= glyph_end - glyph; + /* simple glyph w/contours, possibly trimmable */ + glyph += GlyphHeader::static_size + 2 * num_contours; + + if (unlikely (glyph + 2 >= glyph_end)) return false; + uint16_t nCoordinates = (uint16_t) StructAtOffset<HBUINT16> (glyph - 2, 0) + 1; + uint16_t nInstructions = (uint16_t) StructAtOffset<HBUINT16> (glyph, 0); + + glyph += 2 + nInstructions; + if (unlikely (glyph + 2 >= glyph_end)) return false; + + unsigned int coordBytes = 0; + unsigned int coordsWithFlags = 0; + while (glyph < glyph_end) + { + uint8_t flag = (uint8_t) *glyph; + glyph++; + + unsigned int repeat = 1; + if (flag & FLAG_REPEAT) + { + if (glyph >= glyph_end) + { + DEBUG_MSG(SUBSET, nullptr, "Bad flag"); + return false; + } + repeat = ((uint8_t) *glyph) + 1; + glyph++; + } + + unsigned int xBytes, yBytes; + xBytes = yBytes = 0; + if (flag & FLAG_X_SHORT) xBytes = 1; + else if ((flag & FLAG_X_SAME) == 0) xBytes = 2; + + if (flag & FLAG_Y_SHORT) yBytes = 1; + else if ((flag & FLAG_Y_SAME) == 0) yBytes = 2; + + coordBytes += (xBytes + yBytes) * repeat; + coordsWithFlags += repeat; + if (coordsWithFlags >= nCoordinates) + break; + } + + if (coordsWithFlags != nCoordinates) + { + DEBUG_MSG(SUBSET, nullptr, "Expect %d coords to have flags, got flags for %d", nCoordinates, coordsWithFlags); + return false; + } + glyph += coordBytes; + + if (glyph < glyph_end) + *end_offset -= glyph_end - glyph; } return true; } inline bool get_offsets (hb_codepoint_t glyph, - unsigned int *start_offset /* OUT */, - unsigned int *end_offset /* OUT */) const + unsigned int *start_offset /* OUT */, + unsigned int *end_offset /* OUT */) const { if (unlikely (glyph >= num_glyphs)) return false; if (short_offset) { - const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ; + const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ; *start_offset = 2 * offsets[glyph]; *end_offset = 2 * offsets[glyph + 1]; } else { - const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ; + const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ; *start_offset = offsets[glyph]; *end_offset = offsets[glyph + 1]; } - if (*start_offset > *end_offset || *end_offset > glyf_len) + if (*start_offset > *end_offset || *end_offset > glyf_table.get_length ()) return false; return true; } - inline bool get_instruction_offsets(unsigned int start_offset, - unsigned int end_offset, - unsigned int *instruction_start /* OUT */, - unsigned int *instruction_end /* OUT */) const + inline bool get_instruction_offsets (unsigned int start_offset, + unsigned int end_offset, + unsigned int *instruction_start /* OUT */, + unsigned int *instruction_end /* OUT */) const { if (end_offset - start_offset < GlyphHeader::static_size) { - *instruction_start = 0; - *instruction_end = 0; - return true; /* Empty glyph; no instructions. */ + *instruction_start = 0; + *instruction_end = 0; + return true; /* Empty glyph; no instructions. */ } const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset); int16_t num_contours = (int16_t) glyph_header.numberOfContours; if (num_contours < 0) { - CompositeGlyphHeader::Iterator composite_it; - if (unlikely (!CompositeGlyphHeader::get_iterator ( - (const char*) this->glyf_table + start_offset, - end_offset - start_offset, &composite_it))) return false; - const CompositeGlyphHeader *last; - do { - last = composite_it.current; - } while (composite_it.move_to_next()); - - if ( (uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS) - *instruction_start = ((char *) last - (char *) glyf_table->dataZ.arrayZ) + last->get_size(); - else - *instruction_start = end_offset; - *instruction_end = end_offset; - if (unlikely (*instruction_start > *instruction_end)) - { - DEBUG_MSG(SUBSET, nullptr, "Invalid instruction offset, %d is outside [%d, %d]", *instruction_start, start_offset, end_offset); - return false; - } + CompositeGlyphHeader::Iterator composite_it; + if (unlikely (!CompositeGlyphHeader::get_iterator ( + (const char*) this->glyf_table + start_offset, + end_offset - start_offset, &composite_it))) return false; + const CompositeGlyphHeader *last; + do { + last = composite_it.current; + } while (composite_it.move_to_next ()); + + if ((uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS) + *instruction_start = ((char *) last - (char *) glyf_table->dataZ.arrayZ) + last->get_size (); + else + *instruction_start = end_offset; + *instruction_end = end_offset; + if (unlikely (*instruction_start > *instruction_end)) + { + DEBUG_MSG(SUBSET, nullptr, "Invalid instruction offset, %d is outside [%d, %d]", *instruction_start, start_offset, end_offset); + return false; + } } else { - unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours; + unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours; if (unlikely (instruction_length_offset + 2 > end_offset)) { DEBUG_MSG(SUBSET, nullptr, "Glyph size is too short, missing field instructionLength."); return false; } - const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset); + const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset); unsigned int start = instruction_length_offset + 2; unsigned int end = start + (uint16_t) instruction_length; if (unlikely (end > end_offset)) // Out of bounds of the current glyph @@ -448,7 +430,7 @@ struct glyf } *instruction_start = start; - *instruction_end = end; + *instruction_end = end; } return true; } @@ -458,7 +440,7 @@ struct glyf { unsigned int start_offset, end_offset; if (!get_offsets (glyph, &start_offset, &end_offset)) - return false; + return false; if (end_offset - start_offset < GlyphHeader::static_size) return true; /* Empty glyph; zero extents. */ @@ -476,11 +458,8 @@ struct glyf private: bool short_offset; unsigned int num_glyphs; - hb_nonnull_ptr_t<const loca> loca_table; - hb_nonnull_ptr_t<const glyf> glyf_table; - hb_blob_t *loca_blob; - hb_blob_t *glyf_blob; - unsigned int glyf_len; + hb_blob_ptr_t<loca> loca_table; + hb_blob_ptr_t<glyf> glyf_table; }; protected: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh index 04511b5d09e..0fea24bca24 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh @@ -44,15 +44,15 @@ struct DeviceRecord struct SubsetView { const DeviceRecord *source_device_record; - unsigned int size_device_record; + unsigned int sizeDeviceRecord; hb_subset_plan_t *subset_plan; - inline void init(const DeviceRecord *source_device_record, - unsigned int size_device_record, - hb_subset_plan_t *subset_plan) + inline void init (const DeviceRecord *source_device_record, + unsigned int sizeDeviceRecord, + hb_subset_plan_t *subset_plan) { this->source_device_record = source_device_record; - this->size_device_record = size_device_record; + this->sizeDeviceRecord = sizeDeviceRecord; this->subset_plan = subset_plan; } @@ -63,15 +63,12 @@ struct DeviceRecord inline const HBUINT8* operator [] (unsigned int i) const { - if (unlikely (i >= len())) return nullptr; + if (unlikely (i >= len ())) return nullptr; hb_codepoint_t gid = this->subset_plan->glyphs [i]; - const HBUINT8* width = &(this->source_device_record->widthsZ[gid]); - - if (width < ((const HBUINT8 *) this->source_device_record) + size_device_record) - return width; - else - return nullptr; + if (gid >= sizeDeviceRecord - DeviceRecord::min_size) + return nullptr; + return &(this->source_device_record->widthsZ[gid]); } }; @@ -84,18 +81,18 @@ struct DeviceRecord { TRACE_SERIALIZE (this); - unsigned int size = get_size (subset_view.len()); + unsigned int size = get_size (subset_view.len ()); if (unlikely (!c->allocate_size<DeviceRecord> (size))) { - DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for DeviceRecord: %d.", - size); + DEBUG_MSG(SUBSET, nullptr, "Couldn't allocate enough space for DeviceRecord: %d.", + size); return_trace (false); } - this->pixel_size.set (subset_view.source_device_record->pixel_size); - this->max_width.set (subset_view.source_device_record->max_width); + this->pixelSize.set (subset_view.source_device_record->pixelSize); + this->maxWidth.set (subset_view.source_device_record->maxWidth); - for (unsigned int i = 0; i < subset_view.len(); i++) + for (unsigned int i = 0; i < subset_view.len (); i++) { const HBUINT8 *width = subset_view[i]; if (!width) @@ -109,16 +106,16 @@ struct DeviceRecord return_trace (true); } - inline bool sanitize (hb_sanitize_context_t *c, unsigned int size_device_record) const + inline bool sanitize (hb_sanitize_context_t *c, unsigned int sizeDeviceRecord) const { TRACE_SANITIZE (this); return_trace (likely (c->check_struct (this) && - c->check_range (this, size_device_record))); + c->check_range (this, sizeDeviceRecord))); } - HBUINT8 pixel_size; /* Pixel size for following widths (as ppem). */ - HBUINT8 max_width; /* Maximum width. */ - UnsizedArrayOf<HBUINT8> widthsZ; /* Array of widths (numGlyphs is from the 'maxp' table). */ + HBUINT8 pixelSize; /* Pixel size for following widths (as ppem). */ + HBUINT8 maxWidth; /* Maximum width. */ + UnsizedArrayOf<HBUINT8> widthsZ; /* Array of widths (numGlyphs is from the 'maxp' table). */ public: DEFINE_SIZE_ARRAY (2, widthsZ); }; @@ -130,13 +127,15 @@ struct hdmx inline unsigned int get_size (void) const { - return min_size + num_records * size_device_record; + return min_size + numRecords * sizeDeviceRecord; } inline const DeviceRecord& operator [] (unsigned int i) const { - if (unlikely (i >= num_records)) return Null(DeviceRecord); - return StructAtOffset<DeviceRecord> (&this->dataZ, i * size_device_record); + /* XXX Null(DeviceRecord) is NOT safe as it's num-glyphs lengthed. + * https://github.com/harfbuzz/harfbuzz/issues/1300 */ + if (unlikely (i >= numRecords)) return Null (DeviceRecord); + return StructAtOffset<DeviceRecord> (&this->firstDeviceRecord, i * sizeDeviceRecord); } inline bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan) @@ -146,13 +145,13 @@ struct hdmx if (unlikely (!c->extend_min ((*this)))) return_trace (false); this->version.set (source_hdmx->version); - this->num_records.set (source_hdmx->num_records); - this->size_device_record.set (DeviceRecord::get_size (plan->glyphs.len)); + this->numRecords.set (source_hdmx->numRecords); + this->sizeDeviceRecord.set (DeviceRecord::get_size (plan->glyphs.len)); - for (unsigned int i = 0; i < source_hdmx->num_records; i++) + for (unsigned int i = 0; i < source_hdmx->numRecords; i++) { DeviceRecord::SubsetView subset_view; - subset_view.init (&(*source_hdmx)[i], source_hdmx->size_device_record, plan); + subset_view.init (&(*source_hdmx)[i], source_hdmx->sizeDeviceRecord, plan); if (!c->start_embed<DeviceRecord> ()->serialize (c, subset_view)) return_trace (false); @@ -163,7 +162,7 @@ struct hdmx static inline size_t get_subsetted_size (const hdmx *source_hdmx, hb_subset_plan_t *plan) { - return min_size + source_hdmx->num_records * DeviceRecord::get_size (plan->glyphs.len); + return min_size + source_hdmx->numRecords * DeviceRecord::get_size (plan->glyphs.len); } inline bool subset (hb_subset_plan_t *plan) const @@ -200,19 +199,19 @@ struct hdmx inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && version == 0 && - !hb_unsigned_mul_overflows (num_records, size_device_record) && - size_device_record >= DeviceRecord::min_size && - c->check_range (this, get_size())); + return_trace (c->check_struct (this) && + !hb_unsigned_mul_overflows (numRecords, sizeDeviceRecord) && + sizeDeviceRecord >= DeviceRecord::min_size && + c->check_range (this, get_size ())); } protected: - HBUINT16 version; /* Table version number (0) */ - HBUINT16 num_records; /* Number of device records. */ - HBUINT32 size_device_record; /* Size of a device record, 32-bit aligned. */ - UnsizedArrayOf<HBUINT8> dataZ; /* Array of device records. */ + HBUINT16 version; /* Table version number (0) */ + HBUINT16 numRecords; /* Number of device records. */ + HBUINT32 sizeDeviceRecord; /* Size of a device record, 32-bit aligned. */ + DeviceRecord firstDeviceRecord; /* Array of device records. */ public: - DEFINE_SIZE_ARRAY (8, dataZ); + DEFINE_SIZE_MIN (8); }; } /* namespace OT */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh index f898a0336a2..091b601173f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hmtx-table.hh @@ -66,10 +66,10 @@ struct hmtxvmtx inline bool subset_update_header (hb_subset_plan_t *plan, - unsigned int num_hmetrics) const + unsigned int num_hmetrics) const { - hb_blob_t *src_blob = hb_sanitize_context_t().reference_table<H> (plan->source, H::tableTag); - hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail(src_blob); + hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table<H> (plan->source, H::tableTag); + hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail (src_blob); hb_blob_destroy (src_blob); if (unlikely (!dest_blob)) { @@ -96,15 +96,15 @@ struct hmtxvmtx hb_vector_t<hb_codepoint_t> &gids = plan->glyphs; unsigned int num_advances = gids.len; unsigned int last_advance = _mtx.get_advance (gids[num_advances - 1]); - while (num_advances > 1 - && last_advance == _mtx.get_advance (gids[num_advances - 2])) + while (num_advances > 1 && + last_advance == _mtx.get_advance (gids[num_advances - 2])) { num_advances--; } /* alloc the new table */ size_t dest_sz = num_advances * 4 - + (gids.len - num_advances) * 2; + + (gids.len - num_advances) * 2; void *dest = (void *) malloc (dest_sz); if (unlikely (!dest)) { @@ -113,7 +113,7 @@ struct hmtxvmtx DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in src has %d advances, %d lsbs", HB_UNTAG(T::tableTag), _mtx.num_advances, _mtx.num_metrics - _mtx.num_advances); DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in dest has %d advances, %d lsbs, %u bytes", HB_UNTAG(T::tableTag), num_advances, gids.len - num_advances, (unsigned int) dest_sz); - const char *source_table = hb_blob_get_data (_mtx.blob, nullptr); + const char *source_table = hb_blob_get_data (_mtx.table.get_blob (), nullptr); // Copy everything over LongMetric * old_metrics = (LongMetric *) source_table; FWORD *lsbs = (FWORD *) (old_metrics + _mtx.num_advances); @@ -194,17 +194,14 @@ struct hmtxvmtx bool got_font_extents = false; if (T::os2Tag) { - hb_blob_t *os2_blob = hb_sanitize_context_t().reference_table<OS2> (face); - const OS2 *os2_table = os2_blob->as<OS2> (); #define USE_TYPO_METRICS (1u<<7) - if (0 != (os2_table->fsSelection & USE_TYPO_METRICS)) + if (0 != (face->table.OS2->fsSelection & USE_TYPO_METRICS)) { - ascender = abs (os2_table->sTypoAscender); - descender = -abs (os2_table->sTypoDescender); - line_gap = os2_table->sTypoLineGap; + ascender = abs (face->table.OS2->sTypoAscender); + descender = -abs (face->table.OS2->sTypoDescender); + line_gap = face->table.OS2->sTypoLineGap; got_font_extents = (ascender | descender) != 0; } - hb_blob_destroy (os2_blob); } hb_blob_t *_hea_blob = hb_sanitize_context_t().reference_table<H> (face); @@ -221,10 +218,10 @@ struct hmtxvmtx has_font_extents = got_font_extents; - blob = hb_sanitize_context_t().reference_table<hmtxvmtx> (face, T::tableTag); + table = hb_sanitize_context_t().reference_table<hmtxvmtx> (face, T::tableTag); /* Cap num_metrics() and num_advances() based on table length. */ - unsigned int len = hb_blob_get_length (blob); + unsigned int len = table.get_length (); if (unlikely (num_advances * 4 > len)) num_advances = len / 4; num_metrics = num_advances + (len - 4 * num_advances) / 2; @@ -234,19 +231,17 @@ struct hmtxvmtx if (unlikely (!num_advances)) { num_metrics = num_advances = 0; - hb_blob_destroy (blob); - blob = hb_blob_get_empty (); + table.destroy (); + table = hb_blob_get_empty (); } - table = blob->as<hmtxvmtx> (); - var_blob = hb_sanitize_context_t().reference_table<HVARVVAR> (face, T::variationsTag); - var_table = var_blob->as<HVARVVAR> (); + var_table = hb_sanitize_context_t().reference_table<HVARVVAR> (face, T::variationsTag); } inline void fini (void) { - hb_blob_destroy (blob); - hb_blob_destroy (var_blob); + table.destroy (); + var_table.destroy (); } /* TODO Add variations version. */ @@ -282,7 +277,7 @@ struct hmtxvmtx hb_font_t *font) const { unsigned int advance = get_advance (glyph); - if (likely(glyph < num_metrics)) + if (likely (glyph < num_metrics)) { advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?! } @@ -291,9 +286,9 @@ struct hmtxvmtx public: bool has_font_extents; - unsigned short ascender; - unsigned short descender; - unsigned short line_gap; + int ascender; + int descender; + int line_gap; protected: unsigned int num_metrics; @@ -301,10 +296,8 @@ struct hmtxvmtx unsigned int default_advance; private: - const hmtxvmtx *table; - hb_blob_t *blob; - const HVARVVAR *var_table; - hb_blob_t *var_blob; + hb_blob_ptr_t<hmtxvmtx> table; + hb_blob_ptr_t<HVARVVAR> var_table; }; protected: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh index 5bc9e436c74..14e0656842b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-kern-table.hh @@ -27,89 +27,7 @@ #ifndef HB_OT_KERN_TABLE_HH #define HB_OT_KERN_TABLE_HH -#include "hb-open-type.hh" -#include "hb-ot-shape.hh" -#include "hb-ot-layout-gsubgpos.hh" -#include "hb-aat-layout-common.hh" - - -template <typename Driver> -struct hb_kern_machine_t -{ - hb_kern_machine_t (const Driver &driver_) : driver (driver_) {} - - HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW - inline void kern (hb_font_t *font, - hb_buffer_t *buffer, - hb_mask_t kern_mask, - bool scale = true) 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 kern = driver.get_kerning (info[i].codepoint, - info[j].codepoint); - - - if (likely (!kern)) - goto skip; - - - if (horizontal) - { - if (scale) - kern = font->em_scale_x (kern); - hb_position_t kern1 = kern >> 1; - hb_position_t kern2 = kern - kern1; - pos[i].x_advance += kern1; - pos[j].x_advance += kern2; - pos[j].x_offset += kern2; - } - else - { - if (scale) - kern = font->em_scale_y (kern); - hb_position_t kern1 = kern >> 1; - hb_position_t kern2 = kern - kern1; - 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; -}; +#include "hb-aat-layout-kerx-table.hh" /* @@ -123,290 +41,7 @@ struct hb_kern_machine_t namespace OT { -struct hb_glyph_pair_t -{ - hb_codepoint_t left; - hb_codepoint_t right; -}; - -struct KernPair -{ - inline int get_kerning (void) const - { return value; } - - inline int cmp (const hb_glyph_pair_t &o) const - { - int ret = left.cmp (o.left); - if (ret) return ret; - return right.cmp (o.right); - } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - protected: - GlyphID left; - GlyphID right; - FWORD value; - public: - DEFINE_SIZE_STATIC (6); -}; - -struct KernSubTableFormat0 -{ - 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 (AAT::hb_aat_apply_context_t *c) const - { - TRACE_APPLY (this); - - if (!c->plan->requested_kerning) - return false; - - hb_kern_machine_t<KernSubTableFormat0> machine (*this); - machine.kern (c->font, c->buffer, c->plan->kern_mask); - - return_trace (true); - } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (pairs.sanitize (c)); - } - - protected: - BinSearchArrayOf<KernPair> pairs; /* Array of kerning pairs. */ - public: - DEFINE_SIZE_ARRAY (8, pairs); -}; - -struct KernSubTableFormat1 -{ - typedef void EntryData; - - struct driver_context_t - { - static const bool in_place = true; - enum Flags - { - Push = 0x8000, /* If set, push this glyph on the kerning stack. */ - DontAdvance = 0x4000, /* If set, don't advance to the next glyph - * before going to the new state. */ - Offset = 0x3FFF, /* Byte offset from beginning of subtable to the - * value table for the glyphs on the kerning stack. */ - }; - - inline driver_context_t (const KernSubTableFormat1 *table_, - AAT::hb_aat_apply_context_t *c_) : - c (c_), - table (table_), - /* Apparently the offset kernAction is from the beginning of the state-machine, - * similar to offsets in morx table, NOT from beginning of this table, like - * other subtables in kerx. Discovered via testing. */ - kernAction (&table->machine + table->kernAction), - depth (0) {} - - inline bool is_actionable (AAT::StateTableDriver<AAT::MortTypes, EntryData> *driver HB_UNUSED, - const AAT::Entry<EntryData> *entry) - { - return entry->flags & Offset; - } - inline bool transition (AAT::StateTableDriver<AAT::MortTypes, EntryData> *driver, - const AAT::Entry<EntryData> *entry) - { - hb_buffer_t *buffer = driver->buffer; - unsigned int flags = entry->flags; - - if (flags & Push) - { - if (likely (depth < ARRAY_LENGTH (stack))) - stack[depth++] = buffer->idx; - else - depth = 0; /* Probably not what CoreText does, but better? */ - } - - if (entry->flags & Offset) - { - unsigned int kernIndex = AAT::MortTypes::offsetToIndex (entry->flags & Offset, &table->machine, kernAction.arrayZ); - const FWORD *actions = &kernAction[kernIndex]; - if (!c->sanitizer.check_array (actions, depth)) - { - depth = 0; - return false; - } - - hb_mask_t kern_mask = c->plan->kern_mask; - for (unsigned int i = 0; i < depth; i++) - { - /* Apparently, when spec says "Each pops one glyph from the kerning stack - * and applies the kerning value to it.", it doesn't mean it in that order. - * The deepest item in the stack corresponds to the first item in the action - * list. Discovered by testing. */ - unsigned int idx = stack[i]; - int v = *actions++; - if (idx < buffer->len && buffer->info[idx].mask & kern_mask) - { - if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) - { - buffer->pos[idx].x_advance += c->font->em_scale_x (v); - if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) - buffer->pos[idx].x_offset += c->font->em_scale_x (v); - } - else - { - buffer->pos[idx].y_advance += c->font->em_scale_y (v); - if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) - buffer->pos[idx].y_offset += c->font->em_scale_y (v); - } - } - } - depth = 0; - } - - return true; - } - - private: - AAT::hb_aat_apply_context_t *c; - const KernSubTableFormat1 *table; - const UnsizedArrayOf<FWORD> &kernAction; - unsigned int stack[8]; - unsigned int depth; - }; - - inline bool apply (AAT::hb_aat_apply_context_t *c) const - { - TRACE_APPLY (this); - - if (!c->plan->requested_kerning) - return false; - - driver_context_t dc (this, c); - - AAT::StateTableDriver<AAT::MortTypes, EntryData> driver (machine, c->buffer, c->font->face); - driver.drive (&dc); - - return_trace (true); - } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - /* The rest of array sanitizations are done at run-time. */ - return_trace (likely (c->check_struct (this) && - machine.sanitize (c))); - } - - protected: - AAT::StateTable<AAT::MortTypes, EntryData> machine; - OffsetTo<UnsizedArrayOf<FWORD>, HBUINT16, false> kernAction; - public: - DEFINE_SIZE_STATIC (10); -}; - -struct KernClassTable -{ - 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 (c->check_struct (this) && - classes.sanitize (c)); - } - - protected: - HBUINT16 firstGlyph; /* First glyph in class range. */ - ArrayOf<HBUINT16> classes; /* Glyph classes. */ - public: - DEFINE_SIZE_ARRAY (4, classes); -}; - -struct KernSubTableFormat2 -{ - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, - AAT::hb_aat_apply_context_t *c) const - { - /* This subtable is disabled. It's not cleaer to me *exactly* where the offests are - * based from. I *think* they should be based from beginning of kern subtable wrapper, - * *NOT* "this". Since we know of no fonts that use this subtable, we are disabling - * it. Someday fix it and re-enable. */ - return 0; - unsigned int l = (this+leftClassTable).get_class (left); - unsigned int r = (this+rightClassTable).get_class (right); - unsigned int offset = l + r; - const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset); -#if 0 - if (unlikely ((const char *) v < (const char *) &array || - (const char *) v > (const char *) end - 2)) -#endif - return 0; - return *v; - } - - inline bool apply (AAT::hb_aat_apply_context_t *c) const - { - TRACE_APPLY (this); - - if (!c->plan->requested_kerning) - return false; - - accelerator_t accel (*this, c); - hb_kern_machine_t<accelerator_t> machine (accel); - machine.kern (c->font, c->buffer, c->plan->kern_mask); - - return_trace (true); - } - - struct accelerator_t - { - const KernSubTableFormat2 &table; - AAT::hb_aat_apply_context_t *c; - - inline accelerator_t (const KernSubTableFormat2 &table_, - AAT::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, c); } - }; - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (true); /* Disabled. See above. */ - return_trace (c->check_struct (this) && - leftClassTable.sanitize (c, this) && - rightClassTable.sanitize (c, this) && - array.sanitize (c, this)); - } - - protected: - HBUINT16 rowWidth; /* The width, in bytes, of a row in the table. */ - OffsetTo<KernClassTable> - leftClassTable; /* Offset from beginning of this subtable to - * left-hand class table. */ - OffsetTo<KernClassTable> - rightClassTable;/* Offset from beginning of this subtable to - * right-hand class table. */ - OffsetTo<FWORD> - array; /* Offset from beginning of this subtable to - * the start of the kerning array. */ - public: - DEFINE_SIZE_MIN (8); -}; - +template <typename KernSubTableHeader> struct KernSubTableFormat3 { inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const @@ -431,7 +66,10 @@ struct KernSubTableFormat3 if (!c->plan->requested_kerning) return false; - hb_kern_machine_t<KernSubTableFormat3> machine (*this); + if (header.coverage & header.Backwards) + return false; + + hb_kern_machine_t<KernSubTableFormat3> machine (*this, header.coverage & header.CrossStream); machine.kern (c->font, c->buffer, c->plan->kern_mask); return_trace (true); @@ -448,299 +86,224 @@ struct KernSubTableFormat3 } protected: - HBUINT16 glyphCount; /* The number of glyphs in this font. */ - HBUINT8 kernValueCount; /* The number of kerning values. */ - HBUINT8 leftClassCount; /* The number of left-hand classes. */ - HBUINT8 rightClassCount;/* The number of right-hand classes. */ - HBUINT8 flags; /* Set to zero (reserved for future use). */ - UnsizedArrayOf<FWORD> - kernValueZ; /* The kerning values. - * Length kernValueCount. */ + KernSubTableHeader header; + HBUINT16 glyphCount; /* The number of glyphs in this font. */ + HBUINT8 kernValueCount; /* The number of kerning values. */ + HBUINT8 leftClassCount; /* The number of left-hand classes. */ + HBUINT8 rightClassCount;/* The number of right-hand classes. */ + HBUINT8 flags; /* Set to zero (reserved for future use). */ + UnsizedArrayOf<FWORD> kernValueZ; /* The kerning values. + * Length kernValueCount. */ #if 0 - UnsizedArrayOf<HBUINT8> - leftClass; /* The left-hand classes. - * Length glyphCount. */ - UnsizedArrayOf<HBUINT8> - RightClass; /* The right-hand classes. - * Length glyphCount. */ - UnsizedArrayOf<HBUINT8> - kernIndex; /* The indices into the kernValue array. - * Length leftClassCount * rightClassCount */ + UnsizedArrayOf<HBUINT8>leftClass; /* The left-hand classes. + * Length glyphCount. */ + UnsizedArrayOf<HBUINT8>rightClass; /* The right-hand classes. + * Length glyphCount. */ + UnsizedArrayOf<HBUINT8>kernIndex; /* The indices into the kernValue array. + * Length leftClassCount * rightClassCount */ #endif public: - DEFINE_SIZE_ARRAY (6, kernValueZ); + DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 6, kernValueZ); }; +template <typename KernSubTableHeader> struct KernSubTable { - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int format) const + inline unsigned int get_size (void) const { return u.header.length; } + inline unsigned int get_type (void) const { return u.header.format; } + + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - switch (format) { + switch (get_type ()) { /* This method hooks up to hb_font_t's get_h_kerning. Only support Format0. */ case 0: return u.format0.get_kerning (left, right); default:return 0; } } - inline void apply (AAT::hb_aat_apply_context_t *c, unsigned int format) const + template <typename context_t> + inline typename context_t::return_t dispatch (context_t *c) const { - /* TODO Switch to dispatch(). */ - switch (format) { - case 0: u.format0.apply (c); return; - case 1: u.format1.apply (c); return; - case 2: u.format2.apply (c); return; - case 3: u.format3.apply (c); return; - default: return; + unsigned int subtable_type = get_type (); + TRACE_DISPATCH (this, subtable_type); + switch (subtable_type) { + case 0: return_trace (c->dispatch (u.format0)); + case 1: return_trace (u.header.apple ? c->dispatch (u.format1) : c->default_return_value ()); + case 2: return_trace (c->dispatch (u.format2)); + case 3: return_trace (u.header.apple ? c->dispatch (u.format3) : c->default_return_value ()); + default: return_trace (c->default_return_value ()); } } - inline bool sanitize (hb_sanitize_context_t *c, unsigned int format) const + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - switch (format) { - case 0: return_trace (u.format0.sanitize (c)); - case 1: return_trace (u.format1.sanitize (c)); - case 2: return_trace (u.format2.sanitize (c)); - case 3: return_trace (u.format3.sanitize (c)); - default:return_trace (true); - } + if (unlikely (!u.header.sanitize (c) || + u.header.length < u.header.min_size || + !c->check_range (this, u.header.length))) return_trace (false); + + return_trace (dispatch (c)); } - protected: + public: union { - KernSubTableFormat0 format0; - KernSubTableFormat1 format1; - KernSubTableFormat2 format2; - KernSubTableFormat3 format3; + KernSubTableHeader header; + AAT::KerxSubTableFormat0<KernSubTableHeader> format0; + AAT::KerxSubTableFormat1<KernSubTableHeader> format1; + AAT::KerxSubTableFormat2<KernSubTableHeader> format2; + KernSubTableFormat3<KernSubTableHeader> format3; } u; public: DEFINE_SIZE_MIN (0); }; -template <typename T> -struct KernSubTableWrapper +struct KernOTSubTableHeader { - /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ - inline const T* thiz (void) const { return static_cast<const T *> (this); } + static const bool apple = false; + typedef AAT::ObsoleteTypes Types; - inline bool is_supported (void) const - { return !(thiz()->coverage & T::CheckFlags); } - - inline bool is_horizontal (void) const - { return (thiz()->coverage & T::Direction) == T::CheckHorizontal; } - - inline bool is_override (void) const - { return bool (thiz()->coverage & T::Override); } - - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return thiz()->subtable.get_kerning (left, right, thiz()->format); } - - inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return is_supported () && is_horizontal () ? get_kerning (left, right) : 0; } + inline unsigned int tuple_count (void) const { return 0; } + inline bool is_horizontal (void) const { return (coverage & Horizontal); } - inline void apply (AAT::hb_aat_apply_context_t *c) const - { thiz()->subtable.apply (c, thiz()->format); } - - inline unsigned int get_size (void) const { return thiz()->length; } + enum Coverage + { + Horizontal = 0x01u, + Minimum = 0x02u, + CrossStream = 0x04u, + Override = 0x08u, + + /* Not supported: */ + Backwards = 0x00u, + Variation = 0x00u, + }; inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (thiz()) && - thiz()->length >= T::min_size && - c->check_range (thiz(), thiz()->length) && - thiz()->subtable.sanitize (c, thiz()->format)); + return_trace (c->check_struct (this)); } + + public: + HBUINT16 versionZ; /* Unused. */ + HBUINT16 length; /* Length of the subtable (including this header). */ + HBUINT8 format; /* Subtable format. */ + HBUINT8 coverage; /* Coverage bits. */ + public: + DEFINE_SIZE_STATIC (6); }; -template <typename T> -struct KernTable +struct KernOT : AAT::KerxTable<KernOT> { - /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ - inline const T* thiz (void) const { return static_cast<const T *> (this); } - - inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { - int v = 0; - const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ); - unsigned int count = thiz()->nTables; - for (unsigned int i = 0; i < count; i++) - { - if (st->is_supported () && st->is_override ()) - v = 0; - v += st->get_h_kerning (left, right); - st = &StructAfter<typename T::SubTableWrapper> (*st); - } - return v; - } + friend struct AAT::KerxTable<KernOT>; - inline void apply (AAT::hb_aat_apply_context_t *c) const - { - c->set_lookup_index (0); - const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ); - unsigned int count = thiz()->nTables; - /* If there's an override subtable, skip subtables before that. */ - unsigned int last_override = 0; - for (unsigned int i = 0; i < count; i++) - { - if (st->is_supported () && st->is_override ()) - last_override = i; - st = &StructAfter<typename T::SubTableWrapper> (*st); - } - st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ); - for (unsigned int i = 0; i < count; i++) - { - if (!st->is_supported ()) - goto skip; + static const hb_tag_t tableTag = HB_OT_TAG_kern; + static const uint16_t minVersion = 0; - if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->is_horizontal ()) - goto skip; + typedef KernOTSubTableHeader SubTableHeader; + typedef SubTableHeader::Types Types; + typedef KernSubTable<SubTableHeader> SubTable; - if (i < last_override) - goto skip; + protected: + HBUINT16 version; /* Version--0x0000u */ + HBUINT16 tableCount; /* Number of subtables in the kerning table. */ + SubTable firstSubTable; /* Subtables. */ + public: + DEFINE_SIZE_MIN (4); +}; - if (!c->buffer->message (c->font, "start kern subtable %d", c->lookup_index)) - goto skip; - c->sanitizer.set_object (*st); +struct KernAATSubTableHeader +{ + static const bool apple = true; + typedef AAT::ObsoleteTypes Types; - st->apply (c); + inline unsigned int tuple_count (void) const { return 0; } + inline bool is_horizontal (void) const { return !(coverage & Vertical); } - (void) c->buffer->message (c->font, "end kern subtable %d", c->lookup_index); + enum Coverage + { + Vertical = 0x80u, + CrossStream = 0x40u, + Variation = 0x20u, - skip: - st = &StructAfter<typename T::SubTableWrapper> (*st); - } - } + /* Not supported: */ + Backwards = 0x00u, + }; inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (thiz()) || - thiz()->version != T::VERSION)) - return_trace (false); - - const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ); - unsigned int count = thiz()->nTables; - for (unsigned int i = 0; i < count; i++) - { - if (unlikely (!st->sanitize (c))) - return_trace (false); - st = &StructAfter<typename T::SubTableWrapper> (*st); - } - - return_trace (true); + return_trace (c->check_struct (this)); } -}; - -struct KernOT : KernTable<KernOT> -{ - friend struct KernTable<KernOT>; - - static const uint16_t VERSION = 0x0000u; - - struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper> - { - friend struct KernTable<KernOT>; - friend struct KernSubTableWrapper<SubTableWrapper>; - - enum Coverage - { - Direction = 0x01u, - Minimum = 0x02u, - CrossStream = 0x04u, - Override = 0x08u, - - Variation = 0x00u, /* Not supported. */ - - CheckFlags = 0x06u, - CheckHorizontal = 0x01u - }; - - protected: - HBUINT16 versionZ; /* Unused. */ - HBUINT16 length; /* Length of the subtable (including this header). */ - HBUINT8 format; /* Subtable format. */ - HBUINT8 coverage; /* Coverage bits. */ - KernSubTable subtable; /* Subtable data. */ - public: - DEFINE_SIZE_MIN (6); - }; - protected: - HBUINT16 version; /* Version--0x0000u */ - HBUINT16 nTables; /* Number of subtables in the kerning table. */ - UnsizedArrayOf<HBUINT8> dataZ; public: - DEFINE_SIZE_ARRAY (4, dataZ); + HBUINT32 length; /* Length of the subtable (including this header). */ + HBUINT8 coverage; /* Coverage bits. */ + HBUINT8 format; /* Subtable format. */ + HBUINT16 tupleIndex; /* The tuple index (used for variations fonts). + * This value specifies which tuple this subtable covers. + * Note: We don't implement. */ + public: + DEFINE_SIZE_STATIC (8); }; -struct KernAAT : KernTable<KernAAT> +struct KernAAT : AAT::KerxTable<KernAAT> { - friend struct KernTable<KernAAT>; + friend struct AAT::KerxTable<KernAAT>; - static const uint32_t VERSION = 0x00010000u; + static const hb_tag_t tableTag = HB_OT_TAG_kern; + static const uint32_t minVersion = 0x00010000u; - struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper> - { - friend struct KernTable<KernAAT>; - friend struct KernSubTableWrapper<SubTableWrapper>; - - enum Coverage - { - Direction = 0x80u, - CrossStream = 0x40u, - Variation = 0x20u, - - Override = 0x00u, /* Not supported. */ - - CheckFlags = 0x60u, - CheckHorizontal = 0x00u - }; - - protected: - HBUINT32 length; /* Length of the subtable (including this header). */ - HBUINT8 coverage; /* Coverage bits. */ - HBUINT8 format; /* Subtable format. */ - HBUINT16 tupleIndex; /* The tuple index (used for variations fonts). - * This value specifies which tuple this subtable covers. */ - KernSubTable subtable; /* Subtable data. */ - public: - DEFINE_SIZE_MIN (8); - }; + typedef KernAATSubTableHeader SubTableHeader; + typedef SubTableHeader::Types Types; + typedef KernSubTable<SubTableHeader> SubTable; protected: - HBUINT32 version; /* Version--0x00010000u */ - HBUINT32 nTables; /* Number of subtables in the kerning table. */ - UnsizedArrayOf<HBUINT8> dataZ; + HBUINT32 version; /* Version--0x00010000u */ + HBUINT32 tableCount; /* Number of subtables in the kerning table. */ + SubTable firstSubTable; /* Subtables. */ public: - DEFINE_SIZE_ARRAY (8, dataZ); + DEFINE_SIZE_MIN (8); }; struct kern { static const hb_tag_t tableTag = HB_OT_TAG_kern; - inline bool has_data (void) const - { return u.version32 != 0; } + inline bool has_data (void) const { return u.version32; } + inline unsigned int get_type (void) const { return u.major; } + + inline bool has_cross_stream (void) const + { + switch (get_type ()) { + case 0: return u.ot.has_cross_stream (); + case 1: return u.aat.has_cross_stream (); + default:return false; + } + } inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const { - switch (u.major) { + switch (get_type ()) { case 0: return u.ot.get_h_kerning (left, right); case 1: return u.aat.get_h_kerning (left, right); default:return 0; } } - inline void apply (AAT::hb_aat_apply_context_t *c) const + inline bool apply (AAT::hb_aat_apply_context_t *c) const + { return dispatch (c); } + + template <typename context_t> + inline typename context_t::return_t dispatch (context_t *c) const { - /* TODO Switch to dispatch(). */ - switch (u.major) { - case 0: u.ot.apply (c); return; - case 1: u.aat.apply (c); return; - default: return; + unsigned int subtable_type = get_type (); + TRACE_DISPATCH (this, subtable_type); + switch (subtable_type) { + case 0: return_trace (c->dispatch (u.ot)); + case 1: return_trace (c->dispatch (u.aat)); + default: return_trace (c->default_return_value ()); } } @@ -748,11 +311,7 @@ struct kern { TRACE_SANITIZE (this); if (!u.version32.sanitize (c)) return_trace (false); - switch (u.major) { - case 0: return_trace (u.ot.sanitize (c)); - case 1: return_trace (u.aat.sanitize (c)); - default:return_trace (true); - } + return_trace (dispatch (c)); } protected: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh index 582e60155b7..fb57e76242e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-base-table.hh @@ -198,6 +198,7 @@ struct MinMax const BaseCoord **min, const BaseCoord **max) const { + /* TODO Replace hb_bsearch() with .bsearch(). */ const FeatMinMaxRecord *minMaxCoord = (const FeatMinMaxRecord *) hb_bsearch (&feature_tag, featMinMaxRecords.arrayZ, featMinMaxRecords.len, @@ -230,7 +231,7 @@ struct MinMax maxCoord; /* Offset to BaseCoord table that defines * maximum extent value, from the beginning * of MinMax table (may be NULL) */ - ArrayOf<FeatMinMaxRecord> + SortedArrayOf<FeatMinMaxRecord> featMinMaxRecords; /* Array of FeatMinMaxRecords, in alphabetical * order by featureTableTag */ @@ -302,6 +303,7 @@ struct BaseScript { inline const MinMax &get_min_max (hb_tag_t language_tag) const { + /* TODO Replace hb_bsearch() with .bsearch(). */ const BaseLangSysRecord* record = (const BaseLangSysRecord *) hb_bsearch (&language_tag, baseLangSysRecords.arrayZ, baseLangSysRecords.len, @@ -332,7 +334,7 @@ struct BaseScript OffsetTo<MinMax> defaultMinMax; /* Offset to MinMax table, from beginning of * BaseScript table (may be NULL) */ - ArrayOf<BaseLangSysRecord> + SortedArrayOf<BaseLangSysRecord> baseLangSysRecords; /* Number of BaseLangSysRecords * defined — may be zero (0) */ @@ -377,6 +379,7 @@ struct BaseScriptList { inline const BaseScriptRecord *find_record (hb_tag_t script) const { + /* TODO Replace hb_bsearch() with .bsearch(). */ return (const BaseScriptRecord *) hb_bsearch (&script, baseScriptRecords.arrayZ, baseScriptRecords.len, BaseScriptRecord::static_size, @@ -400,7 +403,7 @@ struct BaseScriptList } protected: - ArrayOf<BaseScriptRecord> + SortedArrayOf<BaseScriptRecord> baseScriptRecords; public: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh index 7b1d39aa0c6..55b05b5136d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-common.hh @@ -131,8 +131,8 @@ struct RecordArrayOf : SortedArrayOf<Record<Type> > /* If we want to allow non-sorted data, we can lsearch(). */ int i = this->/*lsearch*/bsearch (tag); if (i != -1) { - if (index) *index = i; - return true; + if (index) *index = i; + return true; } else { if (index) *index = Index::NOT_FOUND_INDEX; return false; @@ -526,21 +526,21 @@ struct FeatureParams { if (tag == HB_TAG ('s','i','z','e')) return u.size; - return Null(FeatureParamsSize); + 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); + 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); + return Null (FeatureParamsCharacterVariants); } private: @@ -704,7 +704,7 @@ struct Lookup for (unsigned int i = 0; i < count; i++) { typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type); if (c->stop_sublookup_iteration (r)) - return_trace (r); + return_trace (r); } return_trace (c->default_return_value ()); } @@ -790,7 +790,7 @@ struct Lookup unsigned int type = get_subtable<TSubTable> (0).u.extension.get_type (); unsigned int count = get_subtable_count (); for (unsigned int i = 1; i < count; i++) - if (get_subtable<TSubTable> (i).u.extension.get_type () != type) + if (get_subtable<TSubTable> (i).u.extension.get_type () != type) return_trace (false); } return_trace (true); @@ -854,7 +854,7 @@ struct CoverageFormat1 unsigned int count = glyphArray.len; for (unsigned int i = 0; i < count; i++) if (glyphs->has (glyphArray[i])) - return true; + return true; return false; } inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const @@ -920,7 +920,7 @@ struct CoverageFormat2 unsigned int num_ranges = 1; for (unsigned int i = 1; i < num_glyphs; i++) if (glyphs[i - 1] + 1 != glyphs[i]) - num_ranges++; + num_ranges++; rangeRecord.len.set (num_ranges); if (unlikely (!c->extend (rangeRecord))) return_trace (false); @@ -932,9 +932,9 @@ struct CoverageFormat2 range++; rangeRecord[range].start = glyphs[i]; rangeRecord[range].value.set (i); - rangeRecord[range].end = glyphs[i]; + rangeRecord[range].end = glyphs[i]; } else { - rangeRecord[range].end = glyphs[i]; + rangeRecord[range].end = glyphs[i]; } glyphs += num_glyphs; return_trace (true); @@ -952,7 +952,7 @@ struct CoverageFormat2 unsigned int count = rangeRecord.len; for (unsigned int i = 0; i < count; i++) if (rangeRecord[i].intersects (glyphs)) - return true; + return true; return false; } inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const @@ -964,9 +964,9 @@ struct CoverageFormat2 if (range.value <= index && index < (unsigned int) range.value + (range.end - range.start) && range.intersects (glyphs)) - return true; + return true; else if (index < range.value) - return false; + return false; } return false; } @@ -976,7 +976,7 @@ struct CoverageFormat2 unsigned int count = rangeRecord.len; for (unsigned int i = 0; i < count; i++) if (unlikely (!rangeRecord[i].add_coverage (glyphs))) - return false; + return false; return true; } @@ -992,8 +992,8 @@ struct CoverageFormat2 j = c->rangeRecord.len ? c->rangeRecord[0].start : 0; if (unlikely (c->rangeRecord[0].start > c->rangeRecord[0].end)) { - /* Broken table. Skip. */ - i = c->rangeRecord.len; + /* Broken table. Skip. */ + i = c->rangeRecord.len; } } inline void fini (void) {} @@ -1002,7 +1002,7 @@ struct CoverageFormat2 { if (j >= c->rangeRecord[i].end) { - i++; + i++; if (more ()) { hb_codepoint_t old = j; @@ -1060,7 +1060,7 @@ struct Coverage unsigned int num_ranges = 1; for (unsigned int i = 1; i < num_glyphs; i++) if (glyphs[i - 1] + 1 != glyphs[i]) - num_ranges++; + num_ranges++; u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2); switch (u.format) { @@ -1213,7 +1213,7 @@ struct ClassDefFormat1 for (unsigned int i = 0; i < count; i++) { if (classValue[i]) - continue; + continue; if (start != i) if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + i))) @@ -1232,10 +1232,7 @@ struct ClassDefFormat1 inline bool add_class (set_t *glyphs, unsigned int klass) const { unsigned int count = classValue.len; for (unsigned int i = 0; i < count; i++) - { - if (classValue[i] == klass) - glyphs->add (startGlyph + i); - } + if (classValue[i] == klass) glyphs->add (startGlyph + i); return true; } @@ -1246,8 +1243,7 @@ struct ClassDefFormat1 hb_codepoint_t end = startGlyph + classValue.len; for (hb_codepoint_t iter = startGlyph - 1; hb_set_next (glyphs, &iter) && iter < end;) - if (classValue[iter - start]) - return true; + if (classValue[iter - start]) return true; return false; } inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { @@ -1256,18 +1252,15 @@ struct ClassDefFormat1 { /* Match if there's any glyph that is not listed! */ hb_codepoint_t g = HB_SET_VALUE_INVALID; - if (!hb_set_next (glyphs, &g)) - return false; - if (g < startGlyph) - return true; + if (!hb_set_next (glyphs, &g)) return false; + if (g < startGlyph) return true; g = startGlyph + count - 1; - if (hb_set_next (glyphs, &g)) - return true; + if (hb_set_next (glyphs, &g)) return true; /* Fall through. */ } for (unsigned int i = 0; i < count; i++) if (classValue[i] == klass && glyphs->has (startGlyph + i)) - return true; + return true; return false; } @@ -1317,7 +1310,7 @@ struct ClassDefFormat2 for (unsigned int i = 0; i < count; i++) { if (rangeRecord[i].value == klass) - if (unlikely (!rangeRecord[i].add_coverage (glyphs))) + if (unlikely (!rangeRecord[i].add_coverage (glyphs))) return false; } return true; @@ -1329,7 +1322,7 @@ struct ClassDefFormat2 unsigned int count = rangeRecord.len; for (unsigned int i = 0; i < count; i++) if (rangeRecord[i].intersects (glyphs)) - return true; + return true; return false; } inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const @@ -1348,12 +1341,12 @@ struct ClassDefFormat2 g = rangeRecord[i].end; } if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g)) - return true; + return true; /* Fall through. */ } for (unsigned int i = 0; i < count; i++) if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs)) - return true; + return true; return false; } @@ -1498,7 +1491,7 @@ struct VarRegionList int coord = i < coord_len ? coords[i] : 0; float factor = axes[i].evaluate (coord); if (factor == 0.f) - return 0.; + return 0.; v *= factor; } return v; @@ -1564,10 +1557,11 @@ struct VarData { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - regionIndices.sanitize(c) && + regionIndices.sanitize (c) && shortCount <= regionIndices.len && - c->check_array (&StructAfter<HBUINT8> (regionIndices), - itemCount, get_row_size ())); + c->check_range (&StructAfter<HBUINT8> (regionIndices), + itemCount, + get_row_size ())); } protected: @@ -1683,7 +1677,7 @@ struct ConditionSet unsigned int count = conditions.len; for (unsigned int i = 0; i < count; i++) if (!(this+conditions.arrayZ[i]).evaluate (coords, coord_len)) - return false; + return false; return true; } @@ -1941,7 +1935,7 @@ struct DeviceHeader struct Device { - inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store=Null(VariationStore)) const + inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store=Null (VariationStore)) const { switch (u.b.format) { @@ -1953,7 +1947,7 @@ struct Device return 0; } } - inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store=Null(VariationStore)) const + inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store=Null (VariationStore)) const { switch (u.b.format) { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh index 5847953d3d1..22e07f7a4f3 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gdef-table.hh @@ -123,10 +123,8 @@ struct CaretValueFormat2 inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const { hb_position_t x, y; - if (font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y)) - return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y; - else - return 0; + font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y); + return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y; } inline bool sanitize (hb_sanitize_context_t *c) const @@ -350,7 +348,7 @@ struct GDEF ComponentGlyph = 4 }; - inline bool has_data (void) const { return version.to_int () != 0; } + inline bool has_data (void) const { return version.to_int (); } inline bool has_glyph_classes (void) const { return glyphClassDef != 0; } inline unsigned int get_glyph_class (hb_codepoint_t glyph) const { return (this+glyphClassDef).get_class (glyph); } @@ -410,15 +408,14 @@ struct GDEF struct accelerator_t { - HB_INTERNAL inline void init (hb_face_t *face); + HB_INTERNAL void init (hb_face_t *face); inline void fini (void) { - hb_blob_destroy (this->blob); + this->table.destroy (); } - hb_blob_t *blob; - hb_nonnull_ptr_t<const GDEF> table; + hb_blob_ptr_t<GDEF> table; }; inline unsigned int get_size (void) const diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh index 399ede434d8..907fd463117 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gpos-table.hh @@ -53,7 +53,7 @@ enum attach_type_t { typedef HBUINT16 Value; -typedef Value ValueRecord[VAR]; +typedef UnsizedArrayOf<Value> ValueRecord; struct ValueFormat : HBUINT16 { @@ -103,56 +103,58 @@ struct ValueFormat : HBUINT16 inline unsigned int get_size (void) const { return get_len () * Value::static_size; } - void apply_value (hb_ot_apply_context_t *c, + bool apply_value (hb_ot_apply_context_t *c, const void *base, const Value *values, hb_glyph_position_t &glyph_pos) const { + bool ret = false; unsigned int format = *this; - if (!format) return; + if (!format) return ret; hb_font_t *font = c->font; - hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (c->direction); + bool horizontal = HB_DIRECTION_IS_HORIZONTAL (c->direction); - if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++)); - if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++)); + if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++, &ret)); + if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++, &ret)); if (format & xAdvance) { - if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values)); + if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values, &ret)); values++; } /* y_advance values grow downward but font-space grows upward, hence negation */ if (format & yAdvance) { - if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values)); + if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values, &ret)); values++; } - if (!has_device ()) return; + if (!has_device ()) return ret; bool use_x_device = font->x_ppem || font->num_coords; bool use_y_device = font->y_ppem || font->num_coords; - if (!use_x_device && !use_y_device) return; + if (!use_x_device && !use_y_device) return ret; const VariationStore &store = c->var_store; /* pixel -> fractional pixel */ if (format & xPlaDevice) { - if (use_x_device) glyph_pos.x_offset += (base + get_device (values)).get_x_delta (font, store); + if (use_x_device) glyph_pos.x_offset += (base + get_device (values, &ret)).get_x_delta (font, store); values++; } if (format & yPlaDevice) { - if (use_y_device) glyph_pos.y_offset += (base + get_device (values)).get_y_delta (font, store); + if (use_y_device) glyph_pos.y_offset += (base + get_device (values, &ret)).get_y_delta (font, store); values++; } if (format & xAdvDevice) { - if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values)).get_x_delta (font, store); + if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values, &ret)).get_x_delta (font, store); values++; } if (format & yAdvDevice) { /* y_advance values grow downward but font-space grows upward, hence negation */ - if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values)).get_y_delta (font, store); + if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values, &ret)).get_y_delta (font, store); values++; } + return ret; } private: @@ -175,11 +177,17 @@ struct ValueFormat : HBUINT16 static inline OffsetTo<Device>& get_device (Value* value) { return *CastP<OffsetTo<Device> > (value); } - static inline const OffsetTo<Device>& get_device (const Value* value) - { return *CastP<OffsetTo<Device> > (value); } + static inline const OffsetTo<Device>& get_device (const Value* value, bool *worked=nullptr) + { + if (worked) *worked |= *value; + return *CastP<OffsetTo<Device> > (value); + } - static inline const HBINT16& get_short (const Value* value) - { return *CastP<HBINT16> (value); } + static inline const HBINT16& get_short (const Value* value, bool *worked=nullptr) + { + if (worked) *worked |= *value; + return *CastP<HBINT16> (value); + } public: @@ -199,13 +207,13 @@ struct ValueFormat : HBUINT16 TRACE_SANITIZE (this); unsigned int len = get_len (); - if (!c->check_array (values, count, get_size ())) return_trace (false); + if (!c->check_range (values, count, get_size ())) return_trace (false); if (!has_device ()) return_trace (true); for (unsigned int i = 0; i < count; i++) { if (!sanitize_value_devices (c, base, values)) - return_trace (false); + return_trace (false); values += len; } @@ -221,7 +229,7 @@ struct ValueFormat : HBUINT16 for (unsigned int i = 0; i < count; i++) { if (!sanitize_value_devices (c, base, values)) - return_trace (false); + return_trace (false); values += stride; } @@ -263,10 +271,10 @@ struct AnchorFormat2 unsigned int x_ppem = font->x_ppem; unsigned int y_ppem = font->y_ppem; hb_position_t cx = 0, cy = 0; - hb_bool_t ret; + bool ret; ret = (x_ppem || y_ppem) && - font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy); + font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy); *x = ret && x_ppem ? cx : font->em_fscale_x (xCoordinate); *y = ret && y_ppem ? cy : font->em_fscale_y (yCoordinate); } @@ -626,7 +634,7 @@ struct PairSet for (unsigned int i = 0; i < count; i++) { if (glyphs->has (record->secondGlyph)) - return true; + return true; record = &StructAtOffset<const PairValueRecord> (record, record_size); } return false; @@ -667,14 +675,15 @@ struct PairSet const PairValueRecord *record = &StructAtOffset<PairValueRecord> (&firstPairValueRecord, record_size * mid); hb_codepoint_t mid_x = record->secondGlyph; if (x < mid_x) - max = mid - 1; + max = mid - 1; else if (x > mid_x) - min = mid + 1; + min = mid + 1; else { - buffer->unsafe_to_break (buffer->idx, pos + 1); - valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()); - valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]); + /* Note the intentional use of "|" instead of short-circuit "||". */ + if (valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()) | + valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos])) + buffer->unsafe_to_break (buffer->idx, pos + 1); if (len2) pos++; buffer->idx = pos; @@ -697,7 +706,10 @@ struct PairSet { TRACE_SANITIZE (this); if (!(c->check_struct (this) - && c->check_array (&firstPairValueRecord, len, HBUINT16::static_size * closure->stride))) return_trace (false); + && c->check_range (&firstPairValueRecord, + len, + HBUINT16::static_size, + closure->stride))) return_trace (false); unsigned int count = len; const PairValueRecord *record = &firstPairValueRecord; @@ -722,10 +734,10 @@ struct PairPosFormat1 for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ + break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ if (glyphs->has (iter.get_glyph ()) && (this+pairSet[iter.get_coverage ()]).intersects (glyphs, valueFormat)) - return true; + return true; } return false; } @@ -837,10 +849,11 @@ struct PairPosFormat2 unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint); if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false); - buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1); const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; - valueFormat1.apply_value (c, this, v, buffer->cur_pos()); - valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]); + /* Note the intentional use of "|" instead of short-circuit "||". */ + if (valueFormat1.apply_value (c, this, v, buffer->cur_pos()) | + valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx])) + buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1); buffer->idx = skippy_iter.idx; if (len2) @@ -869,7 +882,9 @@ struct PairPosFormat2 unsigned int stride = len1 + len2; unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size (); unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count; - return_trace (c->check_array (values, count, record_size) && + return_trace (c->check_range ((const void *) values, + count, + record_size) && valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) && valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride)); } @@ -1406,7 +1421,7 @@ struct MarkMarkPosFormat1 if (id1 == 0) /* Marks belonging to the same base. */ goto good; else if (comp1 == comp2) /* Marks belonging to the same ligature component. */ - goto good; + goto good; } else { /* If ligature ids don't match, it may be the case that one of the marks * itself is a ligature. In which case match. */ @@ -1736,18 +1751,21 @@ GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) } +struct GPOS_accelerator_t : GPOS::accelerator_t {}; + + /* Out-of-class implementation for methods recursing */ template <typename context_t> /*static*/ inline typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index) { - const PosLookup &l = _get_gpos_relaxed (c->face)->get_lookup (lookup_index); + const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index); return l.dispatch (c); } /*static*/ inline bool PosLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index) { - const PosLookup &l = _get_gpos_relaxed (c->face).get_lookup (lookup_index); + const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index); unsigned int saved_lookup_props = c->lookup_props; unsigned int saved_lookup_index = c->lookup_index; c->set_lookup_index (lookup_index); @@ -1758,8 +1776,6 @@ template <typename context_t> return ret; } -struct GPOS_accelerator_t : GPOS::accelerator_t {}; - } /* namespace OT */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh index d24ea59afec..715317b59ab 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsub-table.hh @@ -588,7 +588,7 @@ struct AlternateSubstFormat1 for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ + break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ if (c->glyphs->has (iter.get_glyph ())) (this+alternateSet[iter.get_coverage ()]).closure (c); } @@ -602,7 +602,7 @@ struct AlternateSubstFormat1 for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ + break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ (this+alternateSet[iter.get_coverage ()]).collect_glyphs (c); } } @@ -1487,6 +1487,9 @@ struct GSUB : GSUBGPOS }; +struct GSUB_accelerator_t : GSUB::accelerator_t {}; + + /* Out-of-class implementation for methods recursing */ /*static*/ inline bool ExtensionSubst::is_reverse (void) const @@ -1500,13 +1503,13 @@ struct GSUB : GSUBGPOS template <typename context_t> /*static*/ inline typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index) { - const SubstLookup &l = _get_gsub_relaxed (c->face).get_lookup (lookup_index); + const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index); return l.dispatch (c); } /*static*/ inline bool SubstLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index) { - const SubstLookup &l = _get_gsub_relaxed (c->face).get_lookup (lookup_index); + const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index); unsigned int saved_lookup_props = c->lookup_props; unsigned int saved_lookup_index = c->lookup_index; c->set_lookup_index (lookup_index); @@ -1517,8 +1520,6 @@ template <typename context_t> return ret; } -struct GSUB_accelerator_t : GSUB::accelerator_t {}; - } /* namespace OT */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh index 0d9eeae585a..3d70c55c2ea 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh @@ -100,14 +100,14 @@ struct hb_closure_context_t : hb_closure_context_t (hb_face_t *face_, hb_set_t *glyphs_, - hb_map_t *done_lookups_, - unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : + hb_map_t *done_lookups_, + unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), glyphs (glyphs_), recurse_func (nullptr), nesting_level_left (nesting_level_left_), debug_depth (0), - done_lookups (done_lookups_) {} + done_lookups (done_lookups_) {} ~hb_closure_context_t (void) { @@ -291,14 +291,14 @@ struct hb_ot_apply_context_t : }; inline may_match_t may_match (const hb_glyph_info_t &info, - const HBUINT16 *glyph_data) const + const HBUINT16 *glyph_data) const { if (!(info.mask & mask) || (syllable && syllable != info.syllable ())) return MATCH_NO; if (match_func) - return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO; + return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO; return MATCH_MAYBE; } @@ -491,7 +491,7 @@ struct hb_ot_apply_context_t : iter_input (), iter_context (), font (font_), face (font->face), buffer (buffer_), recurse_func (nullptr), - gdef (_get_gdef (face)), + gdef (*face->table.GDEF->table), var_store (gdef.get_var_store ()), direction (buffer_->props.direction), lookup_mask (1), @@ -852,9 +852,9 @@ static inline bool match_input (hb_ot_apply_context_t *c, * component, otherwise we shouldn't ligate them... */ if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp) { - /* ...unless, we are attached to a base ligature and that base + /* ...unless, we are attached to a base ligature and that base * ligature is ignorable. */ - if (ligbase == LIGBASE_NOT_CHECKED) + if (ligbase == LIGBASE_NOT_CHECKED) { bool found = false; const hb_glyph_info_t *out = buffer->out_info; @@ -876,7 +876,7 @@ static inline bool match_input (hb_ot_apply_context_t *c, ligbase = LIGBASE_MAY_NOT_SKIP; } - if (ligbase == LIGBASE_MAY_NOT_SKIP) + if (ligbase == LIGBASE_MAY_NOT_SKIP) return_trace (false); } } @@ -977,7 +977,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, { if (is_ligature) { - unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); + unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); if (this_comp == 0) this_comp = last_num_components; unsigned int new_lig_comp = components_so_far - last_num_components + @@ -999,7 +999,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, /* Re-adjust components for any marks following. */ for (unsigned int i = buffer->idx; i < buffer->len; i++) { if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) { - unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]); + unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]); if (!this_comp) break; unsigned int new_lig_comp = components_so_far - last_num_components + @@ -1133,7 +1133,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c, int delta = new_len - orig_len; if (!delta) - continue; + continue; /* Recursed lookup changed buffer len. Adjust. * @@ -1376,7 +1376,7 @@ struct RuleSet unsigned int num_rules = rule.len; for (unsigned int i = 0; i < num_rules; i++) if ((this+rule[i]).intersects (glyphs, lookup_context)) - return true; + return true; return false; } @@ -1403,7 +1403,7 @@ struct RuleSet for (unsigned int i = 0; i < num_rules; i++) { if ((this+rule[i]).would_apply (c, lookup_context)) - return_trace (true); + return_trace (true); } return_trace (false); } @@ -1415,7 +1415,7 @@ struct RuleSet for (unsigned int i = 0; i < num_rules; i++) { if ((this+rule[i]).apply (c, lookup_context)) - return_trace (true); + return_trace (true); } return_trace (false); } @@ -1448,10 +1448,10 @@ struct ContextFormat1 for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ + break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ if (glyphs->has (iter.get_glyph ()) && (this+ruleSet[iter.get_coverage ()]).intersects (glyphs, lookup_context)) - return true; + return true; } return false; } @@ -1469,7 +1469,7 @@ struct ContextFormat1 for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ + break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ if (c->glyphs->has (iter.get_glyph ())) (this+ruleSet[iter.get_coverage ()]).closure (c, lookup_context); } @@ -1564,7 +1564,7 @@ struct ContextFormat2 for (unsigned int i = 0; i < count; i++) if (class_def.intersects_class (glyphs, i) && (this+ruleSet[i]).intersects (glyphs, lookup_context)) - return true; + return true; return false; } @@ -1868,15 +1868,15 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c, } static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, - unsigned int backtrackCount, - const HBUINT16 backtrack[], - unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ - unsigned int lookaheadCount, - const HBUINT16 lookahead[], - unsigned int lookupCount, - const LookupRecord lookupRecord[], - ChainContextCollectGlyphsLookupContext &lookup_context) + unsigned int backtrackCount, + const HBUINT16 backtrack[], + unsigned int inputCount, /* Including the first glyph (not matched) */ + const HBUINT16 input[], /* Array of input values--start with second glyph */ + unsigned int lookaheadCount, + const HBUINT16 lookahead[], + unsigned int lookupCount, + const LookupRecord lookupRecord[], + ChainContextCollectGlyphsLookupContext &lookup_context) { collect_array (c, c->before, backtrackCount, backtrack, @@ -1934,10 +1934,10 @@ static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c, lookup_context.funcs.match, lookup_context.match_data[2], match_length, &end_index) && (c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index), - apply_lookup (c, - inputCount, match_positions, - lookupCount, lookupRecord, - match_length)); + apply_lookup (c, + inputCount, match_positions, + lookupCount, lookupRecord, + match_length)); } struct ChainRule @@ -2044,7 +2044,7 @@ struct ChainRuleSet unsigned int num_rules = rule.len; for (unsigned int i = 0; i < num_rules; i++) if ((this+rule[i]).intersects (glyphs, lookup_context)) - return true; + return true; return false; } inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const @@ -2069,7 +2069,7 @@ struct ChainRuleSet unsigned int num_rules = rule.len; for (unsigned int i = 0; i < num_rules; i++) if ((this+rule[i]).would_apply (c, lookup_context)) - return_trace (true); + return_trace (true); return_trace (false); } @@ -2080,7 +2080,7 @@ struct ChainRuleSet unsigned int num_rules = rule.len; for (unsigned int i = 0; i < num_rules; i++) if ((this+rule[i]).apply (c, lookup_context)) - return_trace (true); + return_trace (true); return_trace (false); } @@ -2112,10 +2112,10 @@ struct ChainContextFormat1 for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ + break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ if (glyphs->has (iter.get_glyph ()) && (this+ruleSet[iter.get_coverage ()]).intersects (glyphs, lookup_context)) - return true; + return true; } return false; } @@ -2133,7 +2133,7 @@ struct ChainContextFormat1 for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { if (unlikely (iter.get_coverage () >= count)) - break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ + break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ if (c->glyphs->has (iter.get_glyph ())) (this+ruleSet[iter.get_coverage ()]).closure (c, lookup_context); } @@ -2230,7 +2230,7 @@ struct ChainContextFormat2 for (unsigned int i = 0; i < count; i++) if (input_class_def.intersects_class (glyphs, i) && (this+ruleSet[i]).intersects (glyphs, lookup_context)) - return true; + return true; return false; } @@ -2644,10 +2644,10 @@ struct hb_ot_layout_lookup_accelerator_t inline bool apply (hb_ot_apply_context_t *c) const { - for (unsigned int i = 0; i < subtables.len; i++) - if (subtables[i].apply (c)) - return true; - return false; + for (unsigned int i = 0; i < subtables.len; i++) + if (subtables[i].apply (c)) + return true; + return false; } private: @@ -2657,7 +2657,7 @@ struct hb_ot_layout_lookup_accelerator_t struct GSUBGPOS { - inline bool has_data (void) const { return version.to_int () != 0; } + inline bool has_data (void) const { return version.to_int (); } inline unsigned int get_script_count (void) const { return (this+scriptList).len; } inline const Tag& get_script_tag (unsigned int i) const @@ -2702,7 +2702,7 @@ struct GSUBGPOS const Feature *feature = (this+featureVars).find_substitute (variations_index, feature_index); if (feature) - return *feature; + return *feature; } return get_feature (feature_index); } @@ -2752,14 +2752,13 @@ struct GSUBGPOS { inline void init (hb_face_t *face) { - this->blob = hb_sanitize_context_t().reference_table<T> (face); - table = this->blob->template as<T> (); + this->table = hb_sanitize_context_t().reference_table<T> (face); this->lookup_count = table->get_lookup_count (); this->accels = (hb_ot_layout_lookup_accelerator_t *) calloc (this->lookup_count, sizeof (hb_ot_layout_lookup_accelerator_t)); if (unlikely (!this->accels)) - this->lookup_count = 0; + this->lookup_count = 0; for (unsigned int i = 0; i < this->lookup_count; i++) this->accels[i].init (table->get_lookup (i)); @@ -2770,11 +2769,10 @@ struct GSUBGPOS for (unsigned int i = 0; i < this->lookup_count; i++) this->accels[i].fini (); free (this->accels); - hb_blob_destroy (this->blob); + this->table.destroy (); } - hb_blob_t *blob; - hb_nonnull_ptr_t<const T> table; + hb_blob_ptr_t<T> table; unsigned int lookup_count; hb_ot_layout_lookup_accelerator_t *accels; }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc index fcdc79ee9bb..092633c5ddc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc @@ -42,6 +42,8 @@ #include "hb-ot-kern-table.hh" #include "hb-ot-name-table.hh" +#include "hb-aat-layout-lcar-table.hh" + /** * SECTION:hb-ot-layout @@ -53,72 +55,29 @@ **/ -static inline const OT::kern& -_get_kern (hb_face_t *face, hb_blob_t **blob = nullptr) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) - { - if (blob) - *blob = hb_blob_get_empty (); - return Null(OT::kern); - } - const OT::kern& kern = *(hb_ot_face_data (face)->kern); - if (blob) - *blob = hb_ot_face_data (face)->kern.get_blob (); - return kern; -} -const OT::GDEF& _get_gdef (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GDEF); - return *hb_ot_face_data (face)->GDEF->table; -} -static hb_blob_t * _get_gsub_blob (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return hb_blob_get_empty (); - return hb_ot_face_data (face)->GSUB->blob; -} -static inline const OT::GSUB& _get_gsub (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GSUB); - return *hb_ot_face_data (face)->GSUB->table; -} -const OT::GSUB& _get_gsub_relaxed (hb_face_t *face) -{ - return *hb_ot_face_data (face)->GSUB.get_relaxed ()->table; -} -static hb_blob_t * _get_gpos_blob (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return hb_blob_get_empty (); - return hb_ot_face_data (face)->GPOS->blob; -} -static inline const OT::GPOS& _get_gpos (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GPOS); - return *hb_ot_face_data (face)->GPOS->table; -} -const OT::GPOS& _get_gpos_relaxed (hb_face_t *face) -{ - return *hb_ot_face_data (face)->GPOS.get_relaxed ()->table; -} - - /* * kern */ -hb_bool_t +bool hb_ot_layout_has_kerning (hb_face_t *face) { - return _get_kern (face).has_data (); + return face->table.kern->has_data (); +} + +bool +hb_ot_layout_has_cross_kerning (hb_face_t *face) +{ + return face->table.kern->has_cross_stream (); } void -hb_ot_layout_kern (hb_ot_shape_plan_t *plan, +hb_ot_layout_kern (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - hb_blob_t *blob; - const AAT::kern& kern = _get_kern (font->face, &blob); + hb_blob_t *blob = font->face->table.kern.get_blob (); + const AAT::kern& kern = *blob->as<AAT::kern> (); AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); @@ -232,20 +191,18 @@ _hb_ot_blacklist_gdef (unsigned int gdef_len, return false; } -inline void +void OT::GDEF::accelerator_t::init (hb_face_t *face) { - this->blob = hb_sanitize_context_t().reference_table<GDEF> (face); + this->table = hb_sanitize_context_t().reference_table<GDEF> (face); - if (unlikely (_hb_ot_blacklist_gdef (this->blob->length, - _get_gsub_blob (face)->length, - _get_gpos_blob (face)->length))) + if (unlikely (_hb_ot_blacklist_gdef (this->table.get_length (), + face->table.GSUB->table.get_length (), + face->table.GPOS->table.get_length ()))) { - hb_blob_destroy (this->blob); - this->blob = hb_blob_get_empty (); + hb_blob_destroy (this->table.get_blob ()); + this->table = hb_blob_get_empty (); } - - table = this->blob->as<GDEF> (); } static void @@ -254,7 +211,7 @@ _hb_ot_layout_set_glyph_props (hb_font_t *font, { _hb_buffer_assert_gsubgpos_vars (buffer); - const OT::GDEF &gdef = _get_gdef (font->face); + const OT::GDEF &gdef = *font->face->table.GDEF->table; unsigned int count = buffer->len; for (unsigned int i = 0; i < count; i++) { @@ -269,7 +226,7 @@ _hb_ot_layout_set_glyph_props (hb_font_t *font, hb_bool_t hb_ot_layout_has_glyph_classes (hb_face_t *face) { - return _get_gdef (face).has_glyph_classes (); + return face->table.GDEF->table->has_glyph_classes (); } /** @@ -281,7 +238,7 @@ hb_ot_layout_glyph_class_t hb_ot_layout_get_glyph_class (hb_face_t *face, hb_codepoint_t glyph) { - return (hb_ot_layout_glyph_class_t) _get_gdef (face).get_glyph_class (glyph); + return (hb_ot_layout_glyph_class_t) face->table.GDEF->table->get_glyph_class (glyph); } /** @@ -294,7 +251,7 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face, hb_ot_layout_glyph_class_t klass, hb_set_t *glyphs /* OUT */) { - return _get_gdef (face).get_glyphs_in_class (klass, glyphs); + return face->table.GDEF->table->get_glyphs_in_class (klass, glyphs); } unsigned int @@ -304,7 +261,10 @@ hb_ot_layout_get_attach_points (hb_face_t *face, unsigned int *point_count /* IN/OUT */, unsigned int *point_array /* OUT */) { - return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, point_array); + return face->table.GDEF->table->get_attach_points (glyph, + start_offset, + point_count, + point_array); } unsigned int @@ -315,7 +275,15 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font, unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) { - return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array); + unsigned int result_caret_count = 0; + unsigned int result = font->face->table.GDEF->table->get_lig_carets (font, direction, glyph, start_offset, &result_caret_count, caret_array); + if (result) + { + if (caret_count) *caret_count = result_caret_count; + } + else + result = font->face->table.lcar->get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array); + return result; } @@ -328,8 +296,8 @@ get_gsubgpos_table (hb_face_t *face, hb_tag_t table_tag) { switch (table_tag) { - case HB_OT_TAG_GSUB: return _get_gsub (face); - case HB_OT_TAG_GPOS: return _get_gpos (face); + case HB_OT_TAG_GSUB: return *face->table.GSUB->table; + case HB_OT_TAG_GPOS: return *face->table.GPOS->table; default: return Null(OT::GSUBGPOS); } } @@ -458,7 +426,7 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face, return g.get_feature_tags (start_offset, feature_count, feature_tags); } -hb_bool_t +bool hb_ot_layout_table_find_feature (hb_face_t *face, hb_tag_t table_tag, hb_tag_t feature_tag, @@ -501,7 +469,12 @@ hb_ot_layout_script_find_language (hb_face_t *face, hb_tag_t language_tag, unsigned int *language_index) { - return hb_ot_layout_script_select_language (face, table_tag, script_index, 1, &language_tag, language_index); + return hb_ot_layout_script_select_language (face, + table_tag, + script_index, + 1, + &language_tag, + language_index); } /** @@ -879,8 +852,6 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, 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; - OT::hb_collect_glyphs_context_t c (face, glyphs_before, glyphs_input, @@ -891,13 +862,13 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, { case HB_OT_TAG_GSUB: { - const OT::SubstLookup& l = hb_ot_face_data (face)->GSUB->table->get_lookup (lookup_index); + const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index); l.collect_glyphs (&c); return; } case HB_OT_TAG_GPOS: { - const OT::PosLookup& l = hb_ot_face_data (face)->GPOS->table->get_lookup (lookup_index); + const OT::PosLookup& l = face->table.GPOS->table->get_lookup (lookup_index); l.collect_glyphs (&c); return; } @@ -944,7 +915,7 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face, hb_bool_t hb_ot_layout_has_substitution (hb_face_t *face) { - return _get_gsub (face).has_data (); + return face->table.GSUB->table->has_data (); } /** @@ -959,23 +930,25 @@ hb_ot_layout_lookup_would_substitute (hb_face_t *face, unsigned int glyphs_length, hb_bool_t zero_context) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false; - return hb_ot_layout_lookup_would_substitute_fast (face, lookup_index, glyphs, glyphs_length, zero_context); + return hb_ot_layout_lookup_would_substitute_fast (face, + lookup_index, + glyphs, glyphs_length, + zero_context); } -hb_bool_t +bool hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face, unsigned int lookup_index, const hb_codepoint_t *glyphs, unsigned int glyphs_length, - hb_bool_t zero_context) + bool zero_context) { - if (unlikely (lookup_index >= hb_ot_face_data (face)->GSUB->lookup_count)) return false; + if (unlikely (lookup_index >= face->table.GSUB->lookup_count)) return false; OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, (bool) zero_context); - const OT::SubstLookup& l = hb_ot_face_data (face)->GSUB->table->get_lookup (lookup_index); + const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index); - return l.would_apply (&c, &hb_ot_face_data (face)->GSUB->accels[lookup_index]); + return l.would_apply (&c, &face->table.GSUB->accels[lookup_index]); } void @@ -985,6 +958,56 @@ hb_ot_layout_substitute_start (hb_font_t *font, _hb_ot_layout_set_glyph_props (font, buffer); } +void +hb_ot_layout_delete_glyphs_inplace (hb_buffer_t *buffer, + bool (*filter) (const hb_glyph_info_t *info)) +{ + /* Merge clusters and delete filtered glyphs. + * NOTE! We can't use out-buffer as we have positioning data. */ + unsigned int j = 0; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + for (unsigned int i = 0; i < count; i++) + { + if (filter (&info[i])) + { + /* Merge clusters. + * Same logic as buffer->delete_glyph(), but for in-place removal. */ + + unsigned int cluster = info[i].cluster; + if (i + 1 < count && cluster == info[i + 1].cluster) + continue; /* Cluster survives; do nothing. */ + + if (j) + { + /* Merge cluster backward. */ + if (cluster < info[j - 1].cluster) + { + unsigned int mask = info[i].mask; + unsigned int old_cluster = info[j - 1].cluster; + for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--) + buffer->set_cluster (info[k - 1], cluster, mask); + } + continue; + } + + if (i + 1 < count) + buffer->merge_clusters (i, i + 2); /* Merge cluster forward. */ + + continue; + } + + if (j != i) + { + info[j] = info[i]; + pos[j] = pos[i]; + } + j++; + } + buffer->len = j; +} + /** * hb_ot_layout_lookup_substitute_closure: * @@ -998,7 +1021,7 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face, hb_map_t done_lookups; OT::hb_closure_context_t c (face, glyphs, &done_lookups); - const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index); + const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index); l.closure (&c, lookup_index); } @@ -1018,7 +1041,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, { hb_map_t done_lookups; OT::hb_closure_context_t c (face, glyphs, &done_lookups); - const OT::GSUB& gsub = _get_gsub (face); + const OT::GSUB& gsub = *face->table.GSUB->table; unsigned int iteration_count = 0; unsigned int glyphs_length; @@ -1035,9 +1058,8 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, for (unsigned int i = 0; i < gsub.get_lookup_count (); i++) gsub.get_lookup (i).closure (&c, i); } - iteration_count++; - } while (iteration_count <= HB_CLOSURE_MAX_STAGES - && glyphs_length != glyphs->get_population ()); + } while (iteration_count++ <= HB_CLOSURE_MAX_STAGES && + glyphs_length != glyphs->get_population ()); } /* @@ -1047,7 +1069,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, hb_bool_t hb_ot_layout_has_positioning (hb_face_t *face) { - return _get_gpos (face).has_data (); + return face->table.GPOS->table->has_data (); } void @@ -1081,7 +1103,7 @@ hb_ot_layout_get_size_params (hb_face_t *face, unsigned int *range_start, /* OUT. May be NULL */ unsigned int *range_end /* OUT. May be NULL */) { - const OT::GPOS &gpos = _get_gpos (face); + const OT::GPOS &gpos = *face->table.GPOS->table; const hb_tag_t tag = HB_TAG ('s','i','z','e'); unsigned int num_features = gpos.get_feature_count (); @@ -1254,8 +1276,8 @@ struct GSUBProxy typedef OT::SubstLookup Lookup; GSUBProxy (hb_face_t *face) : - table (*hb_ot_face_data (face)->GSUB->table), - accels (hb_ot_face_data (face)->GSUB->accels) {} + table (*face->table.GSUB->table), + accels (face->table.GSUB->accels) {} const OT::GSUB &table; const OT::hb_ot_layout_lookup_accelerator_t *accels; @@ -1268,8 +1290,8 @@ struct GPOSProxy typedef OT::PosLookup Lookup; GPOSProxy (hb_face_t *face) : - table (*hb_ot_face_data (face)->GPOS->table), - accels (hb_ot_face_data (face)->GPOS->accels) {} + table (*face->table.GPOS->table), + accels (face->table.GPOS->accels) {} const OT::GPOS &table; const OT::hb_ot_layout_lookup_accelerator_t *accels; @@ -1311,10 +1333,8 @@ apply_backward (OT::hb_ot_apply_context_t *c, if (accel.may_have (buffer->cur().codepoint) && (buffer->cur().mask & c->lookup_mask) && c->check_glyph_property (&buffer->cur(), c->lookup_props)) - { - if (accel.apply (c)) - ret = true; - } + ret |= accel.apply (c); + /* The reverse lookup doesn't "advance" cursor (for good reason). */ buffer->idx--; @@ -1427,8 +1447,7 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, #if 0 static const OT::BASE& _get_base (hb_face_t *face) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::BASE); - return *hb_ot_face_data (face)->BASE; + return *face->table.BASE; } hb_bool_t diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh index b29f87c5a36..db85508d2a4 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.hh @@ -38,35 +38,28 @@ #include "hb-set-digest.hh" -namespace OT -{ - struct GDEF; - struct GSUB; - struct GPOS; -} - -HB_INTERNAL const OT::GDEF& _get_gdef (hb_face_t *face); -HB_INTERNAL const OT::GSUB& _get_gsub_relaxed (hb_face_t *face); -HB_INTERNAL const OT::GPOS& _get_gpos_relaxed (hb_face_t *face); - struct hb_ot_shape_plan_t; + /* * kern */ -HB_INTERNAL hb_bool_t +HB_INTERNAL bool hb_ot_layout_has_kerning (hb_face_t *face); +HB_INTERNAL bool +hb_ot_layout_has_cross_kerning (hb_face_t *face); + HB_INTERNAL void -hb_ot_layout_kern (hb_ot_shape_plan_t *plan, +hb_ot_layout_kern (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); /* Private API corresponding to hb-ot-layout.h: */ -HB_INTERNAL hb_bool_t +HB_INTERNAL bool hb_ot_layout_table_find_feature (hb_face_t *face, hb_tag_t table_tag, hb_tag_t feature_tag, @@ -100,12 +93,12 @@ HB_MARK_AS_FLAG_T (hb_ot_layout_glyph_props_flags_t); * GSUB/GPOS */ -HB_INTERNAL hb_bool_t +HB_INTERNAL bool hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face, unsigned int lookup_index, const hb_codepoint_t *glyphs, unsigned int glyphs_length, - hb_bool_t zero_context); + bool zero_context); /* Should be called before all the substitute_lookup's are done. */ @@ -113,6 +106,9 @@ HB_INTERNAL void hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer); +HB_INTERNAL void +hb_ot_layout_delete_glyphs_inplace (hb_buffer_t *buffer, + bool (*filter) (const hb_glyph_info_t *info)); namespace OT { struct hb_ot_apply_context_t; @@ -313,13 +309,13 @@ _hb_glyph_info_get_unicode_space_fallback_type (const hb_glyph_info_t *info) static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info); -static inline hb_bool_t +static inline bool _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) { return (info->unicode_props() & UPROPS_MASK_IGNORABLE) && !_hb_glyph_info_ligated (info); } -static inline hb_bool_t +static inline bool _hb_glyph_info_is_default_ignorable_and_not_hidden (const hb_glyph_info_t *info) { return ((info->unicode_props() & (UPROPS_MASK_IGNORABLE|UPROPS_MASK_HIDDEN)) @@ -373,17 +369,17 @@ _hb_glyph_info_is_unicode_format (const hb_glyph_info_t *info) return _hb_glyph_info_get_general_category (info) == HB_UNICODE_GENERAL_CATEGORY_FORMAT; } -static inline hb_bool_t +static inline bool _hb_glyph_info_is_zwnj (const hb_glyph_info_t *info) { return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWNJ); } -static inline hb_bool_t +static inline bool _hb_glyph_info_is_zwj (const hb_glyph_info_t *info) { return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWJ); } -static inline hb_bool_t +static inline bool _hb_glyph_info_is_joiner (const hb_glyph_info_t *info) { return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & (UPROPS_MASK_Cf_ZWNJ|UPROPS_MASK_Cf_ZWJ)); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc index fd8109950ed..95f794ab4a2 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.cc @@ -27,7 +27,7 @@ */ #include "hb-ot-map.hh" - +#include "hb-ot-shape.hh" #include "hb-ot-layout.hh" @@ -143,9 +143,8 @@ void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::paus } void -hb_ot_map_builder_t::compile (hb_ot_map_t &m, - const int *coords, - unsigned int num_coords) +hb_ot_map_builder_t::compile (hb_ot_map_t &m, + const hb_ot_shape_plan_key_t &key) { static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), ""); unsigned int global_bit_mask = HB_GLYPH_FLAG_DEFINED + 1; @@ -282,13 +281,6 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, { /* Collect lookup indices for features */ - unsigned int variations_index; - hb_ot_layout_table_find_feature_variations (face, - table_tags[table_index], - coords, - num_coords, - &variations_index); - unsigned int stage_index = 0; unsigned int last_num_lookups = 0; for (unsigned stage = 0; stage < current_stage[table_index]; stage++) @@ -297,14 +289,14 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, required_feature_stage[table_index] == stage) add_lookups (m, table_index, required_feature_index[table_index], - variations_index, + key.variations_index[table_index], global_bit_mask); for (unsigned i = 0; i < m.features.len; i++) if (m.features[i].stage[table_index] == stage) add_lookups (m, table_index, m.features[i].index[table_index], - variations_index, + key.variations_index[table_index], m.features[i].mask, m.features[i].auto_zwnj, m.features[i].auto_zwj, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh index fde85b1ddc0..8e1f5aa8c3e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-map.hh @@ -188,6 +188,7 @@ struct hb_ot_map_feature_t hb_ot_map_feature_flags_t flags; }; +struct hb_ot_shape_plan_key_t; struct hb_ot_map_builder_t { @@ -218,9 +219,8 @@ struct hb_ot_map_builder_t inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func) { add_pause (1, pause_func); } - HB_INTERNAL void compile (hb_ot_map_t &m, - const int *coords, - unsigned int num_coords); + HB_INTERNAL void compile (hb_ot_map_t &m, + const hb_ot_shape_plan_key_t &key); private: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh index e20935972e9..b8730497988 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math-table.hh @@ -74,7 +74,7 @@ struct MathConstants inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && sanitize_math_value_records(c)); + return_trace (c->check_struct (this) && sanitize_math_value_records (c)); } inline hb_position_t get_value (hb_ot_math_constant_t constant, @@ -94,7 +94,7 @@ struct MathConstants case HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE: case HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP: case HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT: - return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_x_value(font, this); + return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_x_value (font, this); case HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT: case HB_OT_MATH_CONSTANT_AXIS_HEIGHT: @@ -143,7 +143,7 @@ struct MathConstants case HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP: case HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN: case HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN: - return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_y_value(font, this); + return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_y_value (font, this); case HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT: return radicalDegreeBottomRaisePercent; @@ -210,7 +210,7 @@ struct MathTopAccentAttachment unsigned int index = (this+topAccentCoverage).get_coverage (glyph); if (index == NOT_COVERED) return font->get_glyph_h_advance (glyph) / 2; - return topAccentAttachment[index].get_x_value(font, this); + return topAccentAttachment[index].get_x_value (font, this); } protected: @@ -265,7 +265,7 @@ struct MathKern while (count > 0) { unsigned int half = count / 2; - hb_position_t height = correctionHeight[i + half].get_y_value(font, this); + hb_position_t height = correctionHeight[i + half].get_y_value (font, this); if (sign * height < sign * correction_height) { i += half + 1; @@ -273,7 +273,7 @@ struct MathKern } else count = half; } - return kernValue[i].get_x_value(font, this); + return kernValue[i].get_x_value (font, this); } protected: @@ -368,7 +368,7 @@ struct MathGlyphInfo mathItalicsCorrectionInfo.sanitize (c, this) && mathTopAccentAttachment.sanitize (c, this) && extendedShapeCoverage.sanitize (c, this) && - mathKernInfo.sanitize(c, this)); + mathKernInfo.sanitize (c, this)); } inline hb_position_t @@ -425,8 +425,8 @@ struct MathGlyphVariantRecord protected: GlyphID variantGlyph; /* Glyph ID for the variant. */ HBUINT16 advanceMeasurement; /* Advance width/height, in design units, of the - * variant, in the direction of requested - * glyph extension. */ + * variant, in the direction of requested + * glyph extension. */ public: DEFINE_SIZE_STATIC (4); @@ -495,8 +495,8 @@ struct MathGlyphAssembly { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - italicsCorrection.sanitize(c, this) && - partRecords.sanitize(c)); + italicsCorrection.sanitize (c, this) && + partRecords.sanitize (c)); } inline unsigned int get_parts (hb_direction_t direction, @@ -540,8 +540,8 @@ struct MathGlyphConstruction { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - glyphAssembly.sanitize(c, this) && - mathGlyphVariantRecord.sanitize(c)); + glyphAssembly.sanitize (c, this) && + mathGlyphVariantRecord.sanitize (c)); } inline const MathGlyphAssembly &get_assembly (void) const @@ -639,7 +639,7 @@ struct MathVariants : horizGlyphCoverage; unsigned int index = (this+coverage).get_coverage (glyph); - if (unlikely (index >= count)) return Null(MathGlyphConstruction); + if (unlikely (index >= count)) return Null (MathGlyphConstruction); if (!vertical) index += vertGlyphCount; @@ -684,7 +684,7 @@ struct MATH { static const hb_tag_t tableTag = HB_OT_TAG_MATH; - inline bool has_data (void) const { return version.to_int () != 0; } + inline bool has_data (void) const { return version.to_int (); } inline bool sanitize (hb_sanitize_context_t *c) const { @@ -700,10 +700,10 @@ struct MATH hb_font_t *font) const { return (this+mathConstants).get_value (constant, font); } - inline const MathGlyphInfo &get_math_glyph_info (void) const + inline const MathGlyphInfo &get_glyph_info (void) const { return this+mathGlyphInfo; } - inline const MathVariants &get_math_variants (void) const + inline const MathVariants &get_variants (void) const { return this+mathVariants; } protected: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc index 3fb720b20f7..bd31bf565ab 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-math.cc @@ -40,14 +40,6 @@ **/ -static inline const OT::MATH& -_get_math (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::MATH); - hb_ot_face_data_t * data = hb_ot_face_data (face); - return *(data->MATH); -} - /* * OT::MATH */ @@ -66,7 +58,7 @@ _get_math (hb_face_t *face) hb_bool_t hb_ot_math_has_data (hb_face_t *face) { - return _get_math (face).has_data (); + return face->table.MATH->has_data (); } /** @@ -88,8 +80,7 @@ hb_position_t hb_ot_math_get_constant (hb_font_t *font, hb_ot_math_constant_t constant) { - const OT::MATH &math = _get_math (font->face); - return math.get_constant(constant, font); + return font->face->table.MATH->get_constant(constant, font); } /** @@ -105,8 +96,7 @@ hb_position_t hb_ot_math_get_glyph_italics_correction (hb_font_t *font, hb_codepoint_t glyph) { - const OT::MATH &math = _get_math (font->face); - return math.get_math_glyph_info().get_italics_correction (glyph, font); + return font->face->table.MATH->get_glyph_info().get_italics_correction (glyph, font); } /** @@ -122,8 +112,7 @@ hb_position_t hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font, hb_codepoint_t glyph) { - const OT::MATH &math = _get_math (font->face); - return math.get_math_glyph_info().get_top_accent_attachment (glyph, font); + return font->face->table.MATH->get_glyph_info().get_top_accent_attachment (glyph, font); } /** @@ -139,8 +128,7 @@ hb_bool_t hb_ot_math_is_glyph_extended_shape (hb_face_t *face, hb_codepoint_t glyph) { - const OT::MATH &math = _get_math (face); - return math.get_math_glyph_info().is_extended_shape (glyph); + return face->table.MATH->get_glyph_info().is_extended_shape (glyph); } /** @@ -166,8 +154,10 @@ hb_ot_math_get_glyph_kerning (hb_font_t *font, hb_ot_math_kern_t kern, hb_position_t correction_height) { - const OT::MATH &math = _get_math (font->face); - return math.get_math_glyph_info().get_kerning (glyph, kern, correction_height, font); + return font->face->table.MATH->get_glyph_info().get_kerning (glyph, + kern, + correction_height, + font); } /** @@ -197,11 +187,10 @@ hb_ot_math_get_glyph_variants (hb_font_t *font, unsigned int *variants_count, /* IN/OUT */ hb_ot_math_glyph_variant_t *variants /* OUT */) { - const OT::MATH &math = _get_math (font->face); - return math.get_math_variants().get_glyph_variants (glyph, direction, font, - start_offset, - variants_count, - variants); + return font->face->table.MATH->get_variants().get_glyph_variants (glyph, direction, font, + start_offset, + variants_count, + variants); } /** @@ -222,8 +211,7 @@ hb_position_t hb_ot_math_get_min_connector_overlap (hb_font_t *font, hb_direction_t direction) { - const OT::MATH &math = _get_math (font->face); - return math.get_math_variants().get_min_connector_overlap (direction, font); + return font->face->table.MATH->get_variants().get_min_connector_overlap (direction, font); } /** @@ -255,10 +243,11 @@ hb_ot_math_get_glyph_assembly (hb_font_t *font, hb_ot_math_glyph_part_t *parts, /* OUT */ hb_position_t *italics_correction /* OUT */) { - const OT::MATH &math = _get_math (font->face); - return math.get_math_variants().get_glyph_parts (glyph, direction, font, - start_offset, - parts_count, - parts, - italics_correction); + return font->face->table.MATH->get_variants().get_glyph_parts (glyph, + direction, + font, + start_offset, + parts_count, + parts, + italics_correction); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh index f1e785f19f7..ab07b7196ad 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name-table.hh @@ -179,11 +179,10 @@ struct name { inline void init (hb_face_t *face) { - this->blob = hb_sanitize_context_t().reference_table<name> (face); - this->table = this->blob->as<name> (); - assert (this->blob->length >= this->table->stringOffset); + this->table = hb_sanitize_context_t().reference_table<name> (face); + assert (this->table.get_length () >= this->table->stringOffset); this->pool = (this->table+this->table->stringOffset).arrayZ; - this->pool_len = this->blob->length - this->table->stringOffset; + this->pool_len = this->table.get_length () - this->table->stringOffset; const hb_array_t<const NameRecord> all_names (this->table->nameRecordZ.arrayZ, this->table->count); @@ -221,7 +220,7 @@ struct name inline void fini (void) { this->names.fini (); - hb_blob_destroy (this->blob); + this->table.destroy (); } inline int get_index (hb_ot_name_id_t name_id, @@ -253,11 +252,10 @@ struct name } private: - hb_blob_t *blob; const void *pool; unsigned int pool_len; public: - hb_nonnull_ptr_t<const name> table; + hb_blob_ptr_t<name> table; hb_vector_t<hb_ot_name_entry_t> names; }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc index f2d1f0c2f71..4c886609688 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-name.cc @@ -42,13 +42,6 @@ **/ -static inline const OT::name_accelerator_t& -_get_name (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::name_accelerator_t); - return *(hb_ot_face_data (face)->name); -} - /** * hb_ot_name_list_names: * @face: font face. @@ -65,7 +58,7 @@ const hb_ot_name_entry_t * hb_ot_name_list_names (hb_face_t *face, unsigned int *num_entries /* OUT */) { - const OT::name_accelerator_t &name = _get_name (face); + const OT::name_accelerator_t &name = *face->table.name; if (num_entries) *num_entries = name.names.len; return name.names.arrayZ(); } @@ -124,7 +117,7 @@ hb_ot_name_get_utf (hb_face_t *face, unsigned int *text_size /* IN/OUT */, typename utf_t::codepoint_t *text /* OUT */) { - const OT::name_accelerator_t &name = _get_name (face); + const OT::name_accelerator_t &name = *face->table.name; if (!language) language = hb_language_from_string ("en", 2); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh index b2495128e81..a5a9c07eadb 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-os2-table.hh @@ -50,7 +50,7 @@ struct OS2 inline bool subset (hb_subset_plan_t *plan) const { - hb_blob_t *os2_blob = hb_sanitize_context_t().reference_table<OS2> (plan->source); + hb_blob_t *os2_blob = hb_sanitize_context_t ().reference_table<OS2> (plan->source); hb_blob_t *os2_prime_blob = hb_blob_create_sub_blob (os2_blob, 0, -1); // TODO(grieger): move to hb_blob_copy_writable_or_fail hb_blob_destroy (os2_blob); @@ -74,7 +74,7 @@ struct OS2 } inline void _update_unicode_ranges (const hb_set_t *codepoints, - HBUINT32 ulUnicodeRange[4]) const + HBUINT32 ulUnicodeRange[4]) const { for (unsigned int i = 0; i < 4; i++) ulUnicodeRange[i].set (0); @@ -84,24 +84,24 @@ struct OS2 unsigned int bit = _hb_ot_os2_get_unicode_range_bit (cp); if (bit < 128) { - unsigned int block = bit / 32; - unsigned int bit_in_block = bit % 32; - unsigned int mask = 1 << bit_in_block; - ulUnicodeRange[block].set (ulUnicodeRange[block] | mask); + unsigned int block = bit / 32; + unsigned int bit_in_block = bit % 32; + unsigned int mask = 1 << bit_in_block; + ulUnicodeRange[block].set (ulUnicodeRange[block] | mask); } if (cp >= 0x10000 && cp <= 0x110000) { - /* the spec says that bit 57 ("Non Plane 0") implies that there's - at least one codepoint beyond the BMP; so I also include all - the non-BMP codepoints here */ - ulUnicodeRange[1].set (ulUnicodeRange[1] | (1 << 25)); + /* the spec says that bit 57 ("Non Plane 0") implies that there's + at least one codepoint beyond the BMP; so I also include all + the non-BMP codepoints here */ + ulUnicodeRange[1].set (ulUnicodeRange[1] | (1 << 25)); } } } static inline void find_min_and_max_codepoint (const hb_set_t *codepoints, - uint16_t *min_cp, /* OUT */ - uint16_t *max_cp /* OUT */) + uint16_t *min_cp, /* OUT */ + uint16_t *max_cp /* OUT */) { *min_cp = codepoints->get_min (); *max_cp = codepoints->get_max (); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh index b15a459b17e..f80303cc8ba 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-post-table.hh @@ -49,12 +49,15 @@ namespace OT { struct postV2Tail { + friend struct post; + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (glyphNameIndex.sanitize (c)); } + protected: ArrayOf<HBUINT16> glyphNameIndex; /* This is not an offset, but is the * ordinal number of the glyph in 'post' * string tables. */ @@ -62,6 +65,7 @@ struct postV2Tail namesX; /* Glyph names with length bytes [variable] * (a Pascal string). */ + public: DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX); }; @@ -69,28 +73,15 @@ struct post { static const hb_tag_t tableTag = HB_OT_TAG_post; - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) - return_trace (false); - if (version.to_int () == 0x00020000) - { - const postV2Tail &v2 = StructAfter<postV2Tail> (*this); - return_trace (v2.sanitize (c)); - } - return_trace (true); - } - inline bool subset (hb_subset_plan_t *plan) const { unsigned int post_prime_length; - hb_blob_t *post_blob = hb_sanitize_context_t().reference_table<post>(plan->source); - hb_blob_t *post_prime_blob = hb_blob_create_sub_blob (post_blob, 0, post::static_size); + hb_blob_t *post_blob = hb_sanitize_context_t ().reference_table<post>(plan->source); + hb_blob_t *post_prime_blob = hb_blob_create_sub_blob (post_blob, 0, post::min_size); post *post_prime = (post *) hb_blob_get_data_writable (post_prime_blob, &post_prime_length); hb_blob_destroy (post_blob); - if (unlikely (!post_prime || post_prime_length != post::static_size)) + if (unlikely (!post_prime || post_prime_length != post::min_size)) { hb_blob_destroy (post_prime_blob); DEBUG_MSG(SUBSET, nullptr, "Invalid source post table with length %d.", post_prime_length); @@ -110,42 +101,39 @@ struct post { index_to_offset.init (); - blob = hb_sanitize_context_t().reference_table<post> (face); - const post *table = blob->as<post> (); - unsigned int table_length = blob->length; + table = hb_sanitize_context_t ().reference_table<post> (face); + unsigned int table_length = table.get_length (); version = table->version.to_int (); - if (version != 0x00020000) - return; + if (version != 0x00020000) return; - const postV2Tail &v2 = StructAfter<postV2Tail> (*table); + const postV2Tail &v2 = table->v2; glyphNameIndex = &v2.glyphNameIndex; pool = &StructAfter<uint8_t> (v2.glyphNameIndex); - const uint8_t *end = (uint8_t *) table + table_length; - for (const uint8_t *data = pool; data < end && data + *data <= end; data += 1 + *data) + const uint8_t *end = (const uint8_t *) (const void *) table + table_length; + for (const uint8_t *data = pool; + index_to_offset.len < 65535 && data < end && data + *data < end; + data += 1 + *data) index_to_offset.push (data - pool); } inline void fini (void) { index_to_offset.fini (); free (gids_sorted_by_name.get ()); - hb_blob_destroy (blob); + table.destroy (); } inline bool get_glyph_name (hb_codepoint_t glyph, char *buf, unsigned int buf_len) const { hb_bytes_t s = find_glyph_name (glyph); - if (!s.len) - return false; - if (!buf_len) - return true; - if (buf_len <= s.len) /* What to do with truncation? Returning false for now. */ - return false; - strncpy (buf, s.arrayZ, s.len); - buf[s.len] = '\0'; + if (!s.len) return false; + if (!buf_len) return true; + unsigned int len = MIN (buf_len - 1, s.len); + strncpy (buf, s.arrayZ, len); + buf[len] = '\0'; return true; } @@ -153,14 +141,11 @@ struct post hb_codepoint_t *glyph) const { unsigned int count = get_glyph_count (); - if (unlikely (!count)) - return false; + if (unlikely (!count)) return false; - if (len < 0) - len = strlen (name); + if (len < 0) len = strlen (name); - if (unlikely (!len)) - return false; + if (unlikely (!len)) return false; retry: uint16_t *gids = gids_sorted_by_name.get (); @@ -198,10 +183,10 @@ struct post inline unsigned int get_glyph_count (void) const { if (version == 0x00010000) - return NUM_FORMAT1_NAMES; + return NUM_FORMAT1_NAMES; if (version == 0x00020000) - return glyphNameIndex->len; + return glyphNameIndex->len; return 0; } @@ -252,14 +237,23 @@ struct post } private: - hb_blob_t *blob; + hb_blob_ptr_t<post> table; uint32_t version; - hb_nonnull_ptr_t<const ArrayOf<HBUINT16> > glyphNameIndex; + const ArrayOf<HBUINT16> *glyphNameIndex; hb_vector_t<uint32_t, 1> index_to_offset; const uint8_t *pool; hb_atomic_ptr_t<uint16_t *> gids_sorted_by_name; }; + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + (version.to_int () == 0x00010000 || + (version.to_int () == 0x00020000 && v2.sanitize (c)) || + version.to_int () == 0x00030000))); + } + public: FixedVersion<>version; /* 0x00010000 for version 1.0 * 0x00020000 for version 2.0 @@ -292,8 +286,8 @@ struct post * is downloaded as a Type 1 font. */ HBUINT32 maxMemType1; /* Maximum memory usage when an OpenType font * is downloaded as a Type 1 font. */ -/*postV2Tail v2[VAR];*/ - DEFINE_SIZE_STATIC (32); + postV2Tail v2; + DEFINE_SIZE_MIN (32); }; struct post_accelerator_t : post::accelerator_t {}; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh index eeb2da85f75..5be6f8d69e9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-arabic-fallback.hh @@ -202,7 +202,7 @@ struct arabic_fallback_plan_t OT::hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS]; }; -#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_WIN1256) +#if defined(_WIN32) && !defined(HB_NO_WIN1256) #define HB_WITH_WIN1256 #endif @@ -212,8 +212,11 @@ struct arabic_fallback_plan_t struct ManifestLookup { + public: OT::Tag tag; OT::OffsetTo<OT::SubstLookup> lookupOffset; + public: + DEFINE_SIZE_STATIC (6); }; typedef OT::ArrayOf<ManifestLookup> Manifest; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc index e9c88aec4c4..bfc92d3b505 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-complex-use-table.cc @@ -582,7 +582,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11310 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11320 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 11330 */ B, O, B, B, O, B, B, B, B, B, O, CMBlw, CMBlw, B, VPst, VPst, - /* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPst, VPst, H, O, O, + /* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPst, VPst, HVM, O, O, /* 11350 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, B, B, /* 11360 */ B, B, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc index 766efe20d5b..d3afdffaf2c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape-fallback.cc @@ -25,7 +25,7 @@ */ #include "hb-ot-shape-fallback.hh" -#include "hb-ot-kern-table.hh" +#include "hb-kern.hh" static unsigned int recategorize_combining_class (hb_codepoint_t u, @@ -464,9 +464,18 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, !font->has_glyph_h_kerning_func () : !font->has_glyph_v_kerning_func ()) return; + + bool reverse = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); + + if (reverse) + buffer->reverse (); + hb_ot_shape_fallback_kern_driver_t driver (font, buffer); - hb_kern_machine_t<hb_ot_shape_fallback_kern_driver_t> machine (driver); + OT::hb_kern_machine_t<hb_ot_shape_fallback_kern_driver_t> machine (driver); machine.kern (font, buffer, plan->kern_mask, false); + + if (reverse) + buffer->reverse (); } @@ -500,16 +509,16 @@ _hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan HB_UNUSED, case t::SPACE_EM_6: case t::SPACE_EM_16: if (horizontal) - pos[i].x_advance = (font->x_scale + ((int) space_type)/2) / (int) space_type; + pos[i].x_advance = +(font->x_scale + ((int) space_type)/2) / (int) space_type; else - pos[i].y_advance = (font->y_scale + ((int) space_type)/2) / (int) space_type; + pos[i].y_advance = -(font->y_scale + ((int) space_type)/2) / (int) space_type; break; case t::SPACE_4_EM_18: if (horizontal) - pos[i].x_advance = (int64_t) font->x_scale * 4 / 18; + pos[i].x_advance = (int64_t) +font->x_scale * 4 / 18; else - pos[i].y_advance = (int64_t) font->y_scale * 4 / 18; + pos[i].y_advance = (int64_t) -font->y_scale * 4 / 18; break; case t::SPACE_FIGURE: diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc index 8c5e38e06dd..ccee8d34300 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc @@ -26,8 +26,6 @@ * Google Author(s): Behdad Esfahbod */ -#define HB_SHAPER ot -#define hb_ot_shape_plan_data_t hb_ot_shape_plan_t #include "hb-shaper-impl.hh" #include "hb-ot-shape.hh" @@ -52,6 +50,11 @@ **/ +static void +hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, + const hb_feature_t *user_features, + unsigned int num_user_features); + static bool _hb_apply_morx (hb_face_t *face) { @@ -59,37 +62,41 @@ _hb_apply_morx (hb_face_t *face) hb_aat_layout_has_substitution (face)) return true; - return !hb_ot_layout_has_substitution (face) && + /* Ignore empty GSUB tables. */ + return (!hb_ot_layout_has_substitution (face) || + !hb_ot_layout_table_get_script_tags (face, + HB_OT_TAG_GSUB, + 0, nullptr, nullptr)) && hb_aat_layout_has_substitution (face); } -hb_ot_shape_planner_t::hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan) : - face (master_plan->face_unsafe), - props (master_plan->props), - map (face, &props), - aat_map (face, &props), +hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *face, + const hb_segment_properties_t *props) : + face (face), + props (*props), + map (face, props), + aat_map (face, props), apply_morx (_hb_apply_morx (face)), shaper (apply_morx ? &_hb_ot_complex_shaper_default : hb_ot_shape_complex_categorize (this)) {} void -hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, - const int *coords, - unsigned int num_coords) +hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, + const hb_ot_shape_plan_key_t &key) { plan.props = props; plan.shaper = shaper; - map.compile (plan.map, coords, num_coords); + map.compile (plan.map, key); if (apply_morx) - aat_map.compile (plan.aat_map, coords, num_coords); + aat_map.compile (plan.aat_map); plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c')); plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r')); plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m')); plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask); plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m')); - hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (plan.props.direction) ? + hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (props.direction) ? HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'); plan.kern_mask = plan.map.get_mask (kern_tag); plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k')); @@ -119,30 +126,91 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, if (hb_options ().aat && hb_aat_layout_has_positioning (face)) plan.apply_kerx = true; - else if (!disable_gpos && hb_ot_layout_has_positioning (face)) + else if (!apply_morx && !disable_gpos && hb_ot_layout_has_positioning (face)) plan.apply_gpos = true; else if (hb_aat_layout_has_positioning (face)) plan.apply_kerx = true; - if (plan.requested_kerning && !plan.apply_kerx && !has_gpos_kern) + if (!plan.apply_kerx && !has_gpos_kern) { /* Apparently Apple applies kerx if GPOS kern was not applied. */ if (hb_aat_layout_has_positioning (face)) plan.apply_kerx = true; - if (hb_ot_layout_has_kerning (face)) + else if (hb_ot_layout_has_kerning (face)) plan.apply_kern = true; - else - plan.fallback_kerning = true; } + bool has_kern_mark = plan.apply_kern && hb_ot_layout_has_cross_kerning (face); + plan.zero_marks = !plan.apply_morx && !plan.apply_kerx && !has_kern_mark; plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k')); - if (!plan.apply_gpos && !plan.apply_kerx) - plan.fallback_mark_positioning = true; + plan.fallback_mark_positioning = !plan.apply_gpos && plan.zero_marks; /* Currently we always apply trak. */ plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face); } +bool +hb_ot_shape_plan_t::init0 (hb_face_t *face, + const hb_shape_plan_key_t *key) +{ + map.init (); + aat_map.init (); + + hb_ot_shape_planner_t planner (face, + &key->props); + hb_ot_shape_collect_features (&planner, + key->user_features, + key->num_user_features); + + planner.compile (*this, key->ot); + + if (shaper->data_create) + { + data = shaper->data_create (this); + if (unlikely (!data)) + return false; + } + + return true; +} + +void +hb_ot_shape_plan_t::fini (void) +{ + if (shaper->data_destroy) + shaper->data_destroy (const_cast<void *> (data)); + + map.fini (); + aat_map.fini (); +} + +void +hb_ot_shape_plan_t::substitute (hb_font_t *font, + hb_buffer_t *buffer) const +{ + if (unlikely (apply_morx)) + hb_aat_layout_substitute (this, font, buffer); + else + map.substitute (this, font, buffer); +} + +void +hb_ot_shape_plan_t::position (hb_font_t *font, + hb_buffer_t *buffer) const +{ + if (this->apply_gpos) + map.position (this, font, buffer); + else if (this->apply_kerx) + hb_aat_layout_position (this, font, buffer); + else if (this->apply_kern) + hb_ot_layout_kern (this, font, buffer); + else + _hb_ot_shape_fallback_kern (this, font, buffer); + + if (this->apply_trak) + hb_aat_layout_track (this, font, buffer); +} + static const hb_ot_map_feature_t common_features[] = @@ -168,7 +236,6 @@ horizontal_features[] = static void hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, - const hb_segment_properties_t *props, const hb_feature_t *user_features, unsigned int num_user_features) { @@ -177,7 +244,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, map->enable_feature (HB_TAG('r','v','r','n')); map->add_gsub_pause (nullptr); - switch (props->direction) { + switch (planner->props.direction) { case HB_DIRECTION_LTR: map->enable_feature (HB_TAG ('l','t','r','a')); map->enable_feature (HB_TAG ('l','t','r','m')); @@ -216,7 +283,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++) map->add_feature (common_features[i]); - if (HB_DIRECTION_IS_HORIZONTAL (props->direction)) + if (HB_DIRECTION_IS_HORIZONTAL (planner->props.direction)) for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++) map->add_feature (horizontal_features[i]); else @@ -256,18 +323,17 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, * shaper face data */ -HB_SHAPER_DATA_ENSURE_DEFINE(ot, face) +struct hb_ot_face_data_t {}; hb_ot_face_data_t * _hb_ot_shaper_face_data_create (hb_face_t *face) { - return _hb_ot_face_data_create (face); + return (hb_ot_face_data_t *) HB_SHAPER_DATA_SUCCEEDED; } void _hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data) { - _hb_ot_face_data_destroy (data); } @@ -275,8 +341,6 @@ _hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data) * shaper font data */ -HB_SHAPER_DATA_ENSURE_DEFINE(ot, font) - struct hb_ot_font_data_t {}; hb_ot_font_data_t * @@ -292,54 +356,6 @@ _hb_ot_shaper_font_data_destroy (hb_ot_font_data_t *data HB_UNUSED) /* - * shaper shape_plan data - */ - -hb_ot_shape_plan_data_t * -_hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, - const hb_feature_t *user_features, - unsigned int num_user_features, - const int *coords, - unsigned int num_coords) -{ - hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t)); - if (unlikely (!plan)) - return nullptr; - - plan->init (); - - hb_ot_shape_planner_t planner (shape_plan); - - hb_ot_shape_collect_features (&planner, &shape_plan->props, - user_features, num_user_features); - - planner.compile (*plan, coords, num_coords); - - if (plan->shaper->data_create) { - plan->data = plan->shaper->data_create (plan); - if (unlikely (!plan->data)) - { - free (plan); - return nullptr; - } - } - - return plan; -} - -void -_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shape_plan_data_t *plan) -{ - if (plan->shaper->data_destroy) - plan->shaper->data_destroy (const_cast<void *> (plan->data)); - - plan->fini (); - - free (plan); -} - - -/* * shaper */ @@ -476,7 +492,9 @@ hb_ensure_native_direction (hb_buffer_t *buffer) } -/* Substitute */ +/* + * Substitute + */ static inline void hb_ot_mirror_chars (const hb_ot_shape_context_t *c) @@ -582,10 +600,8 @@ hb_ot_shape_setup_masks (const hb_ot_shape_context_t *c) } static void -hb_ot_zero_width_default_ignorables (const hb_ot_shape_context_t *c) +hb_ot_zero_width_default_ignorables (const hb_buffer_t *buffer) { - hb_buffer_t *buffer = c->buffer; - if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) || (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) || (buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES)) @@ -601,21 +617,19 @@ hb_ot_zero_width_default_ignorables (const hb_ot_shape_context_t *c) } static void -hb_ot_hide_default_ignorables (const hb_ot_shape_context_t *c) +hb_ot_hide_default_ignorables (hb_buffer_t *buffer, + hb_font_t *font) { - hb_buffer_t *buffer = c->buffer; - if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) || (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)) return; unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; - hb_glyph_position_t *pos = buffer->pos; - hb_codepoint_t invisible = c->buffer->invisible; + hb_codepoint_t invisible = buffer->invisible; if (!(buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) && - (invisible || c->font->get_nominal_glyph (' ', &invisible))) + (invisible || font->get_nominal_glyph (' ', &invisible))) { /* Replace default-ignorables with a zero-advance invisible glyph. */ for (unsigned int i = 0; i < count; i++) @@ -625,49 +639,7 @@ hb_ot_hide_default_ignorables (const hb_ot_shape_context_t *c) } } else - { - /* Merge clusters and delete default-ignorables. - * NOTE! We can't use out-buffer as we have positioning data. */ - unsigned int j = 0; - for (unsigned int i = 0; i < count; i++) - { - if (_hb_glyph_info_is_default_ignorable (&info[i])) - { - /* Merge clusters. - * Same logic as buffer->delete_glyph(), but for in-place removal. */ - - unsigned int cluster = info[i].cluster; - if (i + 1 < count && cluster == info[i + 1].cluster) - continue; /* Cluster survives; do nothing. */ - - if (j) - { - /* Merge cluster backward. */ - if (cluster < info[j - 1].cluster) - { - unsigned int mask = info[i].mask; - unsigned int old_cluster = info[j - 1].cluster; - for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--) - buffer->set_cluster (info[k - 1], cluster, mask); - } - continue; - } - - if (i + 1 < count) - buffer->merge_clusters (i, i + 2); /* Merge cluster forward. */ - - continue; - } - - if (j != i) - { - info[j] = info[i]; - pos[j] = pos[i]; - } - j++; - } - buffer->len = j; - } + hb_ot_layout_delete_glyphs_inplace (buffer, _hb_glyph_info_is_default_ignorable); } @@ -684,10 +656,10 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer) } static inline void -hb_synthesize_glyph_classes (const hb_ot_shape_context_t *c) +hb_synthesize_glyph_classes (hb_buffer_t *buffer) { - unsigned int count = c->buffer->len; - hb_glyph_info_t *info = c->buffer->info; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) { hb_ot_layout_glyph_props_flags_t klass; @@ -739,16 +711,13 @@ hb_ot_substitute_complex (const hb_ot_shape_context_t *c) hb_ot_layout_substitute_start (c->font, buffer); if (c->plan->fallback_glyph_classes) - hb_synthesize_glyph_classes (c); + hb_synthesize_glyph_classes (c->buffer); - if (unlikely (c->plan->apply_morx)) - hb_aat_layout_substitute (c->plan, c->font, c->buffer); - else - c->plan->substitute (c->font, buffer); + c->plan->substitute (c->font, buffer); } static inline void -hb_ot_substitute (const hb_ot_shape_context_t *c) +hb_ot_substitute_pre (const hb_ot_shape_context_t *c) { hb_ot_substitute_default (c); @@ -757,7 +726,21 @@ hb_ot_substitute (const hb_ot_shape_context_t *c) hb_ot_substitute_complex (c); } -/* Position */ +static inline void +hb_ot_substitute_post (const hb_ot_shape_context_t *c) +{ + hb_ot_hide_default_ignorables (c->buffer, c->font); + if (c->plan->apply_morx) + hb_aat_layout_remove_deleted_glyphs (c->buffer); + + if (c->plan->shaper->postprocess_glyphs) + c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font); +} + + +/* + * Position + */ static inline void adjust_mark_offsets (hb_glyph_position_t *pos) @@ -852,7 +835,7 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c) hb_ot_layout_position_start (c->font, c->buffer); - if (!c->plan->apply_kerx) + if (c->plan->zero_marks) switch (c->plan->shaper->zero_width_marks) { case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: @@ -865,15 +848,9 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c) break; } - if (c->plan->apply_gpos) - c->plan->position (c->font, c->buffer); - else if (c->plan->apply_kerx) - hb_aat_layout_position (c->plan, c->font, c->buffer); - - if (c->plan->apply_trak) - hb_aat_layout_track (c->plan, c->font, c->buffer); + c->plan->position (c->font, c->buffer); - if (!c->plan->apply_kerx) + if (c->plan->zero_marks) switch (c->plan->shaper->zero_width_marks) { case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: @@ -886,9 +863,11 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c) break; } - /* Finishing off GPOS has to follow a certain order. */ + /* Finish off. Has to follow a certain order. */ hb_ot_layout_position_finish_advances (c->font, c->buffer); - hb_ot_zero_width_default_ignorables (c); + hb_ot_zero_width_default_ignorables (c->buffer); + if (c->plan->apply_morx) + hb_aat_layout_zero_width_deleted_glyphs (c->buffer); hb_ot_layout_position_finish_offsets (c->font, c->buffer); /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ @@ -897,6 +876,9 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c) c->font->subtract_glyph_h_origin (info[i].codepoint, &pos[i].x_offset, &pos[i].y_offset); + + if (c->plan->fallback_mark_positioning && c->plan->shaper->fallback_position) + _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer); } static inline void @@ -908,19 +890,9 @@ hb_ot_position (const hb_ot_shape_context_t *c) hb_ot_position_complex (c); - 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->apply_kern) - hb_ot_layout_kern (c->plan, c->font, c->buffer); - else if (c->plan->fallback_kerning) - _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); - _hb_buffer_deallocate_gsubgpos_vars (c->buffer); } @@ -986,13 +958,9 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) if (c->plan->shaper->preprocess_text) c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font); - hb_ot_substitute (c); + hb_ot_substitute_pre (c); hb_ot_position (c); - - hb_ot_hide_default_ignorables (c); - - if (c->plan->shaper->postprocess_glyphs) - c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font); + hb_ot_substitute_post (c); hb_propagate_flags (c->buffer); @@ -1013,7 +981,7 @@ _hb_ot_shape (hb_shape_plan_t *shape_plan, const hb_feature_t *features, unsigned int num_features) { - hb_ot_shape_context_t c = {HB_SHAPER_DATA_GET (shape_plan), font, font->face, buffer, features, num_features}; + hb_ot_shape_context_t c = {&shape_plan->ot, font, font->face, buffer, features, num_features}; hb_ot_shape_internal (&c); return true; @@ -1030,8 +998,7 @@ hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, hb_tag_t table_tag, hb_set_t *lookup_indexes /* OUT */) { - /* XXX Does the first part always succeed? */ - HB_SHAPER_DATA_GET (shape_plan)->collect_lookups (table_tag, lookup_indexes); + shape_plan->ot.collect_lookups (table_tag, lookup_indexes); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh index 1cb9e24d7f6..397634c25cc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.hh @@ -31,9 +31,32 @@ #include "hb-ot-map.hh" #include "hb-aat-map.hh" -#include "hb-shape-plan.hh" +struct hb_ot_shape_plan_key_t +{ + unsigned int variations_index[2]; + + inline void init (hb_face_t *face, + const int *coords, + unsigned int num_coords) + { + for (unsigned int table_index = 0; table_index < 2; table_index++) + hb_ot_layout_table_find_feature_variations (face, + table_tags[table_index], + coords, + num_coords, + &variations_index[table_index]); + } + + inline bool equal (const hb_ot_shape_plan_key_t *other) + { + return 0 == memcmp (this, other, sizeof (*this)); + } +}; + + +struct hb_shape_plan_key_t; struct hb_ot_shape_plan_t { @@ -51,8 +74,8 @@ struct hb_ot_shape_plan_t bool requested_tracking : 1; bool has_frac : 1; bool has_gpos_mark : 1; + bool zero_marks : 1; bool fallback_glyph_classes : 1; - bool fallback_kerning : 1; bool fallback_mark_positioning : 1; bool apply_gpos : 1; @@ -61,7 +84,6 @@ struct hb_ot_shape_plan_t bool apply_morx : 1; bool apply_trak : 1; - inline void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const { unsigned int table_index; @@ -72,21 +94,17 @@ struct hb_ot_shape_plan_t } map.collect_lookups (table_index, lookups); } - inline void substitute (hb_font_t *font, hb_buffer_t *buffer) const { map.substitute (this, font, buffer); } - inline void position (hb_font_t *font, hb_buffer_t *buffer) const { map.position (this, font, buffer); } - void init (void) - { - memset (this, 0, sizeof (*this)); - map.init (); - aat_map.init (); - } - void fini (void) { - map.fini (); - aat_map.fini (); - } + HB_INTERNAL bool init0 (hb_face_t *face, + const hb_shape_plan_key_t *key); + HB_INTERNAL void fini (void); + + HB_INTERNAL void substitute (hb_font_t *font, hb_buffer_t *buffer) const; + HB_INTERNAL void position (hb_font_t *font, hb_buffer_t *buffer) const; }; +struct hb_shape_plan_t; + struct hb_ot_shape_planner_t { /* In the order that they are filled in. */ @@ -97,11 +115,11 @@ struct hb_ot_shape_planner_t bool apply_morx : 1; const struct hb_ot_complex_shaper_t *shaper; - HB_INTERNAL hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan); + HB_INTERNAL hb_ot_shape_planner_t (hb_face_t *face, + const hb_segment_properties_t *props); - HB_INTERNAL void compile (hb_ot_shape_plan_t &plan, - const int *coords, - unsigned int num_coords); + HB_INTERNAL void compile (hb_ot_shape_plan_t &plan, + const hb_ot_shape_plan_key_t &key); }; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh new file mode 100644 index 00000000000..02c376e5de2 --- /dev/null +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-stat-table.hh @@ -0,0 +1,280 @@ +/* + * 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_STAT_TABLE_HH +#define HB_OT_STAT_TABLE_HH + +#include "hb-open-type.hh" +#include "hb-ot-layout-common.hh" + +/* + * STAT -- Style Attributes + * https://docs.microsoft.com/en-us/typography/opentype/spec/stat + */ +#define HB_OT_TAG_STAT HB_TAG('S','T','A','T') + + +namespace OT { + +enum +{ + OLDER_SIBLING_FONT_ATTRIBUTE = 0x0001, /* If set, this axis value table + * provides axis value information + * that is applicable to other fonts + * within the same font family. This + * is used if the other fonts were + * released earlier and did not include + * information about values for some axis. + * If newer versions of the other + * fonts include the information + * themselves and are present, + * then this record is ignored. */ + ELIDABLE_AXIS_VALUE_NAME = 0x0002 /* If set, it indicates that the axis + * value represents the “normal” value + * for the axis and may be omitted when + * composing name strings. */ + // Reserved = 0xFFFC /* Reserved for future use — set to zero. */ +}; + +struct StatAxisRecord +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + protected: + Tag axisTag; /* A tag identifying the axis of design variation. */ + NameID axisNameID; /* The name ID for entries in the 'name' table that + * provide a display string for this axis. */ + HBUINT16 axisOrdering; /* A value that applications can use to determine + * primary sorting of face names, or for ordering + * of descriptors when composing family or face names. */ + public: + DEFINE_SIZE_STATIC (8); +}; + +struct AxisValueFormat1 +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + protected: + HBUINT16 format; /* Format identifier — set to 1. */ + HBUINT16 axisIndex; /* Zero-base index into the axis record array + * identifying the axis of design variation + * to which the axis value record applies. + * Must be less than designAxisCount. */ + HBUINT16 flags; /* Flags — see below for details. */ + NameID valueNameID; /* The name ID for entries in the 'name' table + * that provide a display string for this + * attribute value. */ + Fixed value; /* A numeric value for this attribute value. */ + public: + DEFINE_SIZE_STATIC (12); +}; + +struct AxisValueFormat2 +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + protected: + HBUINT16 format; /* Format identifier — set to 2. */ + HBUINT16 axisIndex; /* Zero-base index into the axis record array + * identifying the axis of design variation + * to which the axis value record applies. + * Must be less than designAxisCount. */ + HBUINT16 flags; /* Flags — see below for details. */ + NameID valueNameID; /* The name ID for entries in the 'name' table + * that provide a display string for this + * attribute value. */ + Fixed nominalValue; /* A numeric value for this attribute value. */ + Fixed rangeMinValue; /* The minimum value for a range associated + * with the specified name ID. */ + Fixed rangeMaxValue; /* The maximum value for a range associated + * with the specified name ID. */ + public: + DEFINE_SIZE_STATIC (20); +}; + +struct AxisValueFormat3 +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + protected: + HBUINT16 format; /* Format identifier — set to 3. */ + HBUINT16 axisIndex; /* Zero-base index into the axis record array + * identifying the axis of design variation + * to which the axis value record applies. + * Must be less than designAxisCount. */ + HBUINT16 flags; /* Flags — see below for details. */ + NameID valueNameID; /* The name ID for entries in the 'name' table + * that provide a display string for this + * attribute value. */ + Fixed value; /* A numeric value for this attribute value. */ + Fixed linkedValue; /* The numeric value for a style-linked mapping + * from this value. */ + public: + DEFINE_SIZE_STATIC (16); +}; + +struct AxisValueRecord +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + protected: + HBUINT16 axisIndex; /* Zero-base index into the axis record array + * identifying the axis to which this value + * applies. Must be less than designAxisCount. */ + Fixed value; /* A numeric value for this attribute value. */ + public: + DEFINE_SIZE_STATIC (6); +}; + +struct AxisValueFormat4 +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + protected: + HBUINT16 format; /* Format identifier — set to 4. */ + HBUINT16 axisCount; /* The total number of axes contributing to + * this axis-values combination. */ + HBUINT16 flags; /* Flags — see below for details. */ + NameID valueNameID; /* The name ID for entries in the 'name' table + * that provide a display string for this + * attribute value. */ + UnsizedArrayOf<AxisValueRecord> + axisValues; /* Array of AxisValue records that provide the + * combination of axis values, one for each + * contributing axis. */ + public: + DEFINE_SIZE_ARRAY (8, axisValues); +}; + +struct AxisValue +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (unlikely (c->check_struct (this))) + return_trace (false); + + switch (u.format) + { + case 1: return_trace (likely (u.format1.sanitize (c))); + case 2: return_trace (likely (u.format2.sanitize (c))); + case 3: return_trace (likely (u.format3.sanitize (c))); + case 4: return_trace (likely (u.format4.sanitize (c))); + default: return_trace (true); + } + } + + protected: + union + { + HBUINT16 format; + AxisValueFormat1 format1; + AxisValueFormat2 format2; + AxisValueFormat3 format3; + AxisValueFormat4 format4; + } u; + public: + DEFINE_SIZE_UNION (2, format); +}; + +struct STAT +{ + static const hb_tag_t tableTag = HB_OT_TAG_STAT; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + majorVersion == 1 && + minorVersion > 0 && + designAxesOffset.sanitize (c, this, designAxisCount) && + offsetToAxisValueOffsets.sanitize (c, this, axisValueCount, &(this+offsetToAxisValueOffsets)))); + } + + protected: + HBUINT16 majorVersion; /* Major version number of the style attributes + * table — set to 1. */ + HBUINT16 minorVersion; /* Minor version number of the style attributes + * table — set to 2. */ + HBUINT16 designAxisSize; /* The size in bytes of each axis record. */ + HBUINT16 designAxisCount;/* The number of design axis records. In a + * font with an 'fvar' table, this value must be + * greater than or equal to the axisCount value + * in the 'fvar' table. In all fonts, must + * be greater than zero if axisValueCount + * is greater than zero. */ + LOffsetTo<UnsizedArrayOf<StatAxisRecord>, false> + designAxesOffset; + /* Offset in bytes from the beginning of + * the STAT table to the start of the design + * axes array. If designAxisCount is zero, + * set to zero; if designAxisCount is greater + * than zero, must be greater than zero. */ + HBUINT16 axisValueCount; /* The number of axis value tables. */ + LOffsetTo<UnsizedArrayOf<OffsetTo<AxisValue> >, false> + offsetToAxisValueOffsets; + /* Offset in bytes from the beginning of + * the STAT table to the start of the design + * axes value offsets array. If axisValueCount + * is zero, set to zero; if axisValueCount is + * greater than zero, must be greater than zero. */ + NameID elidedFallbackNameID; + /* Name ID used as fallback when projection of + * names into a particular font model produces + * a subfamily name containing only elidable + * elements. */ + public: + DEFINE_SIZE_STATIC (20); +}; + + +} /* namespace OT */ + + +#endif /* HB_OT_STAT_TABLE_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh index d100ca21ef8..c2b110a2199 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-avar-table.hh @@ -94,7 +94,7 @@ struct SegmentMaps : ArrayOf<AxisValueMap> } public: - DEFINE_SIZE_ARRAY (2, arrayZ); + DEFINE_SIZE_ARRAY (2, *this); }; struct avar @@ -109,7 +109,7 @@ struct avar c->check_struct (this)))) return_trace (false); - const SegmentMaps *map = axisSegmentMapsZ.arrayZ; + const SegmentMaps *map = &firstAxisSegmentMaps; unsigned int count = axisCount; for (unsigned int i = 0; i < count; i++) { @@ -125,7 +125,7 @@ struct avar { unsigned int count = MIN<unsigned int> (coords_length, axisCount); - const SegmentMaps *map = axisSegmentMapsZ.arrayZ; + const SegmentMaps *map = &firstAxisSegmentMaps; for (unsigned int i = 0; i < count; i++) { coords[i] = map->map (coords[i]); @@ -140,8 +140,7 @@ struct avar HBUINT16 axisCount; /* The number of variation axes in the font. This * must be the same number as axisCount in the * 'fvar' table. */ - UnsizedArrayOf<SegmentMaps> - axisSegmentMapsZ; + SegmentMaps firstAxisSegmentMaps; public: DEFINE_SIZE_MIN (8); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh index 96c39c10954..6d229c38625 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-fvar-table.hh @@ -88,7 +88,7 @@ struct fvar { static const hb_tag_t tableTag = HB_OT_TAG_fvar; - inline bool has_data (void) const { return version.to_int () != 0; } + inline bool has_data (void) const { return version.to_int (); } inline bool sanitize (hb_sanitize_context_t *c) const { diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh index 66e086e1d95..62a6547b50c 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-hvar-table.hh @@ -39,7 +39,9 @@ struct DeltaSetIndexMap { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - c->check_array (mapDataZ.arrayZ, mapCount, get_width ())); + c->check_range (mapDataZ.arrayZ, + mapCount, + get_width ())); } unsigned int map (unsigned int v) const /* Returns 16.16 outer.inner. */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh index 5d6b559541e..b16a09b3d14 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var-mvar-table.hh @@ -68,7 +68,9 @@ struct MVAR c->check_struct (this) && valueRecordSize >= VariationValueRecord::static_size && varStore.sanitize (c, this) && - c->check_array (valuesZ.arrayZ, valueRecordCount, valueRecordSize)); + c->check_range (valuesZ.arrayZ, + valueRecordCount, + valueRecordSize)); } inline float get_var (hb_tag_t tag, diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc index 4363f85ee7f..c97e9c49413 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-var.cc @@ -47,18 +47,6 @@ * fvar/avar */ -static inline const OT::fvar& -_get_fvar (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::fvar); - return *(hb_ot_face_data (face)->fvar); -} -static inline const OT::avar& -_get_avar (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::avar); - return *(hb_ot_face_data (face)->avar); -} /** * hb_ot_var_has_data: @@ -74,7 +62,7 @@ _get_avar (hb_face_t *face) hb_bool_t hb_ot_var_has_data (hb_face_t *face) { - return _get_fvar (face).has_data (); + return face->table.fvar->has_data (); } /** @@ -85,8 +73,7 @@ hb_ot_var_has_data (hb_face_t *face) unsigned int hb_ot_var_get_axis_count (hb_face_t *face) { - const OT::fvar &fvar = _get_fvar (face); - return fvar.get_axis_count (); + return face->table.fvar->get_axis_count (); } /** @@ -100,8 +87,7 @@ hb_ot_var_get_axes (hb_face_t *face, unsigned int *axes_count /* IN/OUT */, hb_ot_var_axis_t *axes_array /* OUT */) { - const OT::fvar &fvar = _get_fvar (face); - return fvar.get_axis_infos (start_offset, axes_count, axes_array); + return face->table.fvar->get_axis_infos (start_offset, axes_count, axes_array); } /** @@ -115,8 +101,7 @@ hb_ot_var_find_axis (hb_face_t *face, unsigned int *axis_index, hb_ot_var_axis_t *axis_info) { - const OT::fvar &fvar = _get_fvar (face); - return fvar.find_axis (axis_tag, axis_index, axis_info); + return face->table.fvar->find_axis (axis_tag, axis_index, axis_info); } @@ -135,7 +120,7 @@ hb_ot_var_normalize_variations (hb_face_t *face, for (unsigned int i = 0; i < coords_length; i++) coords[i] = 0; - const OT::fvar &fvar = _get_fvar (face); + const OT::fvar &fvar = *face->table.fvar; for (unsigned int i = 0; i < variations_length; i++) { unsigned int axis_index; @@ -144,8 +129,7 @@ hb_ot_var_normalize_variations (hb_face_t *face, coords[axis_index] = fvar.normalize_axis_value (axis_index, variations[i].value); } - const OT::avar &avar = _get_avar (face); - avar.map_coords (coords, coords_length); + face->table.avar->map_coords (coords, coords_length); } /** @@ -159,10 +143,9 @@ hb_ot_var_normalize_coords (hb_face_t *face, const float *design_coords, /* IN */ int *normalized_coords /* OUT */) { - const OT::fvar &fvar = _get_fvar (face); + const OT::fvar &fvar = *face->table.fvar; for (unsigned int i = 0; i < coords_length; i++) normalized_coords[i] = fvar.normalize_axis_value (i, design_coords[i]); - const OT::avar &avar = _get_avar (face); - avar.map_coords (normalized_coords, coords_length); + face->table.avar->map_coords (normalized_coords, coords_length); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh index 21a22525f88..bc26ed3c03b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-set.hh @@ -90,7 +90,7 @@ struct hb_set_t inline bool is_equal (const page_t *other) const { - return 0 == memcmp (&v, &other->v, sizeof (v)); + return 0 == hb_memcmp (&v, &other->v, sizeof (v)); } inline unsigned int get_population (void) const @@ -375,8 +375,8 @@ struct hb_set_t if (!resize (count)) return; population = other->population; - memcpy (pages, other->pages, count * sizeof (pages[0])); - memcpy (page_map, other->page_map, count * sizeof (page_map[0])); + memcpy (pages, other->pages, count * pages.item_size); + memcpy (page_map, other->page_map, count * page_map.item_size); } inline bool is_equal (const hb_set_t *other) const diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc index f2f21019690..bc3d81636b9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.cc @@ -44,88 +44,118 @@ **/ -static void -hb_shape_plan_plan (hb_shape_plan_t *shape_plan, - const hb_feature_t *user_features, - unsigned int num_user_features, - const int *coords, - unsigned int num_coords, - const char * const *shaper_list) +/* + * hb_shape_plan_key_t + */ + +bool +hb_shape_plan_key_t::init (bool copy, + hb_face_t *face, + const hb_segment_properties_t *props, + const hb_feature_t *user_features, + unsigned int num_user_features, + const int *coords, + unsigned int num_coords, + const char * const *shaper_list) { - DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, - "num_features=%d num_coords=%d shaper_list=%p", - num_user_features, - num_coords, - shaper_list); + hb_feature_t *features = nullptr; + if (copy && num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t)))) + goto bail; + + this->props = *props; + this->num_user_features = num_user_features; + this->user_features = copy ? features : user_features; + if (copy && num_user_features) + { + memcpy (features, user_features, num_user_features * sizeof (hb_feature_t)); + /* Make start/end uniform to easier catch bugs. */ + for (unsigned int i = 0; i < num_user_features; i++) + { + if (features[0].start != HB_FEATURE_GLOBAL_START) + features[0].start = 1; + if (features[0].end != HB_FEATURE_GLOBAL_END) + features[0].end = 2; + } + } + this->shaper_func = nullptr; + this->shaper_name = nullptr; + this->ot.init (face, coords, num_coords); - const hb_shaper_pair_t *shapers = _hb_shapers_get (); + /* + * Choose shaper. + */ #define HB_SHAPER_PLAN(shaper) \ HB_STMT_START { \ - if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) \ + if (face->data.shaper) \ { \ - /* XXX-MT-bug What happened to *ensure*ing this?!!!! */ \ - HB_SHAPER_DATA (shaper, shape_plan).set_relaxed ( \ - HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, \ - user_features, num_user_features, \ - coords, num_coords)); \ - shape_plan->shaper_func = _hb_##shaper##_shape; \ - shape_plan->shaper_name = #shaper; \ - return; \ + this->shaper_func = _hb_##shaper##_shape; \ + this->shaper_name = #shaper; \ + return true; \ } \ } HB_STMT_END - if (likely (!shaper_list)) { - for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++) + if (unlikely (shaper_list)) + { + for (; *shaper_list; shaper_list++) if (false) ; #define HB_SHAPER_IMPLEMENT(shaper) \ - else if (shapers[i].func == _hb_##shaper##_shape) \ + else if (0 == strcmp (*shaper_list, #shaper)) \ HB_SHAPER_PLAN (shaper); #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT - } else { - for (; *shaper_list; shaper_list++) + } + else + { + const hb_shaper_entry_t *shapers = _hb_shapers_get (); + for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++) if (false) ; #define HB_SHAPER_IMPLEMENT(shaper) \ - else if (0 == strcmp (*shaper_list, #shaper)) \ + else if (shapers[i].func == _hb_##shaper##_shape) \ HB_SHAPER_PLAN (shaper); #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT } - #undef HB_SHAPER_PLAN -} +bail: + ::free (features); + return false; +} -/* - * hb_shape_plan_t - */ - -DEFINE_NULL_INSTANCE (hb_shape_plan_t) = +bool +hb_shape_plan_key_t::user_features_match (const hb_shape_plan_key_t *other) { - HB_OBJECT_HEADER_STATIC, - - true, /* default_shaper_list */ - nullptr, /* face */ - HB_SEGMENT_PROPERTIES_DEFAULT, /* props */ - - nullptr, /* shaper_func */ - nullptr, /* shaper_name */ + if (this->num_user_features != other->num_user_features) + return false; + for (unsigned int i = 0; i < num_user_features; i++) + { + if (this->user_features[i].tag != other->user_features[i].tag || + this->user_features[i].value != other->user_features[i].value || + (this->user_features[i].start == HB_FEATURE_GLOBAL_START && + this->user_features[i].end == HB_FEATURE_GLOBAL_END) != + (other->user_features[i].start == HB_FEATURE_GLOBAL_START && + other->user_features[i].end == HB_FEATURE_GLOBAL_END)) + return false; + } + return true; +} - nullptr, /* user_features */ - 0, /* num_user_featurs */ +bool +hb_shape_plan_key_t::equal (const hb_shape_plan_key_t *other) +{ + return hb_segment_properties_equal (&this->props, &other->props) && + this->user_features_match (other) && + this->ot.equal (&other->ot) && + this->shaper_func == other->shaper_func; +} - nullptr, /* coords */ - 0, /* num_coords */ - { -#define HB_SHAPER_IMPLEMENT(shaper) HB_ATOMIC_PTR_INIT (HB_SHAPER_DATA_INVALID), -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT - }, -}; +/* + * hb_shape_plan_t + */ /** @@ -160,7 +190,7 @@ hb_shape_plan_create2 (hb_face_t *face, const hb_segment_properties_t *props, const hb_feature_t *user_features, unsigned int num_user_features, - const int *orig_coords, + const int *coords, unsigned int num_coords, const char * const *shaper_list) { @@ -171,49 +201,40 @@ hb_shape_plan_create2 (hb_face_t *face, num_coords, shaper_list); + assert (props->direction != HB_DIRECTION_INVALID); + hb_shape_plan_t *shape_plan; - hb_feature_t *features = nullptr; - int *coords = nullptr; - if (unlikely (!face)) - face = hb_face_get_empty (); if (unlikely (!props)) - return hb_shape_plan_get_empty (); - if (num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t)))) - return hb_shape_plan_get_empty (); - if (num_coords && !(coords = (int *) calloc (num_coords, sizeof (int)))) - { - free (features); - return hb_shape_plan_get_empty (); - } + goto bail; if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) - { - free (coords); - free (features); - return hb_shape_plan_get_empty (); - } - - assert (props->direction != HB_DIRECTION_INVALID); + goto bail; + if (unlikely (!face)) + face = hb_face_get_empty (); hb_face_make_immutable (face); - shape_plan->default_shaper_list = !shaper_list; shape_plan->face_unsafe = face; - shape_plan->props = *props; - shape_plan->num_user_features = num_user_features; - shape_plan->user_features = features; - if (num_user_features) - memcpy (features, user_features, num_user_features * sizeof (hb_feature_t)); - shape_plan->num_coords = num_coords; - shape_plan->coords = coords; - if (num_coords) - memcpy (coords, orig_coords, num_coords * sizeof (int)); - hb_shape_plan_plan (shape_plan, - user_features, num_user_features, - coords, num_coords, - shaper_list); + if (unlikely (!shape_plan->key.init (true, + face, + props, + user_features, + num_user_features, + coords, + num_coords, + shaper_list))) + goto bail2; + if (unlikely (!shape_plan->ot.init0 (face, &shape_plan->key))) + goto bail3; return shape_plan; + +bail3: + shape_plan->key.free (); +bail2: + free (shape_plan); +bail: + return hb_shape_plan_get_empty (); } /** @@ -260,13 +281,8 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) { if (!hb_object_destroy (shape_plan)) return; -#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, shape_plan); -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT - - free (shape_plan->user_features); - free (shape_plan->coords); - + shape_plan->ot.fini (); + shape_plan->key.free (); free (shape_plan); } @@ -312,6 +328,22 @@ hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan, return hb_object_get_user_data (shape_plan, key); } +/** + * hb_shape_plan_get_shaper: + * @shape_plan: a shape plan. + * + * + * + * Return value: (transfer none): + * + * Since: 0.9.7 + **/ +const char * +hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan) +{ + return shape_plan->key.shaper_name; +} + /** * hb_shape_plan_execute: @@ -337,8 +369,8 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, "num_features=%d shaper_func=%p, shaper_name=%s", num_features, - shape_plan->shaper_func, - shape_plan->shaper_name); + shape_plan->key.shaper_func, + shape_plan->key.shaper_name); if (unlikely (!buffer->len)) return true; @@ -350,19 +382,18 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, return false; assert (shape_plan->face_unsafe == font->face); - assert (hb_segment_properties_equal (&shape_plan->props, &buffer->props)); + assert (hb_segment_properties_equal (&shape_plan->key.props, &buffer->props)); #define HB_SHAPER_EXECUTE(shaper) \ HB_STMT_START { \ - return HB_SHAPER_DATA (shaper, shape_plan).get () && \ - hb_##shaper##_shaper_font_data_ensure (font) && \ + return font->data.shaper && \ _hb_##shaper##_shape (shape_plan, font, buffer, features, num_features); \ } HB_STMT_END if (false) ; #define HB_SHAPER_IMPLEMENT(shaper) \ - else if (shape_plan->shaper_func == _hb_##shaper##_shape) \ + else if (shape_plan->key.shaper_func == _hb_##shaper##_shape) \ HB_SHAPER_EXECUTE (shaper); #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT @@ -374,92 +405,9 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, /* - * caching + * Caching */ -#if 0 -static unsigned int -hb_shape_plan_hash (const hb_shape_plan_t *shape_plan) -{ - return hb_segment_properties_hash (&shape_plan->props) + - shape_plan->default_shaper_list ? 0 : (intptr_t) shape_plan->shaper_func; -} -#endif - -/* User-feature caching is currently somewhat dumb: - * it only finds matches where the feature array is identical, - * not cases where the feature lists would be compatible for plan purposes - * but have different ranges, for example. - */ -struct hb_shape_plan_proposal_t -{ - const hb_segment_properties_t props; - const char * const *shaper_list; - const hb_feature_t *user_features; - unsigned int num_user_features; - const int *coords; - unsigned int num_coords; - hb_shape_func_t *shaper_func; -}; - -static inline hb_bool_t -hb_shape_plan_user_features_match (const hb_shape_plan_t *shape_plan, - const hb_shape_plan_proposal_t *proposal) -{ - if (proposal->num_user_features != shape_plan->num_user_features) - return false; - for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++) - if (proposal->user_features[i].tag != shape_plan->user_features[i].tag || - proposal->user_features[i].value != shape_plan->user_features[i].value || - proposal->user_features[i].start != shape_plan->user_features[i].start || - proposal->user_features[i].end != shape_plan->user_features[i].end) - return false; - return true; -} - -static inline hb_bool_t -hb_shape_plan_coords_match (const hb_shape_plan_t *shape_plan, - const hb_shape_plan_proposal_t *proposal) -{ - if (proposal->num_coords != shape_plan->num_coords) - return false; - for (unsigned int i = 0, n = proposal->num_coords; i < n; i++) - if (proposal->coords[i] != shape_plan->coords[i]) - return false; - return true; -} - -static hb_bool_t -hb_shape_plan_matches (const hb_shape_plan_t *shape_plan, - const hb_shape_plan_proposal_t *proposal) -{ - return hb_segment_properties_equal (&shape_plan->props, &proposal->props) && - hb_shape_plan_user_features_match (shape_plan, proposal) && - hb_shape_plan_coords_match (shape_plan, proposal) && - ((shape_plan->default_shaper_list && !proposal->shaper_list) || - (shape_plan->shaper_func == proposal->shaper_func)); -} - -static inline hb_bool_t -hb_non_global_user_features_present (const hb_feature_t *user_features, - unsigned int num_user_features) -{ - while (num_user_features) { - if (user_features->start != 0 || user_features->end != (unsigned int) -1) - return true; - num_user_features--; - user_features++; - } - return false; -} - -static inline hb_bool_t -hb_coords_present (const int *coords HB_UNUSED, - unsigned int num_coords) -{ - return num_coords != 0; -} - /** * hb_shape_plan_create_cached: * @face: @@ -502,62 +450,38 @@ hb_shape_plan_create_cached2 (hb_face_t *face, num_user_features, shaper_list); - hb_shape_plan_proposal_t proposal = { - *props, - shaper_list, - user_features, - num_user_features, - nullptr - }; - - if (shaper_list) { - /* Choose shaper. Adapted from hb_shape_plan_plan(). - * Must choose shaper exactly the same way as that function. */ - for (const char * const *shaper_item = shaper_list; *shaper_item; shaper_item++) - if (false) - ; -#define HB_SHAPER_IMPLEMENT(shaper) \ - else if (0 == strcmp (*shaper_item, #shaper) && \ - hb_##shaper##_shaper_face_data_ensure (face)) \ - { \ - proposal.shaper_func = _hb_##shaper##_shape; \ - break; \ - } -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT - - if (unlikely (!proposal.shaper_func)) - return hb_shape_plan_get_empty (); - } - - retry: hb_face_t::plan_node_t *cached_plan_nodes = face->shape_plans; - /* Don't look for plan in the cache if there were variation coordinates XXX Fix me. */ - if (!hb_coords_present (coords, num_coords)) + bool dont_cache = hb_object_is_inert (face); + + if (likely (!dont_cache)) + { + hb_shape_plan_key_t key; + if (!key.init (false, + face, + props, + user_features, + num_user_features, + coords, + num_coords, + shaper_list)) + return hb_shape_plan_get_empty (); + for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next) - if (hb_shape_plan_matches (node->shape_plan, &proposal)) + if (node->shape_plan->key.equal (&key)) { DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache"); return hb_shape_plan_reference (node->shape_plan); } + } - /* Not found. */ hb_shape_plan_t *shape_plan = hb_shape_plan_create2 (face, props, user_features, num_user_features, coords, num_coords, shaper_list); - /* Don't add to the cache if face is inert. */ - if (unlikely (hb_object_is_inert (face))) - return shape_plan; - - /* Don't add the plan to the cache if there were user features with non-global ranges */ - if (hb_non_global_user_features_present (user_features, num_user_features)) - return shape_plan; - /* Don't add the plan to the cache if there were variation coordinates XXX Fix me. */ - if (hb_coords_present (coords, num_coords)) + if (unlikely (dont_cache)) return shape_plan; hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t)); @@ -577,19 +501,3 @@ retry: return hb_shape_plan_reference (shape_plan); } - -/** - * hb_shape_plan_get_shaper: - * @shape_plan: a shape plan. - * - * - * - * Return value: (transfer none): - * - * Since: 0.9.7 - **/ -const char * -hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan) -{ - return shape_plan->shaper_name; -} diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.hh index 403c3ebdf32..d9aa3ee1ab4 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape-plan.hh @@ -1,5 +1,5 @@ /* - * Copyright © 2012 Google, Inc. + * Copyright © 2012,2018 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -29,38 +29,47 @@ #include "hb.hh" #include "hb-shaper.hh" +#include "hb-ot-shape.hh" -struct hb_shape_plan_t +struct hb_shape_plan_key_t { - hb_object_header_t header; + hb_segment_properties_t props; - hb_bool_t default_shaper_list; - hb_face_t *face_unsafe; /* We don't carry a reference to face. */ - hb_segment_properties_t props; + const hb_feature_t *user_features; + unsigned int num_user_features; + + hb_ot_shape_plan_key_t ot; + + hb_shape_func_t *shaper_func; + const char *shaper_name; - hb_shape_func_t *shaper_func; - const char *shaper_name; + HB_INTERNAL inline bool init (bool copy, + hb_face_t *face, + const hb_segment_properties_t *props, + const hb_feature_t *user_features, + unsigned int num_user_features, + const int *coords, + unsigned int num_coords, + const char * const *shaper_list); - hb_feature_t *user_features; - unsigned int num_user_features; + HB_INTERNAL inline void free (void) + { + ::free ((void *) user_features); + } - int *coords; - unsigned int num_coords; + HB_INTERNAL bool user_features_match (const hb_shape_plan_key_t *other); - struct hb_shaper_data_t shaper_data; + HB_INTERNAL bool equal (const hb_shape_plan_key_t *other); }; -DECLARE_NULL_INSTANCE (hb_shape_plan_t); -#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS \ - , const hb_feature_t *user_features \ - , unsigned int num_user_features \ - , const int *coords \ - , unsigned int num_coords -#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, shape_plan); -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT -#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS +struct hb_shape_plan_t +{ + hb_object_header_t header; + hb_face_t *face_unsafe; /* We don't carry a reference to face. */ + hb_shape_plan_key_t key; + hb_ot_shape_plan_t ot; +}; #endif /* HB_SHAPE_PLAN_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc index f98bc6e51a6..270da3d77ca 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shape.cc @@ -63,7 +63,7 @@ static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_t<const char *, if (unlikely (!shaper_list)) return nullptr; - const hb_shaper_pair_t *shapers = _hb_shapers_get (); + const hb_shaper_entry_t *shapers = _hb_shapers_get (); unsigned int i; for (i = 0; i < HB_SHAPERS_COUNT; i++) shaper_list[i] = shapers[i].name; diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-impl.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-impl.hh index d40cb085a23..b674fceb6af 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-impl.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper-impl.hh @@ -30,14 +30,9 @@ #include "hb.hh" #include "hb-shaper.hh" -#include "hb-shape-plan.hh" +#include "hb-face.hh" #include "hb-font.hh" +#include "hb-shape-plan.hh" #include "hb-buffer.hh" - -#ifdef HB_SHAPER -#define HB_SHAPER_DATA_GET(object) HB_SHAPER_DATA (HB_SHAPER, object).get () -#endif - - #endif /* HB_SHAPER_IMPL_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc index 52418c08234..abea544f8e8 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.cc @@ -29,7 +29,7 @@ #include "hb-machinery.hh" -static const hb_shaper_pair_t all_shapers[] = { +static const hb_shaper_entry_t all_shapers[] = { #define HB_SHAPER_IMPLEMENT(name) {#name, _hb_##name##_shape}, #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT @@ -39,16 +39,16 @@ static const hb_shaper_pair_t all_shapers[] = { static void free_static_shapers (void); #endif -static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_pair_t, +static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_entry_t, hb_shapers_lazy_loader_t> { - static inline hb_shaper_pair_t *create (void) + static inline hb_shaper_entry_t *create (void) { char *env = getenv ("HB_SHAPER_LIST"); if (!env || !*env) return nullptr; - hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) calloc (1, sizeof (all_shapers)); + hb_shaper_entry_t *shapers = (hb_shaper_entry_t *) calloc (1, sizeof (all_shapers)); if (unlikely (!shapers)) return nullptr; @@ -68,7 +68,7 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_pair_t 0 == strncmp (shapers[j].name, p, end - p)) { /* Reorder this shaper to position i */ - struct hb_shaper_pair_t t = shapers[j]; + struct hb_shaper_entry_t t = shapers[j]; memmove (&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i)); shapers[i] = t; i++; @@ -86,11 +86,11 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_pair_t return shapers; } - static inline void destroy (const hb_shaper_pair_t *p) + static inline void destroy (const hb_shaper_entry_t *p) { free ((void *) p); } - static inline const hb_shaper_pair_t *get_null (void) + static inline const hb_shaper_entry_t *get_null (void) { return all_shapers; } @@ -104,7 +104,7 @@ void free_static_shapers (void) } #endif -const hb_shaper_pair_t * +const hb_shaper_entry_t * _hb_shapers_get (void) { return static_shapers.get_unconst (); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.hh index 361165e4f95..3fda27bc0ec 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-shaper.hh @@ -28,6 +28,7 @@ #define HB_SHAPER_HH #include "hb.hh" +#include "hb-machinery.hh" typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t *shape_plan, hb_font_t *font, @@ -40,95 +41,94 @@ typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t *shape_plan, #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT -struct hb_shaper_pair_t { +struct hb_shaper_entry_t { char name[16]; hb_shape_func_t *func; }; -HB_INTERNAL const hb_shaper_pair_t * +HB_INTERNAL const hb_shaper_entry_t * _hb_shapers_get (void); -/* Means: succeeded, but don't need to keep any data. */ -#define HB_SHAPER_DATA_SUCCEEDED ((void *) +1) -/* Means: tried but failed to create. */ -#define HB_SHAPER_DATA_INVALID ((void *) -1) +template <typename Data, unsigned int WheresData, typename T> +struct hb_shaper_lazy_loader_t; -#define HB_SHAPER_DATA_TYPE_NAME(shaper, object) hb_##shaper##_##object##_data_t -#define HB_SHAPER_DATA_TYPE(shaper, object) struct HB_SHAPER_DATA_TYPE_NAME(shaper, object) -#define HB_SHAPER_DATA_INSTANCE(shaper, object, instance) (* reinterpret_cast<hb_atomic_ptr_t<HB_SHAPER_DATA_TYPE(shaper, object) *> *> (&(instance)->shaper_data.shaper)) -#define HB_SHAPER_DATA(shaper, object) HB_SHAPER_DATA_INSTANCE(shaper, object, object) +#define HB_SHAPER_ORDER(Shaper) \ + HB_PASTE (HB_SHAPER_ORDER_, Shaper) +enum hb_shaper_order_t +{ + _HB_SHAPER_ORDER_ORDER_ZERO, +#define HB_SHAPER_IMPLEMENT(Shaper) \ + HB_SHAPER_ORDER (Shaper), +#include "hb-shaper-list.hh" +#undef HB_SHAPER_IMPLEMENT + _HB_SHAPERS_COUNT_PLUS_ONE, + HB_SHAPERS_COUNT = _HB_SHAPERS_COUNT_PLUS_ONE - 1, +}; + +template <enum hb_shaper_order_t order, typename Object> struct hb_shaper_object_data_type_t; + +#define HB_SHAPER_DATA_SUCCEEDED ((void *) +1) +#define HB_SHAPER_DATA_TYPE(shaper, object) hb_##shaper##_##object##_data_t #define HB_SHAPER_DATA_CREATE_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_create #define HB_SHAPER_DATA_DESTROY_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_destroy -#define HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) hb_##shaper##_shaper_##object##_data_ensure -#define HB_SHAPER_DATA_PROTOTYPE(shaper, object) \ - HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \ +#define HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, object) \ + \ + struct HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \ extern "C" HB_INTERNAL HB_SHAPER_DATA_TYPE (shaper, object) * \ - HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (hb_##object##_t *object HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS); \ + HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (hb_##object##_t *object); \ extern "C" HB_INTERNAL void \ - HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *data); \ - extern "C" HB_INTERNAL bool \ - HB_SHAPER_DATA_ENSURE_FUNC (shaper, object) (hb_##object##_t *object) - -#define HB_SHAPER_DATA_DESTROY(shaper, object) \ - if (HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object).get ()) \ - if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED) \ - HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); - -#define HB_SHAPER_DATA_ENSURE_DEFINE(shaper, object) \ - HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, true) - -#define HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, condition) \ -bool \ -HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \ -{\ - retry: \ - HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object).get (); \ - if (likely (data) && !(condition)) { \ - /* XXX-MT-bug \ - * Note that evaluating condition above can be dangerous if another thread \ - * got here first and destructed data. That's, as always, bad use pattern. \ - * If you modify the font (change font size), other threads must not be \ - * using it at the same time. However, since this check is delayed to \ - * when one actually tries to shape something, this is a XXX race condition \ - * (and the only know we have that I know of) right now. Ie. you modify the \ - * font size in one thread, then (supposedly safely) try to use it from two \ - * or more threads and BOOM! I'm not sure how to fix this. We want RCU. \ - * Maybe when it doesn't matter when we finally implement AAT shaping, as - * this (condition) is currently only used by hb-coretext. */ \ - /* Drop and recreate. */ \ - /* If someone dropped it in the mean time, throw it away and don't touch it. \ - * Otherwise, destruct it. */ \ - if (likely (HB_SHAPER_DATA (shaper, object).cmpexch (data, nullptr))) \ - { \ - HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \ - } \ - goto retry; \ - } \ - if (unlikely (!data)) { \ - data = HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (object); \ - if (unlikely (!data)) \ - data = (HB_SHAPER_DATA_TYPE (shaper, object) *) HB_SHAPER_DATA_INVALID; \ - if (unlikely (!HB_SHAPER_DATA (shaper, object).cmpexch (nullptr, data))) { \ - if (data && \ - data != HB_SHAPER_DATA_INVALID && \ - data != HB_SHAPER_DATA_SUCCEEDED) \ - HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \ - goto retry; \ - } \ - } \ - return data != nullptr && (void *) data != HB_SHAPER_DATA_INVALID; \ -} - - -/* For embedding in face / font / ... */ -struct hb_shaper_data_t { -#define HB_SHAPER_IMPLEMENT(shaper) hb_atomic_ptr_t<void *> shaper; + HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *shaper##_##object); \ + \ + template <> \ + struct hb_shaper_object_data_type_t<HB_SHAPER_ORDER (shaper), hb_##object##_t> \ + { \ + typedef HB_SHAPER_DATA_TYPE(shaper, object) value; \ + }; \ + \ + template <unsigned int WheresData> \ + struct hb_shaper_lazy_loader_t<hb_##object##_t, WheresData, HB_SHAPER_DATA_TYPE(shaper, object)> \ + : hb_lazy_loader_t<HB_SHAPER_DATA_TYPE(shaper, object), \ + hb_shaper_lazy_loader_t<hb_##object##_t, \ + WheresData, \ + HB_SHAPER_DATA_TYPE(shaper, object)>, \ + hb_##object##_t, WheresData> \ + { \ + typedef HB_SHAPER_DATA_TYPE(shaper, object) Type; \ + static inline Type* create (hb_##object##_t *data) \ + { return HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (data); } \ + static inline Type *get_null (void) { return nullptr; } \ + static inline void destroy (Type *p) { HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (p); } \ + }; \ + \ + static_assert (true, "") /* Require semicolon. */ + + +template <typename Object> +struct hb_shaper_object_dataset_t +{ + inline void init0 (Object *parent_data) + { + this->parent_data = parent_data; +#define HB_SHAPER_IMPLEMENT(shaper) shaper.init0 (); #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT -}; -#define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *)) + } + inline void fini (void) + { +#define HB_SHAPER_IMPLEMENT(shaper) shaper.fini (); +#include "hb-shaper-list.hh" +#undef HB_SHAPER_IMPLEMENT + } + Object *parent_data; /* MUST be JUST before the lazy loaders. */ +#define HB_SHAPER_IMPLEMENT(shaper) \ + hb_shaper_lazy_loader_t<Object, HB_SHAPER_ORDER(shaper), \ + typename hb_shaper_object_data_type_t<HB_SHAPER_ORDER(shaper), Object>::value \ + > shaper; +#include "hb-shaper-list.hh" +#undef HB_SHAPER_IMPLEMENT +}; #endif /* HB_SHAPER_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc index 3669e08b70d..73d9528e64f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-static.cc @@ -46,24 +46,26 @@ DEFINE_NULL_NAMESPACE_BYTES (OT, RangeRecord) = {0x00,0x01, 0x00,0x00, 0x00, 0x0 const unsigned char _hb_Null_AAT_Lookup[2] = {0xFF, 0xFF}; -void +unsigned int hb_face_t::load_num_glyphs (void) const { hb_sanitize_context_t c = hb_sanitize_context_t (); c.set_num_glyphs (0); /* So we don't recurse ad infinitum. */ hb_blob_t *maxp_blob = c.reference_table<OT::maxp> (this); const OT::maxp *maxp_table = maxp_blob->as<OT::maxp> (); - num_glyphs = maxp_table->get_num_glyphs (); + + unsigned int ret = maxp_table->get_num_glyphs (); + num_glyphs.set_relaxed (ret); hb_blob_destroy (maxp_blob); + return ret; } -void +unsigned int hb_face_t::load_upem (void) const { - hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<OT::head> (this); - const OT::head *head_table = head_blob->as<OT::head> (); - upem = head_table->get_upem (); - hb_blob_destroy (head_blob); + unsigned int ret = table.head->get_upem (); + upem.set_relaxed (ret); + return ret; } #endif diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc index 499380a9773..2219d379c1e 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.cc @@ -31,12 +31,12 @@ static bool _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf, - hb_vector_t<hb_codepoint_t> &glyph_ids, - hb_bool_t drop_hints, - bool *use_short_loca /* OUT */, - unsigned int *glyf_size /* OUT */, - unsigned int *loca_size /* OUT */, - hb_vector_t<unsigned int> *instruction_ranges /* OUT */) + hb_vector_t<hb_codepoint_t> &glyph_ids, + hb_bool_t drop_hints, + bool *use_short_loca /* OUT */, + unsigned int *glyf_size /* OUT */, + unsigned int *loca_size /* OUT */, + hb_vector_t<unsigned int> *instruction_ranges /* OUT */) { unsigned int total = 0; for (unsigned int i = 0; i < glyph_ids.len; i++) @@ -53,8 +53,8 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf, *instruction_end = 0; unsigned int start_offset, end_offset; - if (unlikely (!(glyf.get_offsets(next_glyph, &start_offset, &end_offset) - && glyf.remove_padding(start_offset, &end_offset)))) + if (unlikely (!(glyf.get_offsets (next_glyph, &start_offset, &end_offset) && + glyf.remove_padding (start_offset, &end_offset)))) { DEBUG_MSG(SUBSET, nullptr, "Invalid gid %d", next_glyph); continue; @@ -64,11 +64,11 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf, if (drop_hints) { - if (unlikely (!glyf.get_instruction_offsets(start_offset, end_offset, - instruction_start, instruction_end))) + if (unlikely (!glyf.get_instruction_offsets (start_offset, end_offset, + instruction_start, instruction_end))) { - DEBUG_MSG(SUBSET, nullptr, "Unable to get instruction offsets for %d", next_glyph); - return false; + DEBUG_MSG(SUBSET, nullptr, "Unable to get instruction offsets for %d", next_glyph); + return false; } } @@ -80,21 +80,21 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf, *glyf_size = total; *use_short_loca = (total <= 131070); *loca_size = (glyph_ids.len + 1) - * (*use_short_loca ? sizeof(OT::HBUINT16) : sizeof(OT::HBUINT32)); + * (*use_short_loca ? sizeof (OT::HBUINT16) : sizeof (OT::HBUINT32)); DEBUG_MSG(SUBSET, nullptr, "preparing to subset glyf: final size %d, loca size %d, using %s loca", - total, - *loca_size, - *use_short_loca ? "short" : "long"); + total, + *loca_size, + *use_short_loca ? "short" : "long"); return true; } static bool _write_loca_entry (unsigned int id, - unsigned int offset, - bool is_short, - void *loca_prime, - unsigned int loca_size) + unsigned int offset, + bool is_short, + void *loca_prime, + unsigned int loca_size) { unsigned int entry_size = is_short ? sizeof (OT::HBUINT16) : sizeof (OT::HBUINT32); if ((id + 1) * entry_size <= loca_size) @@ -108,11 +108,11 @@ _write_loca_entry (unsigned int id, } // Offset was not written because the write is out of bounds. - DEBUG_MSG (SUBSET, - nullptr, - "WARNING: Attempted to write an out of bounds loca entry at index %d. Loca size is %d.", - id, - loca_size); + DEBUG_MSG(SUBSET, + nullptr, + "WARNING: Attempted to write an out of bounds loca entry at index %d. Loca size is %d.", + id, + loca_size); return false; } @@ -130,15 +130,15 @@ _update_components (hb_subset_plan_t * plan, { hb_codepoint_t new_gid; if (!plan->new_gid_for_old_gid (iterator.current->glyphIndex, - &new_gid)) + &new_gid)) continue; ((OT::glyf::CompositeGlyphHeader *) iterator.current)->glyphIndex.set (new_gid); - } while (iterator.move_to_next()); + } while (iterator.move_to_next ()); } } -static bool _remove_composite_instruction_flag(char *glyf_prime, unsigned int length) +static bool _remove_composite_instruction_flag (char *glyf_prime, unsigned int length) { /* remove WE_HAVE_INSTRUCTIONS from flags in dest */ OT::glyf::CompositeGlyphHeader::Iterator composite_it; @@ -148,20 +148,20 @@ static bool _remove_composite_instruction_flag(char *glyf_prime, unsigned int le glyph = composite_it.current; OT::HBUINT16 *flags = const_cast<OT::HBUINT16 *> (&glyph->flags); flags->set ( (uint16_t) *flags & ~OT::glyf::CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS); - } while (composite_it.move_to_next()); + } while (composite_it.move_to_next ()); return true; } static bool _write_glyf_and_loca_prime (hb_subset_plan_t *plan, const OT::glyf::accelerator_t &glyf, - const char *glyf_data, - bool use_short_loca, - hb_vector_t<unsigned int> &instruction_ranges, - unsigned int glyf_prime_size, - char *glyf_prime_data /* OUT */, - unsigned int loca_prime_size, - char *loca_prime_data /* OUT */) + const char *glyf_data, + bool use_short_loca, + hb_vector_t<unsigned int> &instruction_ranges, + unsigned int glyf_prime_size, + char *glyf_prime_data /* OUT */, + unsigned int loca_prime_size, + char *loca_prime_data /* OUT */) { hb_vector_t<hb_codepoint_t> &glyph_ids = plan->glyphs; char *glyf_prime_data_next = glyf_prime_data; @@ -170,8 +170,8 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan, for (unsigned int i = 0; i < glyph_ids.len; i++) { unsigned int start_offset, end_offset; - if (unlikely (!(glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset) - && glyf.remove_padding(start_offset, &end_offset)))) + if (unlikely (!(glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset) && + glyf.remove_padding (start_offset, &end_offset)))) end_offset = start_offset = 0; unsigned int instruction_start = instruction_ranges[i * 2]; @@ -181,10 +181,10 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan, if (glyf_prime_data_next + length > glyf_prime_data + glyf_prime_size) { - DEBUG_MSG (SUBSET, - nullptr, - "WARNING: Attempted to write an out of bounds glyph entry for gid %d (length %d)", - i, length); + DEBUG_MSG(SUBSET, + nullptr, + "WARNING: Attempted to write an out of bounds glyph entry for gid %d (length %d)", + i, length); return false; } @@ -197,18 +197,18 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan, /* if the instructions end at the end this was a composite glyph, else simple */ if (instruction_end == end_offset) { - if (unlikely (!_remove_composite_instruction_flag (glyf_prime_data_next, length))) return false; + if (unlikely (!_remove_composite_instruction_flag (glyf_prime_data_next, length))) return false; } else - /* zero instruction length, which is just before instruction_start */ - memset (glyf_prime_data_next + instruction_start - start_offset - 2, 0, 2); + /* zero instruction length, which is just before instruction_start */ + memset (glyf_prime_data_next + instruction_start - start_offset - 2, 0, 2); } success = success && _write_loca_entry (i, - glyf_prime_data_next - glyf_prime_data, - use_short_loca, - loca_prime_data, - loca_prime_size); + glyf_prime_data_next - glyf_prime_data, + use_short_loca, + loca_prime_data, + loca_prime_size); _update_components (plan, glyf_prime_data_next, length); // TODO: don't align to two bytes if using long loca. @@ -216,20 +216,20 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan, } success = success && _write_loca_entry (glyph_ids.len, - glyf_prime_data_next - glyf_prime_data, - use_short_loca, - loca_prime_data, - loca_prime_size); + glyf_prime_data_next - glyf_prime_data, + use_short_loca, + loca_prime_data, + loca_prime_size); return success; } static bool _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf, - const char *glyf_data, - hb_subset_plan_t *plan, - bool *use_short_loca, - hb_blob_t **glyf_prime /* OUT */, - hb_blob_t **loca_prime /* OUT */) + const char *glyf_data, + hb_subset_plan_t *plan, + bool *use_short_loca, + hb_blob_t **glyf_prime /* OUT */, + hb_blob_t **loca_prime /* OUT */) { // TODO(grieger): Sanity check allocation size for the new table. hb_vector_t<hb_codepoint_t> &glyphs_to_retain = plan->glyphs; @@ -237,43 +237,43 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf, unsigned int glyf_prime_size; unsigned int loca_prime_size; hb_vector_t<unsigned int> instruction_ranges; - instruction_ranges.init(); + instruction_ranges.init (); if (unlikely (!_calculate_glyf_and_loca_prime_size (glyf, - glyphs_to_retain, - plan->drop_hints, - use_short_loca, - &glyf_prime_size, - &loca_prime_size, - &instruction_ranges))) { - instruction_ranges.fini(); + glyphs_to_retain, + plan->drop_hints, + use_short_loca, + &glyf_prime_size, + &loca_prime_size, + &instruction_ranges))) { + instruction_ranges.fini (); return false; } char *glyf_prime_data = (char *) calloc (1, glyf_prime_size); char *loca_prime_data = (char *) calloc (1, loca_prime_size); if (unlikely (!_write_glyf_and_loca_prime (plan, glyf, glyf_data, - *use_short_loca, - instruction_ranges, - glyf_prime_size, glyf_prime_data, - loca_prime_size, loca_prime_data))) { + *use_short_loca, + instruction_ranges, + glyf_prime_size, glyf_prime_data, + loca_prime_size, loca_prime_data))) { free (glyf_prime_data); free (loca_prime_data); - instruction_ranges.fini(); + instruction_ranges.fini (); return false; } - instruction_ranges.fini(); + instruction_ranges.fini (); *glyf_prime = hb_blob_create (glyf_prime_data, - glyf_prime_size, - HB_MEMORY_MODE_READONLY, - glyf_prime_data, - free); + glyf_prime_size, + HB_MEMORY_MODE_READONLY, + glyf_prime_data, + free); *loca_prime = hb_blob_create (loca_prime_data, - loca_prime_size, - HB_MEMORY_MODE_READONLY, - loca_prime_data, - free); + loca_prime_size, + HB_MEMORY_MODE_READONLY, + loca_prime_data, + free); return true; } @@ -287,24 +287,24 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf, **/ bool hb_subset_glyf_and_loca (hb_subset_plan_t *plan, - bool *use_short_loca, /* OUT */ - hb_blob_t **glyf_prime, /* OUT */ - hb_blob_t **loca_prime /* OUT */) + bool *use_short_loca, /* OUT */ + hb_blob_t **glyf_prime, /* OUT */ + hb_blob_t **loca_prime /* OUT */) { hb_blob_t *glyf_blob = hb_sanitize_context_t ().reference_table<OT::glyf> (plan->source); - const char *glyf_data = hb_blob_get_data(glyf_blob, nullptr); + const char *glyf_data = hb_blob_get_data (glyf_blob, nullptr); OT::glyf::accelerator_t glyf; - glyf.init(plan->source); + glyf.init (plan->source); bool result = _hb_subset_glyf_and_loca (glyf, - glyf_data, - plan, - use_short_loca, - glyf_prime, - loca_prime); + glyf_data, + plan, + use_short_loca, + glyf_prime, + loca_prime); hb_blob_destroy (glyf_blob); - glyf.fini(); + glyf.fini (); return result; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.hh index 3109ecb643a..99cf8f07112 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-glyf.hh @@ -33,8 +33,8 @@ HB_INTERNAL bool hb_subset_glyf_and_loca (hb_subset_plan_t *plan, - bool *use_short_loca, /* OUT */ - hb_blob_t **glyf_prime /* OUT */, - hb_blob_t **loca_prime /* OUT */); + bool *use_short_loca, /* OUT */ + hb_blob_t **glyf_prime /* OUT */, + hb_blob_t **loca_prime /* OUT */); #endif /* HB_SUBSET_GLYF_HH */ diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc index d59b5bae03c..aafd31b9d3f 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-input.cc @@ -72,7 +72,7 @@ hb_subset_input_reference (hb_subset_input_t *subset_input) * Since: 1.8.0 **/ void -hb_subset_input_destroy(hb_subset_input_t *subset_input) +hb_subset_input_destroy (hb_subset_input_t *subset_input) { if (!hb_object_destroy (subset_input)) return; @@ -121,7 +121,7 @@ hb_subset_input_get_drop_hints (hb_subset_input_t *subset_input) HB_EXTERN void hb_subset_input_set_drop_layout (hb_subset_input_t *subset_input, - hb_bool_t drop_layout) + hb_bool_t drop_layout) { subset_input->drop_layout = drop_layout; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc index 64c8ad7982d..56a2bba522d 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.cc @@ -57,24 +57,35 @@ _gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain) { hb_set_t lookup_indices; hb_ot_layout_collect_lookups (face, - HB_OT_TAG_GSUB, - nullptr, - nullptr, - nullptr, - &lookup_indices); + HB_OT_TAG_GSUB, + nullptr, + nullptr, + nullptr, + &lookup_indices); hb_ot_layout_lookups_substitute_closure (face, - &lookup_indices, - gids_to_retain); + &lookup_indices, + gids_to_retain); } +static void +_remove_invalid_gids (hb_set_t *glyphs, + unsigned int num_glyphs) +{ + hb_codepoint_t gid = HB_SET_VALUE_INVALID; + while (glyphs->next (&gid)) + { + if (gid >= num_glyphs) + glyphs->del (gid); + } +} static hb_set_t * _populate_gids_to_retain (hb_face_t *face, - const hb_set_t *unicodes, - bool close_over_gsub, - hb_set_t *unicodes_to_retain, - hb_map_t *codepoint_to_glyph, - hb_vector_t<hb_codepoint_t> *glyphs) + const hb_set_t *unicodes, + bool close_over_gsub, + hb_set_t *unicodes_to_retain, + hb_map_t *codepoint_to_glyph, + hb_vector_t<hb_codepoint_t> *glyphs) { OT::cmap::accelerator_t cmap; OT::glyf::accelerator_t glyf; @@ -112,6 +123,8 @@ _populate_gids_to_retain (hb_face_t *face, } hb_set_destroy (initial_gids_to_retain); + _remove_invalid_gids (all_gids_to_retain, face->get_num_glyphs ()); + glyphs->alloc (all_gids_to_retain->get_population ()); gid = HB_SET_VALUE_INVALID; while (all_gids_to_retain->next (&gid)) @@ -125,7 +138,7 @@ _populate_gids_to_retain (hb_face_t *face, static void _create_old_gid_to_new_gid_map (const hb_vector_t<hb_codepoint_t> &glyphs, - hb_map_t *glyph_map) + hb_map_t *glyph_map) { for (unsigned int i = 0; i < glyphs.len; i++) { glyph_map->set (glyphs[i], i); @@ -144,7 +157,7 @@ _create_old_gid_to_new_gid_map (const hb_vector_t<hb_codepoint_t> &glyphs, **/ hb_subset_plan_t * hb_subset_plan_create (hb_face_t *face, - hb_subset_input_t *input) + hb_subset_input_t *input) { hb_subset_plan_t *plan = hb_object_create<hb_subset_plan_t> (); @@ -163,7 +176,7 @@ hb_subset_plan_create (hb_face_t *face, plan->codepoint_to_glyph, &plan->glyphs); _create_old_gid_to_new_gid_map (plan->glyphs, - plan->glyph_map); + plan->glyph_map); return plan; } @@ -179,7 +192,7 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) if (!hb_object_destroy (plan)) return; hb_set_destroy (plan->unicodes); - plan->glyphs.fini(); + plan->glyphs.fini (); hb_face_destroy (plan->source); hb_face_destroy (plan->dest); hb_map_destroy (plan->codepoint_to_glyph); diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh index 5ab32ad8f37..c574f8f810b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset-plan.hh @@ -56,7 +56,7 @@ struct hb_subset_plan_t inline bool new_gid_for_codepoint (hb_codepoint_t codepoint, - hb_codepoint_t *new_gid) const + hb_codepoint_t *new_gid) const { hb_codepoint_t old_gid = codepoint_to_glyph->get (codepoint); if (old_gid == HB_MAP_VALUE_INVALID) @@ -67,7 +67,7 @@ struct hb_subset_plan_t inline bool new_gid_for_old_gid (hb_codepoint_t old_gid, - hb_codepoint_t *new_gid) const + hb_codepoint_t *new_gid) const { hb_codepoint_t gid = glyph_map->get (old_gid); if (gid == HB_MAP_VALUE_INVALID) @@ -79,13 +79,13 @@ struct hb_subset_plan_t inline bool add_table (hb_tag_t tag, - hb_blob_t *contents) + hb_blob_t *contents) { hb_blob_t *source_blob = source->reference_table (tag); DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes", - HB_UNTAG(tag), - hb_blob_get_length (contents), - hb_blob_get_length (source_blob)); + HB_UNTAG(tag), + hb_blob_get_length (contents), + hb_blob_get_length (source_blob)); hb_blob_destroy (source_blob); return hb_face_builder_add_table (dest, tag, contents); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc index a1c52c57a72..a3917b8626b 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.cc @@ -70,10 +70,10 @@ _subset2 (hb_subset_plan_t *plan) { hb_vector_t<char> buf; unsigned int buf_size = _plan_estimate_subset_table_size (plan, source_blob->length); - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG(tag), buf_size); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size); if (unlikely (!buf.alloc (buf_size))) { - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG(tag), buf_size); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size); return false; } retry: @@ -83,10 +83,10 @@ _subset2 (hb_subset_plan_t *plan) if (serializer.ran_out_of_room) { buf_size += (buf_size >> 1) + 32; - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG(tag), buf_size); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (tag), buf_size); if (unlikely (!buf.alloc (buf_size))) { - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG(tag), buf_size); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (tag), buf_size); return false; } goto retry; @@ -94,21 +94,21 @@ _subset2 (hb_subset_plan_t *plan) if (result) { hb_blob_t *dest_blob = serializer.copy_blob (); - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG(tag), dest_blob->length); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length); result = c.plan->add_table (tag, dest_blob); hb_blob_destroy (dest_blob); } else { - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG(tag)); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag)); result = true; } } else - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG(tag)); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); hb_blob_destroy (source_blob); - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG(tag), result ? "success" : "FAILED!"); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG (tag), result ? "success" : "FAILED!"); return result; } @@ -124,19 +124,19 @@ _subset (hb_subset_plan_t *plan) if (source_blob->data) result = table->subset (plan); else - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG(tag)); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); hb_blob_destroy (source_blob); - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG(tag), result ? "success" : "FAILED!"); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG (tag), result ? "success" : "FAILED!"); return result; } static bool _subset_table (hb_subset_plan_t *plan, - hb_tag_t tag) + hb_tag_t tag) { - DEBUG_MSG(SUBSET, nullptr, "begin subset %c%c%c%c", HB_UNTAG(tag)); + DEBUG_MSG(SUBSET, nullptr, "begin subset %c%c%c%c", HB_UNTAG (tag)); bool result = true; switch (tag) { case HB_OT_TAG_glyf: @@ -186,20 +186,20 @@ _subset_table (hb_subset_plan_t *plan, break; default: - hb_blob_t *source_table = hb_face_reference_table(plan->source, tag); + hb_blob_t *source_table = hb_face_reference_table (plan->source, tag); if (likely (source_table)) - result = plan->add_table(tag, source_table); + result = plan->add_table (tag, source_table); else - result = false; + result = false; hb_blob_destroy (source_table); break; } - DEBUG_MSG(SUBSET, nullptr, "subset %c%c%c%c %s", HB_UNTAG(tag), result ? "ok" : "FAILED"); + DEBUG_MSG(SUBSET, nullptr, "subset %c%c%c%c %s", HB_UNTAG (tag), result ? "ok" : "FAILED"); return result; } static bool -_should_drop_table(hb_subset_plan_t *plan, hb_tag_t tag) +_should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) { switch (tag) { case HB_TAG ('c', 'v', 'a', 'r'): /* hint table, fallthrough */ @@ -248,9 +248,9 @@ _should_drop_table(hb_subset_plan_t *plan, hb_tag_t tag) **/ hb_face_t * hb_subset (hb_face_t *source, - hb_subset_input_t *input) + hb_subset_input_t *input) { - if (unlikely (!input || !source)) return hb_face_get_empty(); + if (unlikely (!input || !source)) return hb_face_get_empty (); hb_subset_plan_t *plan = hb_subset_plan_create (source, input); @@ -263,17 +263,17 @@ hb_subset (hb_face_t *source, for (unsigned int i = 0; i < count; i++) { hb_tag_t tag = table_tags[i]; - if (_should_drop_table(plan, tag)) + if (_should_drop_table (plan, tag)) { - DEBUG_MSG(SUBSET, nullptr, "drop %c%c%c%c", HB_UNTAG(tag)); - continue; + DEBUG_MSG(SUBSET, nullptr, "drop %c%c%c%c", HB_UNTAG (tag)); + continue; } success = success && _subset_table (plan, tag); } offset += count; } while (success && count == ARRAY_LENGTH (table_tags)); - hb_face_t *result = success ? hb_face_reference(plan->dest) : hb_face_get_empty(); + hb_face_t *result = success ? hb_face_reference (plan->dest) : hb_face_get_empty (); hb_subset_plan_destroy (plan); return result; } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h index 8b07a45e923..3b306dd81f5 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-subset.h @@ -62,15 +62,14 @@ hb_subset_input_get_drop_hints (hb_subset_input_t *subset_input); HB_EXTERN void hb_subset_input_set_drop_layout (hb_subset_input_t *subset_input, - hb_bool_t drop_layout); + hb_bool_t drop_layout); HB_EXTERN hb_bool_t hb_subset_input_get_drop_layout (hb_subset_input_t *subset_input); -/* hb_subset() */ +/* hb_subset () */ HB_EXTERN hb_face_t * -hb_subset (hb_face_t *source, - hb_subset_input_t *input); +hb_subset (hb_face_t *source, hb_subset_input_t *input); HB_END_DECLS diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc index e77825b343f..1331704e9e9 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-uniscribe.cc @@ -25,7 +25,6 @@ */ #include "hb.hh" -#define HB_SHAPER uniscribe #include "hb-shaper-impl.hh" #include <windows.h> @@ -314,9 +313,6 @@ struct range_record_t { unsigned int index_last; /* == end - 1 */ }; -HB_SHAPER_DATA_ENSURE_DEFINE(uniscribe, face) -HB_SHAPER_DATA_ENSURE_DEFINE(uniscribe, font) - /* * shaper face data @@ -503,11 +499,12 @@ _hb_uniscribe_shaper_face_data_destroy (hb_uniscribe_face_data_t *data) * shaper font data */ -struct hb_uniscribe_font_data_t { +struct hb_uniscribe_font_data_t +{ HDC hdc; - LOGFONTW log_font; + mutable LOGFONTW log_font; HFONT hfont; - SCRIPT_CACHE script_cache; + mutable SCRIPT_CACHE script_cache; double x_mult, y_mult; /* From LOGFONT space to HB space. */ }; @@ -520,10 +517,7 @@ populate_log_font (LOGFONTW *lf, lf->lfHeight = - (int) font_size; lf->lfCharSet = DEFAULT_CHARSET; - hb_face_t *face = font->face; - hb_uniscribe_face_data_t *face_data = HB_SHAPER_DATA_GET (face); - - memcpy (lf->lfFaceName, face_data->face_name, sizeof (lf->lfFaceName)); + memcpy (lf->lfFaceName, font->face->data.uniscribe->face_name, sizeof (lf->lfFaceName)); return true; } @@ -531,8 +525,6 @@ populate_log_font (LOGFONTW *lf, hb_uniscribe_font_data_t * _hb_uniscribe_shaper_font_data_create (hb_font_t *font) { - if (unlikely (!hb_uniscribe_shaper_face_data_ensure (font->face))) return nullptr; - hb_uniscribe_font_data_t *data = (hb_uniscribe_font_data_t *) calloc (1, sizeof (hb_uniscribe_font_data_t)); if (unlikely (!data)) return nullptr; @@ -586,39 +578,15 @@ _hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_font_data_t *data) LOGFONTW * hb_uniscribe_font_get_logfontw (hb_font_t *font) { - if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return nullptr; - hb_uniscribe_font_data_t *font_data = HB_SHAPER_DATA_GET (font); - return &font_data->log_font; + const hb_uniscribe_font_data_t *data = font->data.uniscribe; + return data ? &data->log_font : nullptr; } HFONT hb_uniscribe_font_get_hfont (hb_font_t *font) { - if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return nullptr; - hb_uniscribe_font_data_t *font_data = HB_SHAPER_DATA_GET (font); - return font_data->hfont; -} - - -/* - * shaper shape_plan data - */ - -struct hb_uniscribe_shape_plan_data_t {}; - -hb_uniscribe_shape_plan_data_t * -_hb_uniscribe_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, - const hb_feature_t *user_features HB_UNUSED, - unsigned int num_user_features HB_UNUSED, - const int *coords HB_UNUSED, - unsigned int num_coords HB_UNUSED) -{ - return (hb_uniscribe_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; -} - -void -_hb_uniscribe_shaper_shape_plan_data_destroy (hb_uniscribe_shape_plan_data_t *data HB_UNUSED) -{ + const hb_uniscribe_font_data_t *data = font->data.uniscribe; + return data ? data->hfont : nullptr; } @@ -635,8 +603,8 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan, unsigned int num_features) { hb_face_t *face = font->face; - hb_uniscribe_face_data_t *face_data = HB_SHAPER_DATA_GET (face); - hb_uniscribe_font_data_t *font_data = HB_SHAPER_DATA_GET (font); + const hb_uniscribe_face_data_t *face_data = face->data.uniscribe; + const hb_uniscribe_font_data_t *font_data = font->data.uniscribe; hb_uniscribe_shaper_funcs_t *funcs = face_data->funcs; /* diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh index fe06addf7bb..7056a5b5493 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-vector.hh @@ -34,6 +34,9 @@ template <typename Type, unsigned int StaticSize=8> struct hb_vector_t { + typedef Type ItemType; + enum { item_size = sizeof (Type) }; + HB_NO_COPY_ASSIGN_TEMPLATE2 (hb_vector_t, Type, StaticSize); inline hb_vector_t (void) { init (); } inline ~hb_vector_t (void) { fini (); } diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh index e3faf17c94f..16ccf87ce97 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb.hh @@ -246,7 +246,7 @@ struct _hb_alignof #endif -#if defined(_WIN32) || defined(__CYGWIN__) +#ifdef _WIN32 /* We need Windows Vista for both Uniscribe backend and for * MemoryBarrier. We don't support compiling on Windows XP, * though we run on it fine. */ |