summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2019-11-11 15:10:08 +0100
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2020-03-04 08:28:04 +0100
commitfb2f42b6044fe4673e71f3d12082b53c9f3182cd (patch)
treed2f579c0362be1def50d957bc4e46eb27ea6198a /src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh
parent4724dfff627f3cd3754f5d4a827c6b6790a89955 (diff)
Update to Harfbuzz 2.6.4
Quite a big change since it has been several years since the last update. This drops the Harfbuzz source on top of the existing code in Qt, and does the following additional changes: 1. Deletes old source files that have been removed upstream (everything named foo-private.hh is now renamed to just foo.hh for instance). 2. Added a header guard to config.h because it may be double-included. 3. Implement a memory barrier needed by hb-atomic.hh. 4. Changed the signature of hb_atomic_int_impl_add() to take a pointer to match new upstream. 5. Updated .pro file to include new files and removed old. 6. Updated qt_attribution.json 7. No longer disable deprecated APIs since hb_ot_tags_from_script() is now deprecated and is used from Qt code. 8. Updated and applied the patch in patches/ for CoreText. 9. Updated tst_qtextscriptengine::thaiWithZWJ() according to changes in Harfbuzz and disabled it for system-harfbuzz, since this may be an older version of harfbuzz depending on the system. Fixes: QTBUG-79606 Change-Id: I3f057a43ff44ee416628b75ef12fb1a221f31910 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh')
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh474
1 files changed, 217 insertions, 257 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh
index e07faca63f..36e5a358e6 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-kern-table.hh
@@ -27,365 +27,325 @@
#ifndef HB_OT_KERN_TABLE_HH
#define HB_OT_KERN_TABLE_HH
-#include "hb-open-type-private.hh"
-
-namespace OT {
+#include "hb-aat-layout-kerx-table.hh"
/*
* kern -- Kerning
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/kern
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html
*/
-
#define HB_OT_TAG_kern HB_TAG('k','e','r','n')
-struct hb_glyph_pair_t
-{
- hb_codepoint_t left;
- hb_codepoint_t right;
-};
-
-struct KernPair
-{
- inline int get_kerning (void) const
- { return value; }
-
- inline int cmp (const hb_glyph_pair_t &o) const
- {
- int ret = left.cmp (o.left);
- if (ret) return ret;
- return right.cmp (o.right);
- }
- inline bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
- }
+namespace OT {
- protected:
- GlyphID left;
- GlyphID right;
- FWORD value;
- public:
- DEFINE_SIZE_STATIC (6);
-};
-struct KernSubTableFormat0
+template <typename KernSubTableHeader>
+struct KernSubTableFormat3
{
- inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
+ int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{
- hb_glyph_pair_t pair = {left, right};
- int i = pairs.bsearch (pair);
- if (i == -1)
+ hb_array_t<const FWORD> kernValue = kernValueZ.as_array (kernValueCount);
+ hb_array_t<const HBUINT8> leftClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (kernValue).as_array (glyphCount);
+ hb_array_t<const HBUINT8> rightClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (leftClass).as_array (glyphCount);
+ hb_array_t<const HBUINT8> kernIndex = StructAfter<const UnsizedArrayOf<HBUINT8>> (rightClass).as_array (leftClassCount * rightClassCount);
+
+ unsigned int leftC = leftClass[left];
+ unsigned int rightC = rightClass[right];
+ if (unlikely (leftC >= leftClassCount || rightC >= rightClassCount))
return 0;
- return pairs[i].get_kerning ();
+ unsigned int i = leftC * rightClassCount + rightC;
+ return kernValue[kernIndex[i]];
}
- inline bool sanitize (hb_sanitize_context_t *c) const
+ bool apply (AAT::hb_aat_apply_context_t *c) const
{
- TRACE_SANITIZE (this);
- return_trace (pairs.sanitize (c));
- }
+ TRACE_APPLY (this);
- protected:
- BinSearchArrayOf<KernPair> pairs; /* Array of kerning pairs. */
- public:
- DEFINE_SIZE_ARRAY (8, pairs);
-};
+ if (!c->plan->requested_kerning)
+ return false;
-struct KernClassTable
-{
- inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; }
-
- inline bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (firstGlyph.sanitize (c) && classes.sanitize (c));
- }
+ if (header.coverage & header.Backwards)
+ return false;
- protected:
- UINT16 firstGlyph; /* First glyph in class range. */
- ArrayOf<UINT16> classes; /* Glyph classes. */
- public:
- DEFINE_SIZE_ARRAY (4, classes);
-};
+ hb_kern_machine_t<KernSubTableFormat3> machine (*this, header.coverage & header.CrossStream);
+ machine.kern (c->font, c->buffer, c->plan->kern_mask);
-struct KernSubTableFormat2
-{
- inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
- {
- unsigned int l = (this+leftClassTable).get_class (left);
- unsigned int r = (this+leftClassTable).get_class (left);
- unsigned int offset = l * rowWidth + r * sizeof (FWORD);
- const FWORD *arr = &(this+array);
- if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
- return 0;
- const FWORD *v = &StructAtOffset<FWORD> (arr, offset);
- if (unlikely ((const void *) v < (const void *) arr || (const void *) (v + 1) > (const void *) end))
- return 0;
- return *v;
+ return_trace (true);
}
- inline bool sanitize (hb_sanitize_context_t *c) const
+ bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (rowWidth.sanitize (c) &&
- leftClassTable.sanitize (c, this) &&
- rightClassTable.sanitize (c, this) &&
- array.sanitize (c, this));
+ return_trace (c->check_struct (this) &&
+ c->check_range (kernValueZ,
+ kernValueCount * sizeof (FWORD) +
+ glyphCount * 2 +
+ leftClassCount * rightClassCount));
}
protected:
- UINT16 rowWidth; /* The width, in bytes, of a row in the table. */
- OffsetTo<KernClassTable>
- leftClassTable; /* Offset from beginning of this subtable to
- * left-hand class table. */
- OffsetTo<KernClassTable>
- rightClassTable;/* Offset from beginning of this subtable to
- * right-hand class table. */
- OffsetTo<FWORD>
- array; /* Offset from beginning of this subtable to
- * the start of the kerning array. */
+ KernSubTableHeader header;
+ HBUINT16 glyphCount; /* The number of glyphs in this font. */
+ HBUINT8 kernValueCount; /* The number of kerning values. */
+ HBUINT8 leftClassCount; /* The number of left-hand classes. */
+ HBUINT8 rightClassCount;/* The number of right-hand classes. */
+ HBUINT8 flags; /* Set to zero (reserved for future use). */
+ UnsizedArrayOf<FWORD> kernValueZ; /* The kerning values.
+ * Length kernValueCount. */
+#if 0
+ UnsizedArrayOf<HBUINT8>leftClass; /* The left-hand classes.
+ * Length glyphCount. */
+ UnsizedArrayOf<HBUINT8>rightClass; /* The right-hand classes.
+ * Length glyphCount. */
+ UnsizedArrayOf<HBUINT8>kernIndex; /* The indices into the kernValue array.
+ * Length leftClassCount * rightClassCount */
+#endif
public:
- DEFINE_SIZE_MIN (8);
+ DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 6, kernValueZ);
};
+template <typename KernSubTableHeader>
struct KernSubTable
{
- inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end, unsigned int format) const
+ unsigned int get_size () const { return u.header.length; }
+ unsigned int get_type () const { return u.header.format; }
+
+ int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{
- switch (format) {
+ switch (get_type ()) {
+ /* This method hooks up to hb_font_t's get_h_kerning. Only support Format0. */
case 0: return u.format0.get_kerning (left, right);
- case 2: return u.format2.get_kerning (left, right, end);
default:return 0;
}
}
- inline bool sanitize (hb_sanitize_context_t *c, unsigned int format) const
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{
- TRACE_SANITIZE (this);
- switch (format) {
- case 0: return_trace (u.format0.sanitize (c));
- case 2: return_trace (u.format2.sanitize (c));
- default:return_trace (true);
+ unsigned int subtable_type = get_type ();
+ TRACE_DISPATCH (this, subtable_type);
+ switch (subtable_type) {
+ case 0: return_trace (c->dispatch (u.format0));
+#ifndef HB_NO_AAT_SHAPE
+ case 1: return_trace (u.header.apple ? c->dispatch (u.format1, hb_forward<Ts> (ds)...) : c->default_return_value ());
+#endif
+ case 2: return_trace (c->dispatch (u.format2));
+#ifndef HB_NO_AAT_SHAPE
+ case 3: return_trace (u.header.apple ? c->dispatch (u.format3, hb_forward<Ts> (ds)...) : c->default_return_value ());
+#endif
+ default: return_trace (c->default_return_value ());
}
}
- protected:
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!u.header.sanitize (c) ||
+ u.header.length < u.header.min_size ||
+ !c->check_range (this, u.header.length))) return_trace (false);
+
+ return_trace (dispatch (c));
+ }
+
+ public:
union {
- KernSubTableFormat0 format0;
- KernSubTableFormat2 format2;
+ KernSubTableHeader header;
+ AAT::KerxSubTableFormat0<KernSubTableHeader> format0;
+ AAT::KerxSubTableFormat1<KernSubTableHeader> format1;
+ AAT::KerxSubTableFormat2<KernSubTableHeader> format2;
+ KernSubTableFormat3<KernSubTableHeader> format3;
} u;
public:
- DEFINE_SIZE_MIN (0);
+ DEFINE_SIZE_MIN (KernSubTableHeader::static_size);
};
-template <typename T>
-struct KernSubTableWrapper
+struct KernOTSubTableHeader
{
- /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
- inline const T* thiz (void) const { return static_cast<const T *> (this); }
+ static constexpr bool apple = false;
+ typedef AAT::ObsoleteTypes Types;
- inline bool is_horizontal (void) const
- { return (thiz()->coverage & T::COVERAGE_CHECK_FLAGS) == T::COVERAGE_CHECK_HORIZONTAL; }
+ unsigned tuple_count () const { return 0; }
+ bool is_horizontal () const { return (coverage & Horizontal); }
- inline bool is_override (void) const
- { return bool (thiz()->coverage & T::COVERAGE_OVERRIDE_FLAG); }
-
- inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
- { return thiz()->subtable.get_kerning (left, right, end, thiz()->format); }
-
- inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
- { return is_horizontal () ? get_kerning (left, right, end) : 0; }
-
- inline unsigned int get_size (void) const { return thiz()->length; }
+ enum Coverage
+ {
+ Horizontal = 0x01u,
+ Minimum = 0x02u,
+ CrossStream = 0x04u,
+ Override = 0x08u,
+
+ /* Not supported: */
+ Backwards = 0x00u,
+ Variation = 0x00u,
+ };
- inline bool sanitize (hb_sanitize_context_t *c) const
+ bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (c->check_struct (thiz()) &&
- thiz()->length >= thiz()->min_size &&
- c->check_array (thiz(), 1, thiz()->length) &&
- thiz()->subtable.sanitize (c, thiz()->format));
+ return_trace (c->check_struct (this));
}
+
+ public:
+ HBUINT16 versionZ; /* Unused. */
+ HBUINT16 length; /* Length of the subtable (including this header). */
+ HBUINT8 format; /* Subtable format. */
+ HBUINT8 coverage; /* Coverage bits. */
+ public:
+ DEFINE_SIZE_STATIC (6);
};
-template <typename T>
-struct KernTable
+struct KernOT : AAT::KerxTable<KernOT>
{
- /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
- inline const T* thiz (void) const { return static_cast<const T *> (this); }
+ friend struct AAT::KerxTable<KernOT>;
- inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
- {
- int v = 0;
- const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (thiz()->data);
- unsigned int count = thiz()->nTables;
- for (unsigned int i = 0; i < count; i++)
- {
- if (st->is_override ())
- v = 0;
- v += st->get_h_kerning (left, right, table_length + (const char *) this);
- st = &StructAfter<typename T::SubTableWrapper> (*st);
- }
- return v;
- }
+ static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
+ static constexpr unsigned minVersion = 0u;
- inline bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- if (unlikely (!c->check_struct (thiz()) ||
- thiz()->version != T::VERSION))
- return_trace (false);
-
- const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (thiz()->data);
- unsigned int count = thiz()->nTables;
- for (unsigned int i = 0; i < count; i++)
- {
- if (unlikely (!st->sanitize (c)))
- return_trace (false);
- st = &StructAfter<typename T::SubTableWrapper> (*st);
- }
+ typedef KernOTSubTableHeader SubTableHeader;
+ typedef SubTableHeader::Types Types;
+ typedef KernSubTable<SubTableHeader> SubTable;
- return_trace (true);
- }
+ protected:
+ HBUINT16 version; /* Version--0x0000u */
+ HBUINT16 tableCount; /* Number of subtables in the kerning table. */
+ SubTable firstSubTable; /* Subtables. */
+ public:
+ DEFINE_SIZE_MIN (4);
};
-struct KernOT : KernTable<KernOT>
+
+struct KernAATSubTableHeader
{
- friend struct KernTable<KernOT>;
+ static constexpr bool apple = true;
+ typedef AAT::ObsoleteTypes Types;
- static const uint16_t VERSION = 0x0000u;
+ unsigned tuple_count () const { return 0; }
+ bool is_horizontal () const { return !(coverage & Vertical); }
- struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
+ enum Coverage
{
- friend struct KernSubTableWrapper<SubTableWrapper>;
-
- enum coverage_flags_t {
- COVERAGE_DIRECTION_FLAG = 0x01u,
- COVERAGE_MINIMUM_FLAG = 0x02u,
- COVERAGE_CROSSSTREAM_FLAG = 0x04u,
- COVERAGE_OVERRIDE_FLAG = 0x08u,
-
- COVERAGE_VARIATION_FLAG = 0x00u, /* Not supported. */
-
- COVERAGE_CHECK_FLAGS = 0x07u,
- COVERAGE_CHECK_HORIZONTAL = 0x01u
- };
-
- protected:
- UINT16 versionZ; /* Unused. */
- UINT16 length; /* Length of the subtable (including this header). */
- UINT8 format; /* Subtable format. */
- UINT8 coverage; /* Coverage bits. */
- KernSubTable subtable; /* Subtable data. */
- public:
- DEFINE_SIZE_MIN (6);
+ Vertical = 0x80u,
+ CrossStream = 0x40u,
+ Variation = 0x20u,
+
+ /* Not supported: */
+ Backwards = 0x00u,
};
- protected:
- UINT16 version; /* Version--0x0000u */
- UINT16 nTables; /* Number of subtables in the kerning table. */
- UINT8 data[VAR];
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ public:
+ HBUINT32 length; /* Length of the subtable (including this header). */
+ HBUINT8 coverage; /* Coverage bits. */
+ HBUINT8 format; /* Subtable format. */
+ HBUINT16 tupleIndex; /* The tuple index (used for variations fonts).
+ * This value specifies which tuple this subtable covers.
+ * Note: We don't implement. */
public:
- DEFINE_SIZE_ARRAY (4, data);
+ DEFINE_SIZE_STATIC (8);
};
-struct KernAAT : KernTable<KernAAT>
+struct KernAAT : AAT::KerxTable<KernAAT>
{
- friend struct KernTable<KernAAT>;
+ friend struct AAT::KerxTable<KernAAT>;
- static const uint32_t VERSION = 0x00010000u;
+ static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
+ static constexpr unsigned minVersion = 0x00010000u;
- struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
- {
- friend struct KernSubTableWrapper<SubTableWrapper>;
-
- enum coverage_flags_t {
- COVERAGE_DIRECTION_FLAG = 0x80u,
- COVERAGE_CROSSSTREAM_FLAG = 0x40u,
- COVERAGE_VARIATION_FLAG = 0x20u,
-
- COVERAGE_OVERRIDE_FLAG = 0x00u, /* Not supported. */
-
- COVERAGE_CHECK_FLAGS = 0xE0u,
- COVERAGE_CHECK_HORIZONTAL = 0x00u
- };
-
- protected:
- UINT32 length; /* Length of the subtable (including this header). */
- UINT8 coverage; /* Coverage bits. */
- UINT8 format; /* Subtable format. */
- UINT16 tupleIndex; /* The tuple index (used for variations fonts).
- * This value specifies which tuple this subtable covers. */
- KernSubTable subtable; /* Subtable data. */
- public:
- DEFINE_SIZE_MIN (8);
- };
+ typedef KernAATSubTableHeader SubTableHeader;
+ typedef SubTableHeader::Types Types;
+ typedef KernSubTable<SubTableHeader> SubTable;
protected:
- UINT32 version; /* Version--0x00010000u */
- UINT32 nTables; /* Number of subtables in the kerning table. */
- UINT8 data[VAR];
+ HBUINT32 version; /* Version--0x00010000u */
+ HBUINT32 tableCount; /* Number of subtables in the kerning table. */
+ SubTable firstSubTable; /* Subtables. */
public:
- DEFINE_SIZE_ARRAY (8, data);
+ DEFINE_SIZE_MIN (8);
};
struct kern
{
- static const hb_tag_t tableTag = HB_OT_TAG_kern;
+ static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
- inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
+ bool has_data () const { return u.version32; }
+ unsigned get_type () const { return u.major; }
+
+ bool has_state_machine () const
{
- switch (u.major) {
- case 0: return u.ot.get_h_kerning (left, right, table_length);
- case 1: return u.aat.get_h_kerning (left, right, table_length);
- default:return 0;
+ switch (get_type ()) {
+ case 0: return u.ot.has_state_machine ();
+#ifndef HB_NO_AAT_SHAPE
+ case 1: return u.aat.has_state_machine ();
+#endif
+ default:return false;
}
}
- inline bool sanitize (hb_sanitize_context_t *c) const
+ bool has_cross_stream () const
{
- TRACE_SANITIZE (this);
- if (!u.major.sanitize (c)) return_trace (false);
- switch (u.major) {
- case 0: return_trace (u.ot.sanitize (c));
- case 1: return_trace (u.aat.sanitize (c));
- default:return_trace (true);
+ switch (get_type ()) {
+ case 0: return u.ot.has_cross_stream ();
+#ifndef HB_NO_AAT_SHAPE
+ case 1: return u.aat.has_cross_stream ();
+#endif
+ default:return false;
}
}
- struct accelerator_t
+ int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{
- inline void init (hb_face_t *face)
- {
- blob = Sanitizer<kern>::sanitize (face->reference_table (HB_OT_TAG_kern));
- table = Sanitizer<kern>::lock_instance (blob);
- table_length = hb_blob_get_length (blob);
- }
- inline void fini (void)
- {
- hb_blob_destroy (blob);
+ switch (get_type ()) {
+ case 0: return u.ot.get_h_kerning (left, right);
+#ifndef HB_NO_AAT_SHAPE
+ case 1: return u.aat.get_h_kerning (left, right);
+#endif
+ default:return 0;
}
+ }
- inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
- { return table->get_h_kerning (left, right, table_length); }
+ bool apply (AAT::hb_aat_apply_context_t *c) const
+ { return dispatch (c); }
- private:
- hb_blob_t *blob;
- const kern *table;
- unsigned int table_length;
- };
+ template <typename context_t, typename ...Ts>
+ typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+ {
+ unsigned int subtable_type = get_type ();
+ TRACE_DISPATCH (this, subtable_type);
+ switch (subtable_type) {
+ case 0: return_trace (c->dispatch (u.ot, hb_forward<Ts> (ds)...));
+#ifndef HB_NO_AAT_SHAPE
+ case 1: return_trace (c->dispatch (u.aat, hb_forward<Ts> (ds)...));
+#endif
+ default: return_trace (c->default_return_value ());
+ }
+ }
+
+ bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!u.version32.sanitize (c)) return_trace (false);
+ return_trace (dispatch (c));
+ }
protected:
union {
- UINT16 major;
+ HBUINT32 version32;
+ HBUINT16 major;
KernOT ot;
+#ifndef HB_NO_AAT_SHAPE
KernAAT aat;
+#endif
} u;
public:
- DEFINE_SIZE_UNION (2, major);
+ DEFINE_SIZE_UNION (4, version32);
};
} /* namespace OT */