From a4a7a623893fd4c8db3a987d81a1c80243006f1e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 11:16:43 -0400 Subject: [PATCH 01/40] [kern] Add buffer message --- src/hb-ot-kern-table.hh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 63551d313..891f3eab9 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -483,7 +483,12 @@ struct kern hb_kern_machine_t machine (*this); + if (!buffer->message (font, "start kern table")) + return; + machine.kern (font, buffer, kern_mask); + + (void) buffer->message (font, "end kern table"); } private: From 1cf075ecb674cc0c7043bffe2fef5ef187c15335 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 11:38:00 -0400 Subject: [PATCH 02/40] Add get_size to UnsizedArrayOf --- src/hb-open-type.hh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 00bd134dd..062576039 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -343,6 +343,9 @@ struct UnsizedArrayOf template inline operator T * (void) { return arrayZ; } template inline operator const T * (void) const { return arrayZ; } + inline unsigned int get_size (unsigned int len) const + { return len * Type::static_size; } + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { TRACE_SANITIZE (this); From 72462eb76584a2892f1d961c90fd289240ea9380 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 11:46:24 -0400 Subject: [PATCH 03/40] Add UnsizedArrayOf::as_array() instead of hb_array() template --- src/hb-aat-layout-trak-table.hh | 2 +- src/hb-dsalgs.hh | 2 -- src/hb-open-file.hh | 2 +- src/hb-open-type.hh | 11 +++-------- src/hb-ot-color-cpal-table.hh | 6 +++--- 5 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/hb-aat-layout-trak-table.hh b/src/hb-aat-layout-trak-table.hh index de2071ad6..c579c1193 100644 --- a/src/hb-aat-layout-trak-table.hh +++ b/src/hb-aat-layout-trak-table.hh @@ -55,7 +55,7 @@ struct TrackTableEntry unsigned int index, unsigned int nSizes) const { - return hb_array (base+valuesZ, nSizes)[index]; + return (base+valuesZ).as_array (nSizes)[index]; } public: diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index 59df860df..0940dc53c 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -572,8 +572,6 @@ struct hb_array_t T *arrayZ; unsigned int len; }; -template static inline -hb_array_t hb_array (T *array, unsigned int len) { return hb_array_t (array, len); } struct HbOpOr diff --git a/src/hb-open-file.hh b/src/hb-open-file.hh index 80dc5e614..2ef6d775f 100644 --- a/src/hb-open-file.hh +++ b/src/hb-open-file.hh @@ -330,7 +330,7 @@ struct ResourceTypeRecord inline const ResourceRecord& get_resource_record (unsigned int i, const void *type_base) const { - return hb_array (type_base+resourcesZ, get_resource_count ())[i]; + return (type_base+resourcesZ).as_array (get_resource_count ())[i]; } inline bool sanitize (hb_sanitize_context_t *c, diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 062576039..7bce7eade 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -346,6 +346,9 @@ struct UnsizedArrayOf inline unsigned int get_size (unsigned int len) const { return len * Type::static_size; } + inline hb_array_t as_array (unsigned int len) { return hb_array_t (arrayZ, len); } + inline hb_array_t as_array (unsigned int len) const { return hb_array_t (arrayZ, len); } + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { TRACE_SANITIZE (this); @@ -393,14 +396,6 @@ struct UnsizedArrayOf public: DEFINE_SIZE_ARRAY (0, arrayZ); }; -} /* namespace OT */ -template static inline -hb_array_t hb_array (OT::UnsizedArrayOf &array, unsigned int len) -{ return hb_array (array.arrayZ, len); } -template static inline -hb_array_t hb_array (const OT::UnsizedArrayOf &array, unsigned int len) -{ return hb_array (array.arrayZ, len); } -namespace OT { /* Unsized array of offset's */ template diff --git a/src/hb-ot-color-cpal-table.hh b/src/hb-ot-color-cpal-table.hh index df4d9b4e7..332f0dd74 100644 --- a/src/hb-ot-color-cpal-table.hh +++ b/src/hb-ot-color-cpal-table.hh @@ -55,7 +55,7 @@ struct CPALV1Tail { if (!paletteFlagsZ) return HB_OT_COLOR_PALETTE_FLAG_DEFAULT; return (hb_ot_color_palette_flags_t) (uint32_t) - hb_array (base+paletteFlagsZ, palette_count)[palette_index]; + (base+paletteFlagsZ).as_array (palette_count)[palette_index]; } inline hb_ot_name_id_t @@ -64,7 +64,7 @@ struct CPALV1Tail unsigned int palette_count) const { if (!paletteLabelsZ) return HB_OT_NAME_ID_INVALID; - return hb_array (base+paletteLabelsZ, palette_count)[palette_index]; + return (base+paletteLabelsZ).as_array (palette_count)[palette_index]; } inline hb_ot_name_id_t @@ -73,7 +73,7 @@ struct CPALV1Tail unsigned int color_count) const { if (!colorLabelsZ) return HB_OT_NAME_ID_INVALID; - return hb_array (base+colorLabelsZ, color_count)[color_index]; + return (base+colorLabelsZ).as_array (color_count)[color_index]; } public: From c6ef5dbd5c40cc8934756456221e080012a82530 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 11:51:21 -0400 Subject: [PATCH 04/40] Add cast operators to hb_array_t --- src/hb-dsalgs.hh | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index 0940dc53c..2249e128d 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -539,19 +539,24 @@ struct hb_bytes_t unsigned int len; }; -template +template struct hb_array_t { inline hb_array_t (void) : arrayZ (nullptr), len (0) {} - inline hb_array_t (T *array_, unsigned int len_) : arrayZ (array_), len (len_) {} + inline hb_array_t (Type *array_, unsigned int len_) : arrayZ (array_), len (len_) {} - inline T& operator [] (unsigned int i) const + inline Type& operator [] (unsigned int i) const { - if (unlikely (i >= len)) return Null(T); + if (unlikely (i >= len)) return Null(Type); return arrayZ[i]; } - inline hb_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const + inline unsigned int get_size (void) { return len * sizeof (Type); } + + template inline operator T * (void) { return arrayZ; } + template inline operator const T * (void) const { return arrayZ; } + + inline hb_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const { unsigned int count = len; if (unlikely (start_offset > count)) @@ -559,17 +564,17 @@ struct hb_array_t else count -= start_offset; count = MIN (count, seg_count); - return hb_array_t (arrayZ + start_offset, count); + return hb_array_t (arrayZ + start_offset, count); } inline hb_bytes_t as_bytes (void) const { - return hb_bytes_t (arrayZ, len * sizeof (T)); + return hb_bytes_t (arrayZ, len * sizeof (Type)); } inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; } - T *arrayZ; + Type *arrayZ; unsigned int len; }; From 6e06fe162ed79bb47f62aae03669cd72b99014a0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 11:56:55 -0400 Subject: [PATCH 05/40] [kern] Implement Format3 Untested. --- src/hb-ot-kern-table.hh | 51 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 891f3eab9..4f196789f 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -239,6 +239,54 @@ struct KernSubTableFormat2 DEFINE_SIZE_MIN (8); }; +struct KernSubTableFormat3 +{ + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const + { + hb_array_t kernValue = kernValueZ.as_array (kernValueCount); + hb_array_t leftClass = StructAfter > (kernValue).as_array (glyphCount); + hb_array_t rightClass = StructAfter > (leftClass).as_array (glyphCount); + hb_array_t kernIndex = StructAfter > (rightClass).as_array (leftClassCount * rightClassCount); + + unsigned int i = leftClass[left] * rightClassCount + rightClass[right]; + return kernValue[kernIndex[i]]; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (true); /* Disabled. See above. */ + return_trace (c->check_struct (this) && + c->check_range (kernValueZ, + kernValueCount + + glyphCount * 2 + + leftClassCount * rightClassCount)); + } + + protected: + HBUINT16 glyphCount; /* The number of glyphs in this font. */ + HBUINT8 kernValueCount; /* The number of kerning values. */ + HBUINT8 leftClassCount; /* The number of left-hand classes. */ + HBUINT8 rightClassCount;/* The number of right-hand classes. */ + HBUINT8 flags; /* Set to zero (reserved for future use). */ + UnsizedArrayOf + kernValueZ; /* The kerning values. + * Length kernValueCount. */ +#if 0 + UnsizedArrayOf + leftClass; /* The left-hand classes. + * Length glyphCount. */ + UnsizedArrayOf + RightClass; /* The right-hand classes. + * Length glyphCount. */ + UnsizedArrayOf + kernIndex; /* The indices into the kernValue array. + * Length leftClassCount * rightClassCount */ +#endif + public: + DEFINE_SIZE_ARRAY (6, kernValueZ); +}; + struct KernSubTable { inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end, unsigned int format) const @@ -246,6 +294,7 @@ struct KernSubTable switch (format) { case 0: return u.format0.get_kerning (left, right); case 2: return u.format2.get_kerning (left, right, end); + case 3: return u.format3.get_kerning (left, right, end); default:return 0; } } @@ -256,6 +305,7 @@ struct KernSubTable switch (format) { case 0: return_trace (u.format0.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); + case 3: return_trace (u.format3.sanitize (c)); default:return_trace (true); } } @@ -264,6 +314,7 @@ struct KernSubTable union { KernSubTableFormat0 format0; KernSubTableFormat2 format2; + KernSubTableFormat3 format3; } u; public: DEFINE_SIZE_MIN (0); From 9b7cb137946013592c9a5a9f0a3464fb4613577b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 12:00:55 -0400 Subject: [PATCH 06/40] Fixup --- src/hb-dsalgs.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index 2249e128d..c1b0a86a8 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -551,7 +551,7 @@ struct hb_array_t return arrayZ[i]; } - inline unsigned int get_size (void) { return len * sizeof (Type); } + inline unsigned int get_size (void) const { return len * sizeof (Type); } template inline operator T * (void) { return arrayZ; } template inline operator const T * (void) const { return arrayZ; } From 91de9dfcf3bba7cbeef1e709679c8e24ab684c97 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 12:14:21 -0400 Subject: [PATCH 07/40] Fix &array_of<> --- src/hb-dsalgs.hh | 3 +++ src/hb-open-type.hh | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index c1b0a86a8..f2bff063d 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -556,6 +556,9 @@ struct hb_array_t template inline operator T * (void) { return arrayZ; } template inline operator const T * (void) const { return arrayZ; } + inline Type * operator & (void) { return arrayZ; } + inline const Type * operator & (void) const { return arrayZ; } + inline hb_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const { unsigned int count = len; diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 7bce7eade..afd75be4d 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -340,7 +340,7 @@ struct UnsizedArrayOf inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; } inline Type& operator [] (unsigned int i) { return arrayZ[i]; } - template inline operator T * (void) { return arrayZ; } + template inline operator T * (void) { return arrayZ; } template inline operator const T * (void) const { return arrayZ; } inline unsigned int get_size (unsigned int len) const @@ -452,7 +452,7 @@ struct ArrayOf return arrayZ[i]; } - template inline operator T * (void) { return arrayZ; } + template inline operator T * (void) { return arrayZ; } template inline operator const T * (void) const { return arrayZ; } inline unsigned int get_size (void) const From 0382b7184addf5b3723db40a57790e5e62ac1703 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 12:23:26 -0400 Subject: [PATCH 08/40] Use as_array in more places --- src/hb-aat-layout-morx-table.hh | 4 ++-- src/hb-ot-layout-gsubgpos.hh | 22 +++++++++++++--------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index d56af7bfe..dab6ec1e9 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -977,7 +977,7 @@ struct Chain inline void apply (hb_aat_apply_context_t *c, hb_mask_t flags) const { - const ChainSubtable *subtable = &StructAtOffset > (&featureZ, featureZ[0].static_size * featureCount); + const ChainSubtable *subtable = &StructAfter > (featureZ.as_array (featureCount)); unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) { @@ -1059,7 +1059,7 @@ struct Chain if (!c->check_array (featureZ.arrayZ, featureCount)) return_trace (false); - const ChainSubtable *subtable = &StructAtOffset > (&featureZ, featureZ[0].static_size * featureCount); + const ChainSubtable *subtable = &StructAfter > (featureZ.as_array (featureCount)); unsigned int count = subtableCount; for (unsigned int i = 0; i < count; i++) { diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index c4af42048..54ae429b1 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -1308,7 +1308,8 @@ struct Rule inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const { TRACE_CLOSURE (this); - const UnsizedArrayOf &lookupRecord = StructAtOffset > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); + const UnsizedArrayOf &lookupRecord = StructAfter > + (inputZ.as_array ((inputCount ? inputCount - 1 : 0))); context_closure_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, @@ -1318,7 +1319,8 @@ struct Rule inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const { TRACE_COLLECT_GLYPHS (this); - const UnsizedArrayOf &lookupRecord = StructAtOffset > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); + const UnsizedArrayOf &lookupRecord = StructAfter > + (inputZ.as_array (inputCount ? inputCount - 1 : 0)); context_collect_glyphs_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, @@ -1328,14 +1330,16 @@ struct Rule inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const { TRACE_WOULD_APPLY (this); - const UnsizedArrayOf &lookupRecord = StructAtOffset > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); + const UnsizedArrayOf &lookupRecord = StructAfter > + (inputZ.as_array (inputCount ? inputCount - 1 : 0)); return_trace (context_would_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context)); } inline bool apply (hb_ot_apply_context_t *c, ContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); - const UnsizedArrayOf &lookupRecord = StructAtOffset > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); + const UnsizedArrayOf &lookupRecord = StructAfter > + (inputZ.as_array (inputCount ? inputCount - 1 : 0)); return_trace (context_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context)); } @@ -1686,7 +1690,7 @@ struct ContextFormat3 if (!(this+coverageZ[0]).intersects (c->glyphs)) return; - const LookupRecord *lookupRecord = &StructAtOffset (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount); + const LookupRecord *lookupRecord = &StructAfter (coverageZ.as_array (glyphCount)); struct ContextClosureLookupContext lookup_context = { {intersects_coverage}, this @@ -1702,7 +1706,7 @@ struct ContextFormat3 TRACE_COLLECT_GLYPHS (this); (this+coverageZ[0]).add_coverage (c->input); - const LookupRecord *lookupRecord = &StructAtOffset (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount); + const LookupRecord *lookupRecord = &StructAfter (coverageZ.as_array (glyphCount)); struct ContextCollectGlyphsLookupContext lookup_context = { {collect_coverage}, this @@ -1718,7 +1722,7 @@ struct ContextFormat3 { TRACE_WOULD_APPLY (this); - const LookupRecord *lookupRecord = &StructAtOffset (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount); + const LookupRecord *lookupRecord = &StructAfter (coverageZ.as_array (glyphCount)); struct ContextApplyLookupContext lookup_context = { {match_coverage}, this @@ -1735,7 +1739,7 @@ struct ContextFormat3 unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const LookupRecord *lookupRecord = &StructAtOffset (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount); + const LookupRecord *lookupRecord = &StructAfter (coverageZ.as_array (glyphCount)); struct ContextApplyLookupContext lookup_context = { {match_coverage}, this @@ -1759,7 +1763,7 @@ struct ContextFormat3 if (!c->check_array (coverageZ.arrayZ, count)) return_trace (false); for (unsigned int i = 0; i < count; i++) if (!coverageZ[i].sanitize (c, this)) return_trace (false); - const LookupRecord *lookupRecord = &StructAtOffset (coverageZ.arrayZ, coverageZ[0].static_size * count); + const LookupRecord *lookupRecord = &StructAfter (coverageZ.as_array (glyphCount)); return_trace (c->check_array (lookupRecord, lookupCount)); } From 949dad89a81ff5b6ef92e8737962b667249a3f2b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 12:47:55 -0400 Subject: [PATCH 09/40] [kern] Remove accelerator It wasn't doing anything. --- src/hb-ot-face.hh | 2 +- src/hb-ot-kern-table.hh | 55 +++++++++++------------------------------ src/hb-ot-layout.cc | 4 +-- 3 files changed, 18 insertions(+), 43 deletions(-) diff --git a/src/hb-ot-face.hh b/src/hb-ot-face.hh index 6e629eb41..caa1d97ef 100644 --- a/src/hb-ot-face.hh +++ b/src/hb-ot-face.hh @@ -67,7 +67,7 @@ HB_OT_ACCELERATOR(OT, hmtx) \ HB_OT_ACCELERATOR(OT, vmtx) \ HB_OT_ACCELERATOR(OT, post) \ - HB_OT_ACCELERATOR(OT, kern) \ + HB_OT_TABLE(OT, kern) \ HB_OT_ACCELERATOR(OT, glyf) \ HB_OT_TABLE(OT, VORG) \ HB_OT_ACCELERATOR(OT, name) \ diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 4f196789f..8c436f990 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -503,49 +503,26 @@ struct kern } } - struct accelerator_t + inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const + { return get_h_kerning (first, second); } + + inline void apply (hb_font_t *font, + hb_buffer_t *buffer, + hb_mask_t kern_mask) const { - inline void init (hb_face_t *face) - { - blob = hb_sanitize_context_t().reference_table (face); - table = blob->as (); - } - inline void fini (void) - { - hb_blob_destroy (blob); - } + /* We only apply horizontal kerning in this table. */ + if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + return; - inline bool has_data (void) const - { return table->has_data (); } + hb_kern_machine_t machine (*this); - inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return table->get_h_kerning (left, right); } + if (!buffer->message (font, "start kern table")) + return; - inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const - { return get_h_kerning (first, second); } + machine.kern (font, buffer, kern_mask); - inline void apply (hb_font_t *font, - hb_buffer_t *buffer, - hb_mask_t kern_mask) const - { - /* We only apply horizontal kerning in this table. */ - if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) - return; - - hb_kern_machine_t machine (*this); - - if (!buffer->message (font, "start kern table")) - return; - - machine.kern (font, buffer, kern_mask); - - (void) buffer->message (font, "end kern table"); - } - - private: - hb_blob_t *blob; - const kern *table; - }; + (void) buffer->message (font, "end kern table"); + } protected: union { @@ -558,8 +535,6 @@ struct kern DEFINE_SIZE_UNION (4, version32); }; -struct kern_accelerator_t : kern::accelerator_t {}; - } /* namespace OT */ diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index e1b6b2e30..f4ae840b6 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -55,9 +55,9 @@ **/ -static const OT::kern::accelerator_t& _get_kern (hb_face_t *face) +static const OT::kern& _get_kern (hb_face_t *face) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern::accelerator_t); + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern); return *hb_ot_face_data (face)->kern; } const OT::GDEF& _get_gdef (hb_face_t *face) From 095f5add0b1ca39dd09842594b80fae92f0796e4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 13:23:54 -0400 Subject: [PATCH 10/40] [kern] Push apply loop to each subtable --- src/hb-ot-kern-table.hh | 153 ++++++++++++++++++++++++++++++++-------- src/hb-ot-layout.cc | 28 ++++++-- src/hb-ot-layout.hh | 8 ++- src/hb-ot-shape.cc | 2 +- 4 files changed, 149 insertions(+), 42 deletions(-) diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 8c436f990..311d61d5c 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -30,6 +30,8 @@ #include "hb-open-type.hh" #include "hb-ot-shape.hh" #include "hb-ot-layout-gsubgpos.hh" +#include "hb-aat-layout-ankr-table.hh" // Ugly but needed. +#include "hb-aat-layout-common.hh" template @@ -165,6 +167,19 @@ struct KernSubTableFormat0 return pairs[i].get_kerning (); } + inline bool apply (AAT::hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + + if (!c->plan->requested_kerning) + return false; + + hb_kern_machine_t machine (*this); + machine.kern (c->font, c->buffer, c->plan->kern_mask); + + return_trace (true); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -196,7 +211,8 @@ struct KernClassTable struct KernSubTableFormat2 { - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, + AAT::hb_aat_apply_context_t *c) const { /* This subtable is disabled. It's not cleaer to me *exactly* where the offests are * based from. I *think* they should be based from beginning of kern subtable wrapper, @@ -208,12 +224,41 @@ struct KernSubTableFormat2 unsigned int r = (this+rightClassTable).get_class (right); unsigned int offset = l + r; const FWORD *v = &StructAtOffset (&(this+array), offset); +#if 0 if (unlikely ((const char *) v < (const char *) &array || (const char *) v > (const char *) end - 2)) +#endif return 0; return *v; } + inline bool apply (AAT::hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + + if (!c->plan->requested_kerning) + return false; + + accelerator_t accel (*this, c); + hb_kern_machine_t machine (accel); + machine.kern (c->font, c->buffer, c->plan->kern_mask); + + return_trace (true); + } + + struct accelerator_t + { + const KernSubTableFormat2 &table; + AAT::hb_aat_apply_context_t *c; + + inline accelerator_t (const KernSubTableFormat2 &table_, + AAT::hb_aat_apply_context_t *c_) : + table (table_), c (c_) {} + + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const + { return table.get_kerning (left, right, c); } + }; + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -241,7 +286,7 @@ struct KernSubTableFormat2 struct KernSubTableFormat3 { - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const { hb_array_t kernValue = kernValueZ.as_array (kernValueCount); hb_array_t leftClass = StructAfter > (kernValue).as_array (glyphCount); @@ -252,6 +297,19 @@ struct KernSubTableFormat3 return kernValue[kernIndex[i]]; } + inline bool apply (AAT::hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + + if (!c->plan->requested_kerning) + return false; + + hb_kern_machine_t machine (*this); + machine.kern (c->font, c->buffer, c->plan->kern_mask); + + return_trace (true); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -289,16 +347,26 @@ struct KernSubTableFormat3 struct KernSubTable { - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end, unsigned int format) const + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int format) const { switch (format) { + /* 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); - case 3: return u.format3.get_kerning (left, right, end); default:return 0; } } + inline void apply (AAT::hb_aat_apply_context_t *c, unsigned int format) const + { + /* TODO Switch to dispatch(). */ + switch (format) { + case 0: u.format0.apply (c); return; + case 2: u.format2.apply (c); return; + case 3: u.format3.apply (c); return; + default: return; + } + } + inline bool sanitize (hb_sanitize_context_t *c, unsigned int format) const { TRACE_SANITIZE (this); @@ -333,11 +401,14 @@ struct KernSubTableWrapper inline bool is_override (void) const { return bool (thiz()->coverage & T::Override); } - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const - { return thiz()->subtable.get_kerning (left, right, end, thiz()->format); } + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const + { return thiz()->subtable.get_kerning (left, right, thiz()->format); } - inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const - { return is_horizontal () ? get_kerning (left, right, end) : 0; } + inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const + { return is_horizontal () ? get_kerning (left, right) : 0; } + + inline void apply (AAT::hb_aat_apply_context_t *c) const + { thiz()->subtable.apply (c, thiz()->format); } inline unsigned int get_size (void) const { return thiz()->length; } @@ -366,12 +437,43 @@ struct KernTable { if (st->is_override ()) v = 0; - v += st->get_h_kerning (left, right, st->length + (const char *) st); + v += st->get_h_kerning (left, right); st = &StructAfter (*st); } return v; } + inline void apply (AAT::hb_aat_apply_context_t *c) const + { + c->set_lookup_index (0); + const typename T::SubTableWrapper *st = CastP (&thiz()->dataZ); + unsigned int count = thiz()->nTables; + /* If there's an override subtable, skip subtables before that. */ + unsigned int last_override = 0; + for (unsigned int i = 0; i < count; i++) + { + if (st->is_override ()) + last_override = i; + st = &StructAfter (*st); + } + st = CastP (&thiz()->dataZ); + for (unsigned int i = 0; i < count; i++) + { + if (i < last_override) + goto skip; + + if (!c->buffer->message (c->font, "start kern subtable %d", c->lookup_index)) + goto skip; + + st->apply (c); + + (void) c->buffer->message (c->font, "end kern subtable %d", c->lookup_index); + + skip: + st = &StructAfter (*st); + } + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -492,6 +594,16 @@ struct kern } } + inline void apply (AAT::hb_aat_apply_context_t *c) const + { + /* TODO Switch to dispatch(). */ + switch (u.major) { + case 0: u.ot.apply (c); return; + case 1: u.aat.apply (c); return; + default: return; + } + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -503,27 +615,6 @@ struct kern } } - inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const - { return get_h_kerning (first, second); } - - inline void apply (hb_font_t *font, - hb_buffer_t *buffer, - hb_mask_t kern_mask) const - { - /* We only apply horizontal kerning in this table. */ - if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) - return; - - hb_kern_machine_t machine (*this); - - if (!buffer->message (font, "start kern table")) - return; - - machine.kern (font, buffer, kern_mask); - - (void) buffer->message (font, "end kern table"); - } - protected: union { HBUINT32 version32; diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index f4ae840b6..b81aabd20 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -55,10 +55,19 @@ **/ -static const OT::kern& _get_kern (hb_face_t *face) +static inline const OT::kern& +_get_kern (hb_face_t *face, hb_blob_t **blob = nullptr) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern); - return *hb_ot_face_data (face)->kern; + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) + { + if (blob) + *blob = hb_blob_get_empty (); + return Null(OT::kern); + } + const OT::kern& kern = *(hb_ot_face_data (face)->kern.get ()); + if (blob) + *blob = hb_ot_face_data (face)->kern.get_blob (); + return kern; } const OT::GDEF& _get_gdef (hb_face_t *face) { @@ -106,11 +115,16 @@ hb_ot_layout_has_kerning (hb_face_t *face) } void -hb_ot_layout_kern (hb_font_t *font, - hb_buffer_t *buffer, - hb_mask_t kern_mask) +hb_ot_layout_kern (hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) { - _get_kern (font->face).apply (font, buffer, kern_mask); + hb_blob_t *blob; + const AAT::kern& kern = _get_kern (font->face, &blob); + + AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); + + kern.apply (&c); } diff --git a/src/hb-ot-layout.hh b/src/hb-ot-layout.hh index 64b3d7480..b29f87c5a 100644 --- a/src/hb-ot-layout.hh +++ b/src/hb-ot-layout.hh @@ -34,6 +34,7 @@ #include "hb-font.hh" #include "hb-buffer.hh" #include "hb-open-type.hh" +#include "hb-ot-shape.hh" #include "hb-set-digest.hh" @@ -48,6 +49,7 @@ HB_INTERNAL const OT::GDEF& _get_gdef (hb_face_t *face); HB_INTERNAL const OT::GSUB& _get_gsub_relaxed (hb_face_t *face); HB_INTERNAL const OT::GPOS& _get_gpos_relaxed (hb_face_t *face); +struct hb_ot_shape_plan_t; /* * kern @@ -57,9 +59,9 @@ HB_INTERNAL hb_bool_t hb_ot_layout_has_kerning (hb_face_t *face); HB_INTERNAL void -hb_ot_layout_kern (hb_font_t *font, - hb_buffer_t *buffer, - hb_mask_t kern_mask); +hb_ot_layout_kern (hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); /* Private API corresponding to hb-ot-layout.h: */ diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index c55d8dcb8..b687996f6 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -918,7 +918,7 @@ hb_ot_position (const hb_ot_shape_context_t *c) /* Visual fallback goes here. */ if (c->plan->apply_kern) - hb_ot_layout_kern (c->font, c->buffer, c->plan->kern_mask); + hb_ot_layout_kern (c->plan, c->font, c->buffer); else if (c->plan->fallback_kerning) _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); From f1df441bedaf5b2c7fadf9954ea39616af87702a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 13:26:15 -0400 Subject: [PATCH 11/40] [kern] Comment --- src/hb-ot-kern-table.hh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 311d61d5c..77dd7b36a 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -217,8 +217,7 @@ struct KernSubTableFormat2 /* This subtable is disabled. It's not cleaer to me *exactly* where the offests are * based from. I *think* they should be based from beginning of kern subtable wrapper, * *NOT* "this". Since we know of no fonts that use this subtable, we are disabling - * it. Someday fix it and re-enable. Better yet, find fonts that use it... Meh, - * Windows doesn't implement it. Maybe just remove... */ + * it. Someday fix it and re-enable. */ return 0; unsigned int l = (this+leftClassTable).get_class (left); unsigned int r = (this+rightClassTable).get_class (right); From 04b82b181d06c229a98314c1620d3ae8a2825267 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 13:47:33 -0400 Subject: [PATCH 12/40] Remove pointer cast operators from ArrayOf<> ArrayOf<>, unlike UnsizedArrayOf<>, has data before the array. This was confusing. Remove. --- src/hb-open-type.hh | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index afd75be4d..0f6efdc69 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -452,9 +452,6 @@ struct ArrayOf return arrayZ[i]; } - template inline operator T * (void) { return arrayZ; } - template inline operator const T * (void) const { return arrayZ; } - inline unsigned int get_size (void) const { return len.static_size + len * Type::static_size; } From 9f880bad0d7291eaab10d814567c7a680e139c48 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 13:57:41 -0400 Subject: [PATCH 13/40] [kern] Minor We like check_struct() more. --- src/hb-ot-kern-table.hh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 77dd7b36a..303e1bb34 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -199,7 +199,8 @@ struct KernClassTable inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (firstGlyph.sanitize (c) && classes.sanitize (c)); + return_trace (c->check_struct (this) && + classes.sanitize (c)); } protected: @@ -262,7 +263,7 @@ struct KernSubTableFormat2 { TRACE_SANITIZE (this); return_trace (true); /* Disabled. See above. */ - return_trace (rowWidth.sanitize (c) && + return_trace (c->check_struct (this) && leftClassTable.sanitize (c, this) && rightClassTable.sanitize (c, this) && array.sanitize (c, this)); From 74c7a2c6c892446dcec574986e128967bd570e47 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 14:26:04 -0400 Subject: [PATCH 14/40] [kern] Respect more flags --- src/hb-ot-kern-table.hh | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 303e1bb34..3845da8ea 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -395,8 +395,11 @@ struct KernSubTableWrapper /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ inline const T* thiz (void) const { return static_cast (this); } + inline bool is_supported (void) const + { return !(thiz()->coverage & T::CheckFlags); } + inline bool is_horizontal (void) const - { return (thiz()->coverage & T::CheckFlags) == T::CheckHorizontal; } + { return (thiz()->coverage & T::Direction) == T::CheckHorizontal; } inline bool is_override (void) const { return bool (thiz()->coverage & T::Override); } @@ -405,7 +408,7 @@ struct KernSubTableWrapper { return thiz()->subtable.get_kerning (left, right, thiz()->format); } inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return is_horizontal () ? get_kerning (left, right) : 0; } + { return is_supported () && is_horizontal () ? get_kerning (left, right) : 0; } inline void apply (AAT::hb_aat_apply_context_t *c) const { thiz()->subtable.apply (c, thiz()->format); } @@ -435,7 +438,7 @@ struct KernTable unsigned int count = thiz()->nTables; for (unsigned int i = 0; i < count; i++) { - if (st->is_override ()) + if (st->is_supported () && st->is_override ()) v = 0; v += st->get_h_kerning (left, right); st = &StructAfter (*st); @@ -452,13 +455,19 @@ struct KernTable unsigned int last_override = 0; for (unsigned int i = 0; i < count; i++) { - if (st->is_override ()) + if (st->is_supported () && st->is_override ()) last_override = i; st = &StructAfter (*st); } st = CastP (&thiz()->dataZ); for (unsigned int i = 0; i < count; i++) { + if (!st->is_supported ()) + goto skip; + + if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->is_horizontal ()) + goto skip; + if (i < last_override) goto skip; @@ -514,7 +523,7 @@ struct KernOT : KernTable Variation = 0x00u, /* Not supported. */ - CheckFlags = 0x07u, + CheckFlags = 0x06u, CheckHorizontal = 0x01u }; @@ -555,7 +564,7 @@ struct KernAAT : KernTable Override = 0x00u, /* Not supported. */ - CheckFlags = 0xE0u, + CheckFlags = 0x60u, CheckHorizontal = 0x00u }; From 46b3885c1a8ea3b85efbdd1704edcee385797c5d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 14:43:38 -0400 Subject: [PATCH 15/40] [kern] Set subtable on sanitizer --- src/hb-ot-kern-table.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 3845da8ea..ec33d6034 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -474,6 +474,8 @@ struct KernTable if (!c->buffer->message (c->font, "start kern subtable %d", c->lookup_index)) goto skip; + c->sanitizer.set_object (*st); + st->apply (c); (void) c->buffer->message (c->font, "end kern subtable %d", c->lookup_index); From 8034d1dda091998d356e77f249d3c9f50501cc77 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 2 Nov 2018 14:47:42 -0400 Subject: [PATCH 16/40] [kern] Implement Format1 Also, implement backwards kerning for Format1 in kern and kerx. Fixes https://github.com/harfbuzz/harfbuzz/issues/1350 --- src/hb-aat-layout-kerx-table.hh | 11 ++- src/hb-ot-kern-table.hh | 127 ++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 2 deletions(-) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 94e0a9b62..b227af105 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -207,11 +207,18 @@ struct KerxSubTableFormat1 int v = *actions++; if (idx < buffer->len && buffer->info[idx].mask & kern_mask) { - /* XXX Non-forward direction... */ if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + { buffer->pos[idx].x_advance += c->font->em_scale_x (v); + if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) + buffer->pos[idx].x_offset += c->font->em_scale_x (v); + } else + { buffer->pos[idx].y_advance += c->font->em_scale_y (v); + if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) + buffer->pos[idx].y_offset += c->font->em_scale_y (v); + } } } depth = 0; @@ -255,7 +262,7 @@ struct KerxSubTableFormat1 protected: KerxSubTableHeader header; - StateTable machine; + StateTable machine; LOffsetTo, false> kernAction; public: DEFINE_SIZE_STATIC (32); diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index ec33d6034..9f8a0115c 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -192,6 +192,130 @@ struct KernSubTableFormat0 DEFINE_SIZE_ARRAY (8, pairs); }; +struct KernSubTableFormat1 +{ + typedef void EntryData; + + struct driver_context_t + { + static const bool in_place = true; + enum Flags + { + Push = 0x8000, /* If set, push this glyph on the kerning stack. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph + * before going to the new state. */ + Offset = 0x3FFF, /* Byte offset from beginning of subtable to the + * value table for the glyphs on the kerning stack. */ + }; + + inline driver_context_t (const KernSubTableFormat1 *table_, + AAT::hb_aat_apply_context_t *c_) : + c (c_), + table (table_), + /* Apparently the offset kernAction is from the beginning of the state-machine, + * similar to offsets in morx table, NOT from beginning of this table, like + * other subtables in kerx. Discovered via testing. */ + kernAction (&table->machine + table->kernAction), + depth (0) {} + + inline bool is_actionable (AAT::StateTableDriver *driver HB_UNUSED, + const AAT::Entry *entry) + { + return entry->flags & Offset; + } + inline bool transition (AAT::StateTableDriver *driver, + const AAT::Entry *entry) + { + hb_buffer_t *buffer = driver->buffer; + unsigned int flags = entry->flags; + + if (flags & Push) + { + if (likely (depth < ARRAY_LENGTH (stack))) + stack[depth++] = buffer->idx; + else + depth = 0; /* Probably not what CoreText does, but better? */ + } + + if (entry->flags & Offset) + { + unsigned int kernIndex = AAT::MortTypes::offsetToIndex (entry->flags & Offset, &table->machine, kernAction.arrayZ); + const FWORD *actions = &kernAction[kernIndex]; + if (!c->sanitizer.check_array (actions, depth)) + { + depth = 0; + return false; + } + + hb_mask_t kern_mask = c->plan->kern_mask; + for (unsigned int i = 0; i < depth; i++) + { + /* Apparently, when spec says "Each pops one glyph from the kerning stack + * and applies the kerning value to it.", it doesn't mean it in that order. + * The deepest item in the stack corresponds to the first item in the action + * list. Discovered by testing. */ + unsigned int idx = stack[i]; + int v = *actions++; + if (idx < buffer->len && buffer->info[idx].mask & kern_mask) + { + if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + { + buffer->pos[idx].x_advance += c->font->em_scale_x (v); + if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) + buffer->pos[idx].x_offset += c->font->em_scale_x (v); + } + else + { + buffer->pos[idx].y_advance += c->font->em_scale_y (v); + if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) + buffer->pos[idx].y_offset += c->font->em_scale_y (v); + } + } + } + depth = 0; + } + + return true; + } + + private: + AAT::hb_aat_apply_context_t *c; + const KernSubTableFormat1 *table; + const UnsizedArrayOf &kernAction; + unsigned int stack[8]; + unsigned int depth; + }; + + inline bool apply (AAT::hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + + if (!c->plan->requested_kerning) + return false; + + driver_context_t dc (this, c); + + AAT::StateTableDriver driver (machine, c->buffer, c->font->face); + driver.drive (&dc); + + return_trace (true); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + /* The rest of array sanitizations are done at run-time. */ + return_trace (likely (c->check_struct (this) && + machine.sanitize (c))); + } + + protected: + AAT::StateTable machine; + OffsetTo, HBUINT16, false> kernAction; + public: + DEFINE_SIZE_STATIC (10); +}; + struct KernClassTable { inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; } @@ -361,6 +485,7 @@ struct KernSubTable /* TODO Switch to dispatch(). */ switch (format) { case 0: u.format0.apply (c); return; + case 1: u.format1.apply (c); return; case 2: u.format2.apply (c); return; case 3: u.format3.apply (c); return; default: return; @@ -372,6 +497,7 @@ struct KernSubTable TRACE_SANITIZE (this); switch (format) { case 0: return_trace (u.format0.sanitize (c)); + case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); case 3: return_trace (u.format3.sanitize (c)); default:return_trace (true); @@ -381,6 +507,7 @@ struct KernSubTable protected: union { KernSubTableFormat0 format0; + KernSubTableFormat1 format1; KernSubTableFormat2 format2; KernSubTableFormat3 format3; } u; From 2c68f34bddbe506d0b22948562f2f59b9a5b6050 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Fri, 2 Nov 2018 23:06:00 +0200 Subject: [PATCH 17/40] [os2] Capitalize table tag and struct Other tables follow the case of the OT tag, except this one. --- src/hb-ot-hmtx-table.hh | 6 +++--- src/hb-ot-os2-table.hh | 12 ++++++------ src/hb-subset.cc | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index 1eb6cc68f..f898a0336 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -194,8 +194,8 @@ struct hmtxvmtx bool got_font_extents = false; if (T::os2Tag) { - hb_blob_t *os2_blob = hb_sanitize_context_t().reference_table (face); - const os2 *os2_table = os2_blob->as (); + hb_blob_t *os2_blob = hb_sanitize_context_t().reference_table (face); + const OS2 *os2_table = os2_blob->as (); #define USE_TYPO_METRICS (1u<<7) if (0 != (os2_table->fsSelection & USE_TYPO_METRICS)) { @@ -336,7 +336,7 @@ struct hmtxvmtx struct hmtx : hmtxvmtx { static const hb_tag_t tableTag = HB_OT_TAG_hmtx; static const hb_tag_t variationsTag = HB_OT_TAG_HVAR; - static const hb_tag_t os2Tag = HB_OT_TAG_os2; + static const hb_tag_t os2Tag = HB_OT_TAG_OS2; }; struct vmtx : hmtxvmtx { static const hb_tag_t tableTag = HB_OT_TAG_vmtx; diff --git a/src/hb-ot-os2-table.hh b/src/hb-ot-os2-table.hh index 71d2bf59d..b2495128e 100644 --- a/src/hb-ot-os2-table.hh +++ b/src/hb-ot-os2-table.hh @@ -36,11 +36,11 @@ namespace OT { * OS/2 and Windows Metrics * https://docs.microsoft.com/en-us/typography/opentype/spec/os2 */ -#define HB_OT_TAG_os2 HB_TAG('O','S','/','2') +#define HB_OT_TAG_OS2 HB_TAG('O','S','/','2') -struct os2 +struct OS2 { - static const hb_tag_t tableTag = HB_OT_TAG_os2; + static const hb_tag_t tableTag = HB_OT_TAG_OS2; inline bool sanitize (hb_sanitize_context_t *c) const { @@ -50,12 +50,12 @@ struct os2 inline bool subset (hb_subset_plan_t *plan) const { - hb_blob_t *os2_blob = hb_sanitize_context_t().reference_table (plan->source); + hb_blob_t *os2_blob = hb_sanitize_context_t().reference_table (plan->source); hb_blob_t *os2_prime_blob = hb_blob_create_sub_blob (os2_blob, 0, -1); // TODO(grieger): move to hb_blob_copy_writable_or_fail hb_blob_destroy (os2_blob); - os2 *os2_prime = (os2 *) hb_blob_get_data_writable (os2_prime_blob, nullptr); + OS2 *os2_prime = (OS2 *) hb_blob_get_data_writable (os2_prime_blob, nullptr); if (unlikely (!os2_prime)) { hb_blob_destroy (os2_prime_blob); return false; @@ -67,7 +67,7 @@ struct os2 os2_prime->usLastCharIndex.set (max_cp); _update_unicode_ranges (plan->unicodes, os2_prime->ulUnicodeRange); - bool result = plan->add_table (HB_OT_TAG_os2, os2_prime_blob); + bool result = plan->add_table (HB_OT_TAG_OS2, os2_prime_blob); hb_blob_destroy (os2_prime_blob); return result; diff --git a/src/hb-subset.cc b/src/hb-subset.cc index ed61c628f..a1c52c57a 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -171,8 +171,8 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_cmap: result = _subset (plan); break; - case HB_OT_TAG_os2: - result = _subset (plan); + case HB_OT_TAG_OS2: + result = _subset (plan); break; case HB_OT_TAG_post: result = _subset (plan); From c560ca92512c0283e826c059431273ffecf5d993 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 3 Nov 2018 13:03:36 +0330 Subject: [PATCH 18/40] [fuzz] A new testcase --- ...case-minimized-hb-shape-fuzzer-5735679418433536 | Bin 0 -> 36 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5735679418433536 diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5735679418433536 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-shape-fuzzer-5735679418433536 new file mode 100644 index 0000000000000000000000000000000000000000..ff6ef6e2b9a25401ddfad32fa1b5a5d904f82b41 GIT binary patch literal 36 gcmZQzWME)mQ~-nQ)S^5P4~PYr8UHK%hX^YG08)_!h5!Hn literal 0 HcmV?d00001 From b8a78ce201608e9ac6d7f77447b2bbef6f09e9ff Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sat, 3 Nov 2018 22:28:30 +0330 Subject: [PATCH 19/40] [BASE] Improvements (#1347) --- src/hb-ot-layout-base-table.hh | 632 ++++++++++++++------------------- src/hb-ot-layout.cc | 65 +++- src/hb-ot-layout.h | 16 - test/api/Makefile.am | 1 + test/api/fonts/base.ttf | Bin 0 -> 5596 bytes test/api/test-baseline.c | 58 +++ 6 files changed, 391 insertions(+), 381 deletions(-) create mode 100644 test/api/fonts/base.ttf create mode 100644 test/api/test-baseline.c diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh index 449e74550..582e60155 100644 --- a/src/hb-ot-layout-base-table.hh +++ b/src/hb-ot-layout-base-table.hh @@ -1,6 +1,7 @@ /* * Copyright © 2016 Elie Roux * Copyright © 2018 Google, Inc. + * Copyright © 2018 Ebrahim Byagowi * * This is part of HarfBuzz, a text shaping library. * @@ -31,6 +32,9 @@ #include "hb-open-type.hh" #include "hb-ot-layout-common.hh" +/* To be removed */ +typedef hb_tag_t hb_ot_layout_baseline_t; + namespace OT { /* @@ -38,19 +42,14 @@ namespace OT { * https://docs.microsoft.com/en-us/typography/opentype/spec/base */ - -/* XXX Review this. */ -#define NOT_INDEXED ((unsigned int) -1) - - struct BaseCoordFormat1 { - inline int get_coord (void) const { return coordinate; } + inline hb_position_t get_coord () const { return coordinate; } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); + return_trace (likely (c->check_struct (this))); } protected: @@ -62,7 +61,7 @@ struct BaseCoordFormat1 struct BaseCoordFormat2 { - inline int get_coord (void) const + inline hb_position_t get_coord () const { /* TODO */ return coordinate; @@ -86,37 +85,45 @@ struct BaseCoordFormat2 struct BaseCoordFormat3 { - inline int get_coord (void) const + inline hb_position_t get_coord (hb_font_t *font, + const VariationStore &var_store, + hb_direction_t direction) const { - /* TODO */ - return coordinate; + const Device &device = this+deviceTable; + return coordinate + (HB_DIRECTION_IS_VERTICAL (direction) ? + device.get_y_delta (font, var_store) : + device.get_x_delta (font, var_store)); } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && deviceTable.sanitize (c, this)); + return_trace (likely (c->check_struct (this) && + deviceTable.sanitize (c, this))); } protected: - HBUINT16 format; /* Format identifier--format = 3 */ - FWORD coordinate; /* X or Y value, in design units */ - OffsetTo deviceTable; /* Offset to Device table for X or - * Y value, from beginning of - * BaseCoord table (may be NULL). */ + HBUINT16 format; /* Format identifier--format = 3 */ + FWORD coordinate; /* X or Y value, in design units */ + OffsetTo + deviceTable; /* Offset to Device table for X or + * Y value, from beginning of + * BaseCoord table (may be NULL). */ public: DEFINE_SIZE_STATIC (6); }; struct BaseCoord { - inline int get_coord (void) const + inline hb_position_t get_coord (hb_font_t *font, + const VariationStore &var_store, + hb_direction_t direction) const { - /* XXX wire up direction and font. */ switch (u.format) { case 1: return u.format1.get_coord (); case 2: return u.format2.get_coord (); - case 3: return u.format3.get_coord (); + case 3: return u.format3.get_coord (font, var_store, direction); default:return 0; } } @@ -124,7 +131,7 @@ struct BaseCoord inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); + if (unlikely (!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)); @@ -146,28 +153,40 @@ struct BaseCoord struct FeatMinMaxRecord { - inline int get_min_value (void) const { return (this+minCoord).get_coord(); } - inline int get_max_value (void) const { return (this+maxCoord).get_coord(); } + static int cmp (const void *key_, const void *entry_) + { + hb_tag_t key = * (hb_tag_t *) key_; + const FeatMinMaxRecord &entry = * (const FeatMinMaxRecord *) entry_; + return key < (unsigned int) entry.tag ? -1 : + key > (unsigned int) entry.tag ? 1 : + 0; + } - inline const Tag& get_tag () const { return tag; } + inline void get_min_max (const BaseCoord **min, const BaseCoord **max) const + { + if (likely (min)) *min = &(this+minCoord); + if (likely (max)) *max = &(this+maxCoord); + } inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - minCoord.sanitize (c, base) && - maxCoord.sanitize (c, base)); + return_trace (likely (c->check_struct (this) && + minCoord.sanitize (c, this) && + maxCoord.sanitize (c, this))); } protected: - Tag tag; /* 4-byte feature identification tag--must - * match feature tag in FeatureList */ - OffsetTo minCoord; /* Offset to BaseCoord table that defines - * the minimum extent value, from beginning - * of MinMax table (may be NULL) */ - OffsetTo maxCoord; /* Offset to BaseCoord table that defines - * the maximum extent value, from beginning - * of MinMax table (may be NULL) */ + Tag tag; /* 4-byte feature identification tag--must + * match feature tag in FeatureList */ + OffsetTo + minCoord; /* Offset to BaseCoord table that defines + * the minimum extent value, from beginning + * of MinMax table (may be NULL) */ + OffsetTo + maxCoord; /* Offset to BaseCoord table that defines + * the maximum extent value, from beginning + * of MinMax table (may be NULL) */ public: DEFINE_SIZE_STATIC (8); @@ -175,257 +194,202 @@ struct FeatMinMaxRecord struct MinMax { - inline unsigned int get_feature_tag_index (Tag featureTableTag) const + inline void get_min_max (hb_tag_t feature_tag, + const BaseCoord **min, + const BaseCoord **max) const { - /* TODO bsearch */ - unsigned int count = featMinMaxRecords.len; - for (unsigned int i = 0; i < count; i++) + const FeatMinMaxRecord *minMaxCoord = (const FeatMinMaxRecord *) + hb_bsearch (&feature_tag, featMinMaxRecords.arrayZ, + featMinMaxRecords.len, + FeatMinMaxRecord::static_size, + FeatMinMaxRecord::cmp); + if (minMaxCoord) + minMaxCoord->get_min_max (min, max); + else { - Tag tag = featMinMaxRecords[i].get_tag (); - int cmp = tag.cmp(featureTableTag); - if (cmp == 0) return i; - if (cmp > 0) return NOT_INDEXED; + if (likely (min)) *min = &(this+minCoord); + if (likely (max)) *max = &(this+maxCoord); } - return NOT_INDEXED; - } - - inline int get_min_value (unsigned int featureTableTagIndex) const - { - if (featureTableTagIndex == NOT_INDEXED) - return (this+minCoord).get_coord(); - return featMinMaxRecords[featureTableTagIndex].get_min_value(); - } - - inline int get_max_value (unsigned int featureTableTagIndex) const - { - if (featureTableTagIndex == NOT_INDEXED) - return (this+maxCoord).get_coord(); - return featMinMaxRecords[featureTableTagIndex].get_max_value(); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - minCoord.sanitize (c, this) && - maxCoord.sanitize (c, this) && - featMinMaxRecords.sanitize (c, this)); + return_trace (likely (c->check_struct (this) && + minCoord.sanitize (c, this) && + maxCoord.sanitize (c, this) && + featMinMaxRecords.sanitize (c, this))); } protected: - OffsetTo minCoord; /* Offset to BaseCoord table that defines - * minimum extent value, from the beginning - * of MinMax table (may be NULL) */ - OffsetTo maxCoord; /* Offset to BaseCoord table that defines - * maximum extent value, from the beginning - * of MinMax table (may be NULL) */ + OffsetTo + minCoord; /* Offset to BaseCoord table that defines + * minimum extent value, from the beginning + * of MinMax table (may be NULL) */ + OffsetTo + maxCoord; /* Offset to BaseCoord table that defines + * maximum extent value, from the beginning + * of MinMax table (may be NULL) */ ArrayOf - featMinMaxRecords; /* Array of FeatMinMaxRecords, in alphabetical - * order by featureTableTag */ + featMinMaxRecords; + /* Array of FeatMinMaxRecords, in alphabetical + * order by featureTableTag */ public: DEFINE_SIZE_ARRAY (6, featMinMaxRecords); }; -/* TODO... */ -struct BaseLangSysRecord -{ - inline const Tag& get_tag(void) const - { return baseLangSysTag; } - - inline unsigned int get_feature_tag_index (Tag featureTableTag) const - { return (this+minMax).get_feature_tag_index( featureTableTag); } - - inline int get_min_value (unsigned int featureTableTagIndex) const - { return (this+minMax).get_min_value( featureTableTagIndex); } - - inline int get_max_value (unsigned int featureTableTagIndex) const - { return (this+minMax).get_max_value (featureTableTagIndex); } - - inline bool sanitize (hb_sanitize_context_t *c, const void *base) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - minMax.sanitize (c, base)); - } - - protected: - Tag baseLangSysTag; - OffsetTo minMax; - public: - DEFINE_SIZE_STATIC (6); - -}; - struct BaseValues { - inline unsigned int get_default_base_tag_index (void) const - { return defaultIndex; } - - inline int get_base_coord (unsigned int baselineTagIndex) const + inline const BaseCoord &get_base_coord (int baseline_tag_index) const { - return (this+baseCoords[baselineTagIndex]).get_coord (); + if (baseline_tag_index == -1) baseline_tag_index = defaultIndex; + return this+baseCoords[baseline_tag_index]; } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - baseCoords.sanitize (c, this)); + return_trace (likely (c->check_struct (this) && + baseCoords.sanitize (c, this))); } protected: - Index defaultIndex; - OffsetArrayOf baseCoords; + Index defaultIndex; /* Index number of default baseline for this + * script — equals index position of baseline tag + * in baselineTags array of the BaseTagList */ + OffsetArrayOf + baseCoords; /* Number of BaseCoord tables defined — should equal + * baseTagCount in the BaseTagList + * + * Array of offsets to BaseCoord tables, from beginning of + * BaseValues table — order matches baselineTags array in + * the BaseTagList */ public: DEFINE_SIZE_ARRAY (4, baseCoords); }; -struct BaseScript { - - inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const +struct BaseLangSysRecord +{ + static int cmp (const void *key_, const void *entry_) { - /* XXX bsearch */ - Tag tag; - int cmp; - unsigned int count = baseLangSysRecords.len; - for (unsigned int i = 0; i < count; i++) - { - tag = baseLangSysRecords[i].get_tag (); - // taking advantage of alphabetical order - cmp = tag.cmp(baseLangSysTag); - if (cmp == 0) return i; - if (cmp > 0) return NOT_INDEXED; - } - return NOT_INDEXED; + hb_tag_t key = * (hb_tag_t *) key_; + const BaseLangSysRecord &entry = * (const BaseLangSysRecord *) entry_; + return key < (unsigned int) entry.baseLangSysTag ? -1 : + key > (unsigned int) entry.baseLangSysTag ? 1 : + 0; } - inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const - { - if (baseLangSysIndex == NOT_INDEXED) - { - if (unlikely(defaultMinMax)) return NOT_INDEXED; - return (this+defaultMinMax).get_feature_tag_index (featureTableTag); - } - return baseLangSysRecords[baseLangSysIndex].get_feature_tag_index (featureTableTag); - } - - inline int get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const - { - if (baseLangSysIndex == NOT_INDEXED) - return (this+defaultMinMax).get_min_value (featureTableTagIndex); - return baseLangSysRecords[baseLangSysIndex].get_max_value (featureTableTagIndex); - } - - inline int get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const - { - if (baseLangSysIndex == NOT_INDEXED) - return (this+defaultMinMax).get_min_value (featureTableTagIndex); - return baseLangSysRecords[baseLangSysIndex].get_max_value (featureTableTagIndex); - } - - inline unsigned int get_default_base_tag_index (void) const - { return (this+baseValues).get_default_base_tag_index (); } - - inline int get_base_coord (unsigned int baselineTagIndex) const - { return (this+baseValues).get_base_coord (baselineTagIndex); } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - baseValues.sanitize (c, this) && - defaultMinMax.sanitize (c, this) && - baseLangSysRecords.sanitize (c, this)); - } - - protected: - OffsetTo baseValues; - OffsetTo defaultMinMax; - ArrayOf baseLangSysRecords; - - public: - DEFINE_SIZE_ARRAY (6, baseLangSysRecords); -}; - - -struct BaseScriptRecord { - - inline const Tag& get_tag (void) const - { return baseScriptTag; } - - inline unsigned int get_default_base_tag_index(void) const - { return (this+baseScript).get_default_base_tag_index (); } - - inline int get_base_coord(unsigned int baselineTagIndex) const - { return (this+baseScript).get_base_coord (baselineTagIndex); } - - inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const - { return (this+baseScript).get_lang_tag_index (baseLangSysTag); } - - inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const - { return (this+baseScript).get_feature_tag_index (baseLangSysIndex, featureTableTag); } - - inline int get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const - { return (this+baseScript).get_max_value (baseLangSysIndex, featureTableTagIndex); } - - inline int get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const - { return (this+baseScript).get_min_value (baseLangSysIndex, featureTableTagIndex); } + inline const MinMax &get_min_max () const + { return this+minMax; } inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - baseScript.sanitize (c, base)); + return_trace (likely (c->check_struct (this) && + minMax.sanitize (c, this))); } protected: - Tag baseScriptTag; - OffsetTo baseScript; - + Tag baseLangSysTag; /* 4-byte language system identification tag */ + OffsetTo + minMax; /* Offset to MinMax table, from beginning + * of BaseScript table */ public: - DEFINE_SIZE_STATIC (6); + DEFINE_SIZE_STATIC (6); }; -struct BaseScriptList { - - inline unsigned int get_base_script_index (Tag baseScriptTag) const +struct BaseScript +{ + inline const MinMax &get_min_max (hb_tag_t language_tag) const { - /* XXX bsearch? */ - unsigned int count = baseScriptRecords.len; - for (unsigned int i = 0; i < count; i++) - if (baseScriptRecords[i].get_tag() == baseScriptTag) - return i; - return NOT_INDEXED; + const BaseLangSysRecord* record = (const BaseLangSysRecord *) + hb_bsearch (&language_tag, baseLangSysRecords.arrayZ, + baseLangSysRecords.len, + BaseLangSysRecord::static_size, + BaseLangSysRecord::cmp); + return record ? record->get_min_max () : this+defaultMinMax; } - inline unsigned int get_default_base_tag_index (unsigned int baseScriptIndex) const + inline const BaseCoord &get_base_coord (int baseline_tag_index) const + { return (this+baseValues).get_base_coord (baseline_tag_index); } + + inline bool is_empty () const + { return !baseValues; } + + inline bool sanitize (hb_sanitize_context_t *c) const { - return baseScriptRecords[baseScriptIndex].get_default_base_tag_index(); + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + baseValues.sanitize (c, this) && + defaultMinMax.sanitize (c, this) && + baseLangSysRecords.sanitize (c, this))); } - inline int get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const + protected: + OffsetTo + baseValues; /* Offset to BaseValues table, from beginning + * of BaseScript table (may be NULL) */ + OffsetTo + defaultMinMax; /* Offset to MinMax table, from beginning of + * BaseScript table (may be NULL) */ + ArrayOf + baseLangSysRecords; + /* Number of BaseLangSysRecords + * defined — may be zero (0) */ + + public: + DEFINE_SIZE_ARRAY (6, baseLangSysRecords); +}; + +struct BaseScriptList; +struct BaseScriptRecord +{ + static int cmp (const void *key_, const void *entry_) { - return baseScriptRecords[baseScriptIndex].get_base_coord(baselineTagIndex); + hb_tag_t key = * (hb_tag_t *) key_; + const BaseScriptRecord &entry = * (const BaseScriptRecord *) entry_; + return key < (unsigned int) entry.baseScriptTag ? -1 : + key > (unsigned int) entry.baseScriptTag ? 1 : + 0; } - inline unsigned int get_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const + inline const BaseScript &get_base_script (const BaseScriptList *list) const + { return list+baseScript; } + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { - return baseScriptRecords[baseScriptIndex].get_lang_tag_index(baseLangSysTag); + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + baseScript.sanitize (c, base))); } - inline unsigned int get_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const + protected: + Tag baseScriptTag; /* 4-byte script identification tag */ + OffsetTo + baseScript; /* Offset to BaseScript table, from beginning + * of BaseScriptList */ + + public: + DEFINE_SIZE_STATIC (6); +}; + +struct BaseScriptList +{ + inline const BaseScriptRecord *find_record (hb_tag_t script) const { - return baseScriptRecords[baseScriptIndex].get_feature_tag_index(baseLangSysIndex, featureTableTag); + return (const BaseScriptRecord *) hb_bsearch (&script, baseScriptRecords.arrayZ, + baseScriptRecords.len, + BaseScriptRecord::static_size, + BaseScriptRecord::cmp); } - inline int get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + /* TODO: Or client should handle fallback? */ + inline const BaseScript &get_base_script (hb_tag_t script) const { - return baseScriptRecords[baseScriptIndex].get_max_value(baseLangSysIndex, featureTableTagIndex); - } + const BaseScriptRecord *record = find_record (script); + if (!record) record = find_record ((hb_script_t) HB_TAG ('D','F','L','T')); - inline int get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const - { - return baseScriptRecords[baseScriptIndex].get_min_value(baseLangSysIndex, featureTableTagIndex); + return record ? record->get_base_script (this) : Null (BaseScript); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -436,86 +400,61 @@ struct BaseScriptList { } protected: - ArrayOf baseScriptRecords; + ArrayOf + baseScriptRecords; public: DEFINE_SIZE_ARRAY (2, baseScriptRecords); }; -struct BaseTagList -{ - inline unsigned int get_tag_index (Tag baselineTag) const - { - /* TODO bsearch? */ - unsigned int count = baselineTags.len; - for (unsigned int i = 0; i < count; i++) - if (baselineTags[i] == baselineTag) - return i; - return NOT_INDEXED; - } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - protected: - SortedArrayOf baselineTags; - - public: - DEFINE_SIZE_ARRAY (2, baselineTags); -}; - struct Axis { - - inline unsigned int get_base_tag_index (Tag baselineTag) const + inline bool get_baseline (hb_ot_layout_baseline_t baseline, + hb_tag_t script_tag, + hb_tag_t language_tag, + const BaseCoord **coord) const { - return (this+baseTagList).get_tag_index(baselineTag); + const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag); + if (base_script.is_empty ()) return false; + + if (likely (coord)) *coord = &base_script.get_base_coord ((this+baseTagList).bsearch (baseline)); + + return true; } - inline unsigned int get_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const + inline bool get_min_max (hb_tag_t script_tag, + hb_tag_t language_tag, + hb_tag_t feature_tag, + const BaseCoord **min_coord, + const BaseCoord **max_coord) const { - return (this+baseScriptList).get_default_base_tag_index(baseScriptIndex); - } + const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag); + if (base_script.is_empty ()) return false; - inline int get_base_coord (unsigned int baseScriptIndex, unsigned int baselineTagIndex) const - { - return (this+baseScriptList).get_base_coord(baseScriptIndex, baselineTagIndex); - } + base_script.get_min_max (language_tag).get_min_max (feature_tag, min_coord, max_coord); - inline unsigned int get_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const - { - return (this+baseScriptList).get_lang_tag_index(baseScriptIndex, baseLangSysTag); - } - - inline unsigned int get_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const - { - return (this+baseScriptList).get_feature_tag_index(baseScriptIndex, baseLangSysIndex, featureTableTag); - } - - inline int get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const - { - return (this+baseScriptList).get_max_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); - } - - inline int get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const - { - return (this+baseScriptList).get_min_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + return true; } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - baseTagList.sanitize (c, this) && - baseScriptList.sanitize (c, this)); + return_trace (likely (c->check_struct (this) && + (this+baseTagList).sanitize (c) && + (this+baseScriptList).sanitize (c))); } protected: - OffsetTo baseTagList; - OffsetTo baseScriptList; + OffsetTo > + baseTagList; /* Offset to BaseTagList table, from beginning + * of Axis table (may be NULL) + * Array of 4-byte baseline identification tags — must + * be in alphabetical order */ + OffsetTo + baseScriptList; /* Offset to BaseScriptList table, from beginning + * of Axis table + * Array of BaseScriptRecords, in alphabetical order + * by baseScriptTag */ public: DEFINE_SIZE_STATIC (4); @@ -525,99 +464,70 @@ struct BASE { static const hb_tag_t tableTag = HB_OT_TAG_BASE; - inline bool has_v_axis(void) { return vAxis != 0; } + inline const Axis &get_axis (hb_direction_t direction) const + { return HB_DIRECTION_IS_VERTICAL (direction) ? this+vAxis : this+hAxis; } - inline bool has_h_axis(void) { return hAxis != 0; } + inline const VariationStore &get_var_store () const + { return version.to_int () < 0x00010001u ? Null (VariationStore) : this+varStore; } - inline unsigned int get_h_base_tag_index (Tag baselineTag) const + inline bool get_baseline (hb_font_t *font, + hb_ot_layout_baseline_t baseline, + hb_direction_t direction, + hb_tag_t script_tag, + hb_tag_t language_tag, + hb_position_t *base) const { - return (this+hAxis).get_base_tag_index(baselineTag); + const BaseCoord *base_coord; + if (!get_axis (direction).get_baseline (baseline, script_tag, language_tag, &base_coord)) + return false; + + if (likely (base && base_coord)) *base = base_coord->get_coord (font, + get_var_store (), + direction); + return true; } - inline unsigned int get_h_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const + /* TODO: Expose this separately sometime? */ + inline bool get_min_max (hb_font_t *font, + hb_direction_t direction, + hb_tag_t script_tag, + hb_tag_t language_tag, + hb_tag_t feature_tag, + hb_position_t *min, + hb_position_t *max) { - return (this+hAxis).get_default_base_tag_index_for_script_index(baseScriptIndex); - } + const BaseCoord *min_coord, *max_coord; + if (!get_axis (direction).get_min_max (script_tag, language_tag, feature_tag, + &min_coord, &max_coord)) + return false; - inline int get_h_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const - { - return (this+hAxis).get_base_coord(baseScriptIndex, baselineTagIndex); - } - - inline unsigned int get_v_base_tag_index(Tag baselineTag) const - { - return (this+vAxis).get_base_tag_index(baselineTag); - } - - inline unsigned int get_v_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const - { - return (this+vAxis).get_default_base_tag_index_for_script_index(baseScriptIndex); - } - - inline int get_v_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const - { - return (this+vAxis).get_base_coord(baseScriptIndex, baselineTagIndex); - } - - inline unsigned int get_h_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const - { - return (this+hAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag); - } - - inline unsigned int get_h_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const - { - return (this+hAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag); - } - - inline int get_h_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const - { - return (this+hAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); - } - - inline int get_h_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const - { - return (this+hAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); - } - - inline unsigned int get_v_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const - { - return (this+vAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag); - } - - inline unsigned int get_v_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const - { - return (this+vAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag); - } - - inline int get_v_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const - { - return (this+vAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); - } - - inline int get_v_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const - { - return (this+vAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + const VariationStore &var_store = get_var_store (); + if (likely (min && min_coord)) *min = min_coord->get_coord (font, var_store, direction); + if (likely (max && max_coord)) *max = max_coord->get_coord (font, var_store, direction); + return true; } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - likely (version.major == 1) && - hAxis.sanitize (c, this) && - vAxis.sanitize (c, this) && - (version.to_int () < 0x00010001u || varStore.sanitize (c, this))); + return_trace (likely (c->check_struct (this) && + likely (version.major == 1) && + hAxis.sanitize (c, this) && + vAxis.sanitize (c, this) && + (version.to_int () < 0x00010001u || varStore.sanitize (c, this)))); } protected: - FixedVersion<> version; - OffsetTo hAxis; - OffsetTo vAxis; + FixedVersion<>version; /* Version of the BASE table */ + OffsetTohAxis; /* Offset to horizontal Axis table, from beginning + * of BASE table (may be NULL) */ + OffsetTovAxis; /* Offset to vertical Axis table, from beginning + * of BASE table (may be NULL) */ LOffsetTo - varStore; /* Offset to the table of Item Variation - * Store--from beginning of BASE - * header (may be NULL). Introduced - * in version 0x00010001. */ + varStore; /* Offset to the table of Item Variation + * Store--from beginning of BASE + * header (may be NULL). Introduced + * in version 0x00010001. */ public: DEFINE_SIZE_MIN (8); }; diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index b81aabd20..f1f09c76d 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -37,10 +37,8 @@ #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" - -#include "hb-ot-layout-base-table.hh" // Just so we compile them; unused otherwise -#include "hb-ot-layout-jstf-table.hh" // Just so we compile them; unused otherwise - +#include "hb-ot-layout-base-table.hh" // Just so we compile it; unused otherwise +#include "hb-ot-layout-jstf-table.hh" // Just so we compile it; unused otherwise #include "hb-ot-kern-table.hh" #include "hb-ot-name-table.hh" @@ -1425,3 +1423,62 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, { apply_string (c, lookup, accel); } + +#if 0 +static const OT::BASE& _get_base (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::BASE); + return *hb_ot_face_data (face)->BASE; +} + +hb_bool_t +hb_ot_layout_get_baseline (hb_font_t *font, + hb_ot_layout_baseline_t baseline, + hb_direction_t direction, + hb_tag_t script_tag, + hb_tag_t language_tag, + hb_position_t *coord /* OUT. May be NULL. */) +{ + const OT::BASE &base = _get_base (font->face); + bool result = base.get_baseline (font, baseline, direction, script_tag, + language_tag, coord); + + /* TODO: Simulate https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags#ideographic-em-box */ + if (!result && coord) *coord = 0; + + if (coord) *coord = font->em_scale_dir (*coord, direction); + + return result; +} + +/* To be moved to public header */ +/* + * BASE + */ + +/** + * hb_ot_layout_baseline_t: + * + * https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags + * + * Since: DONTREPLACEME + */ +typedef enum { + HB_OT_LAYOUT_BASELINE_HANG = HB_TAG('h','a','n','g'), + HB_OT_LAYOUT_BASELINE_ICFB = HB_TAG('i','c','f','b'), + HB_OT_LAYOUT_BASELINE_ICFT = HB_TAG('i','c','f','t'), + HB_OT_LAYOUT_BASELINE_IDEO = HB_TAG('i','d','e','o'), + HB_OT_LAYOUT_BASELINE_IDTB = HB_TAG('i','d','t','b'), + HB_OT_LAYOUT_BASELINE_MATH = HB_TAG('m','a','t','h'), + HB_OT_LAYOUT_BASELINE_ROMN = HB_TAG('r','o','m','n') +} hb_ot_layout_baseline_t; + +HB_EXTERN hb_bool_t +hb_ot_layout_get_baseline (hb_font_t *font, + hb_ot_layout_baseline_t baseline, + hb_direction_t direction, + hb_tag_t script_tag, + hb_tag_t language_tag, + hb_position_t *coord /* OUT. May be NULL. */); + +#endif diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 7a016c390..e47395412 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -391,22 +391,6 @@ hb_ot_layout_feature_get_characters (hb_face_t *face, unsigned int *char_count /* IN/OUT. May be NULL */, hb_codepoint_t *characters /* OUT. May be NULL */); -/* - * BASE - */ -#if 0 - -#define HB_OT_TAG_BASE_HANG HB_TAG('h','a','n','g') -#define HB_OT_TAG_BASE_ICFB HB_TAG('i','c','f','b') -#define HB_OT_TAG_BASE_ICFT HB_TAG('i','c','f','t') -#define HB_OT_TAG_BASE_IDEO HB_TAG('i','d','e','o') -#define HB_OT_TAG_BASE_IDTB HB_TAG('i','d','t','b') -#define HB_OT_TAG_BASE_MATH HB_TAG('m','a','t','h') -#define HB_OT_TAG_BASE_ROMN HB_TAG('r','o','m','n') - -#endif - - HB_END_DECLS #endif /* HB_OT_LAYOUT_H */ diff --git a/test/api/Makefile.am b/test/api/Makefile.am index c233a90ed..3b9857035 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -28,6 +28,7 @@ check_PROGRAMS = $(TEST_PROGS) noinst_PROGRAMS = $(TEST_PROGS) TEST_PROGS = \ + test-baseline \ test-blob \ test-buffer \ test-collect-unicodes \ diff --git a/test/api/fonts/base.ttf b/test/api/fonts/base.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d98496683c503a9ee00806af6ed47c4c06d7674b GIT binary patch literal 5596 zcmbU_3sh5Aw&y0~CWIK3a4`xcS44`+uYf#8ZL7#vQ4sJ)Q3)SODv(G5!qg8AR&W48 z5Ey?|YDH;vUdvNTwOA0ps8sFLu1=k0E45I4e!6PkNj!0Q``iRO)0y`=@7=7k_dfgV zv(Mi9?31(aO-xNqM59p|5+h^eoRsK{Z@2m(#En4+U6~sb!&kiW>IsD8o(RcqM5V;X z0-r%hr2s68O<5e-yYlI$(02p&`-v$*A&Xyo@DtD(FrKj_F*#Pe7AWL)7Jw`(Uu!%b zF6#vHD99x0a#Z;d{BtgjaG4v-; zPoS0mI5E|2)#zD2A+dM}IOwy$AHgRF_86`d-xeF8D@G#9g$L$2RsOXbSVPDIIg4)# znuH+-5F-S3(kO|=ZA=}4HATM{QLE?MF|!hdFwwwufuWIyk&RG*=R`#&qS=VATOc+L zSJD-k*}$eYBaue*7eKtw8-vb+ZH$vMaO$DiX$HAM&rXYw620S~#V8WBJ7}lBk&z%X zdg9=-h-Y*TT86@yN(b$Xl9-Pjw49NP6b{-2g^ArA^e9o2c%Fk+qAsr~qZbXd!5$P%DgO!-$`t)eQU@C!C==+uqX}SqPpjih}X2HS&RQ!A_5d8*)!)QL(vg#duns8 zuv13x(FC!Nf?gnu&WAA?mjsA;fgnjW7-7_aUWc(P@Rb+#A`52fp=am$12-2UPztg- zpiRK1l60-rAXgyBjzpc>VStFzz0ks}Jm}lk$cA<48g|Jk5M>@M02vcBGc@W855CTU z3`vFEPX@2~+);HyYqF}3!^nuOf3N3%@|*_?@}T8ID**j867(GWYZ+@6yv>2!O%-B6 z&q56NMK#e=VgS$0knuEg>ABH^eje7-gNJlI8Y6m2Mj~AZv>7zn&se;04iX_Q_8s|I zbHd+gpppM)SxqyWo+G+T|C(jlf}|O&rFmQgw%F~npA?!yJo1Lf(^En-&Kq!~(5F3W z$5P;@!tNwO9;OQYIj}>?AhQtq@o@g=T)JyKobyEBMhP?G1=>Cq17lQvIpFy)N@b|- z9I(nB9U7+`R3c;y{gdqx%ERv2wT{d+344(R+G$2- zfmZsjR3Q96X#wU4cGCSS1UqQdNB(E1g;bL6Hnon9(rg~db2^?2tJzNkJu6fzFP!lr z!LuUJMg5>TW%uUSb~W%9nQQ`!>CPHqRTIR9+Li~H`j`tjoCvv_@ch4u4?Z9KQSe2$ z+29fs?l;76fa%5Q1NRC8m!dPhSpaiz(;;*hnv0U5h(6^?<~uuus+G*3gKShX^tOMC zc9qQc4sNTGx#uANUCG>ckey0~RuJ^*Q8Ewg6zWql4;|!ZO6HM+yakv+bqkPugrK*& zzdAj z%L|OfOJvcAEovt+RUxh-il?ThP7<#PNTbj+E4*>zX#CDtyh}0JlYOM{K~jccm5Wy! z-aIfT+mM+PpPf@+)|*S`8jPid`dpov4+(xLEC4__F9`4{r6zMuzKM@7$TAcf4TV~B zPB!nSGn=oH*S1z7#um>nD0INhi)4<$+>+`6fQ}1#^AS z;{QEfHYmRC&dV*|ksmmGs9QRCT0eE#vK2uZyxr!`kxBT^k}nT;_5ard>%JxIOKkj7RaJ(&H*wc{-#d3wliDlE zSfek>@Cb^!i&x{UFYey%Xfx|uHD}IAPUx0=5bZ%;ATlzF{DJJk65@rr}UB-I6ZxXO&eC@x33h z=qm?&=VR-4xzqdxUv=ZO;^UYhk?E>>^Fk_wzxgC%v_4>TX$xrZpr z$%aZIsUyyHA;;2h%9M*f7kq8IR(7@zeC;|7zFx6>1-P5m#o~Yl9J3#@?=Cr|4l3h^9LrTV%k$FLc_fpjz*t_LWQPcV} ze`$NT`yON<{*KH0Am-ymZD}jj=hpNuYs--xBz~O!{ist552vqCUs!W}`O(#~)(DO) zjlp9{GP^SKHLW(kJxYD5qw_>Z$K{s?bu=VS6-ie&C1VimtoH15niyP z_PVC#?dA`5?w6IlNc?|CMtczF=?y31G^^h(YAJ4(DP#K|9(rub%LXpSHdR`^r)u}E z2?wQ?JmSLPmu-1RrTEnboV*Xa9a-{`nn>1?+!7L9E+auw;C6`MLWr#xVyi?VhLNi*yu!EDQz~_}OjP)`c}l%qH|(;Sn%S%JTP{}{_9zs$niQj+ zu6M&$?yQPzukw_{RI%seeJCMOT#wd`Fy6~ADUO75{F z3X(Apzbl!>l5`s@sj#p?tP66c7fUWWh8{6WW;`>Ed6|i4Qd+OQd;8#LGLjL8MeN#H zYr>65GCY=DA7!3tOj%Q`&(tkH9jER)a;&e#DZqRJ=k|g=E6O>>n$bg-Jc8qDs_Ky$6JaY zcK$+0=!F{*)7{DedP7#?dxUjtyMesYW6qQ?rELi5^g!eO|$*m zeW_&wnabe|QY_tkWZj83-is|(H=CN*G_IAA8WO^iQRO5$mW+e#Yb$BmbOkH-;#am~ zPUZqxvc;?X_v@+(s~djXP*hV23sg7m*SytKx2tV}OF4{{RIROUSntAZ>?pcgdOE&D zy?1F#OtV(zav9J3ngn$Vc2YRSMOo@e>LlT2R@`DmgmBz&8z@wjdX|0n{VkJgvC^-bP@2equ6D>pLj3>@%DM zj%Qk29FKg`;!=3zpB9(O!lP!_gp5#IGf+}eKCBB+iky)f z@`Q@pAH13cZ$b(19!0%p;4RCJV;nfjfg>GwwgbQ7z_T29h66_c4u{6TR|*QJf-MZJ zL~D94C{`JyhDN_=QNHli39O=gTJlN((>@cuL0 WffzAF8om)y+ZlL|V#Fr_m;5)%n?nl# literal 0 HcmV?d00001 diff --git a/test/api/test-baseline.c b/test/api/test-baseline.c new file mode 100644 index 000000000..a120e14f3 --- /dev/null +++ b/test/api/test-baseline.c @@ -0,0 +1,58 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include "hb-test.h" + +#include + +/* Unit tests for hb-ot-layout.h baseline */ + +static void +test_ot_layout_base (void) +{ + hb_face_t *face = hb_test_open_font_file ("fonts/base.ttf"); + hb_font_t *font = hb_font_create (face); + +#if 0 + hb_position_t position; + g_assert (hb_ot_layout_get_baseline (font, HB_OT_LAYOUT_BASELINE_ICFB, HB_DIRECTION_TTB, + HB_TAG ('h','a','n','i'), + HB_TAG ('E','N','G',' '), + &position)); + g_assert_cmpint (46, ==, position); +#endif + + hb_font_destroy (font); + hb_face_destroy (face); +} + +int +main (int argc, char **argv) +{ + hb_test_init (&argc, &argv); + + hb_test_add (test_ot_layout_base); + + return hb_test_run(); +} From ee351a38ec0c62b76dd1b3f20fe56cb4d63e62be Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 14:28:55 -0400 Subject: [PATCH 20/40] [object] Add "writable" --- src/hb-object.hh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/hb-object.hh b/src/hb-object.hh index 106f59206..309aa2b41 100644 --- a/src/hb-object.hh +++ b/src/hb-object.hh @@ -194,9 +194,10 @@ struct hb_user_data_array_t struct hb_object_header_t { hb_reference_count_t ref_count; + hb_atomic_int_t writable; hb_atomic_ptr_t user_data; }; -#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_ATOMIC_PTR_INIT (nullptr)} +#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_ATOMIC_INT_INIT (0), HB_ATOMIC_PTR_INIT (nullptr)} /* @@ -228,6 +229,7 @@ template static inline void hb_object_init (Type *obj) { obj->header.ref_count.init (); + obj->header.writable.set_relaxed (true); obj->header.user_data.init (); } template @@ -241,6 +243,16 @@ static inline bool hb_object_is_valid (const Type *obj) return likely (obj->header.ref_count.is_valid ()); } template +static inline bool hb_object_is_immutable (const Type *obj) +{ + return !obj->header.writable.get_relaxed (); +} +template +static inline bool hb_object_make_immutable (const Type *obj) +{ + return !obj->header.writable.set_relaxed (false); +} +template static inline Type *hb_object_reference (Type *obj) { hb_object_trace (obj, HB_FUNC); From 5570c87f21f061cc197e02bd0526ab44c63ed6f1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 14:51:38 -0400 Subject: [PATCH 21/40] Port objects to use header.writable instead of immutable Saves 4 or 8 bytes per object on 64bit archs. --- src/hb-blob.cc | 12 ++++-------- src/hb-blob.hh | 2 -- src/hb-face.cc | 16 ++++++---------- src/hb-face.hh | 2 -- src/hb-font.cc | 46 +++++++++++++++++++--------------------------- src/hb-font.hh | 4 ---- src/hb-ft.cc | 2 +- src/hb-object.hh | 11 ++++++++--- src/hb-unicode.cc | 11 ++++------- src/hb-unicode.hh | 2 -- 10 files changed, 42 insertions(+), 66 deletions(-) diff --git a/src/hb-blob.cc b/src/hb-blob.cc index 51f22ce4d..4b036e804 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -57,8 +57,6 @@ DEFINE_NULL_INSTANCE (hb_blob_t) = { HB_OBJECT_HEADER_STATIC, - true, /* immutable */ - nullptr, /* data */ 0, /* length */ HB_MEMORY_MODE_READONLY, /* mode */ @@ -299,12 +297,10 @@ hb_blob_get_user_data (hb_blob_t *blob, void hb_blob_make_immutable (hb_blob_t *blob) { - if (hb_object_is_inert (blob)) - return; - if (blob->immutable) + if (hb_object_is_immutable (blob)) return; - blob->immutable = true; + hb_object_make_immutable (blob); } /** @@ -320,7 +316,7 @@ hb_blob_make_immutable (hb_blob_t *blob) hb_bool_t hb_blob_is_immutable (hb_blob_t *blob) { - return blob->immutable; + return hb_object_is_immutable (blob); } @@ -454,7 +450,7 @@ hb_blob_t::try_make_writable_inplace (void) bool hb_blob_t::try_make_writable (void) { - if (this->immutable) + if (hb_object_is_immutable (this)) return false; if (this->mode == HB_MEMORY_MODE_WRITABLE) diff --git a/src/hb-blob.hh b/src/hb-blob.hh index 0181e94a4..1f7499fbf 100644 --- a/src/hb-blob.hh +++ b/src/hb-blob.hh @@ -70,8 +70,6 @@ struct hb_blob_t public: hb_object_header_t header; - bool immutable; - const char *data; unsigned int length; hb_memory_mode_t mode; diff --git a/src/hb-face.cc b/src/hb-face.cc index 7ca4b1ba2..50ab10e38 100644 --- a/src/hb-face.cc +++ b/src/hb-face.cc @@ -82,8 +82,6 @@ DEFINE_NULL_INSTANCE (hb_face_t) = { HB_OBJECT_HEADER_STATIC, - true, /* immutable */ - nullptr, /* reference_table_func */ nullptr, /* user_data */ nullptr, /* destroy */ @@ -336,12 +334,10 @@ hb_face_get_user_data (const hb_face_t *face, void hb_face_make_immutable (hb_face_t *face) { - if (unlikely (hb_object_is_inert (face))) - return; - if (face->immutable) + if (hb_object_is_immutable (face)) return; - face->immutable = true; + hb_object_make_immutable (face); } /** @@ -357,7 +353,7 @@ hb_face_make_immutable (hb_face_t *face) hb_bool_t hb_face_is_immutable (const hb_face_t *face) { - return face->immutable; + return hb_object_is_immutable (face); } @@ -408,7 +404,7 @@ void hb_face_set_index (hb_face_t *face, unsigned int index) { - if (face->immutable) + if (hb_object_is_immutable (face)) return; face->index = index; @@ -443,7 +439,7 @@ void hb_face_set_upem (hb_face_t *face, unsigned int upem) { - if (face->immutable) + if (hb_object_is_immutable (face)) return; face->upem = upem; @@ -478,7 +474,7 @@ void hb_face_set_glyph_count (hb_face_t *face, unsigned int glyph_count) { - if (face->immutable) + if (hb_object_is_immutable (face)) return; face->num_glyphs = glyph_count; diff --git a/src/hb-face.hh b/src/hb-face.hh index 89673ff84..520bdfdf8 100644 --- a/src/hb-face.hh +++ b/src/hb-face.hh @@ -43,8 +43,6 @@ struct hb_face_t { hb_object_header_t header; - hb_bool_t immutable; - hb_reference_table_func_t reference_table_func; void *user_data; hb_destroy_func_t destroy; diff --git a/src/hb-font.cc b/src/hb-font.cc index 86b03f4b6..567cdedc0 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -471,8 +471,6 @@ DEFINE_NULL_INSTANCE (hb_font_funcs_t) = { HB_OBJECT_HEADER_STATIC, - true, /* immutable */ - { #define HB_FONT_FUNC_IMPLEMENT(name) nullptr, HB_FONT_FUNCS_IMPLEMENT_CALLBACKS @@ -495,8 +493,6 @@ DEFINE_NULL_INSTANCE (hb_font_funcs_t) = static const hb_font_funcs_t _hb_font_funcs_default = { HB_OBJECT_HEADER_STATIC, - true, /* immutable */ - { #define HB_FONT_FUNC_IMPLEMENT(name) nullptr, HB_FONT_FUNCS_IMPLEMENT_CALLBACKS @@ -645,12 +641,10 @@ hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, void hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) { - if (unlikely (hb_object_is_inert (ffuncs))) - return; - if (ffuncs->immutable) + if (hb_object_is_immutable (ffuncs)) return; - ffuncs->immutable = true; + hb_object_make_immutable (ffuncs); } /** @@ -666,7 +660,7 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) hb_bool_t hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) { - return ffuncs->immutable; + return hb_object_is_immutable (ffuncs); } @@ -678,7 +672,7 @@ hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ void *user_data, \ hb_destroy_func_t destroy) \ { \ - if (ffuncs->immutable) { \ + if (hb_object_is_immutable (ffuncs)) { \ if (destroy) \ destroy (user_data); \ return; \ @@ -1299,8 +1293,6 @@ DEFINE_NULL_INSTANCE (hb_font_t) = { HB_OBJECT_HEADER_STATIC, - true, /* immutable */ - nullptr, /* parent */ const_cast (&_hb_Null_hb_face_t), @@ -1525,15 +1517,13 @@ hb_font_get_user_data (hb_font_t *font, void hb_font_make_immutable (hb_font_t *font) { - if (unlikely (hb_object_is_inert (font))) - return; - if (font->immutable) + if (hb_object_is_immutable (font)) return; if (font->parent) hb_font_make_immutable (font->parent); - font->immutable = true; + hb_object_make_immutable (font); } /** @@ -1549,7 +1539,7 @@ hb_font_make_immutable (hb_font_t *font) hb_bool_t hb_font_is_immutable (hb_font_t *font) { - return font->immutable; + return hb_object_is_immutable (font); } /** @@ -1565,7 +1555,7 @@ void hb_font_set_parent (hb_font_t *font, hb_font_t *parent) { - if (font->immutable) + if (hb_object_is_immutable (font)) return; if (!parent) @@ -1607,7 +1597,7 @@ void hb_font_set_face (hb_font_t *font, hb_face_t *face) { - if (font->immutable) + if (hb_object_is_immutable (font)) return; if (unlikely (!face)) @@ -1654,7 +1644,8 @@ hb_font_set_funcs (hb_font_t *font, void *font_data, hb_destroy_func_t destroy) { - if (font->immutable) { + if (hb_object_is_immutable (font)) + { if (destroy) destroy (font_data); return; @@ -1689,7 +1680,8 @@ hb_font_set_funcs_data (hb_font_t *font, hb_destroy_func_t destroy) { /* Destroy user_data? */ - if (font->immutable) { + if (hb_object_is_immutable (font)) + { if (destroy) destroy (font_data); return; @@ -1718,7 +1710,7 @@ hb_font_set_scale (hb_font_t *font, int x_scale, int y_scale) { - if (font->immutable) + if (hb_object_is_immutable (font)) return; font->x_scale = x_scale; @@ -1759,7 +1751,7 @@ hb_font_set_ppem (hb_font_t *font, unsigned int x_ppem, unsigned int y_ppem) { - if (font->immutable) + if (hb_object_is_immutable (font)) return; font->x_ppem = x_ppem; @@ -1799,7 +1791,7 @@ hb_font_get_ppem (hb_font_t *font, void hb_font_set_ptem (hb_font_t *font, float ptem) { - if (font->immutable) + if (hb_object_is_immutable (font)) return; font->ptem = ptem; @@ -1846,7 +1838,7 @@ hb_font_set_variations (hb_font_t *font, const hb_variation_t *variations, unsigned int variations_length) { - if (font->immutable) + if (hb_object_is_immutable (font)) return; if (!variations_length) @@ -1877,7 +1869,7 @@ hb_font_set_var_coords_design (hb_font_t *font, const float *coords, unsigned int coords_length) { - if (font->immutable) + if (hb_object_is_immutable (font)) return; int *normalized = coords_length ? (int *) calloc (coords_length, sizeof (int)) : nullptr; @@ -1898,7 +1890,7 @@ hb_font_set_var_coords_normalized (hb_font_t *font, const int *coords, /* 2.14 normalized */ unsigned int coords_length) { - if (font->immutable) + if (hb_object_is_immutable (font)) return; int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : nullptr; diff --git a/src/hb-font.hh b/src/hb-font.hh index 3dce233db..fb29bcc22 100644 --- a/src/hb-font.hh +++ b/src/hb-font.hh @@ -63,8 +63,6 @@ struct hb_font_funcs_t { hb_object_header_t header; - hb_bool_t immutable; - struct { #define HB_FONT_FUNC_IMPLEMENT(name) void *name; HB_FONT_FUNCS_IMPLEMENT_CALLBACKS @@ -102,8 +100,6 @@ struct hb_font_t { hb_object_header_t header; - hb_bool_t immutable; - hb_font_t *parent; hb_face_t *face; diff --git a/src/hb-ft.cc b/src/hb-ft.cc index 5e0511052..8b80b960b 100644 --- a/src/hb-ft.cc +++ b/src/hb-ft.cc @@ -135,7 +135,7 @@ _hb_ft_font_destroy (void *data) void hb_ft_font_set_load_flags (hb_font_t *font, int load_flags) { - if (font->immutable) + if (hb_object_is_immutable (font)) return; if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy) diff --git a/src/hb-object.hh b/src/hb-object.hh index 309aa2b41..74340c555 100644 --- a/src/hb-object.hh +++ b/src/hb-object.hh @@ -197,7 +197,12 @@ struct hb_object_header_t hb_atomic_int_t writable; hb_atomic_ptr_t user_data; }; -#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_ATOMIC_INT_INIT (0), HB_ATOMIC_PTR_INIT (nullptr)} +#define HB_OBJECT_HEADER_STATIC \ + { \ + HB_REFERENCE_COUNT_INIT, \ + HB_ATOMIC_INT_INIT (false), \ + HB_ATOMIC_PTR_INIT (nullptr) \ + } /* @@ -248,9 +253,9 @@ static inline bool hb_object_is_immutable (const Type *obj) return !obj->header.writable.get_relaxed (); } template -static inline bool hb_object_make_immutable (const Type *obj) +static inline void hb_object_make_immutable (const Type *obj) { - return !obj->header.writable.set_relaxed (false); + obj->header.writable.set_relaxed (false); } template static inline Type *hb_object_reference (Type *obj) diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc index 8cf7898a1..5accf3643 100644 --- a/src/hb-unicode.cc +++ b/src/hb-unicode.cc @@ -187,7 +187,6 @@ DEFINE_NULL_INSTANCE (hb_unicode_funcs_t) = HB_OBJECT_HEADER_STATIC, nullptr, /* parent */ - true, /* immutable */ { #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil, HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS @@ -303,12 +302,10 @@ hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs, void hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs) { - if (unlikely (hb_object_is_inert (ufuncs))) - return; - if (ufuncs->immutable) + if (hb_object_is_immutable (ufuncs)) return; - ufuncs->immutable = true; + hb_object_make_immutable (ufuncs); } /** @@ -324,7 +321,7 @@ hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs) hb_bool_t hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs) { - return ufuncs->immutable; + return hb_object_is_immutable (ufuncs); } /** @@ -352,7 +349,7 @@ hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t *ufuncs, \ void *user_data, \ hb_destroy_func_t destroy) \ { \ - if (ufuncs->immutable) \ + if (hb_object_is_immutable (ufuncs)) \ return; \ \ if (ufuncs->destroy.name) \ diff --git a/src/hb-unicode.hh b/src/hb-unicode.hh index 0b66ce8a1..d3fd5ea4b 100644 --- a/src/hb-unicode.hh +++ b/src/hb-unicode.hh @@ -66,8 +66,6 @@ struct hb_unicode_funcs_t hb_unicode_funcs_t *parent; - bool immutable; - #define HB_UNICODE_FUNC_IMPLEMENT(return_type, name) \ inline return_type name (hb_codepoint_t unicode) { return func.name (this, unicode, user_data.name); } HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE From 0589787ff55bff9bd5849c4443229e926cc574a5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 14:58:54 -0400 Subject: [PATCH 22/40] [kern] Fix access violation in Format3 Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11245 --- src/hb-ot-kern-table.hh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 9f8a0115c..28ea9526d 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -417,7 +417,11 @@ struct KernSubTableFormat3 hb_array_t rightClass = StructAfter > (leftClass).as_array (glyphCount); hb_array_t kernIndex = StructAfter > (rightClass).as_array (leftClassCount * rightClassCount); - unsigned int i = leftClass[left] * rightClassCount + rightClass[right]; + unsigned int leftC = leftClass[left]; + unsigned int rightC = rightClass[right]; + if (unlikely (leftC >= leftClassCount || rightC >= rightClassCount)) + return 0; + unsigned int i = leftC * rightClassCount + rightC; return kernValue[kernIndex[i]]; } From 93ef20a83b31e6528bb1835d2b4b83b913805885 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 15:03:06 -0400 Subject: [PATCH 23/40] Replace most uses of is_inert with is_immutable --- src/hb-buffer.cc | 32 ++++++++++++++++---------------- src/hb-coretext.cc | 2 +- src/hb-font.cc | 2 +- src/hb-set.hh | 8 +++++--- src/hb-shape-plan.cc | 2 +- 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index 5a8152ed4..1a5547b35 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -217,7 +217,7 @@ hb_buffer_t::get_scratch_buffer (unsigned int *size) void hb_buffer_t::reset (void) { - if (unlikely (hb_object_is_inert (this))) + if (unlikely (hb_object_is_immutable (this))) return; hb_unicode_funcs_destroy (unicode); @@ -232,7 +232,7 @@ hb_buffer_t::reset (void) void hb_buffer_t::clear (void) { - if (unlikely (hb_object_is_inert (this))) + if (unlikely (hb_object_is_immutable (this))) return; hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT; @@ -289,7 +289,7 @@ hb_buffer_t::add_info (const hb_glyph_info_t &glyph_info) void hb_buffer_t::remove_output (void) { - if (unlikely (hb_object_is_inert (this))) + if (unlikely (hb_object_is_immutable (this))) return; have_output = false; @@ -302,7 +302,7 @@ hb_buffer_t::remove_output (void) void hb_buffer_t::clear_output (void) { - if (unlikely (hb_object_is_inert (this))) + if (unlikely (hb_object_is_immutable (this))) return; have_output = true; @@ -315,7 +315,7 @@ hb_buffer_t::clear_output (void) void hb_buffer_t::clear_positions (void) { - if (unlikely (hb_object_is_inert (this))) + if (unlikely (hb_object_is_immutable (this))) return; have_output = false; @@ -873,7 +873,7 @@ void hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, hb_unicode_funcs_t *unicode_funcs) { - if (unlikely (hb_object_is_inert (buffer))) + if (unlikely (hb_object_is_immutable (buffer))) return; if (!unicode_funcs) @@ -920,7 +920,7 @@ hb_buffer_set_direction (hb_buffer_t *buffer, hb_direction_t direction) { - if (unlikely (hb_object_is_inert (buffer))) + if (unlikely (hb_object_is_immutable (buffer))) return; buffer->props.direction = direction; @@ -964,7 +964,7 @@ void hb_buffer_set_script (hb_buffer_t *buffer, hb_script_t script) { - if (unlikely (hb_object_is_inert (buffer))) + if (unlikely (hb_object_is_immutable (buffer))) return; buffer->props.script = script; @@ -1008,7 +1008,7 @@ void hb_buffer_set_language (hb_buffer_t *buffer, hb_language_t language) { - if (unlikely (hb_object_is_inert (buffer))) + if (unlikely (hb_object_is_immutable (buffer))) return; buffer->props.language = language; @@ -1046,7 +1046,7 @@ void hb_buffer_set_segment_properties (hb_buffer_t *buffer, const hb_segment_properties_t *props) { - if (unlikely (hb_object_is_inert (buffer))) + if (unlikely (hb_object_is_immutable (buffer))) return; buffer->props = *props; @@ -1082,7 +1082,7 @@ void hb_buffer_set_flags (hb_buffer_t *buffer, hb_buffer_flags_t flags) { - if (unlikely (hb_object_is_inert (buffer))) + if (unlikely (hb_object_is_immutable (buffer))) return; buffer->flags = flags; @@ -1118,7 +1118,7 @@ void hb_buffer_set_cluster_level (hb_buffer_t *buffer, hb_buffer_cluster_level_t cluster_level) { - if (unlikely (hb_object_is_inert (buffer))) + if (unlikely (hb_object_is_immutable (buffer))) return; buffer->cluster_level = cluster_level; @@ -1157,7 +1157,7 @@ void hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, hb_codepoint_t replacement) { - if (unlikely (hb_object_is_inert (buffer))) + if (unlikely (hb_object_is_immutable (buffer))) return; buffer->replacement = replacement; @@ -1197,7 +1197,7 @@ void hb_buffer_set_invisible_glyph (hb_buffer_t *buffer, hb_codepoint_t invisible) { - if (unlikely (hb_object_is_inert (buffer))) + if (unlikely (hb_object_is_immutable (buffer))) return; buffer->invisible = invisible; @@ -1329,7 +1329,7 @@ hb_bool_t hb_buffer_set_length (hb_buffer_t *buffer, unsigned int length) { - if (unlikely (hb_object_is_inert (buffer))) + if (unlikely (hb_object_is_immutable (buffer))) return length == 0; if (!buffer->ensure (length)) @@ -1535,7 +1535,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer, assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE || (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID)); - if (unlikely (hb_object_is_inert (buffer))) + if (unlikely (hb_object_is_immutable (buffer))) return; if (text_length == -1) diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc index 184db4944..893a8761d 100644 --- a/src/hb-coretext.cc +++ b/src/hb-coretext.cc @@ -353,7 +353,7 @@ hb_coretext_font_create (CTFontRef ct_font) hb_font_t *font = hb_font_create (face); hb_face_destroy (face); - if (unlikely (hb_object_is_inert (font))) + if (unlikely (hb_object_is_immutable (font))) return font; hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font))); diff --git a/src/hb-font.cc b/src/hb-font.cc index 567cdedc0..b24995b12 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -1377,7 +1377,7 @@ hb_font_create_sub_font (hb_font_t *parent) hb_font_t *font = _hb_font_create (parent->face); - if (unlikely (hb_object_is_inert (font))) + if (unlikely (hb_object_is_immutable (font))) return font; font->parent = hb_font_reference (parent); diff --git a/src/hb-set.hh b/src/hb-set.hh index 947e8d9d1..21a22525f 100644 --- a/src/hb-set.hh +++ b/src/hb-set.hh @@ -225,15 +225,17 @@ struct hb_set_t return true; } - inline void clear (void) { - if (unlikely (hb_object_is_inert (this))) + inline void clear (void) + { + if (unlikely (hb_object_is_immutable (this))) return; successful = true; population = 0; page_map.resize (0); pages.resize (0); } - inline bool is_empty (void) const { + inline bool is_empty (void) const + { unsigned int count = pages.len; for (unsigned int i = 0; i < count; i++) if (!pages[i].is_empty ()) diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index 4648cc757..8d002f8a7 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -343,7 +343,7 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, if (unlikely (!buffer->len)) return true; - assert (!hb_object_is_inert (buffer)); + assert (!hb_object_is_immutable (buffer)); assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE); if (unlikely (hb_object_is_inert (shape_plan))) From f074da8c2b6a7061c71d12213a6c494c119eb20e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 15:06:45 -0400 Subject: [PATCH 24/40] [kern] Really fix access violation in Format3 Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11245 --- src/hb-ot-kern-table.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 28ea9526d..b0ed4399b 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -444,7 +444,7 @@ struct KernSubTableFormat3 return_trace (true); /* Disabled. See above. */ return_trace (c->check_struct (this) && c->check_range (kernValueZ, - kernValueCount + + kernValueCount * sizeof (FWORD) + glyphCount * 2 + leftClassCount * rightClassCount)); } From 8d98c51d133b058a845ed7a84bfe8a43083bbb03 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 15:14:57 -0400 Subject: [PATCH 25/40] [kern] Third try fix access violation in Format3 Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11245 --- src/hb-ot-kern-table.hh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index b0ed4399b..e361330b0 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -441,7 +441,6 @@ struct KernSubTableFormat3 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (true); /* Disabled. See above. */ return_trace (c->check_struct (this) && c->check_range (kernValueZ, kernValueCount * sizeof (FWORD) + From fb0f30f55a5d654b2f1f9b99efa9b8abc51dbf34 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 15:24:14 -0400 Subject: [PATCH 26/40] Add hb_nonnull_ptr_t Towards fixing https://github.com/harfbuzz/harfbuzz/issues/1146 --- src/hb-null.hh | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/hb-null.hh b/src/hb-null.hh index d5b74bf56..151277ca7 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -103,4 +103,32 @@ struct CrapOrNull { #define CrapOrNull(Type) CrapOrNull::get () +/* + * hb_nonnull_ptr_t + */ + +template +struct hb_nonnull_ptr_t +{ + typedef typename hb_remove_pointer

::value T; + + inline hb_nonnull_ptr_t (T *v_ = nullptr) : v (v_) {} + inline T * operator = (T *v_) { return v = v_; } + inline T * operator -> (void) { return get (); } + inline const T * operator -> (void) const { return get (); } + inline T & operator * (void) { return *get (); } + inline const T & operator * (void) const { return *get (); } + inline T ** operator & (void) { return &v; } + inline const T ** operator & (void) const { return &v; } + inline operator T * (void) { return get (); } + inline operator const T * (void) const { return get (); } + inline T * get (void) { return v ? v : const_cast (&Null(T)); } + inline const T * get (void) const { return v ? v : const_cast (&Null(T)); } + inline T * get_raw (void) { return v; } + inline const T * get_raw (void) const { return v; } + + T *v; +}; + + #endif /* HB_NULL_HH */ From da408fce98153e0fab3d82fe28813085feed0974 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 15:49:37 -0400 Subject: [PATCH 27/40] [blob] Allow null parent in create_sub_blob() Like font and unicode. --- src/hb-blob.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-blob.cc b/src/hb-blob.cc index 4b036e804..9271200b1 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -149,7 +149,7 @@ hb_blob_create_sub_blob (hb_blob_t *parent, { hb_blob_t *blob; - if (!length || offset >= parent->length) + if (!length || !parent || offset >= parent->length) return hb_blob_get_empty (); hb_blob_make_immutable (parent); From 7430ff604aa54bedcb07cc1c2962eae85fcade76 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 15:59:13 -0400 Subject: [PATCH 28/40] Template casts in hb_nonnull_ptr_t --- src/hb-null.hh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hb-null.hh b/src/hb-null.hh index 151277ca7..a3f0ea079 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -120,8 +120,10 @@ struct hb_nonnull_ptr_t inline const T & operator * (void) const { return *get (); } inline T ** operator & (void) { return &v; } inline const T ** operator & (void) const { return &v; } - inline operator T * (void) { return get (); } - inline operator const T * (void) const { return get (); } + template + inline operator C * (void) { return get (); } + template + inline operator const C * (void) const { return get (); } inline T * get (void) { return v ? v : const_cast (&Null(T)); } inline const T * get (void) const { return v ? v : const_cast (&Null(T)); } inline T * get_raw (void) { return v; } From d6fdae310f2a98ca624c3a77c3aa03b8b3bd393a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 16:02:03 -0400 Subject: [PATCH 29/40] Add operator char * to hb_nonnull_ptr_t --- src/hb-null.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb-null.hh b/src/hb-null.hh index a3f0ea079..c91af1636 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -120,10 +120,10 @@ struct hb_nonnull_ptr_t inline const T & operator * (void) const { return *get (); } inline T ** operator & (void) { return &v; } inline const T ** operator & (void) const { return &v; } - template - inline operator C * (void) { return get (); } - template - inline operator const C * (void) const { return get (); } + template inline operator C * (void) { return get (); } + template inline operator const C * (void) const { return get (); } + inline operator char * (void) { return (char *) get (); } + inline operator const char * (void) const { return (const char *) get (); } inline T * get (void) { return v ? v : const_cast (&Null(T)); } inline const T * get (void) const { return v ? v : const_cast (&Null(T)); } inline T * get_raw (void) { return v; } From db889c182ee5f54127285bfaab5bc94dafe46bda Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 16:04:19 -0400 Subject: [PATCH 30/40] Add operator char * to the naked array types as well --- src/hb-dsalgs.hh | 4 +++- src/hb-open-type.hh | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index f2bff063d..fafac1f72 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -553,8 +553,10 @@ struct hb_array_t inline unsigned int get_size (void) const { return len * sizeof (Type); } - template inline operator T * (void) { return arrayZ; } + template inline operator T * (void) { return arrayZ; } template inline operator const T * (void) const { return arrayZ; } + inline operator char * (void) { return (char *) arrayZ; } + inline operator const char * (void) const { return (const char *) arrayZ; } inline Type * operator & (void) { return arrayZ; } inline const Type * operator & (void) const { return arrayZ; } diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 0f6efdc69..e1dc8aab1 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -342,6 +342,8 @@ struct UnsizedArrayOf template inline operator T * (void) { return arrayZ; } template inline operator const T * (void) const { return arrayZ; } + inline operator char * (void) { return (char *) arrayZ; } + inline operator const char * (void) const { return (const char *) arrayZ; } inline unsigned int get_size (unsigned int len) const { return len * Type::static_size; } From 0b0b38ec1e6a815a30bef98193043d255b52c4a1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 16:15:30 -0400 Subject: [PATCH 31/40] Fix null accelerator's Fixes all except for cmap. To be done separately. Part of https://github.com/harfbuzz/harfbuzz/issues/1146 --- src/hb-ot-color-cbdt-table.hh | 10 ++-------- src/hb-ot-color-sbix-table.hh | 11 ++++------- src/hb-ot-color-svg-table.hh | 11 ++++------- src/hb-ot-glyf-table.hh | 6 +++--- src/hb-ot-layout-gdef-table.hh | 2 +- src/hb-ot-layout-gsubgpos.hh | 2 +- src/hb-ot-name-table.hh | 2 +- src/hb-ot-post-table.hh | 2 +- 8 files changed, 17 insertions(+), 29 deletions(-) diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 614cc80ce..580dc3769 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -409,9 +409,6 @@ struct CBDT inline bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { - if (!cblc) - return false; - const void *base; const BitmapSizeTable &strike = this->cblc->choose_strike (font); const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base); @@ -467,9 +464,6 @@ struct CBDT inline hb_blob_t* reference_png (hb_font_t *font, hb_codepoint_t glyph) const { - if (!cblc) - return hb_blob_get_empty (); - const void *base; const BitmapSizeTable &strike = this->cblc->choose_strike (font); const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base); @@ -525,8 +519,8 @@ struct CBDT private: hb_blob_t *cblc_blob; hb_blob_t *cbdt_blob; - const CBLC *cblc; - const CBDT *cbdt; + hb_nonnull_ptr_t cblc; + hb_nonnull_ptr_t cbdt; unsigned int cbdt_len; unsigned int upem; diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 065c0dd18..7a01d14ae 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -152,9 +152,6 @@ struct sbix inline bool has_data () const { - /* XXX Fix somehow and remove next line. - * https://github.com/harfbuzz/harfbuzz/issues/1146 */ - if (!num_glyphs) return false; return table->has_data (); } @@ -234,8 +231,8 @@ struct sbix hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { - /* Following code is safe to call even without data (XXX currently - * isn't. See has_data()), but faster to short-circuit. */ + /* Following code is safe to call even without data. + * But faster to short-circuit. */ if (!has_data ()) return false; @@ -262,12 +259,12 @@ struct sbix hb_blob_destroy (blob); - return true; + return strike_ppem; } private: hb_blob_t *sbix_blob; - const sbix *table; + hb_nonnull_ptr_t table; unsigned int num_glyphs; }; diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index bb4c4f757..069c54788 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -75,12 +75,13 @@ struct SVG { static const hb_tag_t tableTag = HB_OT_TAG_SVG; + inline bool has_data (void) const { return svgDocEntries; } + struct accelerator_t { inline void init (hb_face_t *face) { svg_blob = hb_sanitize_context_t().reference_table (face); - svg_len = hb_blob_get_length (svg_blob); table = svg_blob->as (); } @@ -91,18 +92,14 @@ struct SVG inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const { - if (unlikely (!svg_len)) - return hb_blob_get_empty (); return table->get_glyph_entry (glyph_id).reference_blob (svg_blob, table->svgDocEntries); } - inline bool has_data () const { return svg_len; } + inline bool has_data () const { return table->has_data (); } private: hb_blob_t *svg_blob; - const SVG *table; - - unsigned int svg_len; + hb_nonnull_ptr_t table; }; inline const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index 7bd175e39..d2a39f230 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -276,7 +276,7 @@ struct glyf if (!get_offsets (glyph, &start_offset, &end_offset)) return false; /* glyph not found */ - return CompositeGlyphHeader::get_iterator ((const char*) this->glyf_table + start_offset, + return CompositeGlyphHeader::get_iterator ((const char *) this->glyf_table + start_offset, end_offset - start_offset, composite); } @@ -476,8 +476,8 @@ struct glyf private: bool short_offset; unsigned int num_glyphs; - const loca *loca_table; - const glyf *glyf_table; + hb_nonnull_ptr_t loca_table; + hb_nonnull_ptr_t glyf_table; hb_blob_t *loca_blob; hb_blob_t *glyf_blob; unsigned int glyf_len; diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh index 757090861..5847953d3 100644 --- a/src/hb-ot-layout-gdef-table.hh +++ b/src/hb-ot-layout-gdef-table.hh @@ -418,7 +418,7 @@ struct GDEF } hb_blob_t *blob; - const GDEF *table; + hb_nonnull_ptr_t table; }; inline unsigned int get_size (void) const diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 54ae429b1..0d9eeae58 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -2774,7 +2774,7 @@ struct GSUBGPOS } hb_blob_t *blob; - const T *table; + hb_nonnull_ptr_t table; unsigned int lookup_count; hb_ot_layout_lookup_accelerator_t *accels; }; diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 9f67b5745..f1e785f19 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -257,7 +257,7 @@ struct name const void *pool; unsigned int pool_len; public: - const name *table; + hb_nonnull_ptr_t table; hb_vector_t names; }; diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh index bd049f9ab..6432f3f15 100644 --- a/src/hb-ot-post-table.hh +++ b/src/hb-ot-post-table.hh @@ -254,7 +254,7 @@ struct post private: hb_blob_t *blob; uint32_t version; - const ArrayOf *glyphNameIndex; + hb_nonnull_ptr_t> glyphNameIndex; hb_vector_t index_to_offset; const uint8_t *pool; hb_atomic_ptr_t gids_sorted_by_name; From 9779e602ed7ac214c0da2c90e104b38460422476 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 20:50:56 -0400 Subject: [PATCH 32/40] [test] Add test for empty face --- test/api/Makefile.am | 1 + test/api/test-ot-face.c | 94 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 test/api/test-ot-face.c diff --git a/test/api/Makefile.am b/test/api/Makefile.am index 3b9857035..b307cd123 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -36,6 +36,7 @@ TEST_PROGS = \ test-font \ test-map \ test-object \ + test-ot-face \ test-set \ test-shape \ test-subset \ diff --git a/test/api/test-ot-face.c b/test/api/test-ot-face.c new file mode 100644 index 000000000..0af584e05 --- /dev/null +++ b/test/api/test-ot-face.c @@ -0,0 +1,94 @@ +/* + * Copyright © 2011 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "hb-test.h" +#include + +/* Unit tests for hb-ot-*.h */ + + +static void +test_ot_face_empty (void) +{ + hb_face_t *face = hb_face_get_empty (); + hb_font_t *font = hb_font_create (face); + hb_set_t *set = hb_set_create (); + + hb_face_collect_unicodes (face, set); + hb_face_collect_variation_selectors (face, set); + hb_face_collect_variation_unicodes (face, 0, set); + + hb_ot_color_has_palettes (face); + hb_ot_color_palette_get_count (face); + hb_ot_color_palette_get_name_id (face, 0); + hb_ot_color_palette_color_get_name_id (face, 0); + hb_ot_color_palette_get_flags (face, 0); + hb_ot_color_palette_get_colors (face, 0, 0, NULL, NULL); + hb_ot_color_has_layers (face); + hb_ot_color_glyph_get_layers (face, 0, 0, NULL, NULL); + hb_ot_color_has_svg (face); + hb_ot_color_glyph_reference_svg (face, 0); + hb_ot_color_has_png (face); + hb_ot_color_glyph_reference_png (font, 0); + + hb_ot_layout_has_glyph_classes (face); + hb_ot_layout_has_substitution (face); + hb_ot_layout_has_positioning (face); + + hb_ot_math_has_data (face); + hb_ot_math_get_constant (font, 0); + hb_ot_math_get_glyph_italics_correction (font, 0); + hb_ot_math_get_glyph_top_accent_attachment (font, 0); + hb_ot_math_is_glyph_extended_shape (face, 0); + hb_ot_math_get_glyph_kerning (font, 0, 0, 0); + hb_ot_math_get_glyph_variants (font, 0, 0, 0, NULL, NULL); + hb_ot_math_get_min_connector_overlap (font, 0); + hb_ot_math_get_glyph_assembly (font, 0, 0, 0, NULL, NULL, NULL); + + hb_ot_name_list_names (face, NULL); + hb_ot_name_get_utf8 (face, 0, NULL, NULL, NULL); + hb_ot_name_get_utf16 (face, 0, NULL, NULL, NULL); + hb_ot_name_get_utf32 (face, 0, NULL, NULL, NULL); + + hb_ot_var_get_axis_count (face); + hb_ot_var_get_axes (face, 0, NULL, NULL); + hb_ot_var_normalize_variations (face, NULL, 0, NULL, 0); + hb_ot_var_normalize_coords (face, 0, NULL, NULL); + + hb_set_destroy (set); + hb_font_destroy (font); + hb_face_destroy (face); +} + +int +main (int argc, char **argv) +{ + hb_test_init (&argc, &argv); + + hb_test_add (test_ot_face_empty); + + return hb_test_run(); +} From c8f94a1ca6928f07749285da910b63087d485537 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 21:07:39 -0400 Subject: [PATCH 33/40] Minor --- src/hb-ot-name.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc index e0c971087..f5ac18d79 100644 --- a/src/hb-ot-name.cc +++ b/src/hb-ot-name.cc @@ -52,7 +52,7 @@ _get_name (hb_face_t *face) /** * hb_ot_name_list_names: * @face: font face. - * @num_entries: (out): number of returned entries. + * @num_entries: (out) (allow-none): number of returned entries. * * Enumerates all available name IDs and language combinations. Returned * array is owned by the @face and should not be modified. It can be @@ -66,7 +66,7 @@ hb_ot_name_list_names (hb_face_t *face, unsigned int *num_entries /* OUT */) { const OT::name_accelerator_t &name = _get_name (face); - *num_entries = name.names.len; + if (num_entries) *num_entries = name.names.len; return name.names.arrayZ(); } From d0163afb7bed83935c6a54d57a0e7366caeba0b3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 21:38:24 -0400 Subject: [PATCH 34/40] Revert "Add operator char * to the naked array types as well" This reverts commit db889c182ee5f54127285bfaab5bc94dafe46bda. Was resulting in ambigious overloads... --- src/hb-dsalgs.hh | 4 +--- src/hb-open-type.hh | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index fafac1f72..f2bff063d 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -553,10 +553,8 @@ struct hb_array_t inline unsigned int get_size (void) const { return len * sizeof (Type); } - template inline operator T * (void) { return arrayZ; } + template inline operator T * (void) { return arrayZ; } template inline operator const T * (void) const { return arrayZ; } - inline operator char * (void) { return (char *) arrayZ; } - inline operator const char * (void) const { return (const char *) arrayZ; } inline Type * operator & (void) { return arrayZ; } inline const Type * operator & (void) const { return arrayZ; } diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index e1dc8aab1..0f6efdc69 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -342,8 +342,6 @@ struct UnsizedArrayOf template inline operator T * (void) { return arrayZ; } template inline operator const T * (void) const { return arrayZ; } - inline operator char * (void) { return (char *) arrayZ; } - inline operator const char * (void) const { return (const char *) arrayZ; } inline unsigned int get_size (unsigned int len) const { return len * Type::static_size; } From ae9ad1076e536aee370f9863cde8351b79f01b3b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 21:41:50 -0400 Subject: [PATCH 35/40] Fix "Warning: extra ";" ignored." --- src/hb.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb.hh b/src/hb.hh index fa6a7404d..e3faf17c9 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -365,10 +365,10 @@ static_assert ((sizeof (hb_var_int_t) == 4), ""); #else /* __cpluspplus >= 201103L */ #define HB_NO_COPY_ASSIGN(TypeName) -#define HB_NO_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) -#define HB_NO_CREATE_COPY_ASSIGN(TypeName) -#define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE(TypeName, T) -#define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) +#define HB_NO_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) static_assert (true, "") +#define HB_NO_CREATE_COPY_ASSIGN(TypeName) static_assert (true, "") +#define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE(TypeName, T) static_assert (true, "") +#define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) static_assert (true, "") #endif /* __cpluspplus >= 201103L */ From 4eb52460c8c6dc48af240f2254f76fae065bfa97 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 3 Nov 2018 21:45:39 -0400 Subject: [PATCH 36/40] Fix >> --- src/hb-ot-post-table.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh index 6432f3f15..b15a459b1 100644 --- a/src/hb-ot-post-table.hh +++ b/src/hb-ot-post-table.hh @@ -254,7 +254,7 @@ struct post private: hb_blob_t *blob; uint32_t version; - hb_nonnull_ptr_t> glyphNameIndex; + hb_nonnull_ptr_t > glyphNameIndex; hb_vector_t index_to_offset; const uint8_t *pool; hb_atomic_ptr_t gids_sorted_by_name; From 17335a8161e674e630287e18a6d304ec0c33767c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 4 Nov 2018 02:25:07 -0500 Subject: [PATCH 37/40] Clean up buffer->swap_buffers() calls That function checks for buffer->successful already. No need to check at call site. --- src/gen-vowel-constraints.py | 4 +--- src/hb-aat-layout-common.hh | 3 +-- src/hb-aat-layout-morx-table.hh | 3 +-- src/hb-ot-shape-complex-indic.cc | 1 - src/hb-ot-shape-complex-khmer.cc | 1 - src/hb-ot-shape-complex-myanmar.cc | 1 - src/hb-ot-shape-complex-thai.cc | 3 +-- src/hb-ot-shape-complex-use.cc | 1 - src/hb-ot-shape-complex-vowel-constraints.cc | 5 ++--- src/hb-ot-shape.cc | 1 - 10 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/gen-vowel-constraints.py b/src/gen-vowel-constraints.py index c4e75aa96..b7f6be223 100755 --- a/src/gen-vowel-constraints.py +++ b/src/gen-vowel-constraints.py @@ -211,9 +211,7 @@ print (' }') print (' if (processed)') print (' {') print (' if (buffer->idx < count)') -print (' buffer->next_glyph ();') -print (' if (likely (buffer->successful))') -print (' buffer->swap_buffers ();') +print (' buffer->next_glyph ();') print (' }') print ('}') diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 51add2213..11c6c5a8b 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -671,8 +671,7 @@ struct StateTableDriver { for (; buffer->successful && buffer->idx < buffer->len;) buffer->next_glyph (); - if (likely (buffer->successful)) - buffer->swap_buffers (); + buffer->swap_buffers (); } } diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index dab6ec1e9..2bc60182e 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -1121,8 +1121,7 @@ struct mortmorx else buffer->next_glyph (); } - if (likely (buffer->successful)) - buffer->swap_buffers (); + buffer->swap_buffers (); } inline void apply (hb_aat_apply_context_t *c) const diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 4f98f7480..8933c1822 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -1018,7 +1018,6 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, else buffer->next_glyph (); } - buffer->swap_buffers (); } diff --git a/src/hb-ot-shape-complex-khmer.cc b/src/hb-ot-shape-complex-khmer.cc index 1142da3ec..497891ea0 100644 --- a/src/hb-ot-shape-complex-khmer.cc +++ b/src/hb-ot-shape-complex-khmer.cc @@ -414,7 +414,6 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, else buffer->next_glyph (); } - buffer->swap_buffers (); } diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc index dcada261c..ca7b5a9b2 100644 --- a/src/hb-ot-shape-complex-myanmar.cc +++ b/src/hb-ot-shape-complex-myanmar.cc @@ -343,7 +343,6 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, else buffer->next_glyph (); } - buffer->swap_buffers (); } diff --git a/src/hb-ot-shape-complex-thai.cc b/src/hb-ot-shape-complex-thai.cc index b687fe61e..650c9800a 100644 --- a/src/hb-ot-shape-complex-thai.cc +++ b/src/hb-ot-shape-complex-thai.cc @@ -357,8 +357,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, buffer->merge_out_clusters (start - 1, end); } } - if (likely (buffer->successful)) - buffer->swap_buffers (); + buffer->swap_buffers (); /* If font has Thai GSUB, we are done. */ if (plan->props.script == HB_SCRIPT_THAI && !plan->map.found_script[0]) diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index 3ab77fc58..af25b07f8 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -552,7 +552,6 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, else buffer->next_glyph (); } - buffer->swap_buffers (); } diff --git a/src/hb-ot-shape-complex-vowel-constraints.cc b/src/hb-ot-shape-complex-vowel-constraints.cc index 20af8711e..0e532581d 100644 --- a/src/hb-ot-shape-complex-vowel-constraints.cc +++ b/src/hb-ot-shape-complex-vowel-constraints.cc @@ -429,9 +429,8 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED, if (processed) { if (buffer->idx < count) - buffer->next_glyph (); - if (likely (buffer->successful)) - buffer->swap_buffers (); + buffer->next_glyph (); + buffer->swap_buffers (); } } diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index b687996f6..8c5e38e06 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -425,7 +425,6 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) buffer->output_info (info); while (buffer->idx < buffer->len && buffer->successful) buffer->next_glyph (); - buffer->swap_buffers (); } From 777c22425cae97009ca4dc5b1e400670c4aa0799 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 4 Nov 2018 02:40:20 -0500 Subject: [PATCH 38/40] [test] More funcs in test-ot-face --- test/api/test-font.c | 5 +++++ test/api/test-ot-face.c | 21 +++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/test/api/test-font.c b/test/api/test-font.c index 3d81cf961..a92d8b26a 100644 --- a/test/api/test-font.c +++ b/test/api/test-font.c @@ -536,6 +536,11 @@ test_font_properties (void) g_assert_cmpint (x_ppem, ==, 17); g_assert_cmpint (y_ppem, ==, 19); + /* Check ptem */ + g_assert_cmpint (hb_font_get_ptem (font), ==, 0); + hb_font_set_ptem (font, 42); + g_assert_cmpint (hb_font_get_ptem (font), ==, 42); + /* Check immutable */ diff --git a/test/api/test-ot-face.c b/test/api/test-ot-face.c index 0af584e05..ac3d7f18f 100644 --- a/test/api/test-ot-face.c +++ b/test/api/test-ot-face.c @@ -35,12 +35,28 @@ test_ot_face_empty (void) { hb_face_t *face = hb_face_get_empty (); hb_font_t *font = hb_font_create (face); - hb_set_t *set = hb_set_create (); + hb_ot_font_set_funcs (font); + hb_set_t *set = hb_set_create (); hb_face_collect_unicodes (face, set); hb_face_collect_variation_selectors (face, set); hb_face_collect_variation_unicodes (face, 0, set); + hb_codepoint_t g; + hb_position_t x, y; + hb_glyph_extents_t extents; + char buf[5] = {0}; + hb_font_get_nominal_glyph (font, 0, &g); + hb_font_get_variation_glyph (font, 0, 0, &g); + hb_font_get_glyph_h_advance (font, g); + hb_font_get_glyph_v_advance (font, g); + hb_font_get_glyph_h_origin (font, g, &x, &y); + hb_font_get_glyph_v_origin (font, g, &x, &y); + hb_font_get_glyph_extents (font, g, &extents); + hb_font_get_glyph_contour_point (font, g, 0, &x, &y); + hb_font_get_glyph_name (font, g, buf, sizeof (buf)); + hb_font_get_glyph_from_name (font, buf, strlen (buf), &g); + hb_ot_color_has_palettes (face); hb_ot_color_palette_get_count (face); hb_ot_color_palette_get_name_id (face, 0); @@ -68,8 +84,9 @@ test_ot_face_empty (void) hb_ot_math_get_min_connector_overlap (font, 0); hb_ot_math_get_glyph_assembly (font, 0, 0, 0, NULL, NULL, NULL); + unsigned int len = sizeof (buf); hb_ot_name_list_names (face, NULL); - hb_ot_name_get_utf8 (face, 0, NULL, NULL, NULL); + hb_ot_name_get_utf8 (face, 0, NULL, &len, buf); hb_ot_name_get_utf16 (face, 0, NULL, NULL, NULL); hb_ot_name_get_utf32 (face, 0, NULL, NULL, NULL); From bce437cf0b71e9b60bbf058eaf61593fed30ae33 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 4 Nov 2018 02:47:34 -0500 Subject: [PATCH 39/40] [test] Call test-ot-face.c test from hb-shape-fuzzer Should increase coverage... --- test/api/test-ot-face.c | 28 ++++++++++++++++++---------- test/fuzzing/hb-shape-fuzzer.cc | 6 ++++++ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/test/api/test-ot-face.c b/test/api/test-ot-face.c index ac3d7f18f..da23fe593 100644 --- a/test/api/test-ot-face.c +++ b/test/api/test-ot-face.c @@ -24,16 +24,17 @@ * Google Author(s): Behdad Esfahbod */ +#ifndef TEST_OT_FACE_NO_MAIN #include "hb-test.h" +#endif #include /* Unit tests for hb-ot-*.h */ static void -test_ot_face_empty (void) +test_face (hb_face_t *face) { - hb_face_t *face = hb_face_get_empty (); hb_font_t *font = hb_font_create (face); hb_ot_font_set_funcs (font); @@ -66,23 +67,23 @@ test_ot_face_empty (void) hb_ot_color_has_layers (face); hb_ot_color_glyph_get_layers (face, 0, 0, NULL, NULL); hb_ot_color_has_svg (face); - hb_ot_color_glyph_reference_svg (face, 0); + hb_blob_destroy (hb_ot_color_glyph_reference_svg (face, 0)); hb_ot_color_has_png (face); - hb_ot_color_glyph_reference_png (font, 0); + hb_blob_destroy (hb_ot_color_glyph_reference_png (font, 0)); hb_ot_layout_has_glyph_classes (face); hb_ot_layout_has_substitution (face); hb_ot_layout_has_positioning (face); hb_ot_math_has_data (face); - hb_ot_math_get_constant (font, 0); + hb_ot_math_get_constant (font, HB_OT_MATH_CONSTANT_MATH_LEADING); hb_ot_math_get_glyph_italics_correction (font, 0); hb_ot_math_get_glyph_top_accent_attachment (font, 0); hb_ot_math_is_glyph_extended_shape (face, 0); - hb_ot_math_get_glyph_kerning (font, 0, 0, 0); - hb_ot_math_get_glyph_variants (font, 0, 0, 0, NULL, NULL); - hb_ot_math_get_min_connector_overlap (font, 0); - hb_ot_math_get_glyph_assembly (font, 0, 0, 0, NULL, NULL, NULL); + hb_ot_math_get_glyph_kerning (font, 0, HB_OT_MATH_KERN_BOTTOM_RIGHT, 0); + hb_ot_math_get_glyph_variants (font, 0, HB_DIRECTION_TTB, 0, NULL, NULL); + hb_ot_math_get_min_connector_overlap (font, HB_DIRECTION_RTL); + hb_ot_math_get_glyph_assembly (font, 0, HB_DIRECTION_BTT, 0, NULL, NULL, NULL); unsigned int len = sizeof (buf); hb_ot_name_list_names (face, NULL); @@ -97,7 +98,13 @@ test_ot_face_empty (void) hb_set_destroy (set); hb_font_destroy (font); - hb_face_destroy (face); +} + +#ifndef TEST_OT_FACE_NO_MAIN +static void +test_ot_face_empty (void) +{ + test_face (hb_face_get_empty ()); } int @@ -109,3 +116,4 @@ main (int argc, char **argv) return hb_test_run(); } +#endif diff --git a/test/fuzzing/hb-shape-fuzzer.cc b/test/fuzzing/hb-shape-fuzzer.cc index e8bc186b1..fedf56e20 100644 --- a/test/fuzzing/hb-shape-fuzzer.cc +++ b/test/fuzzing/hb-shape-fuzzer.cc @@ -3,6 +3,10 @@ #include #include +#define TEST_OT_FACE_NO_MAIN 1 +#include "../api/test-ot-face.c" +#undef TEST_OT_FACE_NO_MAIN + extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { hb_blob_t *blob = hb_blob_create ((const char *)data, size, @@ -48,6 +52,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) hb_buffer_destroy (buffer); } + /* Misc calls on face. */ + test_face (face); hb_font_destroy (font); hb_face_destroy (face); From b605db2f65e62ad6727a61481f78015933dbf207 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 4 Nov 2018 12:58:02 -0500 Subject: [PATCH 40/40] [aat] Clean up ankr table include mess --- src/hb-aat-layout-ankr-table.hh | 2 ++ src/hb-aat-layout-common.hh | 31 +++++++----------------- src/hb-aat-layout-kerx-table.hh | 16 ++++++------- src/hb-aat-layout.cc | 42 +++++++++++++++++++++++++++++++-- src/hb-ot-kern-table.hh | 1 - src/hb-static.cc | 1 - 6 files changed, 59 insertions(+), 34 deletions(-) diff --git a/src/hb-aat-layout-ankr-table.hh b/src/hb-aat-layout-ankr-table.hh index 5f7656d2a..b793245a0 100644 --- a/src/hb-aat-layout-ankr-table.hh +++ b/src/hb-aat-layout-ankr-table.hh @@ -36,6 +36,8 @@ namespace AAT { +using namespace OT; + struct Anchor { diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 11c6c5a8b..ee2136ed9 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -698,36 +698,23 @@ struct hb_aat_apply_context_t : hb_face_t *face; hb_buffer_t *buffer; hb_sanitize_context_t sanitizer; - const ankr &ankr_table; + const ankr *ankr_table; const char *ankr_end; /* Unused. For debug tracing only. */ unsigned int lookup_index; unsigned int debug_depth; - inline hb_aat_apply_context_t (hb_ot_shape_plan_t *plan_, - hb_font_t *font_, - hb_buffer_t *buffer_, - hb_blob_t *blob = const_cast (&Null(hb_blob_t)), - const ankr &ankr_table_ = Null(ankr), - const char *ankr_end_ = nullptr) : - plan (plan_), font (font_), face (font->face), buffer (buffer_), - sanitizer (), - ankr_table (ankr_table_), ankr_end (ankr_end_), - lookup_index (0), debug_depth (0) - { - sanitizer.init (blob); - sanitizer.set_num_glyphs (face->get_num_glyphs ()); - sanitizer.start_processing (); - sanitizer.set_max_ops (HB_SANITIZE_MAX_OPS_MAX); - } + HB_INTERNAL hb_aat_apply_context_t (hb_ot_shape_plan_t *plan_, + hb_font_t *font_, + hb_buffer_t *buffer_, + hb_blob_t *blob = const_cast (&Null(hb_blob_t))); + + HB_INTERNAL ~hb_aat_apply_context_t (void); + + HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_, const char *ankr_end_); inline void set_lookup_index (unsigned int i) { lookup_index = i; } - - inline ~hb_aat_apply_context_t (void) - { - sanitizer.end_processing (); - } }; diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index b227af105..d2242c549 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -423,14 +423,14 @@ struct KerxSubTableFormat4 return false; unsigned int markAnchorPoint = *data++; unsigned int currAnchorPoint = *data++; - const Anchor markAnchor = c->ankr_table.get_anchor (c->buffer->info[mark].codepoint, - markAnchorPoint, - c->sanitizer.get_num_glyphs (), - c->ankr_end); - const Anchor currAnchor = c->ankr_table.get_anchor (c->buffer->cur ().codepoint, - currAnchorPoint, - c->sanitizer.get_num_glyphs (), - c->ankr_end); + const Anchor markAnchor = c->ankr_table->get_anchor (c->buffer->info[mark].codepoint, + markAnchorPoint, + c->sanitizer.get_num_glyphs (), + c->ankr_end); + const Anchor currAnchor = c->ankr_table->get_anchor (c->buffer->cur ().codepoint, + currAnchorPoint, + c->sanitizer.get_num_glyphs (), + c->ankr_end); o.x_offset = c->font->em_scale_x (markAnchor.xCoordinate) - c->font->em_scale_x (currAnchor.xCoordinate); o.y_offset = c->font->em_scale_y (markAnchor.yCoordinate) - c->font->em_scale_y (currAnchor.yCoordinate); diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index d917c29c6..80bf2d766 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -130,6 +130,44 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag) } +/* + * hb_aat_apply_context_t + */ + +AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (hb_ot_shape_plan_t *plan_, + hb_font_t *font_, + hb_buffer_t *buffer_, + hb_blob_t *blob) : + plan (plan_), + font (font_), + face (font->face), + buffer (buffer_), + sanitizer (), + ankr_table (&Null(AAT::ankr)), + ankr_end (nullptr), + lookup_index (0), + debug_depth (0) +{ + sanitizer.init (blob); + sanitizer.set_num_glyphs (face->get_num_glyphs ()); + sanitizer.start_processing (); + sanitizer.set_max_ops (HB_SANITIZE_MAX_OPS_MAX); +} + +AAT::hb_aat_apply_context_t::~hb_aat_apply_context_t (void) +{ + sanitizer.end_processing (); +} + +void +AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_, + const char *ankr_end_) +{ + ankr_table = ankr_table_; + ankr_end = ankr_end_; +} + + /* * mort/morx/kerx/trak */ @@ -273,8 +311,8 @@ hb_aat_layout_position (hb_ot_shape_plan_t *plan, hb_blob_t *ankr_blob; const AAT::ankr& ankr = _get_ankr (font->face, &ankr_blob); - AAT::hb_aat_apply_context_t c (plan, font, buffer, blob, - ankr, ankr_blob->data + ankr_blob->length); + AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); + c.set_ankr_table (&ankr, ankr_blob->data + ankr_blob->length); kerx.apply (&c); } diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index e361330b0..5bc9e436c 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -30,7 +30,6 @@ #include "hb-open-type.hh" #include "hb-ot-shape.hh" #include "hb-ot-layout-gsubgpos.hh" -#include "hb-aat-layout-ankr-table.hh" // Ugly but needed. #include "hb-aat-layout-common.hh" diff --git a/src/hb-static.cc b/src/hb-static.cc index e5507960d..3669e08b7 100644 --- a/src/hb-static.cc +++ b/src/hb-static.cc @@ -28,7 +28,6 @@ #include "hb-open-type.hh" #include "hb-ot-layout-common.hh" -#include "hb-aat-layout-ankr-table.hh" /* I don't even want to know why... */ #include "hb-aat-layout-common.hh" #include "hb-face.hh"