src/hb-aat-layout-common-private.hh | 23 +++++- src/hb-aat-layout-morx-table.hh | 34 +++++++--- test/shaping/data/text-rendering-tests/DISABLED | 1 test/shaping/data/text-rendering-tests/Makefile.sources | 2 test/shaping/data/text-rendering-tests/fonts/TestMORXTwelve.ttf |binary test/shaping/data/text-rendering-tests/tests/MORX-12.tests | 3 6 files changed, 49 insertions(+), 14 deletions(-)
New commits: commit 7e2fed6d73f89986e5777028cdcd24e3baf2f86c Author: Behdad Esfahbod <[email protected]> Date: Thu Jan 11 19:25:21 2018 +0100 [aat] Allow DontAdvance Apparently CoreText does allow these. To be done: detect infinite loops. Fixes MORX-12 test. diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 50805eb8..cc15fddb 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -155,7 +155,7 @@ struct RearrangementSubtable } } - if (false/* TODO */ && flags & DontAdvance) + if (flags & DontAdvance) i--; /* TODO Detect infinite loop. */ state = entry->newState; @@ -259,7 +259,7 @@ struct ContextualSubtable } } - if (false/* TODO */ && flags & DontAdvance) + if (flags & DontAdvance) i--; /* TODO Detect infinite loop. */ state = entry->newState; commit 1387fe8f9c474e88f86828733d4c01bd56f44432 Author: Behdad Esfahbod <[email protected]> Date: Thu Jan 11 19:22:37 2018 +0100 [test/text-rendering-tests] Update from upstream diff --git a/test/shaping/data/text-rendering-tests/DISABLED b/test/shaping/data/text-rendering-tests/DISABLED index 610e1957..809edb61 100644 --- a/test/shaping/data/text-rendering-tests/DISABLED +++ b/test/shaping/data/text-rendering-tests/DISABLED @@ -13,6 +13,7 @@ tests/MORX-8.tests tests/MORX-9.tests tests/MORX-10.tests tests/MORX-11.tests +tests/MORX-12.tests # Rounding differences tests/SHARAN-1.tests diff --git a/test/shaping/data/text-rendering-tests/Makefile.sources b/test/shaping/data/text-rendering-tests/Makefile.sources index e09091a6..a3acf276 100644 --- a/test/shaping/data/text-rendering-tests/Makefile.sources +++ b/test/shaping/data/text-rendering-tests/Makefile.sources @@ -28,6 +28,7 @@ TESTS = \ tests/HVAR-2.tests \ tests/KERN-1.tests \ tests/KERN-2.tests \ + tests/MORX-12.tests \ tests/SHBALI-3.tests \ tests/SHKNDA-1.tests \ $(NULL) @@ -36,6 +37,7 @@ DISBALED_TESTS = \ tests/CMAP-3.tests \ tests/MORX-10.tests \ tests/MORX-11.tests \ + tests/MORX-12.tests \ tests/MORX-1.tests \ tests/MORX-2.tests \ tests/MORX-3.tests \ diff --git a/test/shaping/data/text-rendering-tests/fonts/TestMORXTwelve.ttf b/test/shaping/data/text-rendering-tests/fonts/TestMORXTwelve.ttf new file mode 100644 index 00000000..b1e4bc44 Binary files /dev/null and b/test/shaping/data/text-rendering-tests/fonts/TestMORXTwelve.ttf differ diff --git a/test/shaping/data/text-rendering-tests/tests/MORX-12.tests b/test/shaping/data/text-rendering-tests/tests/MORX-12.tests new file mode 100644 index 00000000..8b9886fc --- /dev/null +++ b/test/shaping/data/text-rendering-tests/tests/MORX-12.tests @@ -0,0 +1,3 @@ +../fonts/TestMORXTwelve.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0041,U+0042,U+0043,U+0058,U+0031:[X|C@598,0|A@1230,0|B@1868,0|X@2518,0|one@3116,0] +../fonts/TestMORXTwelve.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0041,U+0042,U+0043,U+0058,U+0032:[X|C@598,0|A@1230,0|B@1868,0|X@2518,0|two@3116,0] +../fonts/TestMORXTwelve.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0041,U+0042,U+0043,U+0058,U+0033:[X|B@598,0|C@1248,0|A@1880,0|X@2518,0|three@3116,0] commit 17f01aff910b3871d0a6c45fd4305304b7f68ab5 Author: Behdad Esfahbod <[email protected]> Date: Thu Jan 11 18:54:49 2018 +0100 [aat] Sanitize ContextualSubtable diff --git a/src/hb-aat-layout-common-private.hh b/src/hb-aat-layout-common-private.hh index 4d2285a8..fca74ea2 100644 --- a/src/hb-aat-layout-common-private.hh +++ b/src/hb-aat-layout-common-private.hh @@ -512,11 +512,17 @@ struct Entry inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && data.sanitize (c)); + /* Note, we don't recurse-sanitize data because we don't access it. + * That said, in our DEFINE_SIZE_STATIC we access T::static_size, + * which ensures that data has a simple sanitize(). To be determined + * if I need to remove that as well. */ + return_trace (c->check_struct (this)); } public: - HBUINT16 newState; /* Byte offset from beginning of state table to the new state. */ + HBUINT16 newState; /* Byte offset from beginning of state table + * to the new state. Really?!?! Or just state + * number? The latter in morx for sure. */ HBUINT16 flags; /* Table specific. */ T data; /* Optional offsets to per-glyph tables. */ public: @@ -550,7 +556,12 @@ struct StateTable { return (this+classTable).get_class (glyph_id, num_glyphs); } - inline const Entry<Extra> *get_entry (unsigned int state, unsigned int klass) const + inline const Entry<Extra> *get_entries () const + { + return (this+entryTable).arrayZ; + } + + inline const Entry<Extra> *get_entryZ (unsigned int state, unsigned int klass) const { if (unlikely (klass >= nClasses)) return nullptr; @@ -562,7 +573,8 @@ struct StateTable return &entries[entry]; } - inline bool sanitize (hb_sanitize_context_t *c) const + inline bool sanitize (hb_sanitize_context_t *c, + unsigned int *num_entries_out = nullptr) const { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) return_trace (false); @@ -600,6 +612,9 @@ struct StateTable } } + if (num_entries_out) + *num_entries_out = num_entries; + return_trace (true); } diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 0433f1f4..50805eb8 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -79,7 +79,7 @@ struct RearrangementSubtable unsigned int klass = i < count ? machine.get_class (info[i].codepoint, num_glyphs) : 0 /* End of text */; - const Entry<void> *entry = machine.get_entry (state, klass); + const Entry<void> *entry = machine.get_entryZ (state, klass); if (unlikely (!entry)) break; @@ -155,8 +155,8 @@ struct RearrangementSubtable } } - if (false/* XXX */ && flags & DontAdvance) - i--; /* XXX Detect infinite loop. */ + if (false/* TODO */ && flags & DontAdvance) + i--; /* TODO Detect infinite loop. */ state = entry->newState; } @@ -224,7 +224,7 @@ struct ContextualSubtable unsigned int klass = i < count ? machine.get_class (info[i].codepoint, num_glyphs) : 0 /* End of text */; - const Entry<EntryData> *entry = machine.get_entry (state, klass); + const Entry<EntryData> *entry = machine.get_entryZ (state, klass); if (unlikely (!entry)) break; @@ -238,7 +238,7 @@ struct ContextualSubtable if (entry->data.markIndex != 0xFFFF) { - const Lookup<GlyphID> &lookup = subs[entry->data.markIndex]; // XXX bounds + const Lookup<GlyphID> &lookup = subs[entry->data.markIndex]; const GlyphID *replacement = lookup.get_value (info[mark].codepoint, num_glyphs); if (replacement) { @@ -249,7 +249,7 @@ struct ContextualSubtable } if (entry->data.currentIndex != 0xFFFF) { - const Lookup<GlyphID> &lookup = subs[entry->data.currentIndex]; // XXX bounds + const Lookup<GlyphID> &lookup = subs[entry->data.currentIndex]; const GlyphID *replacement = lookup.get_value (info[i].codepoint, num_glyphs); if (replacement) { @@ -259,8 +259,8 @@ struct ContextualSubtable } } - if (false/* XXX */ && flags & DontAdvance) - i--; /* XXX Detect infinite loop. */ + if (false/* TODO */ && flags & DontAdvance) + i--; /* TODO Detect infinite loop. */ state = entry->newState; } @@ -271,8 +271,22 @@ struct ContextualSubtable inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (machine.sanitize (c) && - substitutionTables.sanitize (c, this, 0U/*XXX count*/)); + + unsigned int num_entries; + if (unlikely (!machine.sanitize (c, &num_entries))) return false; + + unsigned int num_lookups = 0; + + const Entry<EntryData> *entries = machine.get_entries (); + for (unsigned int i = 0; i < num_entries; i++) + { + const EntryData &data = entries[i].data; + + num_lookups = MAX<unsigned int> (num_lookups, 1 + data.markIndex); + num_lookups = MAX<unsigned int> (num_lookups, 1 + data.currentIndex); + } + + return_trace (substitutionTables.sanitize (c, this, num_lookups)); } protected: _______________________________________________ HarfBuzz mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/harfbuzz
