summaryrefslogtreecommitdiff
path: root/thirdparty/harfbuzz/src/OT
diff options
context:
space:
mode:
authorbruvzg <7645683+bruvzg@users.noreply.github.com>2022-07-24 23:05:03 +0300
committerbruvzg <7645683+bruvzg@users.noreply.github.com>2022-07-24 23:05:03 +0300
commit5f5a9f256cad866172c18939e31162ba038ac02e (patch)
treec0d398d0ae345b40fd7b847057267f4ad1852554 /thirdparty/harfbuzz/src/OT
parentb3df27526a0374f2fd5f44eab99da4b4bfd9f9ec (diff)
HarfBuzz: Update to version 5.0.1
Diffstat (limited to 'thirdparty/harfbuzz/src/OT')
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh338
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh126
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh233
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/Common/RangeRecord.hh85
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh8
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh (renamed from thirdparty/harfbuzz/src/OT/Layout/GPOS.hh)34
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh56
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh10
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh14
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh10
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh56
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh10
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh15
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh14
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh253
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh11
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh173
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh97
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh3
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh6
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh5
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh17
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh16
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/ChainContextSubst.hh2
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh2
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/ContextSubst.hh2
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/ExtensionSubst.hh2
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh17
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh12
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh15
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh18
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh23
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh17
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubstFormat1.hh15
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh2
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh24
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh5
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh40
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh54
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh13
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh13
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookupSubTable.hh2
-rw-r--r--thirdparty/harfbuzz/src/OT/Layout/types.hh66
-rw-r--r--thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh36
-rw-r--r--thirdparty/harfbuzz/src/OT/glyf/Glyph.hh20
-rw-r--r--thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh8
-rw-r--r--thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh4
-rw-r--r--thirdparty/harfbuzz/src/OT/glyf/glyf.hh59
48 files changed, 1571 insertions, 490 deletions
diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh
new file mode 100644
index 0000000000..e52a617c86
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh
@@ -0,0 +1,338 @@
+/*
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2010,2012 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod, Garret Rieger
+ */
+
+#ifndef OT_LAYOUT_COMMON_COVERAGE_HH
+#define OT_LAYOUT_COMMON_COVERAGE_HH
+
+#include "../types.hh"
+#include "CoverageFormat1.hh"
+#include "CoverageFormat2.hh"
+
+namespace OT {
+namespace Layout {
+namespace Common {
+
+template<typename Iterator>
+static inline void Coverage_serialize (hb_serialize_context_t *c,
+ Iterator it);
+
+struct Coverage
+{
+
+ protected:
+ union {
+ HBUINT16 format; /* Format identifier */
+ CoverageFormat1_3<SmallTypes> format1;
+ CoverageFormat2_4<SmallTypes> format2;
+#ifndef HB_NO_BORING_EXPANSION
+ CoverageFormat1_3<MediumTypes>format3;
+ CoverageFormat2_4<MediumTypes>format4;
+#endif
+ } u;
+ public:
+ DEFINE_SIZE_UNION (2, format);
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!u.format.sanitize (c)) return_trace (false);
+ switch (u.format)
+ {
+ case 1: return_trace (u.format1.sanitize (c));
+ case 2: return_trace (u.format2.sanitize (c));
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: return_trace (u.format3.sanitize (c));
+ case 4: return_trace (u.format4.sanitize (c));
+#endif
+ default:return_trace (true);
+ }
+ }
+
+ /* Has interface. */
+ static constexpr unsigned SENTINEL = NOT_COVERED;
+ typedef unsigned int value_t;
+ value_t operator [] (hb_codepoint_t k) const { return get (k); }
+ bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+ /* Predicate. */
+ bool operator () (hb_codepoint_t k) const { return has (k); }
+
+ unsigned int get (hb_codepoint_t k) const { return get_coverage (k); }
+ unsigned int get_coverage (hb_codepoint_t glyph_id) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.get_coverage (glyph_id);
+ case 2: return u.format2.get_coverage (glyph_id);
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: return u.format3.get_coverage (glyph_id);
+ case 4: return u.format4.get_coverage (glyph_id);
+#endif
+ default:return NOT_COVERED;
+ }
+ }
+
+ unsigned get_population () const
+ {
+ switch (u.format) {
+ case 1: return u.format1.get_population ();
+ case 2: return u.format2.get_population ();
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: return u.format3.get_population ();
+ case 4: return u.format4.get_population ();
+#endif
+ default:return NOT_COVERED;
+ }
+ }
+
+ template <typename Iterator,
+ hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
+ bool serialize (hb_serialize_context_t *c, Iterator glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (this))) return_trace (false);
+
+ unsigned count = 0;
+ unsigned num_ranges = 0;
+ hb_codepoint_t last = (hb_codepoint_t) -2;
+ for (auto g: glyphs)
+ {
+ if (last + 1 != g)
+ num_ranges++;
+ last = g;
+ count++;
+ }
+ u.format = count <= num_ranges * 3 ? 1 : 2;
+
+#ifndef HB_NO_BORING_EXPANSION
+ if (count && last > 0xFFFFu)
+ u.format += 2;
+#endif
+
+ switch (u.format)
+ {
+ case 1: return_trace (u.format1.serialize (c, glyphs));
+ case 2: return_trace (u.format2.serialize (c, glyphs));
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: return_trace (u.format3.serialize (c, glyphs));
+ case 4: return_trace (u.format4.serialize (c, glyphs));
+#endif
+ default:return_trace (false);
+ }
+ }
+
+ bool subset (hb_subset_context_t *c) const
+ {
+ TRACE_SUBSET (this);
+ auto it =
+ + iter ()
+ | hb_filter (c->plan->glyph_map_gsub)
+ | hb_map_retains_sorting (c->plan->glyph_map_gsub)
+ ;
+
+ // Cache the iterator result as it will be iterated multiple times
+ // by the serialize code below.
+ hb_sorted_vector_t<hb_codepoint_t> glyphs (it);
+ Coverage_serialize (c->serializer, glyphs.iter ());
+ return_trace (bool (glyphs));
+ }
+
+ bool intersects (const hb_set_t *glyphs) const
+ {
+ switch (u.format)
+ {
+ case 1: return u.format1.intersects (glyphs);
+ case 2: return u.format2.intersects (glyphs);
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: return u.format3.intersects (glyphs);
+ case 4: return u.format4.intersects (glyphs);
+#endif
+ default:return false;
+ }
+ }
+ bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
+ {
+ switch (u.format)
+ {
+ case 1: return u.format1.intersects_coverage (glyphs, index);
+ case 2: return u.format2.intersects_coverage (glyphs, index);
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: return u.format3.intersects_coverage (glyphs, index);
+ case 4: return u.format4.intersects_coverage (glyphs, index);
+#endif
+ default:return false;
+ }
+ }
+
+ /* Might return false if array looks unsorted.
+ * Used for faster rejection of corrupt data. */
+ template <typename set_t>
+ bool collect_coverage (set_t *glyphs) const
+ {
+ switch (u.format)
+ {
+ case 1: return u.format1.collect_coverage (glyphs);
+ case 2: return u.format2.collect_coverage (glyphs);
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: return u.format3.collect_coverage (glyphs);
+ case 4: return u.format4.collect_coverage (glyphs);
+#endif
+ default:return false;
+ }
+ }
+
+ template <typename IterableOut,
+ hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))>
+ void intersect_set (const hb_set_t &glyphs, IterableOut &intersect_glyphs) const
+ {
+ switch (u.format)
+ {
+ case 1: return u.format1.intersect_set (glyphs, intersect_glyphs);
+ case 2: return u.format2.intersect_set (glyphs, intersect_glyphs);
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: return u.format3.intersect_set (glyphs, intersect_glyphs);
+ case 4: return u.format4.intersect_set (glyphs, intersect_glyphs);
+#endif
+ default:return ;
+ }
+ }
+
+ struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
+ {
+ static constexpr bool is_sorted_iterator = true;
+ iter_t (const Coverage &c_ = Null (Coverage))
+ {
+ memset (this, 0, sizeof (*this));
+ format = c_.u.format;
+ switch (format)
+ {
+ case 1: u.format1.init (c_.u.format1); return;
+ case 2: u.format2.init (c_.u.format2); return;
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: u.format3.init (c_.u.format3); return;
+ case 4: u.format4.init (c_.u.format4); return;
+#endif
+ default: return;
+ }
+ }
+ bool __more__ () const
+ {
+ switch (format)
+ {
+ case 1: return u.format1.__more__ ();
+ case 2: return u.format2.__more__ ();
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: return u.format3.__more__ ();
+ case 4: return u.format4.__more__ ();
+#endif
+ default:return false;
+ }
+ }
+ void __next__ ()
+ {
+ switch (format)
+ {
+ case 1: u.format1.__next__ (); break;
+ case 2: u.format2.__next__ (); break;
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: u.format3.__next__ (); break;
+ case 4: u.format4.__next__ (); break;
+#endif
+ default: break;
+ }
+ }
+ typedef hb_codepoint_t __item_t__;
+ __item_t__ __item__ () const { return get_glyph (); }
+
+ hb_codepoint_t get_glyph () const
+ {
+ switch (format)
+ {
+ case 1: return u.format1.get_glyph ();
+ case 2: return u.format2.get_glyph ();
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: return u.format3.get_glyph ();
+ case 4: return u.format4.get_glyph ();
+#endif
+ default:return 0;
+ }
+ }
+ bool operator != (const iter_t& o) const
+ {
+ if (unlikely (format != o.format)) return true;
+ switch (format)
+ {
+ case 1: return u.format1 != o.u.format1;
+ case 2: return u.format2 != o.u.format2;
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: return u.format3 != o.u.format3;
+ case 4: return u.format4 != o.u.format4;
+#endif
+ default:return false;
+ }
+ }
+ iter_t __end__ () const
+ {
+ iter_t it = {};
+ it.format = format;
+ switch (format)
+ {
+ case 1: it.u.format1 = u.format1.__end__ (); break;
+ case 2: it.u.format2 = u.format2.__end__ (); break;
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: it.u.format3 = u.format3.__end__ (); break;
+ case 4: it.u.format4 = u.format4.__end__ (); break;
+#endif
+ default: break;
+ }
+ return it;
+ }
+
+ private:
+ unsigned int format;
+ union {
+#ifndef HB_NO_BORING_EXPANSION
+ CoverageFormat2_4<MediumTypes>::iter_t format4; /* Put this one first since it's larger; helps shut up compiler. */
+ CoverageFormat1_3<MediumTypes>::iter_t format3;
+#endif
+ CoverageFormat2_4<SmallTypes>::iter_t format2; /* Put this one first since it's larger; helps shut up compiler. */
+ CoverageFormat1_3<SmallTypes>::iter_t format1;
+ } u;
+ };
+ iter_t iter () const { return iter_t (*this); }
+};
+
+template<typename Iterator>
+static inline void
+Coverage_serialize (hb_serialize_context_t *c,
+ Iterator it)
+{ c->start_embed<Coverage> ()->serialize (c, it); }
+
+}
+}
+}
+
+#endif // #ifndef OT_LAYOUT_COMMON_COVERAGE_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh
new file mode 100644
index 0000000000..886babd2d1
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh
@@ -0,0 +1,126 @@
+/*
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2010,2012 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod, Garret Rieger
+ */
+
+
+#ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH
+#define OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH
+
+namespace OT {
+namespace Layout {
+namespace Common {
+
+#define NOT_COVERED ((unsigned int) -1)
+
+template <typename Types>
+struct CoverageFormat1_3
+{
+ friend struct Coverage;
+
+ protected:
+ HBUINT16 coverageFormat; /* Format identifier--format = 1 */
+ SortedArray16Of<typename Types::HBGlyphID>
+ glyphArray; /* Array of GlyphIDs--in numerical order */
+ public:
+ DEFINE_SIZE_ARRAY (4, glyphArray);
+
+ private:
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (glyphArray.sanitize (c));
+ }
+
+ unsigned int get_coverage (hb_codepoint_t glyph_id) const
+ {
+ unsigned int i;
+ glyphArray.bfind (glyph_id, &i, HB_NOT_FOUND_STORE, NOT_COVERED);
+ return i;
+ }
+
+ unsigned get_population () const
+ {
+ return glyphArray.len;
+ }
+
+ template <typename Iterator,
+ hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
+ bool serialize (hb_serialize_context_t *c, Iterator glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ return_trace (glyphArray.serialize (c, glyphs));
+ }
+
+ bool intersects (const hb_set_t *glyphs) const
+ {
+ /* TODO Speed up, using hb_set_next() and bsearch()? */
+ for (const auto& g : glyphArray.as_array ())
+ if (glyphs->has (g))
+ return true;
+ return false;
+ }
+ bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
+ { return glyphs->has (glyphArray[index]); }
+
+ template <typename IterableOut,
+ hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))>
+ void intersect_set (const hb_set_t &glyphs, IterableOut &intersect_glyphs) const
+ {
+ unsigned count = glyphArray.len;
+ for (unsigned i = 0; i < count; i++)
+ if (glyphs.has (glyphArray[i]))
+ intersect_glyphs << glyphArray[i];
+ }
+
+ template <typename set_t>
+ bool collect_coverage (set_t *glyphs) const
+ { return glyphs->add_sorted_array (glyphArray.as_array ()); }
+
+ public:
+ /* Older compilers need this to be public. */
+ struct iter_t
+ {
+ void init (const struct CoverageFormat1_3 &c_) { c = &c_; i = 0; }
+ bool __more__ () const { return i < c->glyphArray.len; }
+ void __next__ () { i++; }
+ hb_codepoint_t get_glyph () const { return c->glyphArray[i]; }
+ bool operator != (const iter_t& o) const
+ { return i != o.i; }
+ iter_t __end__ () const { iter_t it; it.init (*c); it.i = c->glyphArray.len; return it; }
+
+ private:
+ const struct CoverageFormat1_3 *c;
+ unsigned int i;
+ };
+ private:
+};
+
+}
+}
+}
+
+#endif // #ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh
new file mode 100644
index 0000000000..4ddb2a73e4
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh
@@ -0,0 +1,233 @@
+/*
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2010,2012 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod, Garret Rieger
+ */
+
+#ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH
+#define OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH
+
+#include "RangeRecord.hh"
+
+namespace OT {
+namespace Layout {
+namespace Common {
+
+template <typename Types>
+struct CoverageFormat2_4
+{
+ friend struct Coverage;
+
+ protected:
+ HBUINT16 coverageFormat; /* Format identifier--format = 2 */
+ SortedArray16Of<RangeRecord<Types>>
+ rangeRecord; /* Array of glyph ranges--ordered by
+ * Start GlyphID. rangeCount entries
+ * long */
+ public:
+ DEFINE_SIZE_ARRAY (4, rangeRecord);
+
+ private:
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (rangeRecord.sanitize (c));
+ }
+
+ unsigned int get_coverage (hb_codepoint_t glyph_id) const
+ {
+ const RangeRecord<Types> &range = rangeRecord.bsearch (glyph_id);
+ return likely (range.first <= range.last)
+ ? (unsigned int) range.value + (glyph_id - range.first)
+ : NOT_COVERED;
+ }
+
+ unsigned get_population () const
+ {
+ typename Types::large_int ret = 0;
+ for (const auto &r : rangeRecord)
+ ret += r.get_population ();
+ return ret > UINT_MAX ? UINT_MAX : (unsigned) ret;
+ }
+
+ template <typename Iterator,
+ hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
+ bool serialize (hb_serialize_context_t *c, Iterator glyphs)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (this))) return_trace (false);
+
+ /* TODO(iter) Write more efficiently? */
+
+ unsigned num_ranges = 0;
+ hb_codepoint_t last = (hb_codepoint_t) -2;
+ for (auto g: glyphs)
+ {
+ if (last + 1 != g)
+ num_ranges++;
+ last = g;
+ }
+
+ if (unlikely (!rangeRecord.serialize (c, num_ranges))) return_trace (false);
+ if (!num_ranges) return_trace (true);
+
+ unsigned count = 0;
+ unsigned range = (unsigned) -1;
+ last = (hb_codepoint_t) -2;
+ for (auto g: glyphs)
+ {
+ if (last + 1 != g)
+ {
+ range++;
+ rangeRecord[range].first = g;
+ rangeRecord[range].value = count;
+ }
+ rangeRecord[range].last = g;
+ last = g;
+ count++;
+ }
+
+ return_trace (true);
+ }
+
+ bool intersects (const hb_set_t *glyphs) const
+ {
+ return hb_any (+ hb_iter (rangeRecord)
+ | hb_map ([glyphs] (const RangeRecord<Types> &range) { return range.intersects (*glyphs); }));
+ }
+ bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
+ {
+ auto cmp = [] (const void *pk, const void *pr) -> int
+ {
+ unsigned index = * (const unsigned *) pk;
+ const RangeRecord<Types> &range = * (const RangeRecord<Types> *) pr;
+ if (index < range.value) return -1;
+ if (index > (unsigned int) range.value + (range.last - range.first)) return +1;
+ return 0;
+ };
+
+ auto arr = rangeRecord.as_array ();
+ unsigned idx;
+ if (hb_bsearch_impl (&idx, index,
+ arr.arrayZ, arr.length, sizeof (arr[0]),
+ (int (*)(const void *_key, const void *_item)) cmp))
+ return arr.arrayZ[idx].intersects (*glyphs);
+ return false;
+ }
+
+ template <typename IterableOut,
+ hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))>
+ void intersect_set (const hb_set_t &glyphs, IterableOut &intersect_glyphs) const
+ {
+ for (const auto& range : rangeRecord)
+ {
+ hb_codepoint_t last = range.last;
+ for (hb_codepoint_t g = range.first - 1;
+ glyphs.next (&g) && g <= last;)
+ intersect_glyphs << g;
+ }
+ }
+
+ template <typename set_t>
+ bool collect_coverage (set_t *glyphs) const
+ {
+ for (const auto& range: rangeRecord)
+ if (unlikely (!range.collect_coverage (glyphs)))
+ return false;
+ return true;
+ }
+
+ public:
+ /* Older compilers need this to be public. */
+ struct iter_t
+ {
+ void init (const CoverageFormat2_4 &c_)
+ {
+ c = &c_;
+ coverage = 0;
+ i = 0;
+ j = c->rangeRecord.len ? c->rangeRecord[0].first : 0;
+ if (unlikely (c->rangeRecord[0].first > c->rangeRecord[0].last))
+ {
+ /* Broken table. Skip. */
+ i = c->rangeRecord.len;
+ j = 0;
+ }
+ }
+ bool __more__ () const { return i < c->rangeRecord.len; }
+ void __next__ ()
+ {
+ if (j >= c->rangeRecord[i].last)
+ {
+ i++;
+ if (__more__ ())
+ {
+ unsigned int old = coverage;
+ j = c->rangeRecord[i].first;
+ coverage = c->rangeRecord[i].value;
+ if (unlikely (coverage != old + 1))
+ {
+ /* Broken table. Skip. Important to avoid DoS.
+ * Also, our callers depend on coverage being
+ * consecutive and monotonically increasing,
+ * ie. iota(). */
+ i = c->rangeRecord.len;
+ j = 0;
+ return;
+ }
+ }
+ else
+ j = 0;
+ return;
+ }
+ coverage++;
+ j++;
+ }
+ hb_codepoint_t get_glyph () const { return j; }
+ bool operator != (const iter_t& o) const
+ { return i != o.i || j != o.j; }
+ iter_t __end__ () const
+ {
+ iter_t it;
+ it.init (*c);
+ it.i = c->rangeRecord.len;
+ it.j = 0;
+ return it;
+ }
+
+ private:
+ const struct CoverageFormat2_4 *c;
+ unsigned int i, coverage;
+ hb_codepoint_t j;
+ };
+ private:
+};
+
+}
+}
+}
+
+#endif // #ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/RangeRecord.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/RangeRecord.hh
new file mode 100644
index 0000000000..a62629fad3
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/Common/RangeRecord.hh
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2010,2012 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod, Garret Rieger
+ */
+
+#ifndef OT_LAYOUT_COMMON_RANGERECORD_HH
+#define OT_LAYOUT_COMMON_RANGERECORD_HH
+
+namespace OT {
+namespace Layout {
+namespace Common {
+
+template <typename Types>
+struct RangeRecord
+{
+ typename Types::HBGlyphID first; /* First GlyphID in the range */
+ typename Types::HBGlyphID last; /* Last GlyphID in the range */
+ HBUINT16 value; /* Value */
+
+ DEFINE_SIZE_STATIC (2 + 2 * Types::size);
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ int cmp (hb_codepoint_t g) const
+ { return g < first ? -1 : g <= last ? 0 : +1; }
+
+ unsigned get_population () const
+ {
+ if (unlikely (last < first)) return 0;
+ return (last - first + 1);
+ }
+
+ bool intersects (const hb_set_t &glyphs) const
+ { return glyphs.intersects (first, last); }
+
+ template <typename set_t>
+ bool collect_coverage (set_t *glyphs) const
+ { return glyphs->add_range (first, last); }
+};
+
+}
+}
+}
+
+// TODO(garretrieger): This was previously implemented using
+// DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (OT, RangeRecord, 9);
+// but that only works when there is only a single namespace level.
+// The macro should probably be fixed so it can work in this situation.
+extern HB_INTERNAL const unsigned char _hb_Null_OT_RangeRecord[9];
+template <typename Spec>
+struct Null<OT::Layout::Common::RangeRecord<Spec>> {
+ static OT::Layout::Common::RangeRecord<Spec> const & get_null () {
+ return *reinterpret_cast<const OT::Layout::Common::RangeRecord<Spec> *> (_hb_Null_OT_RangeRecord);
+ }
+};
+
+
+#endif // #ifndef OT_LAYOUT_COMMON_RANGERECORD_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh
index e212fab976..7c34bb3c93 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh
@@ -140,7 +140,7 @@ struct CursivePosFormat1
unsigned int i = skippy_iter.idx;
unsigned int j = buffer->idx;
- buffer->unsafe_to_break (i, j);
+ buffer->unsafe_to_break (i, j + 1);
float entry_x, entry_y, exit_x, exit_y;
(this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y);
(this+this_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y);
@@ -223,7 +223,13 @@ struct CursivePosFormat1
* https://github.com/harfbuzz/harfbuzz/issues/2469
*/
if (unlikely (pos[parent].attach_chain() == -pos[child].attach_chain()))
+ {
pos[parent].attach_chain() = 0;
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
+ pos[parent].y_offset = 0;
+ else
+ pos[parent].x_offset = 0;
+ }
buffer->idx++;
return_trace (true);
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh
index 224d6b746b..72829377a6 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh
@@ -1,12 +1,15 @@
-#ifndef OT_LAYOUT_GPOS_HH
-#define OT_LAYOUT_GPOS_HH
+#ifndef OT_LAYOUT_GPOS_GPOS_HH
+#define OT_LAYOUT_GPOS_GPOS_HH
-#include "../../hb-ot-layout-common.hh"
-#include "../../hb-ot-layout-gsubgpos.hh"
-#include "GPOS/Common.hh"
-#include "GPOS/PosLookup.hh"
+#include "../../../hb-ot-layout-common.hh"
+#include "../../../hb-ot-layout-gsubgpos.hh"
+#include "Common.hh"
+#include "PosLookup.hh"
namespace OT {
+
+using Layout::GPOS_impl::PosLookup;
+
namespace Layout {
static void
@@ -25,10 +28,10 @@ struct GPOS : GSUBGPOS
{
static constexpr hb_tag_t tableTag = HB_OT_TAG_GPOS;
- using Lookup = GPOS_impl::PosLookup;
+ using Lookup = PosLookup;
- const GPOS_impl::PosLookup& get_lookup (unsigned int i) const
- { return static_cast<const GPOS_impl::PosLookup &> (GSUBGPOS::get_lookup (i)); }
+ const PosLookup& get_lookup (unsigned int i) const
+ { return static_cast<const PosLookup &> (GSUBGPOS::get_lookup (i)); }
static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer);
@@ -37,11 +40,14 @@ struct GPOS : GSUBGPOS
bool subset (hb_subset_context_t *c) const
{
hb_subset_layout_context_t l (c, tableTag, c->plan->gpos_lookups, c->plan->gpos_langsys, c->plan->gpos_features);
- return GSUBGPOS::subset<GPOS_impl::PosLookup> (&l);
+ return GSUBGPOS::subset<PosLookup> (&l);
}
bool sanitize (hb_sanitize_context_t *c) const
- { return GSUBGPOS::sanitize<GPOS_impl::PosLookup> (c); }
+ {
+ TRACE_SANITIZE (this);
+ return_trace (GSUBGPOS::sanitize<PosLookup> (c));
+ }
HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
hb_face_t *face) const;
@@ -51,7 +57,7 @@ struct GPOS : GSUBGPOS
for (unsigned i = 0; i < GSUBGPOS::get_lookup_count (); i++)
{
if (!c->gpos_lookups->has (i)) continue;
- const GPOS_impl::PosLookup &l = get_lookup (i);
+ const PosLookup &l = get_lookup (i);
l.dispatch (c);
}
}
@@ -59,7 +65,7 @@ struct GPOS : GSUBGPOS
void closure_lookups (hb_face_t *face,
const hb_set_t *glyphs,
hb_set_t *lookup_indexes /* IN/OUT */) const
- { GSUBGPOS::closure_lookups<GPOS_impl::PosLookup> (face, glyphs, lookup_indexes); }
+ { GSUBGPOS::closure_lookups<PosLookup> (face, glyphs, lookup_indexes); }
typedef GSUBGPOS::accelerator_t<GPOS> accelerator_t;
};
@@ -162,4 +168,4 @@ struct GPOS_accelerator_t : Layout::GPOS::accelerator_t {
}
-#endif /* OT_LAYOUT_GPOS_HH */
+#endif /* OT_LAYOUT_GPOS_GPOS_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh
new file mode 100644
index 0000000000..a2d807cc32
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh
@@ -0,0 +1,56 @@
+#ifndef OT_LAYOUT_GPOS_LIGATUREARRAY_HH
+#define OT_LAYOUT_GPOS_LIGATUREARRAY_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+
+typedef AnchorMatrix LigatureAttach; /* component-major--
+ * in order of writing direction--,
+ * mark-minor--
+ * ordered by class--zero-based. */
+
+/* Array of LigatureAttach tables ordered by LigatureCoverage Index */
+struct LigatureArray : List16OfOffset16To<LigatureAttach>
+{
+ template <typename Iterator,
+ hb_requires (hb_is_iterator (Iterator))>
+ bool subset (hb_subset_context_t *c,
+ Iterator coverage,
+ unsigned class_count,
+ const hb_map_t *klass_mapping) const
+ {
+ TRACE_SUBSET (this);
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+
+ auto *out = c->serializer->start_embed (this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+ for (const auto _ : + hb_zip (coverage, *this)
+ | hb_filter (glyphset, hb_first))
+ {
+ auto *matrix = out->serialize_append (c->serializer);
+ if (unlikely (!matrix)) return_trace (false);
+
+ const LigatureAttach& src = (this + _.second);
+ auto indexes =
+ + hb_range (src.rows * class_count)
+ | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); })
+ ;
+ matrix->serialize_subset (c,
+ _.second,
+ this,
+ src.rows,
+ indexes);
+ }
+ return_trace (this->len);
+ }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_LIGATUREARRAY_HH */
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh
index e99e13ff84..c99b6b2e4b 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh
@@ -11,8 +11,11 @@ struct MarkBasePos
{
protected:
union {
- HBUINT16 format; /* Format identifier */
- MarkBasePosFormat1 format1;
+ HBUINT16 format; /* Format identifier */
+ MarkBasePosFormat1_2<SmallTypes> format1;
+#ifndef HB_NO_BORING_EXPANSION
+ MarkBasePosFormat1_2<MediumTypes> format2;
+#endif
} u;
public:
@@ -23,6 +26,9 @@ struct MarkBasePos
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BORING_EXPANSION
+ case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#endif
default:return_trace (c->default_return_value ());
}
}
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
index a10b806fe5..ebb8c31c67 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
@@ -12,26 +12,27 @@ typedef AnchorMatrix BaseArray; /* base-major--
* mark-minor--
* ordered by class--zero-based. */
-struct MarkBasePosFormat1
+template <typename Types>
+struct MarkBasePosFormat1_2
{
protected:
HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
markCoverage; /* Offset to MarkCoverage table--from
* beginning of MarkBasePos subtable */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
baseCoverage; /* Offset to BaseCoverage table--from
* beginning of MarkBasePos subtable */
HBUINT16 classCount; /* Number of classes defined for marks */
- Offset16To<MarkArray>
+ typename Types::template OffsetTo<MarkArray>
markArray; /* Offset to MarkArray table--from
* beginning of MarkBasePos subtable */
- Offset16To<BaseArray>
+ typename Types::template OffsetTo<BaseArray>
baseArray; /* Offset to BaseArray table--from
* beginning of MarkBasePos subtable */
public:
- DEFINE_SIZE_STATIC (12);
+ DEFINE_SIZE_STATIC (4 + 4 * Types::size);
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -117,6 +118,7 @@ struct MarkBasePosFormat1
0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) ||
(skippy_iter.idx == 0 ||
_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx - 1]) ||
+ !_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx - 1]) ||
_hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]) !=
_hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx - 1]) ||
_hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) !=
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh
index 7e74aa73e0..8a4de9ffaa 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh
@@ -11,8 +11,11 @@ struct MarkLigPos
{
protected:
union {
- HBUINT16 format; /* Format identifier */
- MarkLigPosFormat1 format1;
+ HBUINT16 format; /* Format identifier */
+ MarkLigPosFormat1_2<SmallTypes> format1;
+#ifndef HB_NO_BORING_EXPANSION
+ MarkLigPosFormat1_2<MediumTypes> format2;
+#endif
} u;
public:
@@ -23,6 +26,9 @@ struct MarkLigPos
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BORING_EXPANSION
+ case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#endif
default:return_trace (c->default_return_value ());
}
}
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
index 4382aa6c6c..1a8021237e 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
@@ -1,72 +1,34 @@
#ifndef OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH
#define OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH
+#include "LigatureArray.hh"
+
namespace OT {
namespace Layout {
namespace GPOS_impl {
-typedef AnchorMatrix LigatureAttach; /* component-major--
- * in order of writing direction--,
- * mark-minor--
- * ordered by class--zero-based. */
-
-/* Array of LigatureAttach tables ordered by LigatureCoverage Index */
-struct LigatureArray : List16OfOffset16To<LigatureAttach>
-{
- template <typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- bool subset (hb_subset_context_t *c,
- Iterator coverage,
- unsigned class_count,
- const hb_map_t *klass_mapping) const
- {
- TRACE_SUBSET (this);
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-
- auto *out = c->serializer->start_embed (this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
-
- for (const auto _ : + hb_zip (coverage, *this)
- | hb_filter (glyphset, hb_first))
- {
- auto *matrix = out->serialize_append (c->serializer);
- if (unlikely (!matrix)) return_trace (false);
-
- const LigatureAttach& src = (this + _.second);
- auto indexes =
- + hb_range (src.rows * class_count)
- | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); })
- ;
- matrix->serialize_subset (c,
- _.second,
- this,
- src.rows,
- indexes);
- }
- return_trace (this->len);
- }
-};
-struct MarkLigPosFormat1
+template <typename Types>
+struct MarkLigPosFormat1_2
{
protected:
HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
markCoverage; /* Offset to Mark Coverage table--from
* beginning of MarkLigPos subtable */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
ligatureCoverage; /* Offset to Ligature Coverage
* table--from beginning of MarkLigPos
* subtable */
HBUINT16 classCount; /* Number of defined mark classes */
- Offset16To<MarkArray>
+ typename Types::template OffsetTo<MarkArray>
markArray; /* Offset to MarkArray table--from
* beginning of MarkLigPos subtable */
- Offset16To<LigatureArray>
+ typename Types::template OffsetTo<LigatureArray>
ligatureArray; /* Offset to LigatureArray table--from
* beginning of MarkLigPos subtable */
public:
- DEFINE_SIZE_STATIC (12);
+ DEFINE_SIZE_STATIC (4 + 4 * Types::size);
bool sanitize (hb_sanitize_context_t *c) const
{
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh
index c0eee6d54c..74b5105c42 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh
@@ -11,8 +11,11 @@ struct MarkMarkPos
{
protected:
union {
- HBUINT16 format; /* Format identifier */
- MarkMarkPosFormat1 format1;
+ HBUINT16 format; /* Format identifier */
+ MarkMarkPosFormat1_2<SmallTypes> format1;
+#ifndef HB_NO_BORING_EXPANSION
+ MarkMarkPosFormat1_2<MediumTypes> format2;
+#endif
} u;
public:
@@ -23,6 +26,9 @@ struct MarkMarkPos
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BORING_EXPANSION
+ case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#endif
default:return_trace (c->default_return_value ());
}
}
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
index c48a74f773..fbcebb8044 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
@@ -12,27 +12,28 @@ typedef AnchorMatrix Mark2Array; /* mark2-major--
* mark1-minor--
* ordered by class--zero-based. */
-struct MarkMarkPosFormat1
+template <typename Types>
+struct MarkMarkPosFormat1_2
{
protected:
HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
mark1Coverage; /* Offset to Combining Mark1 Coverage
* table--from beginning of MarkMarkPos
* subtable */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
mark2Coverage; /* Offset to Combining Mark2 Coverage
* table--from beginning of MarkMarkPos
* subtable */
HBUINT16 classCount; /* Number of defined mark classes */
- Offset16To<MarkArray>
+ typename Types::template OffsetTo<MarkArray>
mark1Array; /* Offset to Mark1Array table--from
* beginning of MarkMarkPos subtable */
- Offset16To<Mark2Array>
+ typename Types::template OffsetTo<Mark2Array>
mark2Array; /* Offset to Mark2Array table--from
* beginning of MarkMarkPos subtable */
public:
- DEFINE_SIZE_STATIC (12);
+ DEFINE_SIZE_STATIC (4 + 4 * Types::size);
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -100,7 +101,7 @@ struct MarkMarkPosFormat1
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset (buffer->idx, 1);
- skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
+ skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags);
unsigned unsafe_from;
if (!skippy_iter.prev (&unsafe_from))
{
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh
index 8479178d38..72bfc43dc4 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh
@@ -12,9 +12,13 @@ struct PairPos
{
protected:
union {
- HBUINT16 format; /* Format identifier */
- PairPosFormat1 format1;
- PairPosFormat2 format2;
+ HBUINT16 format; /* Format identifier */
+ PairPosFormat1_3<SmallTypes> format1;
+ PairPosFormat2_4<SmallTypes> format2;
+#ifndef HB_NO_BORING_EXPANSION
+ PairPosFormat1_3<MediumTypes> format3;
+ PairPosFormat2_4<MediumTypes> format4;
+#endif
} u;
public:
@@ -26,6 +30,10 @@ struct PairPos
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
+ case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
+#endif
default:return_trace (c->default_return_value ());
}
}
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh
index 35a2db2d45..3cb207281d 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh
@@ -1,248 +1,22 @@
#ifndef OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH
#define OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH
+#include "PairSet.hh"
+
namespace OT {
namespace Layout {
namespace GPOS_impl {
-struct PairValueRecord
-{
- friend struct PairSet;
-
- int cmp (hb_codepoint_t k) const
- { return secondGlyph.cmp (k); }
-
- struct context_t
- {
- const void *base;
- const ValueFormat *valueFormats;
- const ValueFormat *newFormats;
- unsigned len1; /* valueFormats[0].get_len() */
- const hb_map_t *glyph_map;
- const hb_map_t *layout_variation_idx_map;
- };
-
- bool subset (hb_subset_context_t *c,
- context_t *closure) const
- {
- TRACE_SERIALIZE (this);
- auto *s = c->serializer;
- auto *out = s->start_embed (*this);
- if (unlikely (!s->extend_min (out))) return_trace (false);
-
- out->secondGlyph = (*closure->glyph_map)[secondGlyph];
-
- closure->valueFormats[0].copy_values (s,
- closure->newFormats[0],
- closure->base, &values[0],
- closure->layout_variation_idx_map);
- closure->valueFormats[1].copy_values (s,
- closure->newFormats[1],
- closure->base,
- &values[closure->len1],
- closure->layout_variation_idx_map);
-
- return_trace (true);
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- const ValueFormat *valueFormats,
- const void *base) const
- {
- unsigned record1_len = valueFormats[0].get_len ();
- unsigned record2_len = valueFormats[1].get_len ();
- const hb_array_t<const Value> values_array = values.as_array (record1_len + record2_len);
-
- if (valueFormats[0].has_device ())
- valueFormats[0].collect_variation_indices (c, base, values_array.sub_array (0, record1_len));
-
- if (valueFormats[1].has_device ())
- valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len));
- }
-
- bool intersects (const hb_set_t& glyphset) const
- {
- return glyphset.has(secondGlyph);
- }
-
- const Value* get_values_1 () const
- {
- return &values[0];
- }
-
- const Value* get_values_2 (ValueFormat format1) const
- {
- return &values[format1.get_len ()];
- }
- protected:
- HBGlyphID16 secondGlyph; /* GlyphID of second glyph in the
- * pair--first glyph is listed in the
- * Coverage table */
- ValueRecord values; /* Positioning data for the first glyph
- * followed by for second glyph */
- public:
- DEFINE_SIZE_ARRAY (2, values);
-};
-
-struct PairSet
+template <typename Types>
+struct PairPosFormat1_3
{
- friend struct PairPosFormat1;
-
- bool intersects (const hb_set_t *glyphs,
- const ValueFormat *valueFormats) const
- {
- unsigned int len1 = valueFormats[0].get_len ();
- unsigned int len2 = valueFormats[1].get_len ();
- unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
-
- const PairValueRecord *record = &firstPairValueRecord;
- unsigned int count = len;
- for (unsigned int i = 0; i < count; i++)
- {
- if (glyphs->has (record->secondGlyph))
- return true;
- record = &StructAtOffset<const PairValueRecord> (record, record_size);
- }
- return false;
- }
-
- void collect_glyphs (hb_collect_glyphs_context_t *c,
- const ValueFormat *valueFormats) const
- {
- unsigned int len1 = valueFormats[0].get_len ();
- unsigned int len2 = valueFormats[1].get_len ();
- unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
-
- const PairValueRecord *record = &firstPairValueRecord;
- c->input->add_array (&record->secondGlyph, len, record_size);
- }
-
- void collect_variation_indices (hb_collect_variation_indices_context_t *c,
- const ValueFormat *valueFormats) const
- {
- unsigned len1 = valueFormats[0].get_len ();
- unsigned len2 = valueFormats[1].get_len ();
- unsigned record_size = HBUINT16::static_size * (1 + len1 + len2);
-
- const PairValueRecord *record = &firstPairValueRecord;
- unsigned count = len;
- for (unsigned i = 0; i < count; i++)
- {
- if (c->glyph_set->has (record->secondGlyph))
- { record->collect_variation_indices (c, valueFormats, this); }
-
- record = &StructAtOffset<const PairValueRecord> (record, record_size);
- }
- }
+ using PairSet = GPOS_impl::PairSet<Types>;
+ using PairValueRecord = GPOS_impl::PairValueRecord<Types>;
- bool apply (hb_ot_apply_context_t *c,
- const ValueFormat *valueFormats,
- unsigned int pos) const
- {
- TRACE_APPLY (this);
- hb_buffer_t *buffer = c->buffer;
- unsigned int len1 = valueFormats[0].get_len ();
- unsigned int len2 = valueFormats[1].get_len ();
- unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
-
- const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint,
- &firstPairValueRecord,
- len,
- record_size);
- if (record)
- {
- bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
- bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
- if (applied_first || applied_second)
- buffer->unsafe_to_break (buffer->idx, pos + 1);
- if (len2)
- pos++;
- buffer->idx = pos;
- return_trace (true);
- }
- buffer->unsafe_to_concat (buffer->idx, pos + 1);
- return_trace (false);
- }
-
- bool subset (hb_subset_context_t *c,
- const ValueFormat valueFormats[2],
- const ValueFormat newFormats[2]) const
- {
- TRACE_SUBSET (this);
- auto snap = c->serializer->snapshot ();
-
- auto *out = c->serializer->start_embed (*this);
- if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- out->len = 0;
-
- const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
- const hb_map_t &glyph_map = *c->plan->glyph_map;
-
- unsigned len1 = valueFormats[0].get_len ();
- unsigned len2 = valueFormats[1].get_len ();
- unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
-
- PairValueRecord::context_t context =
- {
- this,
- valueFormats,
- newFormats,
- len1,
- &glyph_map,
- c->plan->layout_variation_idx_map
- };
-
- const PairValueRecord *record = &firstPairValueRecord;
- unsigned count = len, num = 0;
- for (unsigned i = 0; i < count; i++)
- {
- if (glyphset.has (record->secondGlyph)
- && record->subset (c, &context)) num++;
- record = &StructAtOffset<const PairValueRecord> (record, record_size);
- }
-
- out->len = num;
- if (!num) c->serializer->revert (snap);
- return_trace (num);
- }
-
- struct sanitize_closure_t
- {
- const ValueFormat *valueFormats;
- unsigned int len1; /* valueFormats[0].get_len() */
- unsigned int stride; /* 1 + len1 + len2 */
- };
-
- bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const
- {
- TRACE_SANITIZE (this);
- if (!(c->check_struct (this)
- && c->check_range (&firstPairValueRecord,
- len,
- HBUINT16::static_size,
- closure->stride))) return_trace (false);
-
- unsigned int count = len;
- const PairValueRecord *record = &firstPairValueRecord;
- return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) &&
- closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride));
- }
-
- protected:
- HBUINT16 len; /* Number of PairValueRecords */
- PairValueRecord firstPairValueRecord;
- /* Array of PairValueRecords--ordered
- * by GlyphID of the second glyph */
- public:
- DEFINE_SIZE_MIN (2);
-};
-
-struct PairPosFormat1
-{
protected:
HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of subtable */
ValueFormat valueFormat[2]; /* [0] Defines the types of data in
@@ -251,11 +25,11 @@ struct PairPosFormat1
/* [1] Defines the types of data in
* ValueRecord2--for the second glyph
* in the pair--may be zero (0) */
- Array16OfOffset16To<PairSet>
+ Array16Of<typename Types::template OffsetTo<PairSet>>
pairSet; /* Array of PairSet tables
* ordered by Coverage Index */
public:
- DEFINE_SIZE_ARRAY (10, pairSet);
+ DEFINE_SIZE_ARRAY (8 + Types::size, pairSet);
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -265,7 +39,7 @@ struct PairPosFormat1
unsigned int len1 = valueFormat[0].get_len ();
unsigned int len2 = valueFormat[1].get_len ();
- PairSet::sanitize_closure_t closure =
+ typename PairSet::sanitize_closure_t closure =
{
valueFormat,
len1,
@@ -275,14 +49,13 @@ struct PairPosFormat1
return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure));
}
-
bool intersects (const hb_set_t *glyphs) const
{
return
+ hb_zip (this+coverage, pairSet)
| hb_filter (*glyphs, hb_first)
| hb_map (hb_second)
- | hb_map ([glyphs, this] (const Offset16To<PairSet> &_)
+ | hb_map ([glyphs, this] (const typename Types::template OffsetTo<PairSet> &_)
{ return (this+_).intersects (glyphs, valueFormat); })
| hb_any
;
@@ -358,7 +131,7 @@ struct PairPosFormat1
+ hb_zip (this+coverage, pairSet)
| hb_filter (glyphset, hb_first)
- | hb_filter ([this, c, out] (const Offset16To<PairSet>& _)
+ | hb_filter ([this, c, out] (const typename Types::template OffsetTo<PairSet>& _)
{
auto snap = c->serializer->snapshot ();
auto *o = out->pairSet.serialize_append (c->serializer);
@@ -391,7 +164,7 @@ struct PairPosFormat1
unsigned format1 = 0;
unsigned format2 = 0;
- for (const Offset16To<PairSet>& _ :
+ for (const auto & _ :
+ hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) | hb_map (hb_second))
{
const PairSet& set = (this + _);
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh
index 3f5f9959c4..f58bcb1b30 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh
@@ -7,11 +7,12 @@ namespace OT {
namespace Layout {
namespace GPOS_impl {
-struct PairPosFormat2
+template <typename Types>
+struct PairPosFormat2_4
{
protected:
HBUINT16 format; /* Format identifier--format = 2 */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of subtable */
ValueFormat valueFormat1; /* ValueRecord definition--for the
@@ -20,11 +21,11 @@ struct PairPosFormat2
ValueFormat valueFormat2; /* ValueRecord definition--for the
* second glyph of the pair--may be
* zero (0) */
- Offset16To<ClassDef>
+ typename Types::template OffsetTo<ClassDef>
classDef1; /* Offset to ClassDef table--from
* beginning of PairPos subtable--for
* the first glyph of the pair */
- Offset16To<ClassDef>
+ typename Types::template OffsetTo<ClassDef>
classDef2; /* Offset to ClassDef table--from
* beginning of PairPos subtable--for
* the second glyph of the pair */
@@ -36,7 +37,7 @@ struct PairPosFormat2
* class1-major, class2-minor,
* Each entry has value1 and value2 */
public:
- DEFINE_SIZE_ARRAY (16, values);
+ DEFINE_SIZE_ARRAY (10 + 3 * Types::size, values);
bool sanitize (hb_sanitize_context_t *c) const
{
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh
new file mode 100644
index 0000000000..58ba4de6c1
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh
@@ -0,0 +1,173 @@
+#ifndef OT_LAYOUT_GPOS_PAIRSET_HH
+#define OT_LAYOUT_GPOS_PAIRSET_HH
+
+#include "PairValueRecord.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+
+template <typename Types>
+struct PairSet
+{
+ template <typename Types2>
+ friend struct PairPosFormat1_3;
+
+ using PairValueRecord = GPOS_impl::PairValueRecord<Types>;
+
+ protected:
+ HBUINT16 len; /* Number of PairValueRecords */
+ PairValueRecord firstPairValueRecord;
+ /* Array of PairValueRecords--ordered
+ * by GlyphID of the second glyph */
+ public:
+ DEFINE_SIZE_MIN (2);
+
+ struct sanitize_closure_t
+ {
+ const ValueFormat *valueFormats;
+ unsigned int len1; /* valueFormats[0].get_len() */
+ unsigned int stride; /* 1 + len1 + len2 */
+ };
+
+ bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const
+ {
+ TRACE_SANITIZE (this);
+ if (!(c->check_struct (this)
+ && c->check_range (&firstPairValueRecord,
+ len,
+ HBUINT16::static_size,
+ closure->stride))) return_trace (false);
+
+ unsigned int count = len;
+ const PairValueRecord *record = &firstPairValueRecord;
+ return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) &&
+ closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride));
+ }
+
+ bool intersects (const hb_set_t *glyphs,
+ const ValueFormat *valueFormats) const
+ {
+ unsigned int len1 = valueFormats[0].get_len ();
+ unsigned int len2 = valueFormats[1].get_len ();
+ unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = &firstPairValueRecord;
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (glyphs->has (record->secondGlyph))
+ return true;
+ record = &StructAtOffset<const PairValueRecord> (record, record_size);
+ }
+ return false;
+ }
+
+ void collect_glyphs (hb_collect_glyphs_context_t *c,
+ const ValueFormat *valueFormats) const
+ {
+ unsigned int len1 = valueFormats[0].get_len ();
+ unsigned int len2 = valueFormats[1].get_len ();
+ unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = &firstPairValueRecord;
+ c->input->add_array (&record->secondGlyph, len, record_size);
+ }
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c,
+ const ValueFormat *valueFormats) const
+ {
+ unsigned len1 = valueFormats[0].get_len ();
+ unsigned len2 = valueFormats[1].get_len ();
+ unsigned record_size = HBUINT16::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = &firstPairValueRecord;
+ unsigned count = len;
+ for (unsigned i = 0; i < count; i++)
+ {
+ if (c->glyph_set->has (record->secondGlyph))
+ { record->collect_variation_indices (c, valueFormats, this); }
+
+ record = &StructAtOffset<const PairValueRecord> (record, record_size);
+ }
+ }
+
+ bool apply (hb_ot_apply_context_t *c,
+ const ValueFormat *valueFormats,
+ unsigned int pos) const
+ {
+ TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int len1 = valueFormats[0].get_len ();
+ unsigned int len2 = valueFormats[1].get_len ();
+ unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint,
+ &firstPairValueRecord,
+ len,
+ record_size);
+ if (record)
+ {
+ bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
+ bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
+ if (applied_first || applied_second)
+ buffer->unsafe_to_break (buffer->idx, pos + 1);
+ if (len2)
+ pos++;
+ buffer->idx = pos;
+ return_trace (true);
+ }
+ buffer->unsafe_to_concat (buffer->idx, pos + 1);
+ return_trace (false);
+ }
+
+ bool subset (hb_subset_context_t *c,
+ const ValueFormat valueFormats[2],
+ const ValueFormat newFormats[2]) const
+ {
+ TRACE_SUBSET (this);
+ auto snap = c->serializer->snapshot ();
+
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->len = 0;
+
+ const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ unsigned len1 = valueFormats[0].get_len ();
+ unsigned len2 = valueFormats[1].get_len ();
+ unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
+
+ typename PairValueRecord::context_t context =
+ {
+ this,
+ valueFormats,
+ newFormats,
+ len1,
+ &glyph_map,
+ c->plan->layout_variation_idx_map
+ };
+
+ const PairValueRecord *record = &firstPairValueRecord;
+ unsigned count = len, num = 0;
+ for (unsigned i = 0; i < count; i++)
+ {
+ if (glyphset.has (record->secondGlyph)
+ && record->subset (c, &context)) num++;
+ record = &StructAtOffset<const PairValueRecord> (record, record_size);
+ }
+
+ out->len = num;
+ if (!num) c->serializer->revert (snap);
+ return_trace (num);
+ }
+};
+
+
+}
+}
+}
+
+#endif // OT_LAYOUT_GPOS_PAIRSET_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh
new file mode 100644
index 0000000000..55de5abebf
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh
@@ -0,0 +1,97 @@
+#ifndef OT_LAYOUT_GPOS_PAIRVALUERECORD_HH
+#define OT_LAYOUT_GPOS_PAIRVALUERECORD_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+
+template <typename Types>
+struct PairValueRecord
+{
+ template <typename Types2>
+ friend struct PairSet;
+
+ protected:
+ typename Types::HBGlyphID
+ secondGlyph; /* GlyphID of second glyph in the
+ * pair--first glyph is listed in the
+ * Coverage table */
+ ValueRecord values; /* Positioning data for the first glyph
+ * followed by for second glyph */
+ public:
+ DEFINE_SIZE_ARRAY (Types::size, values);
+
+ int cmp (hb_codepoint_t k) const
+ { return secondGlyph.cmp (k); }
+
+ struct context_t
+ {
+ const void *base;
+ const ValueFormat *valueFormats;
+ const ValueFormat *newFormats;
+ unsigned len1; /* valueFormats[0].get_len() */
+ const hb_map_t *glyph_map;
+ const hb_map_t *layout_variation_idx_map;
+ };
+
+ bool subset (hb_subset_context_t *c,
+ context_t *closure) const
+ {
+ TRACE_SERIALIZE (this);
+ auto *s = c->serializer;
+ auto *out = s->start_embed (*this);
+ if (unlikely (!s->extend_min (out))) return_trace (false);
+
+ out->secondGlyph = (*closure->glyph_map)[secondGlyph];
+
+ closure->valueFormats[0].copy_values (s,
+ closure->newFormats[0],
+ closure->base, &values[0],
+ closure->layout_variation_idx_map);
+ closure->valueFormats[1].copy_values (s,
+ closure->newFormats[1],
+ closure->base,
+ &values[closure->len1],
+ closure->layout_variation_idx_map);
+
+ return_trace (true);
+ }
+
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c,
+ const ValueFormat *valueFormats,
+ const void *base) const
+ {
+ unsigned record1_len = valueFormats[0].get_len ();
+ unsigned record2_len = valueFormats[1].get_len ();
+ const hb_array_t<const Value> values_array = values.as_array (record1_len + record2_len);
+
+ if (valueFormats[0].has_device ())
+ valueFormats[0].collect_variation_indices (c, base, values_array.sub_array (0, record1_len));
+
+ if (valueFormats[1].has_device ())
+ valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len));
+ }
+
+ bool intersects (const hb_set_t& glyphset) const
+ {
+ return glyphset.has(secondGlyph);
+ }
+
+ const Value* get_values_1 () const
+ {
+ return &values[0];
+ }
+
+ const Value* get_values_2 (ValueFormat format1) const
+ {
+ return &values[format1.get_len ()];
+ }
+};
+
+
+}
+}
+}
+
+#endif // OT_LAYOUT_GPOS_PAIRVALUERECORD_HH
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh
index 57e146befd..702f578b3c 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh
@@ -45,10 +45,7 @@ struct SinglePos
ValueFormat new_format = src->get_value_format ();
if (glyph_val_iter_pairs)
- {
format = get_format (glyph_val_iter_pairs);
- new_format = src->get_value_format ().get_effective_format (+ glyph_val_iter_pairs | hb_map (hb_second));
- }
u.format = format;
switch (u.format) {
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh
index 8b7840ed0e..c0e7d29cea 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh
@@ -104,9 +104,11 @@ struct SinglePosFormat1
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
+ hb_set_t intersection;
+ (this+coverage).intersect_set (glyphset, intersection);
+
auto it =
- + hb_iter (this+coverage)
- | hb_filter (glyphset)
+ + hb_iter (intersection)
| hb_map_retains_sorting (glyph_map)
| hb_zip (hb_repeat (values.as_array (valueFormat.get_len ())))
;
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh
index 484f347468..a5dcb65359 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh
@@ -5,12 +5,13 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
+template <typename Types>
struct AlternateSet
{
protected:
- Array16Of<HBGlyphID16>
+ Array16Of<typename Types::HBGlyphID>
alternates; /* Array of alternate GlyphIDs--in
* arbitrary order */
public:
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh
index e5d999261f..37406179a2 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh
@@ -6,14 +6,17 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
struct AlternateSubst
{
protected:
union {
- HBUINT16 format; /* Format identifier */
- AlternateSubstFormat1 format1;
+ HBUINT16 format; /* Format identifier */
+ AlternateSubstFormat1_2<SmallTypes> format1;
+#ifndef HB_NO_BORING_EXPANSION
+ AlternateSubstFormat1_2<MediumTypes> format2;
+#endif
} u;
public:
@@ -24,10 +27,15 @@ struct AlternateSubst
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BORING_EXPANSION
+ case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#endif
default:return_trace (c->default_return_value ());
}
}
+ /* TODO This function is unused and not updated to 24bit GIDs. Should be done by using
+ * iterators. While at it perhaps using iterator of arrays of hb_codepoint_t instead. */
bool serialize (hb_serialize_context_t *c,
hb_sorted_array_t<const HBGlyphID16> glyphs,
hb_array_t<const unsigned int> alternate_len_list,
@@ -42,6 +50,9 @@ struct AlternateSubst
default:return_trace (false);
}
}
+
+ /* TODO subset() should choose format. */
+
};
}
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh
index af1cd7bedb..adec65d586 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh
@@ -6,20 +6,21 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
-struct AlternateSubstFormat1
+template <typename Types>
+struct AlternateSubstFormat1_2
{
protected:
HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
- Array16OfOffset16To<AlternateSet>
+ Array16Of<typename Types::template OffsetTo<AlternateSet<Types>>>
alternateSet; /* Array of AlternateSet tables
* ordered by Coverage Index */
public:
- DEFINE_SIZE_ARRAY (6, alternateSet);
+ DEFINE_SIZE_ARRAY (2 + 2 * Types::size, alternateSet);
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -39,9 +40,8 @@ struct AlternateSubstFormat1
| hb_filter (c->parent_active_glyphs (), hb_first)
| hb_map (hb_second)
| hb_map (hb_add (this))
- | hb_apply ([c] (const AlternateSet &_) { _.closure (c); })
+ | hb_apply ([c] (const AlternateSet<Types> &_) { _.closure (c); })
;
-
}
void closure_lookups (hb_closure_lookups_context_t *c) const {}
@@ -52,7 +52,7 @@ struct AlternateSubstFormat1
+ hb_zip (this+coverage, alternateSet)
| hb_map (hb_second)
| hb_map (hb_add (this))
- | hb_apply ([c] (const AlternateSet &_) { _.collect_glyphs (c); })
+ | hb_apply ([c] (const AlternateSet<Types> &_) { _.collect_glyphs (c); })
;
}
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ChainContextSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ChainContextSubst.hh
index bbb88b222f..08fd779f73 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ChainContextSubst.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ChainContextSubst.hh
@@ -7,7 +7,7 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
struct ChainContextSubst : ChainContext {};
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh
index f4c78a9f02..968bba0481 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh
@@ -6,7 +6,7 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t;
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ContextSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ContextSubst.hh
index 2af54e8ff4..9f8cb46b5e 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ContextSubst.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ContextSubst.hh
@@ -7,7 +7,7 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
struct ContextSubst : Context {};
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ExtensionSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ExtensionSubst.hh
index 40a3ff439f..831a7dfa2d 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ExtensionSubst.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ExtensionSubst.hh
@@ -7,7 +7,7 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
struct ExtensionSubst : Extension<ExtensionSubst>
{
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh
index 3f0c4b2ad9..c0ff098f49 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh
@@ -1,16 +1,15 @@
#ifndef OT_LAYOUT_GSUB_GSUB_HH
#define OT_LAYOUT_GSUB_GSUB_HH
-// TODO(garretrieger): move to new layout.
#include "../../../hb-ot-layout-gsubgpos.hh"
#include "Common.hh"
#include "SubstLookup.hh"
-using OT::Layout::GSUB::SubstLookup;
-
namespace OT {
+
+using Layout::GSUB_impl::SubstLookup;
+
namespace Layout {
-namespace GSUB {
/*
* GSUB -- Glyph Substitution
@@ -33,7 +32,10 @@ struct GSUB : GSUBGPOS
}
bool sanitize (hb_sanitize_context_t *c) const
- { return GSUBGPOS::sanitize<SubstLookup> (c); }
+ {
+ TRACE_SANITIZE (this);
+ return_trace (GSUBGPOS::sanitize<SubstLookup> (c));
+ }
HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
hb_face_t *face) const;
@@ -48,10 +50,9 @@ struct GSUB : GSUBGPOS
}
-}
-struct GSUB_accelerator_t : Layout::GSUB::GSUB::accelerator_t {
- GSUB_accelerator_t (hb_face_t *face) : Layout::GSUB::GSUB::accelerator_t (face) {}
+struct GSUB_accelerator_t : Layout::GSUB::accelerator_t {
+ GSUB_accelerator_t (hb_face_t *face) : Layout::GSUB::accelerator_t (face) {}
};
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh
index 0448d925d1..22ed65f858 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh
@@ -5,18 +5,20 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
+template <typename Types>
struct Ligature
{
protected:
- HBGlyphID16 ligGlyph; /* GlyphID of ligature to substitute */
- HeadlessArrayOf<HBGlyphID16>
- component; /* Array of component GlyphIDs--start
+ typename Types::HBGlyphID
+ ligGlyph; /* GlyphID of ligature to substitute */
+ HeadlessArrayOf<typename Types::HBGlyphID>
+ component; /* Array of component GlyphIDs--start
* with the second component--ordered
* in writing direction */
public:
- DEFINE_SIZE_ARRAY (4, component);
+ DEFINE_SIZE_ARRAY (Types::size + 2, component);
bool sanitize (hb_sanitize_context_t *c) const
{
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh
index 185b324b35..637cec7137 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh
@@ -6,12 +6,13 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
+template <typename Types>
struct LigatureSet
{
protected:
- Array16OfOffset16To<Ligature>
+ Array16OfOffset16To<Ligature<Types>>
ligature; /* Array LigatureSet tables
* ordered by preference */
public:
@@ -28,7 +29,7 @@ struct LigatureSet
return
+ hb_iter (ligature)
| hb_map (hb_add (this))
- | hb_map ([glyphs] (const Ligature &_) { return _.intersects (glyphs); })
+ | hb_map ([glyphs] (const Ligature<Types> &_) { return _.intersects (glyphs); })
| hb_any
;
}
@@ -37,7 +38,7 @@ struct LigatureSet
{
+ hb_iter (ligature)
| hb_map (hb_add (this))
- | hb_apply ([c] (const Ligature &_) { _.closure (c); })
+ | hb_apply ([c] (const Ligature<Types> &_) { _.closure (c); })
;
}
@@ -45,7 +46,7 @@ struct LigatureSet
{
+ hb_iter (ligature)
| hb_map (hb_add (this))
- | hb_apply ([c] (const Ligature &_) { _.collect_glyphs (c); })
+ | hb_apply ([c] (const Ligature<Types> &_) { _.collect_glyphs (c); })
;
}
@@ -54,7 +55,7 @@ struct LigatureSet
return
+ hb_iter (ligature)
| hb_map (hb_add (this))
- | hb_map ([c] (const Ligature &_) { return _.would_apply (c); })
+ | hb_map ([c] (const Ligature<Types> &_) { return _.would_apply (c); })
| hb_any
;
}
@@ -65,7 +66,7 @@ struct LigatureSet
unsigned int num_ligs = ligature.len;
for (unsigned int i = 0; i < num_ligs; i++)
{
- const Ligature &lig = this+ligature[i];
+ const auto &lig = this+ligature[i];
if (lig.apply (c)) return_trace (true);
}
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh
index a029bf5e9f..63707972a8 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh
@@ -6,14 +6,17 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
struct LigatureSubst
{
protected:
union {
- HBUINT16 format; /* Format identifier */
- LigatureSubstFormat1 format1;
+ HBUINT16 format; /* Format identifier */
+ LigatureSubstFormat1_2<SmallTypes> format1;
+#ifndef HB_NO_BORING_EXPANSION
+ LigatureSubstFormat1_2<MediumTypes> format2;
+#endif
} u;
public:
@@ -24,10 +27,16 @@ struct LigatureSubst
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BORING_EXPANSION
+ case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#endif
default:return_trace (c->default_return_value ());
}
}
+ /* TODO This function is only used by small GIDs, and not updated to 24bit GIDs. Should
+ * be done by using iterators. While at it perhaps using iterator of arrays of hb_codepoint_t
+ * instead. */
bool serialize (hb_serialize_context_t *c,
hb_sorted_array_t<const HBGlyphID16> first_glyphs,
hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
@@ -49,6 +58,9 @@ struct LigatureSubst
default:return_trace (false);
}
}
+
+ /* TODO subset() should choose format. */
+
};
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
index 19dfe98469..32b642c38a 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh
@@ -6,20 +6,21 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
-struct LigatureSubstFormat1
+template <typename Types>
+struct LigatureSubstFormat1_2
{
protected:
HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
- Array16OfOffset16To<LigatureSet>
+ Array16Of<typename Types::template OffsetTo<LigatureSet<Types>>>
ligatureSet; /* Array LigatureSet tables
* ordered by Coverage Index */
public:
- DEFINE_SIZE_ARRAY (6, ligatureSet);
+ DEFINE_SIZE_ARRAY (4 + Types::size, ligatureSet);
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -33,7 +34,7 @@ struct LigatureSubstFormat1
+ hb_zip (this+coverage, ligatureSet)
| hb_filter (*glyphs, hb_first)
| hb_map (hb_second)
- | hb_map ([this, glyphs] (const Offset16To<LigatureSet> &_)
+ | hb_map ([this, glyphs] (const typename Types::template OffsetTo<LigatureSet<Types>> &_)
{ return (this+_).intersects (glyphs); })
| hb_any
;
@@ -48,7 +49,7 @@ struct LigatureSubstFormat1
| hb_filter (c->parent_active_glyphs (), hb_first)
| hb_map (hb_second)
| hb_map (hb_add (this))
- | hb_apply ([c] (const LigatureSet &_) { _.closure (c); })
+ | hb_apply ([c] (const LigatureSet<Types> &_) { _.closure (c); })
;
}
@@ -62,7 +63,7 @@ struct LigatureSubstFormat1
+ hb_zip (this+coverage, ligatureSet)
| hb_map (hb_second)
| hb_map (hb_add (this))
- | hb_apply ([c] (const LigatureSet &_) { _.collect_glyphs (c); })
+ | hb_apply ([c] (const LigatureSet<Types> &_) { _.collect_glyphs (c); })
;
}
@@ -73,7 +74,7 @@ struct LigatureSubstFormat1
unsigned int index = (this+coverage).get_coverage (c->glyphs[0]);
if (likely (index == NOT_COVERED)) return false;
- const LigatureSet &lig_set = this+ligatureSet[index];
+ const auto &lig_set = this+ligatureSet[index];
return lig_set.would_apply (c);
}
@@ -84,7 +85,7 @@ struct LigatureSubstFormat1
unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
- const LigatureSet &lig_set = this+ligatureSet[index];
+ const auto &lig_set = this+ligatureSet[index];
return_trace (lig_set.apply (c));
}
@@ -128,7 +129,7 @@ struct LigatureSubstFormat1
hb_set_t new_coverage;
+ hb_zip (this+coverage, hb_iter (ligatureSet) | hb_map (hb_add (this)))
| hb_filter (glyphset, hb_first)
- | hb_filter ([&] (const LigatureSet& _) {
+ | hb_filter ([&] (const LigatureSet<Types>& _) {
return _.intersects (&glyphset);
}, hb_second)
| hb_map (hb_first)
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh
index b289175504..98f2f5fe7a 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh
@@ -6,14 +6,17 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
struct MultipleSubst
{
protected:
union {
- HBUINT16 format; /* Format identifier */
- MultipleSubstFormat1 format1;
+ HBUINT16 format; /* Format identifier */
+ MultipleSubstFormat1_2<SmallTypes> format1;
+#ifndef HB_NO_BORING_EXPANSION
+ MultipleSubstFormat1_2<MediumTypes> format2;
+#endif
} u;
public:
@@ -25,10 +28,15 @@ struct MultipleSubst
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BORING_EXPANSION
+ case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#endif
default:return_trace (c->default_return_value ());
}
}
+ /* TODO This function is unused and not updated to 24bit GIDs. Should be done by using
+ * iterators. While at it perhaps using iterator of arrays of hb_codepoint_t instead. */
bool serialize (hb_serialize_context_t *c,
hb_sorted_array_t<const HBGlyphID16> glyphs,
hb_array_t<const unsigned int> substitute_len_list,
@@ -43,6 +51,9 @@ struct MultipleSubst
default:return_trace (false);
}
}
+
+ /* TODO subset() should choose format. */
+
};
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubstFormat1.hh
index 54c6dc8478..89a04ec3b1 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubstFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubstFormat1.hh
@@ -6,20 +6,21 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
-struct MultipleSubstFormat1
+template <typename Types>
+struct MultipleSubstFormat1_2
{
protected:
HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
- Array16OfOffset16To<Sequence>
+ Array16Of<typename Types::template OffsetTo<Sequence<Types>>>
sequence; /* Array of Sequence tables
* ordered by Coverage Index */
public:
- DEFINE_SIZE_ARRAY (6, sequence);
+ DEFINE_SIZE_ARRAY (4 + Types::size, sequence);
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -39,7 +40,7 @@ struct MultipleSubstFormat1
| hb_filter (c->parent_active_glyphs (), hb_first)
| hb_map (hb_second)
| hb_map (hb_add (this))
- | hb_apply ([c] (const Sequence &_) { _.closure (c); })
+ | hb_apply ([c] (const Sequence<Types> &_) { _.closure (c); })
;
}
@@ -51,7 +52,7 @@ struct MultipleSubstFormat1
+ hb_zip (this+coverage, sequence)
| hb_map (hb_second)
| hb_map (hb_add (this))
- | hb_apply ([c] (const Sequence &_) { _.collect_glyphs (c); })
+ | hb_apply ([c] (const Sequence<Types> &_) { _.collect_glyphs (c); })
;
}
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh
index 435d80fd31..48e208efb9 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh
@@ -6,7 +6,7 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
struct ReverseChainSingleSubst
{
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
index 7a79a9df25..1d27df95dd 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
@@ -5,7 +5,7 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
struct ReverseChainSingleSubstFormat1
{
@@ -33,10 +33,10 @@ struct ReverseChainSingleSubstFormat1
TRACE_SANITIZE (this);
if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
return_trace (false);
- const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
+ const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
if (!lookahead.sanitize (c, this))
return_trace (false);
- const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
+ const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
return_trace (substitute.sanitize (c));
}
@@ -45,7 +45,7 @@ struct ReverseChainSingleSubstFormat1
if (!(this+coverage).intersects (glyphs))
return false;
- const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
+ const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
unsigned int count;
@@ -69,8 +69,8 @@ struct ReverseChainSingleSubstFormat1
{
if (!intersects (c->glyphs)) return;
- const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
- const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
+ const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
+ const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
+ hb_zip (this+coverage, substitute)
| hb_filter (c->parent_active_glyphs (), hb_first)
@@ -91,12 +91,12 @@ struct ReverseChainSingleSubstFormat1
for (unsigned int i = 0; i < count; i++)
if (unlikely (!(this+backtrack[i]).collect_coverage (c->before))) return;
- const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
+ const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
count = lookahead.len;
for (unsigned int i = 0; i < count; i++)
if (unlikely (!(this+lookahead[i]).collect_coverage (c->after))) return;
- const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
+ const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
count = substitute.len;
c->output->add_array (substitute.arrayZ, substitute.len);
}
@@ -115,8 +115,8 @@ struct ReverseChainSingleSubstFormat1
unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
- const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
- const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
+ const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
+ const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
if (unlikely (index >= substitute.len)) return_trace (false);
@@ -206,8 +206,8 @@ struct ReverseChainSingleSubstFormat1
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
- const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
- const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
+ const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack);
+ const auto &substitute = StructAfter<decltype (substituteX)> (lookahead);
auto it =
+ hb_zip (this+coverage, substitute)
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh
index ebd451e6ba..c5cd15bb23 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh
@@ -5,12 +5,13 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
+template <typename Types>
struct Sequence
{
protected:
- Array16Of<HBGlyphID16>
+ Array16Of<typename Types::HBGlyphID>
substitute; /* String of GlyphIDs to substitute */
public:
DEFINE_SIZE_ARRAY (2, substitute);
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh
index 786428fe45..6942e6997f 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh
@@ -7,15 +7,19 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
struct SingleSubst
{
protected:
union {
- HBUINT16 format; /* Format identifier */
- SingleSubstFormat1 format1;
- SingleSubstFormat2 format2;
+ HBUINT16 format; /* Format identifier */
+ SingleSubstFormat1_3<SmallTypes> format1;
+ SingleSubstFormat2_4<SmallTypes> format2;
+#ifndef HB_NO_BORING_EXPANSION
+ SingleSubstFormat1_3<MediumTypes> format3;
+ SingleSubstFormat2_4<MediumTypes> format4;
+#endif
} u;
public:
@@ -28,6 +32,10 @@ struct SingleSubst
switch (u.format) {
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
+ case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
+#endif
default:return_trace (c->default_return_value ());
}
}
@@ -45,11 +53,24 @@ struct SingleSubst
if (glyphs)
{
format = 1;
+ hb_codepoint_t mask = 0xFFFFu;
+
+#ifndef HB_NO_BORING_EXPANSION
+ if (+ glyphs
+ | hb_map_retains_sorting (hb_first)
+ | hb_filter ([] (hb_codepoint_t gid) { return gid > 0xFFFFu; }))
+ {
+ format += 2;
+ mask = 0xFFFFFFu;
+ }
+#endif
+
auto get_delta = [=] (hb_codepoint_pair_t _)
- { return (unsigned) (_.second - _.first) & 0xFFFF; };
+ { return (unsigned) (_.second - _.first) & mask; };
delta = get_delta (*glyphs);
- if (!hb_all (++(+glyphs), delta, get_delta)) format = 2;
+ if (!hb_all (++(+glyphs), delta, get_delta)) format += 1;
}
+
u.format = format;
switch (u.format) {
case 1: return_trace (u.format1.serialize (c,
@@ -57,6 +78,13 @@ struct SingleSubst
| hb_map_retains_sorting (hb_first),
delta));
case 2: return_trace (u.format2.serialize (c, glyphs));
+#ifndef HB_NO_BORING_EXPANSION
+ case 3: return_trace (u.format3.serialize (c,
+ + glyphs
+ | hb_map_retains_sorting (hb_first),
+ delta));
+ case 4: return_trace (u.format4.serialize (c, glyphs));
+#endif
default:return_trace (false);
}
}
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh
index 3c6b2954ce..dd44595741 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh
@@ -5,20 +5,22 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
-struct SingleSubstFormat1
+template <typename Types>
+struct SingleSubstFormat1_3
{
protected:
HBUINT16 format; /* Format identifier--format = 1 */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
- HBUINT16 deltaGlyphID; /* Add to original GlyphID to get
+ typename Types::HBUINT
+ deltaGlyphID; /* Add to original GlyphID to get
* substitute GlyphID, modulo 0x10000 */
public:
- DEFINE_SIZE_STATIC (6);
+ DEFINE_SIZE_STATIC (2 + 2 * Types::size);
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -26,6 +28,9 @@ struct SingleSubstFormat1
return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
}
+ hb_codepoint_t get_mask () const
+ { return (1 << (8 * Types::size)) - 1; }
+
bool intersects (const hb_set_t *glyphs) const
{ return (this+coverage).intersects (glyphs); }
@@ -34,14 +39,16 @@ struct SingleSubstFormat1
void closure (hb_closure_context_t *c) const
{
- unsigned d = deltaGlyphID;
+ hb_codepoint_t d = deltaGlyphID;
+ hb_codepoint_t mask = get_mask ();
- + hb_iter (this+coverage)
- | hb_filter (c->parent_active_glyphs ())
- | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
+ hb_set_t intersection;
+ (this+coverage).intersect_set (c->parent_active_glyphs (), intersection);
+
+ + hb_iter (intersection)
+ | hb_map ([d, mask] (hb_codepoint_t g) { return (g + d) & mask; })
| hb_sink (c->output)
;
-
}
void closure_lookups (hb_closure_lookups_context_t *c) const {}
@@ -49,9 +56,11 @@ struct SingleSubstFormat1
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
- unsigned d = deltaGlyphID;
+ hb_codepoint_t d = deltaGlyphID;
+ hb_codepoint_t mask = get_mask ();
+
+ hb_iter (this+coverage)
- | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
+ | hb_map ([d, mask] (hb_codepoint_t g) { return (g + d) & mask; })
| hb_sink (c->output)
;
}
@@ -68,9 +77,11 @@ struct SingleSubstFormat1
unsigned int index = (this+coverage).get_coverage (glyph_id);
if (likely (index == NOT_COVERED)) return_trace (false);
- /* According to the Adobe Annotated OpenType Suite, result is always
- * limited to 16bit. */
- glyph_id = (glyph_id + deltaGlyphID) & 0xFFFFu;
+ hb_codepoint_t d = deltaGlyphID;
+ hb_codepoint_t mask = get_mask ();
+
+ glyph_id = (glyph_id + d) & mask;
+
c->replace_glyph (glyph_id);
return_trace (true);
@@ -95,14 +106,17 @@ struct SingleSubstFormat1
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
- hb_codepoint_t delta = deltaGlyphID;
+ hb_codepoint_t d = deltaGlyphID;
+ hb_codepoint_t mask = get_mask ();
+
+ hb_set_t intersection;
+ (this+coverage).intersect_set (glyphset, intersection);
auto it =
- + hb_iter (this+coverage)
- | hb_filter (glyphset)
- | hb_map_retains_sorting ([&] (hb_codepoint_t g) {
+ + hb_iter (intersection)
+ | hb_map_retains_sorting ([d, mask] (hb_codepoint_t g) {
return hb_codepoint_pair_t (g,
- (g + delta) & 0xFFFF); })
+ (g + d) & mask); })
| hb_filter (glyphset, hb_second)
| hb_map_retains_sorting ([&] (hb_codepoint_pair_t p) -> hb_codepoint_pair_t
{ return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh
index df75bb52bb..386419a2a5 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh
@@ -5,21 +5,22 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
-struct SingleSubstFormat2
+template <typename Types>
+struct SingleSubstFormat2_4
{
protected:
HBUINT16 format; /* Format identifier--format = 2 */
- Offset16To<Coverage>
+ typename Types::template OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
- Array16Of<HBGlyphID16>
+ Array16Of<typename Types::HBGlyphID>
substitute; /* Array of substitute
* GlyphIDs--ordered by Coverage Index */
public:
- DEFINE_SIZE_ARRAY (6, substitute);
+ DEFINE_SIZE_ARRAY (4 + Types::size, substitute);
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -103,7 +104,7 @@ struct SingleSubstFormat2
+ hb_zip (this+coverage, substitute)
| hb_filter (glyphset, hb_first)
| hb_filter (glyphset, hb_second)
- | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID16 &> p) -> hb_codepoint_pair_t
+ | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const typename Types::HBGlyphID &> p) -> hb_codepoint_pair_t
{ return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
;
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh
index 8fb3b55097..320685b868 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh
@@ -6,7 +6,7 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
struct SubstLookup : Lookup
{
@@ -25,7 +25,7 @@ struct SubstLookup : Lookup
{
unsigned int type = get_type ();
if (unlikely (type == SubTable::Extension))
- return reinterpret_cast<const ExtensionSubst &> (get_subtable (0)).is_reverse ();
+ return get_subtable (0).u.extension.is_reverse ();
return lookup_type_is_reverse (type);
}
@@ -98,10 +98,15 @@ struct SubstLookup : Lookup
return dispatch (c);
}
+ template<typename Glyphs, typename Substitutes,
+ hb_requires (hb_is_sorted_source_of (Glyphs,
+ const hb_codepoint_t) &&
+ hb_is_source_of (Substitutes,
+ const hb_codepoint_t))>
bool serialize_single (hb_serialize_context_t *c,
uint32_t lookup_props,
- hb_sorted_array_t<const HBGlyphID16> glyphs,
- hb_array_t<const HBGlyphID16> substitutes)
+ Glyphs glyphs,
+ Substitutes substitutes)
{
TRACE_SERIALIZE (this);
if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false);
diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookupSubTable.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookupSubTable.hh
index 53e963e2a2..a525fba039 100644
--- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookupSubTable.hh
+++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookupSubTable.hh
@@ -13,7 +13,7 @@
namespace OT {
namespace Layout {
-namespace GSUB {
+namespace GSUB_impl {
struct SubstLookupSubTable
{
diff --git a/thirdparty/harfbuzz/src/OT/Layout/types.hh b/thirdparty/harfbuzz/src/OT/Layout/types.hh
new file mode 100644
index 0000000000..6a43403e94
--- /dev/null
+++ b/thirdparty/harfbuzz/src/OT/Layout/types.hh
@@ -0,0 +1,66 @@
+/*
+ * Copyright © 2007,2008,2009 Red Hat, Inc.
+ * Copyright © 2010,2012 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod, Garret Rieger
+ */
+
+#ifndef OT_LAYOUT_TYPES_HH
+#define OT_LAYOUT_TYPES_HH
+
+namespace OT {
+namespace Layout {
+
+struct SmallTypes {
+ static constexpr unsigned size = 2;
+ using large_int = uint32_t;
+ using HBUINT = HBUINT16;
+ using HBGlyphID = HBGlyphID16;
+ using Offset = Offset16;
+ template <typename Type, bool has_null=true>
+ using OffsetTo = OT::Offset16To<Type, has_null>;
+ template <typename Type>
+ using ArrayOf = OT::Array16Of<Type>;
+ template <typename Type>
+ using SortedArrayOf = OT::SortedArray16Of<Type>;
+};
+
+struct MediumTypes {
+ static constexpr unsigned size = 3;
+ using large_int = uint64_t;
+ using HBUINT = HBUINT24;
+ using HBGlyphID = HBGlyphID24;
+ using Offset = Offset24;
+ template <typename Type, bool has_null=true>
+ using OffsetTo = OT::Offset24To<Type, has_null>;
+ template <typename Type>
+ using ArrayOf = OT::Array24Of<Type>;
+ template <typename Type>
+ using SortedArrayOf = OT::SortedArray24Of<Type>;
+};
+
+}
+}
+
+#endif /* OT_LAYOUT_TYPES_HH */
diff --git a/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh
index c145beaa49..abe4c8330c 100644
--- a/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh
+++ b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh
@@ -25,13 +25,16 @@ struct CompositeGlyphRecord
USE_MY_METRICS = 0x0200,
OVERLAP_COMPOUND = 0x0400,
SCALED_COMPONENT_OFFSET = 0x0800,
- UNSCALED_COMPONENT_OFFSET = 0x1000
+ UNSCALED_COMPONENT_OFFSET = 0x1000,
+ GID_IS_24BIT = 0x2000
};
public:
unsigned int get_size () const
{
unsigned int size = min_size;
+ /* glyphIndex is 24bit instead of 16bit */
+ if (flags & GID_IS_24BIT) size += HBGlyphID24::static_size - HBGlyphID16::static_size;
/* arg1 and 2 are int16 */
if (flags & ARG_1_AND_2_ARE_WORDS) size += 4;
/* arg1 and 2 are int8 */
@@ -60,7 +63,11 @@ struct CompositeGlyphRecord
bool is_anchored () const { return !(flags & ARGS_ARE_XY_VALUES); }
void get_anchor_points (unsigned int &point1, unsigned int &point2) const
{
- const HBUINT8 *p = &StructAfter<const HBUINT8> (glyphIndex);
+ const auto *p = &StructAfter<const HBUINT8> (flags);
+ if (flags & GID_IS_24BIT)
+ p += HBGlyphID24::static_size;
+ else
+ p += HBGlyphID16::static_size;
if (flags & ARG_1_AND_2_ARE_WORDS)
{
point1 = ((const HBUINT16 *) p)[0];
@@ -101,8 +108,12 @@ struct CompositeGlyphRecord
matrix[0] = matrix[3] = 1.f;
matrix[1] = matrix[2] = 0.f;
+ const auto *p = &StructAfter<const HBINT8> (flags);
+ if (flags & GID_IS_24BIT)
+ p += HBGlyphID24::static_size;
+ else
+ p += HBGlyphID16::static_size;
int tx, ty;
- const HBINT8 *p = &StructAfter<const HBINT8> (glyphIndex);
if (flags & ARG_1_AND_2_ARE_WORDS)
{
tx = *(const HBINT16 *) p;
@@ -145,8 +156,25 @@ struct CompositeGlyphRecord
}
public:
+ hb_codepoint_t get_gid () const
+ {
+ if (flags & GID_IS_24BIT)
+ return StructAfter<const HBGlyphID24> (flags);
+ else
+ return StructAfter<const HBGlyphID16> (flags);
+ }
+ void set_gid (hb_codepoint_t gid)
+ {
+ if (flags & GID_IS_24BIT)
+ StructAfter<HBGlyphID24> (flags) = gid;
+ else
+ /* TODO assert? */
+ StructAfter<HBGlyphID16> (flags) = gid;
+ }
+
+ protected:
HBUINT16 flags;
- HBGlyphID16 glyphIndex;
+ HBUINT24 pad;
public:
DEFINE_SIZE_MIN (4);
};
diff --git a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh
index 2199d2c48b..3efe538f37 100644
--- a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh
+++ b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh
@@ -105,19 +105,21 @@ struct Glyph
if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false;
hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
{
- int h_delta = (int) header->xMin -
- glyf_accelerator.hmtx->get_side_bearing (gid);
+ int lsb = 0;
+ int h_delta = glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ?
+ (int) header->xMin - lsb : 0;
+ int tsb = 0;
int v_orig = (int) header->yMax +
#ifndef HB_NO_VERTICAL
- glyf_accelerator.vmtx->get_side_bearing (gid)
+ ((void) glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb)
#else
0
#endif
;
- unsigned h_adv = glyf_accelerator.hmtx->get_advance (gid);
+ unsigned h_adv = glyf_accelerator.hmtx->get_advance_without_var_unscaled (gid);
unsigned v_adv =
#ifndef HB_NO_VERTICAL
- glyf_accelerator.vmtx->get_advance (gid)
+ glyf_accelerator.vmtx->get_advance_without_var_unscaled (gid)
#else
- font->face->get_upem ()
#endif
@@ -144,7 +146,7 @@ struct Glyph
for (auto &item : get_composite_iterator ())
{
comp_points.reset ();
- if (unlikely (!glyf_accelerator.glyph_for_gid (item.glyphIndex)
+ if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
.get_points (font, glyf_accelerator, comp_points,
phantom_only, depth + 1)))
return false;
@@ -198,11 +200,11 @@ struct Glyph
return !all_points.in_error ();
}
- bool get_extents (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator,
- hb_glyph_extents_t *extents) const
+ bool get_extents_without_var_scaled (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator,
+ hb_glyph_extents_t *extents) const
{
if (type == EMPTY) return true; /* Empty glyph; zero extents. */
- return header->get_extents (font, glyf_accelerator, gid, extents);
+ return header->get_extents_without_var_scaled (font, glyf_accelerator, gid, extents);
}
hb_bytes_t get_bytes () const { return bytes; }
diff --git a/thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh b/thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh
index 792bd5478f..e4a9168b79 100644
--- a/thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh
+++ b/thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh
@@ -14,12 +14,14 @@ struct GlyphHeader
bool has_data () const { return numberOfContours; }
template <typename accelerator_t>
- bool get_extents (hb_font_t *font, const accelerator_t &glyf_accelerator,
- hb_codepoint_t gid, hb_glyph_extents_t *extents) const
+ bool get_extents_without_var_scaled (hb_font_t *font, const accelerator_t &glyf_accelerator,
+ hb_codepoint_t gid, hb_glyph_extents_t *extents) const
{
/* Undocumented rasterizer behavior: shift glyph to the left by (lsb - xMin), i.e., xMin = lsb */
/* extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); */
- extents->x_bearing = font->em_scale_x (glyf_accelerator.hmtx->get_side_bearing (gid));
+ int lsb = hb_min (xMin, xMax);
+ (void) glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb);
+ extents->x_bearing = font->em_scale_x (lsb);
extents->y_bearing = font->em_scale_y (hb_max (yMin, yMax));
extents->width = font->em_scale_x (hb_max (xMin, xMax) - hb_min (xMin, xMax));
extents->height = font->em_scale_y (hb_min (yMin, yMax) - hb_max (yMin, yMax));
diff --git a/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh
index ebe4372047..7ae8fe3078 100644
--- a/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh
+++ b/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh
@@ -42,8 +42,8 @@ struct SubsetGlyph
for (auto &_ : Glyph (dest_glyph).get_composite_iterator ())
{
hb_codepoint_t new_gid;
- if (plan->new_gid_for_old_gid (_.glyphIndex, &new_gid))
- const_cast<CompositeGlyphRecord &> (_).glyphIndex = new_gid;
+ if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid))
+ const_cast<CompositeGlyphRecord &> (_).set_gid (new_gid);
}
if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
diff --git a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh
index f74513cb96..bcaf44fc1e 100644
--- a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh
+++ b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh
@@ -194,6 +194,7 @@ struct glyf_accelerator_t
hb_font_t *font;
hb_glyph_extents_t *extents;
contour_point_t *phantoms;
+ bool scaled;
struct contour_bounds_t
{
@@ -209,7 +210,7 @@ struct glyf_accelerator_t
bool empty () const { return (min_x >= max_x) || (min_y >= max_y); }
- void get_extents (hb_font_t *font, hb_glyph_extents_t *extents)
+ void get_extents (hb_font_t *font, hb_glyph_extents_t *extents, bool scaled)
{
if (unlikely (empty ()))
{
@@ -219,26 +220,37 @@ struct glyf_accelerator_t
extents->y_bearing = 0;
return;
}
- extents->x_bearing = font->em_scalef_x (min_x);
- extents->width = font->em_scalef_x (max_x) - extents->x_bearing;
- extents->y_bearing = font->em_scalef_y (max_y);
- extents->height = font->em_scalef_y (min_y) - extents->y_bearing;
+ if (scaled)
+ {
+ extents->x_bearing = font->em_scalef_x (min_x);
+ extents->width = font->em_scalef_x (max_x) - extents->x_bearing;
+ extents->y_bearing = font->em_scalef_y (max_y);
+ extents->height = font->em_scalef_y (min_y) - extents->y_bearing;
+ }
+ else
+ {
+ extents->x_bearing = roundf (min_x);
+ extents->width = roundf (max_x - extents->x_bearing);
+ extents->y_bearing = roundf (max_y);
+ extents->height = roundf (min_y - extents->y_bearing);
+ }
}
protected:
float min_x, min_y, max_x, max_y;
} bounds;
- points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_)
+ points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_, bool scaled_)
{
font = font_;
extents = extents_;
phantoms = phantoms_;
+ scaled = scaled_;
if (extents) bounds = contour_bounds_t ();
}
void consume_point (const contour_point_t &point) { bounds.add (point); }
- void points_end () { bounds.get_extents (font, extents); }
+ void points_end () { bounds.get_extents (font, extents, scaled); }
bool is_consuming_contour_points () { return extents; }
contour_point_t *get_phantoms_sink () { return phantoms; }
@@ -246,22 +258,22 @@ struct glyf_accelerator_t
public:
unsigned
- get_advance_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
+ get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
{
if (unlikely (gid >= num_glyphs)) return 0;
bool success = false;
contour_point_t phantoms[glyf_impl::PHANTOM_COUNT];
- if (likely (font->num_coords == gvar->get_axis_count ()))
- success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms));
+ if (font->num_coords)
+ success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false));
if (unlikely (!success))
return
#ifndef HB_NO_VERTICAL
- is_vertical ? vmtx->get_advance (gid) :
+ is_vertical ? vmtx->get_advance_without_var_unscaled (gid) :
#endif
- hmtx->get_advance (gid);
+ hmtx->get_advance_without_var_unscaled (gid);
float result = is_vertical
? phantoms[glyf_impl::PHANTOM_TOP].y - phantoms[glyf_impl::PHANTOM_BOTTOM].y
@@ -269,23 +281,20 @@ struct glyf_accelerator_t
return hb_clamp (roundf (result), 0.f, (float) UINT_MAX / 2);
}
- int get_side_bearing_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
+ bool get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical, int *lsb) const
{
- if (unlikely (gid >= num_glyphs)) return 0;
+ if (unlikely (gid >= num_glyphs)) return false;
hb_glyph_extents_t extents;
contour_point_t phantoms[glyf_impl::PHANTOM_COUNT];
- if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms))))
- return
-#ifndef HB_NO_VERTICAL
- is_vertical ? vmtx->get_side_bearing (gid) :
-#endif
- hmtx->get_side_bearing (gid);
+ if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false))))
+ return false;
- return is_vertical
- ? ceilf (phantoms[glyf_impl::PHANTOM_TOP].y) - extents.y_bearing
- : floorf (phantoms[glyf_impl::PHANTOM_LEFT].x);
+ *lsb = is_vertical
+ ? roundf (phantoms[glyf_impl::PHANTOM_TOP].y) - extents.y_bearing
+ : roundf (phantoms[glyf_impl::PHANTOM_LEFT].x);
+ return true;
}
#endif
@@ -296,9 +305,9 @@ struct glyf_accelerator_t
#ifndef HB_NO_VAR
if (font->num_coords)
- return get_points (font, gid, points_aggregator_t (font, extents, nullptr));
+ return get_points (font, gid, points_aggregator_t (font, extents, nullptr, true));
#endif
- return glyph_for_gid (gid).get_extents (font, *this, extents);
+ return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents);
}
const glyf_impl::Glyph