src/hb-aat-layout-kerx-table.hh | 298 ++++++++++++++++------------------------ src/hb-ot-colr-table.hh | 27 ++- src/hb-ot-cpal-table.hh | 14 - 3 files changed, 148 insertions(+), 191 deletions(-)
New commits: commit b73a5a1c240478616827529c94f0133018f9f790 Author: Ebrahim Byagowi <ebra...@gnu.org> Date: Fri Mar 2 00:07:26 2018 +0330 [aat/kerx] Make parsing of the table actually work (#850) diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 505e5084..b3c6a11d 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -1,6 +1,6 @@ /* - * Copyright © 2018 Google, Inc. * Copyright © 2018 Ebrahim Byagowi + * Copyright © 2018 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -28,35 +28,19 @@ #ifndef HB_AAT_LAYOUT_KERX_TABLE_HH #define HB_AAT_LAYOUT_KERX_TABLE_HH +#include "hb-open-type-private.hh" #include "hb-aat-layout-common-private.hh" -namespace AAT { +#define HB_AAT_TAG_KERX HB_TAG('k','e','r','x') -/* - * kerx -- Kerning - */ +namespace AAT { -#define HB_AAT_TAG_kerx HB_TAG('k','e','r','x') +using namespace OT; -struct hb_glyph_pair_t -{ - hb_codepoint_t left; - hb_codepoint_t right; -}; -struct KerxPair +struct KerxFormat0Records { - inline int get_kerning (void) const - { return value; } - - inline int cmp (const hb_glyph_pair_t &o) const - { - int ret = left.cmp (o.left); - if (ret) return ret; - return right.cmp (o.right); - } - inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -67,59 +51,60 @@ struct KerxPair GlyphID left; GlyphID right; FWORD value; - HBUINT16 pad; public: - DEFINE_SIZE_STATIC (8); + DEFINE_SIZE_STATIC (6); }; struct KerxSubTableFormat0 { - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { - //hb_glyph_pair_t pair = {left, right}; - //int i = pairs.bsearch (pair); - //if (i == -1) - return 0; - //return pairs[i].get_kerning (); - } + // TODO(ebraminio) Enable when we got suitable BinSearchArrayOf + // inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const + // { + // hb_glyph_pair_t pair = {left, right}; + // int i = pairs.bsearch (pair); + // if (i == -1) + // return 0; + // return pairs[i].get_kerning (); + // } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (pairs.sanitize (c)); + return_trace (c->check_struct (this) && + c->check_array (records, records[0].static_size, nPairs)); } protected: - BinSearchArrayOf<KerxPair> pairs; /* Array of kerning pairs. */ - //FIXME: BinSearchArrayOf and its BinSearchHeader should be - //modified in a way to accept uint32s + // TODO(ebraminio): A custom version of "BinSearchArrayOf<KerxPair> pairs;" is + // needed here to use HBUINT32 instead + HBUINT32 nPairs; /* The number of kerning pairs in this subtable */ + HBUINT32 searchRange; /* The largest power of two less than or equal to the value of nPairs, + * multiplied by the size in bytes of an entry in the subtable. */ + HBUINT32 entrySelector; /* This is calculated as log2 of the largest power of two less + * than or equal to the value of nPairs. */ + HBUINT32 rangeShift; /* The value of nPairs minus the largest power of two less than or equal to nPairs. */ + KerxFormat0Records records[VAR]; /* VAR=nPairs */ public: - //DEFINE_SIZE_ARRAY (16, pairs); -}; - -struct KerxAction -{ - HBUINT16 index; + DEFINE_SIZE_ARRAY (16, records); }; struct KerxSubTableFormat1 { inline bool sanitize (hb_sanitize_context_t *c) const { - //TRACE_SANITIZE (this); - //return_trace (stateHeader.sanitize (c)); - return false; + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + stateHeader.sanitize (c)); } protected: - StateTable<KerxAction> stateHeader; - OffsetTo<ArrayOf<HBUINT16>, HBUINT32> valueTable; - + StateTable<HBUINT16> stateHeader; + LOffsetTo<ArrayOf<HBUINT16> > valueTable; public: - //DEFINE_SIZE_MIN (4); + DEFINE_SIZE_STATIC (20); }; -//FIXME: Maybe this can be replaced with Lookup<HBUINT16>? +// TODO(ebraminio): Maybe this can be replaced with Lookup<HBUINT16>? struct KerxClassTable { inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; } @@ -156,7 +141,8 @@ struct KerxSubTableFormat2 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (rowWidth.sanitize (c) && + return_trace (c->check_struct (this) && + rowWidth.sanitize (c) && leftClassTable.sanitize (c, this) && rightClassTable.sanitize (c, this) && array.sanitize (c, this)); @@ -174,7 +160,7 @@ struct KerxSubTableFormat2 array; /* Offset from beginning of this subtable to * the start of the kerning array. */ public: - DEFINE_SIZE_MIN (16); + DEFINE_SIZE_STATIC (16); }; struct KerxSubTableFormat4 @@ -182,7 +168,8 @@ struct KerxSubTableFormat4 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (rowWidth.sanitize (c) && + return_trace (c->check_struct (this) && + rowWidth.sanitize (c) && leftClassTable.sanitize (c, this) && rightClassTable.sanitize (c, this) && array.sanitize (c, this)); @@ -200,182 +187,145 @@ struct KerxSubTableFormat4 array; /* Offset from beginning of this subtable to * the start of the kerning array. */ public: - DEFINE_SIZE_MIN (16); + DEFINE_SIZE_STATIC (16); }; struct KerxSubTableFormat6 { inline bool sanitize (hb_sanitize_context_t *c) const { - //TRACE_SANITIZE (this); - //return_trace ; - return false; + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); } protected: - HBUINT32 flags; - HBUINT16 rowCount; - HBUINT16 columnCount; - HBUINT32 rowIndexTableOffset; - HBUINT32 columnIndexTableOffset; - HBUINT32 kerningArrayOffset; - HBUINT32 kerningVectorOffset; - + HBUINT32 flags; + HBUINT16 rowCount; + HBUINT16 columnCount; + HBUINT32 rowIndexTableOffset; + HBUINT32 columnIndexTableOffset; + HBUINT32 kerningArrayOffset; + HBUINT32 kerningVectorOffset; public: - DEFINE_SIZE_MIN (24); + DEFINE_SIZE_STATIC (24); }; -struct KerxSubTable +enum coverage_flags_t { - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end, unsigned int format) const + COVERAGE_VERTICAL_FLAG = 0x80u, + COVERAGE_CROSSSTREAM_FLAG = 0x40u, + COVERAGE_VARIATION_FLAG = 0x20u, + COVERAGE_PROCESS_DIRECTION = 0x10u, +}; + +struct KerxTable +{ + inline bool apply (hb_aat_apply_context_t *c, const AAT::ankr *ankr) const { - switch (format) { - case 0: return u.format0.get_kerning (left, right); - case 2: return u.format2.get_kerning (left, right, end); - default:return 0; - } + TRACE_APPLY (this); + /* TODO */ + return_trace (false); } - inline bool sanitize (hb_sanitize_context_t *c, unsigned int format) const + inline unsigned int get_size (void) const { return length; } + + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); + if (!c->check_struct (this)) + return_trace (false); + switch (format) { - case 0: return_trace (u.format0.sanitize (c)); - case 2: return_trace (u.format2.sanitize (c)); - default:return_trace (true); + case 0: return u.format0.sanitize (c); + case 1: return u.format1.sanitize (c); + case 2: return u.format2.sanitize (c); + case 4: return u.format4.sanitize (c); + case 6: return u.format6.sanitize (c); + default:return_trace (false); } } - protected: +protected: + HBUINT32 length; + HBUINT8 coverage; + HBUINT16 unused; + HBUINT8 format; + HBUINT32 tupleIndex; union { KerxSubTableFormat0 format0; + KerxSubTableFormat1 format1; KerxSubTableFormat2 format2; KerxSubTableFormat4 format4; KerxSubTableFormat6 format6; } u; - public: - DEFINE_SIZE_MIN (0); +public: + DEFINE_SIZE_MIN (12); }; +struct SubtableGlyphCoverageArray +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + protected: + HBUINT32 length; + HBUINT32 coverage; + HBUINT32 tupleCount; + public: + DEFINE_SIZE_STATIC (12); +}; struct kerx { - static const hb_tag_t tableTag = HB_AAT_TAG_kerx; + static const hb_tag_t tableTag = HB_AAT_TAG_KERX; inline bool apply (hb_aat_apply_context_t *c, const AAT::ankr *ankr) const { TRACE_APPLY (this); - /* TODO */ - return_trace (false); + const KerxTable &table = StructAfter<KerxTable> (*this); + return_trace (table.apply (c, ankr)); } - struct SubTableWrapper + inline bool sanitize (hb_sanitize_context_t *c) const { - enum coverage_flags_t { - COVERAGE_VERTICAL_FLAG = 0x8000u, - COVERAGE_CROSSSTREAM_FLAG = 0x4000u, - COVERAGE_VARIATION_FLAG = 0x2000u, - - COVERAGE_OVERRIDE_FLAG = 0x0000u, /* Not supported. */ - - COVERAGE_CHECK_FLAGS = 0x0700u, //FIXME: Where these two come from? - COVERAGE_CHECK_HORIZONTAL = 0x0100u - }; - - protected: - HBUINT32 length; /* Length of the subtable (including this header). */ - HBUINT16 coverage; /* Coverage bits. */ - HBUINT16 format; /* Subtable format. */ - HBUINT32 tupleIndex; /* The tuple index (used for variations fonts). - * This value specifies which tuple this subtable covers. */ - KerxSubTable subtable; /* Subtable data. */ - public: - inline bool is_horizontal (void) const - { return (coverage & COVERAGE_CHECK_FLAGS) == COVERAGE_CHECK_HORIZONTAL; } - - inline bool is_override (void) const - { return bool (coverage & COVERAGE_OVERRIDE_FLAG); } - - inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const - { return subtable.get_kerning (left, right, end, 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; } + TRACE_SANITIZE (this); + if (!(c->check_struct (this))) + return_trace (false); - inline unsigned int get_size (void) const { return length; } + const KerxTable *table = &StructAfter<KerxTable> (*this); + if (!(table->sanitize (c))) + return_trace (false); - inline bool sanitize (hb_sanitize_context_t *c) const + for (unsigned int i = 0; i < nTables - 1; ++i) { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - length >= min_size && - c->check_array (this, 1, length) && - subtable.sanitize (c, format)); + table = &StructAfter<KerxTable> (*table); + if (!(table->sanitize (c))) + return_trace (false); } - DEFINE_SIZE_MIN (12); - }; - inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const - { - int v = 0; - const SubTableWrapper *st = (SubTableWrapper *) data; - unsigned int count = nTables; - for (unsigned int i = 0; i < count; i++) - { - if (st->is_override ()) - v = 0; - v += st->get_h_kerning (left, right, table_length + (const char *) this); - st = (SubTableWrapper *) st; - } - return v; - } + // If version is less than 3, we are done here; otherwise better to check footer also + if (version < 3) + return_trace (true); - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - const SubTableWrapper *st = (SubTableWrapper *) data; - unsigned int count = nTables; - for (unsigned int i = 0; i < count; i++) - { - if (unlikely (!st->sanitize (c))) - return_trace (false); - st = (SubTableWrapper *) st; - } + // TODO: Investigate why this just work on some fonts no matter of version + // const SubtableGlyphCoverageArray &footer = + // StructAfter<SubtableGlyphCoverageArray> (*table); + // return_trace (footer.sanitize (c)); return_trace (true); } - struct accelerator_t - { - inline void init (hb_face_t *face) - { - blob = Sanitizer<kerx>().sanitize (face->reference_table (HB_AAT_TAG_kerx)); - table = Sanitizer<kerx>::lock_instance (blob); - table_length = hb_blob_get_length (blob); - } - inline void fini (void) - { - hb_blob_destroy (blob); - } - - inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return table->get_h_kerning (left, right, table_length); } - - private: - hb_blob_t *blob; - const kerx *table; - unsigned int table_length; - }; - protected: HBUINT16 version; HBUINT16 padding; - HBUINT32 nTables; /* Number of subtables in the kerning table. */ - HBUINT8 data[VAR]; - //ArrayOf<GlyphCoverageArray> subtableGlyphCoverageArray; + HBUINT32 nTables; +/*KerxTable tables[VAR];*/ +/*SubtableGlyphCoverageArray coverage_array;*/ public: - DEFINE_SIZE_ARRAY (8, data); + DEFINE_SIZE_STATIC (8); }; } /* namespace AAT */ commit a570edcde2f89e59b5ccd4867a8c0eed084bf35d Author: Ebrahim Byagowi <ebra...@gnu.org> Date: Fri Mar 2 00:06:03 2018 +0330 [COLR] Sanitize BaseGlyphRecord (#854) diff --git a/src/hb-ot-colr-table.hh b/src/hb-ot-colr-table.hh index c5bc2ccb..08a39a99 100644 --- a/src/hb-ot-colr-table.hh +++ b/src/hb-ot-colr-table.hh @@ -42,10 +42,10 @@ struct LayerRecord inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (true); + return_trace (c->check_struct (this)); } - HBUINT16 gID; /* Glyph ID of layer glyph */ + GlyphID gID; /* Glyph ID of layer glyph */ HBUINT16 paletteIndex; /* Index value to use with a selected color palette */ public: DEFINE_SIZE_STATIC (4); @@ -53,13 +53,15 @@ struct LayerRecord struct BaseGlyphRecord { - inline bool sanitize (hb_sanitize_context_t *c, unsigned int palettes) const + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); + return_trace (c->check_struct (this) && + firstLayerIndex.sanitize (c, base) && + c->check_array ((const void*) &firstLayerIndex, sizeof (LayerRecord), numLayers)); } - HBUINT16 gID; /* Glyph ID of reference glyph */ + GlyphID gID; /* Glyph ID of reference glyph */ OffsetTo<LayerRecord> firstLayerIndex; /* Index to the layer record */ HBUINT16 numLayers; /* Number of color layers associated with this glyph */ @@ -74,9 +76,17 @@ struct COLR inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - c->check_array ((const void*) &baseGlyphRecords, sizeof (BaseGlyphRecord), numBaseGlyphRecords) && - c->check_array ((const void*) &layerRecordsOffset, sizeof (LayerRecord), numLayerRecords)); + if (!(c->check_struct (this) && + c->check_array ((const void*) &baseGlyphRecords, sizeof (BaseGlyphRecord), numBaseGlyphRecords) && + c->check_array ((const void*) &layerRecordsOffset, sizeof (LayerRecord), numLayerRecords))) + return_trace (false); + + const BaseGlyphRecord *base_glyph_records = &baseGlyphRecords (this); + for (unsigned int i = 0; i < numBaseGlyphRecords; ++i) + if (!(base_glyph_records[i].sanitize (c, this))) + return_trace (false); + + return_trace (true); } protected: @@ -87,7 +97,6 @@ struct COLR LOffsetTo<LayerRecord> layerRecordsOffset; /* Offset to Layer Records */ HBUINT16 numLayerRecords; /* Number of Layer Records */ - public: DEFINE_SIZE_STATIC (14); }; commit 7e958646a4a825bfe3aac56ddb96100d68c5592c Author: Ebrahim Byagowi <ebra...@gnu.org> Date: Thu Mar 1 10:27:18 2018 +0330 [CPAL] Fix version checking logic on sanitizer (#851) diff --git a/src/hb-ot-cpal-table.hh b/src/hb-ot-cpal-table.hh index aade0e73..740a94b3 100644 --- a/src/hb-ot-cpal-table.hh +++ b/src/hb-ot-cpal-table.hh @@ -89,7 +89,6 @@ struct CPALV1Tail LOffsetTo<HBUINT32> paletteFlags; LOffsetTo<HBUINT16> paletteLabel; LOffsetTo<HBUINT16> paletteEntryLabel; - public: DEFINE_SIZE_STATIC (12); }; @@ -113,13 +112,12 @@ struct CPAL if (colorRecordIndices[i] + numPaletteEntries > colorRecords.get_size ()) return_trace (false); - if (version > 1) - { - const CPALV1Tail &v1 = StructAfter<CPALV1Tail> (*this); - return_trace (v1.sanitize (c, palettes)); - } - else + // If version is zero, we are done here; otherwise we need to check tail also + if (version == 0) return_trace (true); + + const CPALV1Tail &v1 = StructAfter<CPALV1Tail> (*this); + return_trace (v1.sanitize (c, palettes)); } inline unsigned int get_size (void) const @@ -158,7 +156,7 @@ struct CPAL HBUINT16 numPalettes; ArrayOf<ColorRecord> colorRecords; HBUINT16 colorRecordIndices[VAR]; // VAR=numPalettes - +/*CPALV1Tail v1[VAR];*/ public: DEFINE_SIZE_ARRAY (12, colorRecordIndices); }; _______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/harfbuzz