src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-common-private.hh
changeset 50352 25db2c8f3cf8
parent 48274 51772bf1fb0c
child 50826 f5b95be8b6e2
equal deleted inserted replaced
50351:9289c4214a35 50352:25db2c8f3cf8
   153   inline bool intersects (const hb_set_t *glyphs) const {
   153   inline bool intersects (const hb_set_t *glyphs) const {
   154     return glyphs->intersects (start, end);
   154     return glyphs->intersects (start, end);
   155   }
   155   }
   156 
   156 
   157   template <typename set_t>
   157   template <typename set_t>
   158   inline void add_coverage (set_t *glyphs) const {
   158   inline bool add_coverage (set_t *glyphs) const {
   159     glyphs->add_range (start, end);
   159     return glyphs->add_range (start, end);
   160   }
   160   }
   161 
   161 
   162   GlyphID       start;          /* First GlyphID in the range */
   162   GlyphID       start;          /* First GlyphID in the range */
   163   GlyphID       end;            /* Last GlyphID in the range */
   163   GlyphID       end;            /* Last GlyphID in the range */
   164   USHORT        value;          /* Value */
   164   HBUINT16      value;          /* Value */
   165   public:
   165   public:
   166   DEFINE_SIZE_STATIC (6);
   166   DEFINE_SIZE_STATIC (6);
   167 };
   167 };
   168 DEFINE_NULL_DATA (RangeRecord, "\000\001");
   168 DEFINE_NULL_DATA (RangeRecord, "\000\001");
   169 
   169 
   173   inline unsigned int get_indexes (unsigned int start_offset,
   173   inline unsigned int get_indexes (unsigned int start_offset,
   174                                    unsigned int *_count /* IN/OUT */,
   174                                    unsigned int *_count /* IN/OUT */,
   175                                    unsigned int *_indexes /* OUT */) const
   175                                    unsigned int *_indexes /* OUT */) const
   176   {
   176   {
   177     if (_count) {
   177     if (_count) {
   178       const USHORT *arr = this->sub_array (start_offset, _count);
   178       const HBUINT16 *arr = this->sub_array (start_offset, _count);
   179       unsigned int count = *_count;
   179       unsigned int count = *_count;
   180       for (unsigned int i = 0; i < count; i++)
   180       for (unsigned int i = 0; i < count; i++)
   181         _indexes[i] = arr[i];
   181         _indexes[i] = arr[i];
   182     }
   182     }
   183     return this->len;
   183     return this->len;
   214   {
   214   {
   215     TRACE_SANITIZE (this);
   215     TRACE_SANITIZE (this);
   216     return_trace (c->check_struct (this) && featureIndex.sanitize (c));
   216     return_trace (c->check_struct (this) && featureIndex.sanitize (c));
   217   }
   217   }
   218 
   218 
   219   Offset<>      lookupOrderZ;   /* = Null (reserved for an offset to a
   219   Offset16      lookupOrderZ;   /* = Null (reserved for an offset to a
   220                                  * reordering table) */
   220                                  * reordering table) */
   221   USHORT        reqFeatureIndex;/* Index of a feature required for this
   221   HBUINT16      reqFeatureIndex;/* Index of a feature required for this
   222                                  * language system--if no required features
   222                                  * language system--if no required features
   223                                  * = 0xFFFFu */
   223                                  * = 0xFFFFu */
   224   IndexArray    featureIndex;   /* Array of indices into the FeatureList */
   224   IndexArray    featureIndex;   /* Array of indices into the FeatureList */
   225   public:
   225   public:
   226   DEFINE_SIZE_ARRAY (6, featureIndex);
   226   DEFINE_SIZE_ARRAY (6, featureIndex);
   297      * Here is one set of rules to determine if the 'size' feature is built
   297      * Here is one set of rules to determine if the 'size' feature is built
   298      * correctly, or as by the older versions of MakeOTF. You may be able to do
   298      * correctly, or as by the older versions of MakeOTF. You may be able to do
   299      * better.
   299      * better.
   300      *
   300      *
   301      * Assume that the offset to the size feature is according to specification,
   301      * Assume that the offset to the size feature is according to specification,
   302      * and make the following value checks. If it fails, assume the the size
   302      * and make the following value checks. If it fails, assume the size
   303      * feature is calculated as versions of MakeOTF before the AFDKO 2.0 built it.
   303      * feature is calculated as versions of MakeOTF before the AFDKO 2.0 built it.
   304      * If this fails, reject the 'size' feature. The older makeOTF's calculated the
   304      * If this fails, reject the 'size' feature. The older makeOTF's calculated the
   305      * offset from the beginning of the FeatureList table, rather than from the
   305      * offset from the beginning of the FeatureList table, rather than from the
   306      * beginning of the 'size' Feature table.
   306      * beginning of the 'size' Feature table.
   307      *
   307      *
   341       return_trace (false);
   341       return_trace (false);
   342     else
   342     else
   343       return_trace (true);
   343       return_trace (true);
   344   }
   344   }
   345 
   345 
   346   USHORT        designSize;     /* Represents the design size in 720/inch
   346   HBUINT16      designSize;     /* Represents the design size in 720/inch
   347                                  * units (decipoints).  The design size entry
   347                                  * units (decipoints).  The design size entry
   348                                  * must be non-zero.  When there is a design
   348                                  * must be non-zero.  When there is a design
   349                                  * size but no recommended size range, the
   349                                  * size but no recommended size range, the
   350                                  * rest of the array will consist of zeros. */
   350                                  * rest of the array will consist of zeros. */
   351   USHORT        subfamilyID;    /* Has no independent meaning, but serves
   351   HBUINT16      subfamilyID;    /* Has no independent meaning, but serves
   352                                  * as an identifier that associates fonts
   352                                  * as an identifier that associates fonts
   353                                  * in a subfamily. All fonts which share a
   353                                  * in a subfamily. All fonts which share a
   354                                  * Preferred or Font Family name and which
   354                                  * Preferred or Font Family name and which
   355                                  * differ only by size range shall have the
   355                                  * differ only by size range shall have the
   356                                  * same subfamily value, and no fonts which
   356                                  * same subfamily value, and no fonts which
   357                                  * differ in weight or style shall have the
   357                                  * differ in weight or style shall have the
   358                                  * same subfamily value. If this value is
   358                                  * same subfamily value. If this value is
   359                                  * zero, the remaining fields in the array
   359                                  * zero, the remaining fields in the array
   360                                  * will be ignored. */
   360                                  * will be ignored. */
   361   USHORT        subfamilyNameID;/* If the preceding value is non-zero, this
   361   HBUINT16      subfamilyNameID;/* If the preceding value is non-zero, this
   362                                  * value must be set in the range 256 - 32767
   362                                  * value must be set in the range 256 - 32767
   363                                  * (inclusive). It records the value of a
   363                                  * (inclusive). It records the value of a
   364                                  * field in the name table, which must
   364                                  * field in the name table, which must
   365                                  * contain English-language strings encoded
   365                                  * contain English-language strings encoded
   366                                  * in Windows Unicode and Macintosh Roman,
   366                                  * in Windows Unicode and Macintosh Roman,
   370                                  * application should use, in combination
   370                                  * application should use, in combination
   371                                  * with the family name, to represent the
   371                                  * with the family name, to represent the
   372                                  * subfamily in a menu.  Applications will
   372                                  * subfamily in a menu.  Applications will
   373                                  * choose the appropriate version based on
   373                                  * choose the appropriate version based on
   374                                  * their selection criteria. */
   374                                  * their selection criteria. */
   375   USHORT        rangeStart;     /* Large end of the recommended usage range
   375   HBUINT16      rangeStart;     /* Large end of the recommended usage range
   376                                  * (inclusive), stored in 720/inch units
   376                                  * (inclusive), stored in 720/inch units
   377                                  * (decipoints). */
   377                                  * (decipoints). */
   378   USHORT        rangeEnd;       /* Small end of the recommended usage range
   378   HBUINT16      rangeEnd;       /* Small end of the recommended usage range
   379                                    (exclusive), stored in 720/inch units
   379                                    (exclusive), stored in 720/inch units
   380                                  * (decipoints). */
   380                                  * (decipoints). */
   381   public:
   381   public:
   382   DEFINE_SIZE_STATIC (10);
   382   DEFINE_SIZE_STATIC (10);
   383 };
   383 };
   391     /* Right now minorVersion is at zero.  Which means, any table supports
   391     /* Right now minorVersion is at zero.  Which means, any table supports
   392      * the uiNameID field. */
   392      * the uiNameID field. */
   393     return_trace (c->check_struct (this));
   393     return_trace (c->check_struct (this));
   394   }
   394   }
   395 
   395 
   396   USHORT        version;        /* (set to 0): This corresponds to a “minor”
   396   HBUINT16      version;        /* (set to 0): This corresponds to a “minor”
   397                                  * version number. Additional data may be
   397                                  * version number. Additional data may be
   398                                  * added to the end of this Feature Parameters
   398                                  * added to the end of this Feature Parameters
   399                                  * table in the future. */
   399                                  * table in the future. */
   400 
   400 
   401   USHORT        uiNameID;       /* The 'name' table name ID that specifies a
   401   HBUINT16      uiNameID;       /* The 'name' table name ID that specifies a
   402                                  * string (or strings, for multiple languages)
   402                                  * string (or strings, for multiple languages)
   403                                  * for a user-interface label for this
   403                                  * for a user-interface label for this
   404                                  * feature.  The values of uiLabelNameId and
   404                                  * feature.  The values of uiLabelNameId and
   405                                  * sampleTextNameId are expected to be in the
   405                                  * sampleTextNameId are expected to be in the
   406                                  * font-specific name ID range (256-32767),
   406                                  * font-specific name ID range (256-32767),
   424     TRACE_SANITIZE (this);
   424     TRACE_SANITIZE (this);
   425     return_trace (c->check_struct (this) &&
   425     return_trace (c->check_struct (this) &&
   426                   characters.sanitize (c));
   426                   characters.sanitize (c));
   427   }
   427   }
   428 
   428 
   429   USHORT        format;                 /* Format number is set to 0. */
   429   HBUINT16      format;                 /* Format number is set to 0. */
   430   USHORT        featUILableNameID;      /* The ‘name’ table name ID that
   430   HBUINT16      featUILableNameID;      /* The ‘name’ table name ID that
   431                                          * specifies a string (or strings,
   431                                          * specifies a string (or strings,
   432                                          * for multiple languages) for a
   432                                          * for multiple languages) for a
   433                                          * user-interface label for this
   433                                          * user-interface label for this
   434                                          * feature. (May be nullptr.) */
   434                                          * feature. (May be nullptr.) */
   435   USHORT        featUITooltipTextNameID;/* The ‘name’ table name ID that
   435   HBUINT16      featUITooltipTextNameID;/* The ‘name’ table name ID that
   436                                          * specifies a string (or strings,
   436                                          * specifies a string (or strings,
   437                                          * for multiple languages) that an
   437                                          * for multiple languages) that an
   438                                          * application can use for tooltip
   438                                          * application can use for tooltip
   439                                          * text for this feature. (May be
   439                                          * text for this feature. (May be
   440                                          * nullptr.) */
   440                                          * nullptr.) */
   441   USHORT        sampleTextNameID;       /* The ‘name’ table name ID that
   441   HBUINT16      sampleTextNameID;       /* The ‘name’ table name ID that
   442                                          * specifies sample text that
   442                                          * specifies sample text that
   443                                          * illustrates the effect of this
   443                                          * illustrates the effect of this
   444                                          * feature. (May be nullptr.) */
   444                                          * feature. (May be nullptr.) */
   445   USHORT        numNamedParameters;     /* Number of named parameters. (May
   445   HBUINT16      numNamedParameters;     /* Number of named parameters. (May
   446                                          * be zero.) */
   446                                          * be zero.) */
   447   USHORT        firstParamUILabelNameID;/* The first ‘name’ table name ID
   447   HBUINT16      firstParamUILabelNameID;/* The first ‘name’ table name ID
   448                                          * used to specify strings for
   448                                          * used to specify strings for
   449                                          * user-interface labels for the
   449                                          * user-interface labels for the
   450                                          * feature parameters. (Must be zero
   450                                          * feature parameters. (Must be zero
   451                                          * if numParameters is zero.) */
   451                                          * if numParameters is zero.) */
   452   ArrayOf<UINT24>
   452   ArrayOf<UINT24>
   560 };
   560 };
   561 
   561 
   562 typedef RecordListOf<Feature> FeatureList;
   562 typedef RecordListOf<Feature> FeatureList;
   563 
   563 
   564 
   564 
   565 struct LookupFlag : USHORT
   565 struct LookupFlag : HBUINT16
   566 {
   566 {
   567   enum Flags {
   567   enum Flags {
   568     RightToLeft         = 0x0001u,
   568     RightToLeft         = 0x0001u,
   569     IgnoreBaseGlyphs    = 0x0002u,
   569     IgnoreBaseGlyphs    = 0x0002u,
   570     IgnoreLigatures     = 0x0004u,
   570     IgnoreLigatures     = 0x0004u,
   606   inline uint32_t get_props (void) const
   606   inline uint32_t get_props (void) const
   607   {
   607   {
   608     unsigned int flag = lookupFlag;
   608     unsigned int flag = lookupFlag;
   609     if (unlikely (flag & LookupFlag::UseMarkFilteringSet))
   609     if (unlikely (flag & LookupFlag::UseMarkFilteringSet))
   610     {
   610     {
   611       const USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
   611       const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
   612       flag += (markFilteringSet << 16);
   612       flag += (markFilteringSet << 16);
   613     }
   613     }
   614     return flag;
   614     return flag;
   615   }
   615   }
   616 
   616 
   638     lookupType.set (lookup_type);
   638     lookupType.set (lookup_type);
   639     lookupFlag.set (lookup_props & 0xFFFFu);
   639     lookupFlag.set (lookup_props & 0xFFFFu);
   640     if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false);
   640     if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false);
   641     if (lookupFlag & LookupFlag::UseMarkFilteringSet)
   641     if (lookupFlag & LookupFlag::UseMarkFilteringSet)
   642     {
   642     {
   643       USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
   643       HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
   644       markFilteringSet.set (lookup_props >> 16);
   644       markFilteringSet.set (lookup_props >> 16);
   645     }
   645     }
   646     return_trace (true);
   646     return_trace (true);
   647   }
   647   }
   648 
   648 
   651     TRACE_SANITIZE (this);
   651     TRACE_SANITIZE (this);
   652     /* Real sanitize of the subtables is done by GSUB/GPOS/... */
   652     /* Real sanitize of the subtables is done by GSUB/GPOS/... */
   653     if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false);
   653     if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false);
   654     if (lookupFlag & LookupFlag::UseMarkFilteringSet)
   654     if (lookupFlag & LookupFlag::UseMarkFilteringSet)
   655     {
   655     {
   656       const USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
   656       const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
   657       if (!markFilteringSet.sanitize (c)) return_trace (false);
   657       if (!markFilteringSet.sanitize (c)) return_trace (false);
   658     }
   658     }
   659     return_trace (true);
   659     return_trace (true);
   660   }
   660   }
   661 
   661 
   662   private:
   662   private:
   663   USHORT        lookupType;             /* Different enumerations for GSUB and GPOS */
   663   HBUINT16      lookupType;             /* Different enumerations for GSUB and GPOS */
   664   USHORT        lookupFlag;             /* Lookup qualifiers */
   664   HBUINT16      lookupFlag;             /* Lookup qualifiers */
   665   ArrayOf<Offset<> >
   665   ArrayOf<Offset16>
   666                 subTable;               /* Array of SubTables */
   666                 subTable;               /* Array of SubTables */
   667   USHORT        markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets
   667   HBUINT16      markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets
   668                                          * structure. This field is only present if bit
   668                                          * structure. This field is only present if bit
   669                                          * UseMarkFilteringSet of lookup flags is set. */
   669                                          * UseMarkFilteringSet of lookup flags is set. */
   670   public:
   670   public:
   671   DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX);
   671   DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX);
   672 };
   672 };
   698     if (unlikely (!c->extend_min (*this))) return_trace (false);
   698     if (unlikely (!c->extend_min (*this))) return_trace (false);
   699     glyphArray.len.set (num_glyphs);
   699     glyphArray.len.set (num_glyphs);
   700     if (unlikely (!c->extend (glyphArray))) return_trace (false);
   700     if (unlikely (!c->extend (glyphArray))) return_trace (false);
   701     for (unsigned int i = 0; i < num_glyphs; i++)
   701     for (unsigned int i = 0; i < num_glyphs; i++)
   702       glyphArray[i] = glyphs[i];
   702       glyphArray[i] = glyphs[i];
   703     glyphs.advance (num_glyphs);
   703     glyphs += num_glyphs;
   704     return_trace (true);
   704     return_trace (true);
   705   }
   705   }
   706 
   706 
   707   inline bool sanitize (hb_sanitize_context_t *c) const
   707   inline bool sanitize (hb_sanitize_context_t *c) const
   708   {
   708   {
   713   inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
   713   inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
   714     return glyphs->has (glyphArray[index]);
   714     return glyphs->has (glyphArray[index]);
   715   }
   715   }
   716 
   716 
   717   template <typename set_t>
   717   template <typename set_t>
   718   inline void add_coverage (set_t *glyphs) const {
   718   inline bool add_coverage (set_t *glyphs) const {
   719     unsigned int count = glyphArray.len;
   719     return glyphs->add_sorted_array (glyphArray.array, glyphArray.len);
   720     for (unsigned int i = 0; i < count; i++)
       
   721       glyphs->add (glyphArray[i]);
       
   722   }
   720   }
   723 
   721 
   724   public:
   722   public:
   725   /* Older compilers need this to be public. */
   723   /* Older compilers need this to be public. */
   726   struct Iter {
   724   struct Iter {
   735     unsigned int i;
   733     unsigned int i;
   736   };
   734   };
   737   private:
   735   private:
   738 
   736 
   739   protected:
   737   protected:
   740   USHORT        coverageFormat; /* Format identifier--format = 1 */
   738   HBUINT16      coverageFormat; /* Format identifier--format = 1 */
   741   SortedArrayOf<GlyphID>
   739   SortedArrayOf<GlyphID>
   742                 glyphArray;     /* Array of GlyphIDs--in numerical order */
   740                 glyphArray;     /* Array of GlyphIDs--in numerical order */
   743   public:
   741   public:
   744   DEFINE_SIZE_ARRAY (4, glyphArray);
   742   DEFINE_SIZE_ARRAY (4, glyphArray);
   745 };
   743 };
   789         rangeRecord[range].value.set (i);
   787         rangeRecord[range].value.set (i);
   790         rangeRecord[range].end = glyphs[i];
   788         rangeRecord[range].end = glyphs[i];
   791       } else {
   789       } else {
   792         rangeRecord[range].end = glyphs[i];
   790         rangeRecord[range].end = glyphs[i];
   793       }
   791       }
   794     glyphs.advance (num_glyphs);
   792     glyphs += num_glyphs;
   795     return_trace (true);
   793     return_trace (true);
   796   }
   794   }
   797 
   795 
   798   inline bool sanitize (hb_sanitize_context_t *c) const
   796   inline bool sanitize (hb_sanitize_context_t *c) const
   799   {
   797   {
   815     }
   813     }
   816     return false;
   814     return false;
   817   }
   815   }
   818 
   816 
   819   template <typename set_t>
   817   template <typename set_t>
   820   inline void add_coverage (set_t *glyphs) const {
   818   inline bool add_coverage (set_t *glyphs) const {
   821     unsigned int count = rangeRecord.len;
   819     unsigned int count = rangeRecord.len;
   822     for (unsigned int i = 0; i < count; i++)
   820     for (unsigned int i = 0; i < count; i++)
   823       rangeRecord[i].add_coverage (glyphs);
   821       if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
       
   822         return false;
       
   823     return true;
   824   }
   824   }
   825 
   825 
   826   public:
   826   public:
   827   /* Older compilers need this to be public. */
   827   /* Older compilers need this to be public. */
   828   struct Iter
   828   struct Iter
   858     unsigned int i, j, coverage;
   858     unsigned int i, j, coverage;
   859   };
   859   };
   860   private:
   860   private:
   861 
   861 
   862   protected:
   862   protected:
   863   USHORT        coverageFormat; /* Format identifier--format = 2 */
   863   HBUINT16      coverageFormat; /* Format identifier--format = 2 */
   864   SortedArrayOf<RangeRecord>
   864   SortedArrayOf<RangeRecord>
   865                 rangeRecord;    /* Array of glyph ranges--ordered by
   865                 rangeRecord;    /* Array of glyph ranges--ordered by
   866                                  * Start GlyphID. rangeCount entries
   866                                  * Start GlyphID. rangeCount entries
   867                                  * long */
   867                                  * long */
   868   public:
   868   public:
   872 struct Coverage
   872 struct Coverage
   873 {
   873 {
   874   inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
   874   inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
   875   {
   875   {
   876     switch (u.format) {
   876     switch (u.format) {
   877     case 1: return u.format1.get_coverage(glyph_id);
   877     case 1: return u.format1.get_coverage (glyph_id);
   878     case 2: return u.format2.get_coverage(glyph_id);
   878     case 2: return u.format2.get_coverage (glyph_id);
   879     default:return NOT_COVERED;
   879     default:return NOT_COVERED;
   880     }
   880     }
   881   }
   881   }
   882 
   882 
   883   inline bool serialize (hb_serialize_context_t *c,
   883   inline bool serialize (hb_serialize_context_t *c,
   925     case 2: return u.format2.intersects_coverage (glyphs, index);
   925     case 2: return u.format2.intersects_coverage (glyphs, index);
   926     default:return false;
   926     default:return false;
   927     }
   927     }
   928   }
   928   }
   929 
   929 
       
   930   /* Might return false if array looks unsorted.
       
   931    * Used for faster rejection of corrupt data. */
   930   template <typename set_t>
   932   template <typename set_t>
   931   inline void add_coverage (set_t *glyphs) const {
   933   inline bool add_coverage (set_t *glyphs) const {
   932     switch (u.format) {
   934     switch (u.format) {
   933     case 1: u.format1.add_coverage (glyphs); break;
   935     case 1: return u.format1.add_coverage (glyphs);
   934     case 2: u.format2.add_coverage (glyphs); break;
   936     case 2: return u.format2.add_coverage (glyphs);
   935     default:                                 break;
   937     default:return false;
   936     }
   938     }
   937   }
   939   }
   938 
   940 
   939   struct Iter {
   941   struct Iter {
   940     Iter (void) : format (0), u () {};
   942     Iter (void) : format (0), u () {};
   983     } u;
   985     } u;
   984   };
   986   };
   985 
   987 
   986   protected:
   988   protected:
   987   union {
   989   union {
   988   USHORT                format;         /* Format identifier */
   990   HBUINT16              format;         /* Format identifier */
   989   CoverageFormat1       format1;
   991   CoverageFormat1       format1;
   990   CoverageFormat2       format2;
   992   CoverageFormat2       format2;
   991   } u;
   993   } u;
   992   public:
   994   public:
   993   DEFINE_SIZE_UNION (2, format);
   995   DEFINE_SIZE_UNION (2, format);
  1016     TRACE_SANITIZE (this);
  1018     TRACE_SANITIZE (this);
  1017     return_trace (c->check_struct (this) && classValue.sanitize (c));
  1019     return_trace (c->check_struct (this) && classValue.sanitize (c));
  1018   }
  1020   }
  1019 
  1021 
  1020   template <typename set_t>
  1022   template <typename set_t>
  1021   inline void add_class (set_t *glyphs, unsigned int klass) const {
  1023   inline bool add_coverage (set_t *glyphs) const {
       
  1024     unsigned int start = 0;
  1022     unsigned int count = classValue.len;
  1025     unsigned int count = classValue.len;
  1023     for (unsigned int i = 0; i < count; i++)
  1026     for (unsigned int i = 0; i < count; i++)
       
  1027     {
       
  1028       if (classValue[i])
       
  1029         continue;
       
  1030 
       
  1031       if (start != i)
       
  1032         if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + i)))
       
  1033           return false;
       
  1034 
       
  1035       start = i + 1;
       
  1036     }
       
  1037     if (start != count)
       
  1038       if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + count)))
       
  1039         return false;
       
  1040 
       
  1041     return true;
       
  1042   }
       
  1043 
       
  1044   template <typename set_t>
       
  1045   inline bool add_class (set_t *glyphs, unsigned int klass) const {
       
  1046     unsigned int count = classValue.len;
       
  1047     for (unsigned int i = 0; i < count; i++)
       
  1048     {
  1024       if (classValue[i] == klass)
  1049       if (classValue[i] == klass)
  1025         glyphs->add (startGlyph + i);
  1050         glyphs->add (startGlyph + i);
       
  1051     }
       
  1052     return true;
  1026   }
  1053   }
  1027 
  1054 
  1028   inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
  1055   inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
  1029     unsigned int count = classValue.len;
  1056     unsigned int count = classValue.len;
  1030     if (klass == 0)
  1057     if (klass == 0)
  1031     {
  1058     {
  1032       /* Match if there's any glyph that is not listed! */
  1059       /* Match if there's any glyph that is not listed! */
  1033       hb_codepoint_t g = -1;
  1060       hb_codepoint_t g = HB_SET_VALUE_INVALID;
  1034       if (!hb_set_next (glyphs, &g))
  1061       if (!hb_set_next (glyphs, &g))
  1035         return false;
  1062         return false;
  1036       if (g < startGlyph)
  1063       if (g < startGlyph)
  1037         return true;
  1064         return true;
  1038       g = startGlyph + count - 1;
  1065       g = startGlyph + count - 1;
  1045         return true;
  1072         return true;
  1046     return false;
  1073     return false;
  1047   }
  1074   }
  1048 
  1075 
  1049   protected:
  1076   protected:
  1050   USHORT        classFormat;            /* Format identifier--format = 1 */
  1077   HBUINT16      classFormat;            /* Format identifier--format = 1 */
  1051   GlyphID       startGlyph;             /* First GlyphID of the classValueArray */
  1078   GlyphID       startGlyph;             /* First GlyphID of the classValueArray */
  1052   ArrayOf<USHORT>
  1079   ArrayOf<HBUINT16>
  1053                 classValue;             /* Array of Class Values--one per GlyphID */
  1080                 classValue;             /* Array of Class Values--one per GlyphID */
  1054   public:
  1081   public:
  1055   DEFINE_SIZE_ARRAY (6, classValue);
  1082   DEFINE_SIZE_ARRAY (6, classValue);
  1056 };
  1083 };
  1057 
  1084 
  1073     TRACE_SANITIZE (this);
  1100     TRACE_SANITIZE (this);
  1074     return_trace (rangeRecord.sanitize (c));
  1101     return_trace (rangeRecord.sanitize (c));
  1075   }
  1102   }
  1076 
  1103 
  1077   template <typename set_t>
  1104   template <typename set_t>
  1078   inline void add_class (set_t *glyphs, unsigned int klass) const {
  1105   inline bool add_coverage (set_t *glyphs) const {
  1079     unsigned int count = rangeRecord.len;
  1106     unsigned int count = rangeRecord.len;
  1080     for (unsigned int i = 0; i < count; i++)
  1107     for (unsigned int i = 0; i < count; i++)
       
  1108       if (rangeRecord[i].value)
       
  1109         if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
       
  1110           return false;
       
  1111     return true;
       
  1112   }
       
  1113 
       
  1114   template <typename set_t>
       
  1115   inline bool add_class (set_t *glyphs, unsigned int klass) const {
       
  1116     unsigned int count = rangeRecord.len;
       
  1117     for (unsigned int i = 0; i < count; i++)
       
  1118     {
  1081       if (rangeRecord[i].value == klass)
  1119       if (rangeRecord[i].value == klass)
  1082         rangeRecord[i].add_coverage (glyphs);
  1120         if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
       
  1121           return false;
       
  1122     }
       
  1123     return true;
  1083   }
  1124   }
  1084 
  1125 
  1085   inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
  1126   inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
  1086     unsigned int count = rangeRecord.len;
  1127     unsigned int count = rangeRecord.len;
  1087     if (klass == 0)
  1128     if (klass == 0)
  1088     {
  1129     {
  1089       /* Match if there's any glyph that is not listed! */
  1130       /* Match if there's any glyph that is not listed! */
  1090       hb_codepoint_t g = (hb_codepoint_t) -1;
  1131       hb_codepoint_t g = HB_SET_VALUE_INVALID;
  1091       for (unsigned int i = 0; i < count; i++)
  1132       for (unsigned int i = 0; i < count; i++)
  1092       {
  1133       {
  1093         if (!hb_set_next (glyphs, &g))
  1134         if (!hb_set_next (glyphs, &g))
  1094           break;
  1135           break;
  1095         if (g < rangeRecord[i].start)
  1136         if (g < rangeRecord[i].start)
  1096           return true;
  1137           return true;
  1097         g = rangeRecord[i].end;
  1138         g = rangeRecord[i].end;
  1098       }
  1139       }
  1099       if (g != (hb_codepoint_t) -1 && hb_set_next (glyphs, &g))
  1140       if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g))
  1100         return true;
  1141         return true;
  1101       /* Fall through. */
  1142       /* Fall through. */
  1102     }
  1143     }
  1103     for (unsigned int i = 0; i < count; i++)
  1144     for (unsigned int i = 0; i < count; i++)
  1104       if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs))
  1145       if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs))
  1105         return true;
  1146         return true;
  1106     return false;
  1147     return false;
  1107   }
  1148   }
  1108 
  1149 
  1109   protected:
  1150   protected:
  1110   USHORT        classFormat;    /* Format identifier--format = 2 */
  1151   HBUINT16      classFormat;    /* Format identifier--format = 2 */
  1111   SortedArrayOf<RangeRecord>
  1152   SortedArrayOf<RangeRecord>
  1112                 rangeRecord;    /* Array of glyph ranges--ordered by
  1153                 rangeRecord;    /* Array of glyph ranges--ordered by
  1113                                  * Start GlyphID */
  1154                                  * Start GlyphID */
  1114   public:
  1155   public:
  1115   DEFINE_SIZE_ARRAY (4, rangeRecord);
  1156   DEFINE_SIZE_ARRAY (4, rangeRecord);
  1118 struct ClassDef
  1159 struct ClassDef
  1119 {
  1160 {
  1120   inline unsigned int get_class (hb_codepoint_t glyph_id) const
  1161   inline unsigned int get_class (hb_codepoint_t glyph_id) const
  1121   {
  1162   {
  1122     switch (u.format) {
  1163     switch (u.format) {
  1123     case 1: return u.format1.get_class(glyph_id);
  1164     case 1: return u.format1.get_class (glyph_id);
  1124     case 2: return u.format2.get_class(glyph_id);
  1165     case 2: return u.format2.get_class (glyph_id);
  1125     default:return 0;
  1166     default:return 0;
  1126     }
  1167     }
  1127   }
  1168   }
  1128 
  1169 
  1129   inline bool sanitize (hb_sanitize_context_t *c) const
  1170   inline bool sanitize (hb_sanitize_context_t *c) const
  1135     case 2: return_trace (u.format2.sanitize (c));
  1176     case 2: return_trace (u.format2.sanitize (c));
  1136     default:return_trace (true);
  1177     default:return_trace (true);
  1137     }
  1178     }
  1138   }
  1179   }
  1139 
  1180 
  1140   inline void add_class (hb_set_t *glyphs, unsigned int klass) const {
  1181   /* Might return false if array looks unsorted.
       
  1182    * Used for faster rejection of corrupt data. */
       
  1183   template <typename set_t>
       
  1184   inline bool add_coverage (set_t *glyphs) const {
  1141     switch (u.format) {
  1185     switch (u.format) {
  1142     case 1: u.format1.add_class (glyphs, klass); return;
  1186     case 1: return u.format1.add_coverage (glyphs);
  1143     case 2: u.format2.add_class (glyphs, klass); return;
  1187     case 2: return u.format2.add_coverage (glyphs);
  1144     default:return;
  1188     default:return false;
       
  1189     }
       
  1190   }
       
  1191 
       
  1192   /* Might return false if array looks unsorted.
       
  1193    * Used for faster rejection of corrupt data. */
       
  1194   template <typename set_t>
       
  1195   inline bool add_class (set_t *glyphs, unsigned int klass) const {
       
  1196     switch (u.format) {
       
  1197     case 1: return u.format1.add_class (glyphs, klass);
       
  1198     case 2: return u.format2.add_class (glyphs, klass);
       
  1199     default:return false;
  1145     }
  1200     }
  1146   }
  1201   }
  1147 
  1202 
  1148   inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
  1203   inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
  1149     switch (u.format) {
  1204     switch (u.format) {
  1153     }
  1208     }
  1154   }
  1209   }
  1155 
  1210 
  1156   protected:
  1211   protected:
  1157   union {
  1212   union {
  1158   USHORT                format;         /* Format identifier */
  1213   HBUINT16              format;         /* Format identifier */
  1159   ClassDefFormat1       format1;
  1214   ClassDefFormat1       format1;
  1160   ClassDefFormat2       format2;
  1215   ClassDefFormat2       format2;
  1161   } u;
  1216   } u;
  1162   public:
  1217   public:
  1163   DEFINE_SIZE_UNION (2, format);
  1218   DEFINE_SIZE_UNION (2, format);
  1218       return 0.;
  1273       return 0.;
  1219 
  1274 
  1220     const VarRegionAxis *axes = axesZ + (region_index * axisCount);
  1275     const VarRegionAxis *axes = axesZ + (region_index * axisCount);
  1221 
  1276 
  1222     float v = 1.;
  1277     float v = 1.;
  1223     unsigned int count = MIN (coord_len, (unsigned int) axisCount);
  1278     unsigned int count = axisCount;
  1224     for (unsigned int i = 0; i < count; i++)
  1279     for (unsigned int i = 0; i < count; i++)
  1225     {
  1280     {
  1226       float factor = axes[i].evaluate (coords[i]);
  1281       int coord = i < coord_len ? coords[i] : 0;
       
  1282       float factor = axes[i].evaluate (coord);
  1227       if (factor == 0.)
  1283       if (factor == 0.)
  1228         return 0.;
  1284         return 0.;
  1229       v *= factor;
  1285       v *= factor;
  1230     }
  1286     }
  1231     return v;
  1287     return v;
  1238                   c->check_array (axesZ, axesZ[0].static_size,
  1294                   c->check_array (axesZ, axesZ[0].static_size,
  1239                                   (unsigned int) axisCount * (unsigned int) regionCount));
  1295                                   (unsigned int) axisCount * (unsigned int) regionCount));
  1240   }
  1296   }
  1241 
  1297 
  1242   protected:
  1298   protected:
  1243   USHORT        axisCount;
  1299   HBUINT16      axisCount;
  1244   USHORT        regionCount;
  1300   HBUINT16      regionCount;
  1245   VarRegionAxis axesZ[VAR];
  1301   VarRegionAxis axesZ[VAR];
  1246   public:
  1302   public:
  1247   DEFINE_SIZE_ARRAY (4, axesZ);
  1303   DEFINE_SIZE_ARRAY (4, axesZ);
  1248 };
  1304 };
  1249 
  1305 
  1263       return 0.;
  1319       return 0.;
  1264 
  1320 
  1265    unsigned int count = regionIndices.len;
  1321    unsigned int count = regionIndices.len;
  1266    unsigned int scount = shortCount;
  1322    unsigned int scount = shortCount;
  1267 
  1323 
  1268    const BYTE *bytes = &StructAfter<BYTE> (regionIndices);
  1324    const HBUINT8 *bytes = &StructAfter<HBUINT8> (regionIndices);
  1269    const BYTE *row = bytes + inner * (scount + count);
  1325    const HBUINT8 *row = bytes + inner * (scount + count);
  1270 
  1326 
  1271    float delta = 0.;
  1327    float delta = 0.;
  1272    unsigned int i = 0;
  1328    unsigned int i = 0;
  1273 
  1329 
  1274    const SHORT *scursor = reinterpret_cast<const SHORT *> (row);
  1330    const HBINT16 *scursor = reinterpret_cast<const HBINT16 *> (row);
  1275    for (; i < scount; i++)
  1331    for (; i < scount; i++)
  1276    {
  1332    {
  1277      float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count);
  1333      float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count);
  1278      delta += scalar * *scursor++;
  1334      delta += scalar * *scursor++;
  1279    }
  1335    }
  1280    const INT8 *bcursor = reinterpret_cast<const INT8 *> (scursor);
  1336    const HBINT8 *bcursor = reinterpret_cast<const HBINT8 *> (scursor);
  1281    for (; i < count; i++)
  1337    for (; i < count; i++)
  1282    {
  1338    {
  1283      float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count);
  1339      float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count);
  1284      delta += scalar * *bcursor++;
  1340      delta += scalar * *bcursor++;
  1285    }
  1341    }
  1291   {
  1347   {
  1292     TRACE_SANITIZE (this);
  1348     TRACE_SANITIZE (this);
  1293     return_trace (c->check_struct (this) &&
  1349     return_trace (c->check_struct (this) &&
  1294                   regionIndices.sanitize(c) &&
  1350                   regionIndices.sanitize(c) &&
  1295                   shortCount <= regionIndices.len &&
  1351                   shortCount <= regionIndices.len &&
  1296                   c->check_array (&StructAfter<BYTE> (regionIndices),
  1352                   c->check_array (&StructAfter<HBUINT8> (regionIndices),
  1297                                   get_row_size (), itemCount));
  1353                                   get_row_size (), itemCount));
  1298   }
  1354   }
  1299 
  1355 
  1300   protected:
  1356   protected:
  1301   USHORT                itemCount;
  1357   HBUINT16              itemCount;
  1302   USHORT                shortCount;
  1358   HBUINT16              shortCount;
  1303   ArrayOf<USHORT>       regionIndices;
  1359   ArrayOf<HBUINT16>     regionIndices;
  1304   BYTE                  bytesX[VAR];
  1360   HBUINT8                       bytesX[VAR];
  1305   public:
  1361   public:
  1306   DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX);
  1362   DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX);
  1307 };
  1363 };
  1308 
  1364 
  1309 struct VariationStore
  1365 struct VariationStore
  1335                   regions.sanitize (c, this) &&
  1391                   regions.sanitize (c, this) &&
  1336                   dataSets.sanitize (c, this));
  1392                   dataSets.sanitize (c, this));
  1337   }
  1393   }
  1338 
  1394 
  1339   protected:
  1395   protected:
  1340   USHORT                                format;
  1396   HBUINT16                              format;
  1341   LOffsetTo<VarRegionList>              regions;
  1397   LOffsetTo<VarRegionList>              regions;
  1342   OffsetArrayOf<VarData, ULONG>         dataSets;
  1398   OffsetArrayOf<VarData, HBUINT32>      dataSets;
  1343   public:
  1399   public:
  1344   DEFINE_SIZE_ARRAY (8, dataSets);
  1400   DEFINE_SIZE_ARRAY (8, dataSets);
  1345 };
  1401 };
  1346 
  1402 
  1347 /*
  1403 /*
  1364     TRACE_SANITIZE (this);
  1420     TRACE_SANITIZE (this);
  1365     return_trace (c->check_struct (this));
  1421     return_trace (c->check_struct (this));
  1366   }
  1422   }
  1367 
  1423 
  1368   protected:
  1424   protected:
  1369   USHORT        format;         /* Format identifier--format = 1 */
  1425   HBUINT16      format;         /* Format identifier--format = 1 */
  1370   USHORT        axisIndex;
  1426   HBUINT16      axisIndex;
  1371   F2DOT14       filterRangeMinValue;
  1427   F2DOT14       filterRangeMinValue;
  1372   F2DOT14       filterRangeMaxValue;
  1428   F2DOT14       filterRangeMaxValue;
  1373   public:
  1429   public:
  1374   DEFINE_SIZE_STATIC (8);
  1430   DEFINE_SIZE_STATIC (8);
  1375 };
  1431 };
  1394     }
  1450     }
  1395   }
  1451   }
  1396 
  1452 
  1397   protected:
  1453   protected:
  1398   union {
  1454   union {
  1399   USHORT                format;         /* Format identifier */
  1455   HBUINT16              format;         /* Format identifier */
  1400   ConditionFormat1      format1;
  1456   ConditionFormat1      format1;
  1401   } u;
  1457   } u;
  1402   public:
  1458   public:
  1403   DEFINE_SIZE_UNION (2, format);
  1459   DEFINE_SIZE_UNION (2, format);
  1404 };
  1460 };
  1419     TRACE_SANITIZE (this);
  1475     TRACE_SANITIZE (this);
  1420     return_trace (conditions.sanitize (c, this));
  1476     return_trace (conditions.sanitize (c, this));
  1421   }
  1477   }
  1422 
  1478 
  1423   protected:
  1479   protected:
  1424   OffsetArrayOf<Condition, ULONG> conditions;
  1480   OffsetArrayOf<Condition, HBUINT32> conditions;
  1425   public:
  1481   public:
  1426   DEFINE_SIZE_ARRAY (2, conditions);
  1482   DEFINE_SIZE_ARRAY (2, conditions);
  1427 };
  1483 };
  1428 
  1484 
  1429 struct FeatureTableSubstitutionRecord
  1485 struct FeatureTableSubstitutionRecord
  1435     TRACE_SANITIZE (this);
  1491     TRACE_SANITIZE (this);
  1436     return_trace (c->check_struct (this) && feature.sanitize (c, base));
  1492     return_trace (c->check_struct (this) && feature.sanitize (c, base));
  1437   }
  1493   }
  1438 
  1494 
  1439   protected:
  1495   protected:
  1440   USHORT                featureIndex;
  1496   HBUINT16              featureIndex;
  1441   LOffsetTo<Feature>    feature;
  1497   LOffsetTo<Feature>    feature;
  1442   public:
  1498   public:
  1443   DEFINE_SIZE_STATIC (6);
  1499   DEFINE_SIZE_STATIC (6);
  1444 };
  1500 };
  1445 
  1501 
  1555   { return get_delta (font->y_ppem, font->y_scale); }
  1611   { return get_delta (font->y_ppem, font->y_scale); }
  1556 
  1612 
  1557   inline unsigned int get_size (void) const
  1613   inline unsigned int get_size (void) const
  1558   {
  1614   {
  1559     unsigned int f = deltaFormat;
  1615     unsigned int f = deltaFormat;
  1560     if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::static_size;
  1616     if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * HBUINT16::static_size;
  1561     return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f)));
  1617     return HBUINT16::static_size * (4 + ((endSize - startSize) >> (4 - f)));
  1562   }
  1618   }
  1563 
  1619 
  1564   inline bool sanitize (hb_sanitize_context_t *c) const
  1620   inline bool sanitize (hb_sanitize_context_t *c) const
  1565   {
  1621   {
  1566     TRACE_SANITIZE (this);
  1622     TRACE_SANITIZE (this);
  1601 
  1657 
  1602     return delta;
  1658     return delta;
  1603   }
  1659   }
  1604 
  1660 
  1605   protected:
  1661   protected:
  1606   USHORT        startSize;              /* Smallest size to correct--in ppem */
  1662   HBUINT16      startSize;              /* Smallest size to correct--in ppem */
  1607   USHORT        endSize;                /* Largest size to correct--in ppem */
  1663   HBUINT16      endSize;                /* Largest size to correct--in ppem */
  1608   USHORT        deltaFormat;            /* Format of DeltaValue array data: 1, 2, or 3
  1664   HBUINT16      deltaFormat;            /* Format of DeltaValue array data: 1, 2, or 3
  1609                                          * 1    Signed 2-bit value, 8 values per uint16
  1665                                          * 1    Signed 2-bit value, 8 values per uint16
  1610                                          * 2    Signed 4-bit value, 4 values per uint16
  1666                                          * 2    Signed 4-bit value, 4 values per uint16
  1611                                          * 3    Signed 8-bit value, 2 values per uint16
  1667                                          * 3    Signed 8-bit value, 2 values per uint16
  1612                                          */
  1668                                          */
  1613   USHORT        deltaValue[VAR];        /* Array of compressed data */
  1669   HBUINT16      deltaValue[VAR];        /* Array of compressed data */
  1614   public:
  1670   public:
  1615   DEFINE_SIZE_ARRAY (6, deltaValue);
  1671   DEFINE_SIZE_ARRAY (6, deltaValue);
  1616 };
  1672 };
  1617 
  1673 
  1618 struct VariationDevice
  1674 struct VariationDevice
  1639   {
  1695   {
  1640     return store.get_delta (outerIndex, innerIndex, font->coords, font->num_coords);
  1696     return store.get_delta (outerIndex, innerIndex, font->coords, font->num_coords);
  1641   }
  1697   }
  1642 
  1698 
  1643   protected:
  1699   protected:
  1644   USHORT        outerIndex;
  1700   HBUINT16      outerIndex;
  1645   USHORT        innerIndex;
  1701   HBUINT16      innerIndex;
  1646   USHORT        deltaFormat;    /* Format identifier for this table: 0x0x8000 */
  1702   HBUINT16      deltaFormat;    /* Format identifier for this table: 0x0x8000 */
  1647   public:
  1703   public:
  1648   DEFINE_SIZE_STATIC (6);
  1704   DEFINE_SIZE_STATIC (6);
  1649 };
  1705 };
  1650 
  1706 
  1651 struct DeviceHeader
  1707 struct DeviceHeader
  1652 {
  1708 {
  1653   protected:
  1709   protected:
  1654   USHORT                reserved1;
  1710   HBUINT16              reserved1;
  1655   USHORT                reserved2;
  1711   HBUINT16              reserved2;
  1656   public:
  1712   public:
  1657   USHORT                format;         /* Format identifier */
  1713   HBUINT16              format;         /* Format identifier */
  1658   public:
  1714   public:
  1659   DEFINE_SIZE_STATIC (6);
  1715   DEFINE_SIZE_STATIC (6);
  1660 };
  1716 };
  1661 
  1717 
  1662 struct Device
  1718 struct Device