< prev index next >

src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-kern-table.hh

Print this page




  10  * all copies of this software.
  11  *
  12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
  13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
  14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
  15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  16  * DAMAGE.
  17  *
  18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
  19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
  22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  23  *
  24  * Google Author(s): Behdad Esfahbod
  25  */
  26 
  27 #ifndef HB_OT_KERN_TABLE_HH
  28 #define HB_OT_KERN_TABLE_HH
  29 
  30 #include "hb-open-type-private.hh"

  31 
  32 /*
  33  * kern -- Kerning
  34  * https://docs.microsoft.com/en-us/typography/opentype/spec/kern
  35  * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html
  36  */
  37 #define HB_OT_TAG_kern HB_TAG('k','e','r','n')
  38 
  39 
  40 namespace OT {
  41 
  42 
  43 struct hb_glyph_pair_t
  44 {
  45   hb_codepoint_t left;
  46   hb_codepoint_t right;
  47 };
  48 
  49 struct KernPair
  50 {
  51   inline int get_kerning (void) const
  52   { return value; }
  53 
  54   inline int cmp (const hb_glyph_pair_t &o) const
  55   {
  56     int ret = left.cmp (o.left);
  57     if (ret) return ret;
  58     return right.cmp (o.right);
  59   }
  60 
  61   inline bool sanitize (hb_sanitize_context_t *c) const
  62   {
  63     TRACE_SANITIZE (this);
  64     return_trace (c->check_struct (this));
  65   }
  66 
  67   protected:
  68   GlyphID       left;
  69   GlyphID       right;
  70   FWORD         value;
  71   public:
  72   DEFINE_SIZE_STATIC (6);
  73 };
  74 
  75 struct KernSubTableFormat0
  76 {
  77   inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
  78   {
  79     hb_glyph_pair_t pair = {left, right};
  80     int i = pairs.bsearch (pair);
  81     if (i == -1)
  82       return 0;
  83     return pairs[i].get_kerning ();

  84   }
  85 
  86   inline bool sanitize (hb_sanitize_context_t *c) const
  87   {
  88     TRACE_SANITIZE (this);
  89     return_trace (pairs.sanitize (c));
  90   }
  91 
  92   protected:
  93   BinSearchArrayOf<KernPair> pairs;     /* Array of kerning pairs. */
  94   public:
  95   DEFINE_SIZE_ARRAY (8, pairs);
  96 };
  97 
  98 struct KernClassTable
  99 {
 100   inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; }
 101 
 102   inline bool sanitize (hb_sanitize_context_t *c) const
 103   {
 104     TRACE_SANITIZE (this);
 105     return_trace (firstGlyph.sanitize (c) && classes.sanitize (c));
 106   }
 107 
 108   protected:
 109   HBUINT16              firstGlyph;     /* First glyph in class range. */
 110   ArrayOf<HBUINT16>     classes;        /* Glyph classes. */
 111   public:
 112   DEFINE_SIZE_ARRAY (4, classes);
 113 };
 114 
 115 struct KernSubTableFormat2
 116 {
 117   inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
 118   {
 119     unsigned int l = (this+leftClassTable).get_class (left);
 120     unsigned int r = (this+rightClassTable).get_class (right);
 121     unsigned int offset = l * rowWidth + r * sizeof (FWORD);
 122     const FWORD *arr = &(this+array);
 123     if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
 124       return 0;
 125     const FWORD *v = &StructAtOffset<FWORD> (arr, offset);
 126     if (unlikely ((const void *) v < (const void *) arr || (const void *) (v + 1) > (const void *) end))
 127       return 0;
 128     return *v;
 129   }
 130 
 131   inline bool sanitize (hb_sanitize_context_t *c) const
 132   {
 133     TRACE_SANITIZE (this);
 134     return_trace (rowWidth.sanitize (c) &&
 135                   leftClassTable.sanitize (c, this) &&
 136                   rightClassTable.sanitize (c, this) &&
 137                   array.sanitize (c, this));

 138   }
 139 
 140   protected:
 141   HBUINT16      rowWidth;       /* The width, in bytes, of a row in the table. */
 142   OffsetTo<KernClassTable>
 143                 leftClassTable; /* Offset from beginning of this subtable to
 144                                  * left-hand class table. */
 145   OffsetTo<KernClassTable>
 146                 rightClassTable;/* Offset from beginning of this subtable to
 147                                  * right-hand class table. */
 148   OffsetTo<FWORD>
 149                 array;          /* Offset from beginning of this subtable to
 150                                  * the start of the kerning array. */






 151   public:
 152   DEFINE_SIZE_MIN (8);
 153 };
 154 

 155 struct KernSubTable
 156 {
 157   inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end, unsigned int format) const



 158   {
 159     switch (format) {

 160     case 0: return u.format0.get_kerning (left, right);
 161     case 2: return u.format2.get_kerning (left, right, end);
 162     default:return 0;
 163     }
 164   }
 165 
 166   inline bool sanitize (hb_sanitize_context_t *c, unsigned int format) const

 167   {
 168     TRACE_SANITIZE (this);
 169     switch (format) {
 170     case 0: return_trace (u.format0.sanitize (c));
 171     case 2: return_trace (u.format2.sanitize (c));
 172     default:return_trace (true);



 173     }
 174   }
 175 
 176   protected:










 177   union {
 178   KernSubTableFormat0   format0;
 179   KernSubTableFormat2   format2;



 180   } u;
 181   public:
 182   DEFINE_SIZE_MIN (0);
 183 };
 184 
 185 
 186 template <typename T>
 187 struct KernSubTableWrapper
 188 {
 189   /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
 190   inline const T* thiz (void) const { return static_cast<const T *> (this); }
 191 
 192   inline bool is_horizontal (void) const
 193   { return (thiz()->coverage & T::COVERAGE_CHECK_FLAGS) == T::COVERAGE_CHECK_HORIZONTAL; }
 194 
 195   inline bool is_override (void) const
 196   { return bool (thiz()->coverage & T::COVERAGE_OVERRIDE_FLAG); }
 197 
 198   inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
 199   { return thiz()->subtable.get_kerning (left, right, end, thiz()->format); }
 200 
 201   inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
 202   { return is_horizontal () ? get_kerning (left, right, end) : 0; }
 203 
 204   inline unsigned int get_size (void) const { return thiz()->length; }

 205 
 206   inline bool sanitize (hb_sanitize_context_t *c) const
 207   {
 208     TRACE_SANITIZE (this);
 209     return_trace (c->check_struct (thiz()) &&
 210                   thiz()->length >= T::min_size &&
 211                   c->check_array (thiz(), 1, thiz()->length) &&
 212                   thiz()->subtable.sanitize (c, thiz()->format));
 213   }
 214 };
 215 
 216 template <typename T>
 217 struct KernTable
 218 {
 219   /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
 220   inline const T* thiz (void) const { return static_cast<const T *> (this); }
 221 
 222   inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
 223   {
 224     int v = 0;
 225     const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (thiz()->data);
 226     unsigned int count = thiz()->nTables;
 227     for (unsigned int i = 0; i < count; i++)
 228     {
 229       if (st->is_override ())
 230         v = 0;
 231       v += st->get_h_kerning (left, right, table_length + (const char *) this);
 232       st = &StructAfter<typename T::SubTableWrapper> (*st);
 233     }
 234     return v;
 235   }
 236 
 237   inline bool sanitize (hb_sanitize_context_t *c) const
 238   {
 239     TRACE_SANITIZE (this);
 240     if (unlikely (!c->check_struct (thiz()) ||
 241                   thiz()->version != T::VERSION))
 242       return_trace (false);
 243 
 244     const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (thiz()->data);
 245     unsigned int count = thiz()->nTables;
 246     for (unsigned int i = 0; i < count; i++)
 247     {
 248       if (unlikely (!st->sanitize (c)))
 249         return_trace (false);
 250       st = &StructAfter<typename T::SubTableWrapper> (*st);
 251     }
 252 
 253     return_trace (true);
 254   }
 255 };
 256 
 257 struct KernOT : KernTable<KernOT>
 258 {
 259   friend struct KernTable<KernOT>;
 260 
 261   static const uint16_t VERSION = 0x0000u;
 262 
 263   struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
 264   {
 265     friend struct KernSubTableWrapper<SubTableWrapper>;
 266 
 267     enum coverage_flags_t {
 268       COVERAGE_DIRECTION_FLAG   = 0x01u,
 269       COVERAGE_MINIMUM_FLAG     = 0x02u,
 270       COVERAGE_CROSSSTREAM_FLAG = 0x04u,
 271       COVERAGE_OVERRIDE_FLAG    = 0x08u,
 272 
 273       COVERAGE_VARIATION_FLAG   = 0x00u, /* Not supported. */
 274 
 275       COVERAGE_CHECK_FLAGS      = 0x07u,
 276       COVERAGE_CHECK_HORIZONTAL = 0x01u
 277     };
 278 
 279     protected:
 280     HBUINT16    versionZ;       /* Unused. */
 281     HBUINT16    length;         /* Length of the subtable (including this header). */
 282     HBUINT8     format;         /* Subtable format. */
 283     HBUINT8     coverage;       /* Coverage bits. */
 284     KernSubTable subtable;      /* Subtable data. */
 285     public:
 286     DEFINE_SIZE_MIN (6);
 287   };











 288 
 289   protected:
 290   HBUINT16      version;        /* Version--0x0000u */
 291   HBUINT16      nTables;        /* Number of subtables in the kerning table. */
 292   HBUINT8               data[VAR];
 293   public:
 294   DEFINE_SIZE_ARRAY (4, data);
 295 };
 296 
 297 struct KernAAT : KernTable<KernAAT>

 298 {
 299   friend struct KernTable<KernAAT>;

 300 
 301   static const uint32_t VERSION = 0x00010000u;

 302 
 303   struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
 304   {
 305     friend struct KernSubTableWrapper<SubTableWrapper>;
 306 
 307     enum coverage_flags_t {
 308       COVERAGE_DIRECTION_FLAG   = 0x80u,
 309       COVERAGE_CROSSSTREAM_FLAG = 0x40u,
 310       COVERAGE_VARIATION_FLAG   = 0x20u,
 311 
 312       COVERAGE_OVERRIDE_FLAG    = 0x00u, /* Not supported. */
 313 
 314       COVERAGE_CHECK_FLAGS      = 0xE0u,
 315       COVERAGE_CHECK_HORIZONTAL = 0x00u
 316     };
 317 
 318     protected:






 319     HBUINT32    length;         /* Length of the subtable (including this header). */
 320     HBUINT8     coverage;       /* Coverage bits. */
 321     HBUINT8     format;         /* Subtable format. */
 322     HBUINT16    tupleIndex;     /* The tuple index (used for variations fonts).
 323                                  * This value specifies which tuple this subtable covers. */
 324     KernSubTable subtable;      /* Subtable data. */
 325     public:
 326     DEFINE_SIZE_MIN (8);
 327   };











 328 
 329   protected:
 330   HBUINT32              version;        /* Version--0x00010000u */
 331   HBUINT32              nTables;        /* Number of subtables in the kerning table. */
 332   HBUINT8               data[VAR];
 333   public:
 334   DEFINE_SIZE_ARRAY (8, data);
 335 };
 336 
 337 struct kern
 338 {
 339   static const hb_tag_t tableTag = HB_OT_TAG_kern;
 340 
 341   inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const



 342   {
 343     switch (u.major) {
 344     case 0: return u.ot.get_h_kerning (left, right, table_length);
 345     case 1: return u.aat.get_h_kerning (left, right, table_length);
 346     default:return 0;
 347     }
 348   }
 349 
 350   inline bool sanitize (hb_sanitize_context_t *c) const
 351   {
 352     TRACE_SANITIZE (this);
 353     if (!u.major.sanitize (c)) return_trace (false);
 354     switch (u.major) {
 355     case 0: return_trace (u.ot.sanitize (c));
 356     case 1: return_trace (u.aat.sanitize (c));
 357     default:return_trace (true);
 358     }
 359   }
 360 
 361   struct accelerator_t
 362   {
 363     inline void init (hb_face_t *face)
 364     {
 365       blob = Sanitizer<kern>().sanitize (face->reference_table (HB_OT_TAG_kern));
 366       table = blob->as<kern> ();
 367       table_length = blob->length;

 368     }
 369     inline void fini (void)
 370     {
 371       hb_blob_destroy (blob);
 372     }
 373 
 374     inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
 375     { return table->get_h_kerning (left, right, table_length); }
 376 
 377     private:
 378     hb_blob_t *blob;
 379     const kern *table;
 380     unsigned int table_length;
 381   };













 382 
 383   protected:
 384   union {

 385   HBUINT16              major;
 386   KernOT                ot;
 387   KernAAT               aat;
 388   } u;
 389   public:
 390   DEFINE_SIZE_UNION (2, major);
 391 };
 392 
 393 } /* namespace OT */
 394 
 395 
 396 #endif /* HB_OT_KERN_TABLE_HH */


  10  * all copies of this software.
  11  *
  12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
  13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
  14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
  15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  16  * DAMAGE.
  17  *
  18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
  19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
  22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  23  *
  24  * Google Author(s): Behdad Esfahbod
  25  */
  26 
  27 #ifndef HB_OT_KERN_TABLE_HH
  28 #define HB_OT_KERN_TABLE_HH
  29 
  30 #include "hb-aat-layout-kerx-table.hh"
  31 
  32 
  33 /*
  34  * kern -- Kerning
  35  * https://docs.microsoft.com/en-us/typography/opentype/spec/kern
  36  * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html
  37  */
  38 #define HB_OT_TAG_kern HB_TAG('k','e','r','n')
  39 
  40 
  41 namespace OT {
  42 
  43 
  44 template <typename KernSubTableHeader>
  45 struct KernSubTableFormat3





  46 {
  47   int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const










  48   {
  49     hb_array_t<const FWORD> kernValue = kernValueZ.as_array (kernValueCount);
  50     hb_array_t<const HBUINT8> leftClass = StructAfter<const UnsizedArrayOf<HBUINT8> > (kernValue).as_array (glyphCount);
  51     hb_array_t<const HBUINT8> rightClass = StructAfter<const UnsizedArrayOf<HBUINT8> > (leftClass).as_array (glyphCount);
  52     hb_array_t<const HBUINT8> kernIndex = StructAfter<const UnsizedArrayOf<HBUINT8> > (rightClass).as_array (leftClassCount * rightClassCount);
  53 
  54     unsigned int leftC = leftClass[left];
  55     unsigned int rightC = rightClass[right];
  56     if (unlikely (leftC >= leftClassCount || rightC >= rightClassCount))











  57       return 0;
  58     unsigned int i = leftC * rightClassCount + rightC;
  59     return kernValue[kernIndex[i]];
  60   }
  61 
  62   bool apply (AAT::hb_aat_apply_context_t *c) const
  63   {
  64     TRACE_APPLY (this);








  65 
  66     if (!c->plan->requested_kerning)
  67       return false;

  68 
  69     if (header.coverage & header.Backwards)
  70       return false;



  71 
  72     hb_kern_machine_t<KernSubTableFormat3> machine (*this, header.coverage & header.CrossStream);
  73     machine.kern (c->font, c->buffer, c->plan->kern_mask);




  74 
  75     return_trace (true);













  76   }
  77 
  78   bool sanitize (hb_sanitize_context_t *c) const
  79   {
  80     TRACE_SANITIZE (this);
  81     return_trace (c->check_struct (this) &&
  82                   c->check_range (kernValueZ,
  83                                   kernValueCount * sizeof (FWORD) +
  84                                   glyphCount * 2 +
  85                                   leftClassCount * rightClassCount));
  86   }
  87 
  88   protected:
  89   KernSubTableHeader    header;
  90   HBUINT16              glyphCount;     /* The number of glyphs in this font. */
  91   HBUINT8               kernValueCount; /* The number of kerning values. */
  92   HBUINT8               leftClassCount; /* The number of left-hand classes. */
  93   HBUINT8               rightClassCount;/* The number of right-hand classes. */
  94   HBUINT8               flags;          /* Set to zero (reserved for future use). */
  95   UnsizedArrayOf<FWORD> kernValueZ;     /* The kerning values.
  96                                          * Length kernValueCount. */
  97 #if 0
  98   UnsizedArrayOf<HBUINT8>leftClass;     /* The left-hand classes.
  99                                          * Length glyphCount. */
 100   UnsizedArrayOf<HBUINT8>rightClass;    /* The right-hand classes.
 101                                          * Length glyphCount. */
 102   UnsizedArrayOf<HBUINT8>kernIndex;     /* The indices into the kernValue array.
 103                                          * Length leftClassCount * rightClassCount */
 104 #endif
 105   public:
 106   DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 6, kernValueZ);
 107 };
 108 
 109 template <typename KernSubTableHeader>
 110 struct KernSubTable
 111 {
 112   unsigned int get_size () const { return u.header.length; }
 113   unsigned int get_type () const { return u.header.format; }
 114 
 115   int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
 116   {
 117     switch (get_type ()) {
 118     /* This method hooks up to hb_font_t's get_h_kerning.  Only support Format0. */
 119     case 0: return u.format0.get_kerning (left, right);

 120     default:return 0;
 121     }
 122   }
 123 
 124   template <typename context_t>
 125   typename context_t::return_t dispatch (context_t *c) const
 126   {
 127     unsigned int subtable_type = get_type ();
 128     TRACE_DISPATCH (this, subtable_type);
 129     switch (subtable_type) {
 130     case 0:     return_trace (c->dispatch (u.format0));
 131     case 1:     return_trace (u.header.apple ? c->dispatch (u.format1) : c->default_return_value ());
 132     case 2:     return_trace (c->dispatch (u.format2));
 133     case 3:     return_trace (u.header.apple ? c->dispatch (u.format3) : c->default_return_value ());
 134     default:    return_trace (c->default_return_value ());
 135     }
 136   }
 137 
 138   bool sanitize (hb_sanitize_context_t *c) const
 139   {
 140     TRACE_SANITIZE (this);
 141     if (unlikely (!u.header.sanitize (c) ||
 142                   u.header.length < u.header.min_size ||
 143                   !c->check_range (this, u.header.length))) return_trace (false);
 144 
 145     return_trace (dispatch (c));
 146   }
 147 
 148   public:
 149   union {
 150   KernSubTableHeader                            header;
 151   AAT::KerxSubTableFormat0<KernSubTableHeader>  format0;
 152   AAT::KerxSubTableFormat1<KernSubTableHeader>  format1;
 153   AAT::KerxSubTableFormat2<KernSubTableHeader>  format2;
 154   KernSubTableFormat3<KernSubTableHeader>       format3;
 155   } u;
 156   public:
 157   DEFINE_SIZE_MIN (KernSubTableHeader::static_size);
 158 };
 159 
 160 
 161 struct KernOTSubTableHeader

 162 {
 163   static constexpr bool apple = false;
 164   typedef AAT::ObsoleteTypes Types;












 165 
 166   unsigned int tuple_count () const { return 0; }
 167   bool is_horizontal () const { return (coverage & Horizontal); }
 168 
 169   enum Coverage
 170   {
 171     Horizontal  = 0x01u,
 172     Minimum     = 0x02u,
 173     CrossStream = 0x04u,
 174     Override    = 0x08u,



 175 
 176     /* Not supported: */
 177     Backwards   = 0x00u,
 178     Variation   = 0x00u,
 179   };
















 180 
 181   bool sanitize (hb_sanitize_context_t *c) const
 182   {
 183     TRACE_SANITIZE (this);
 184     return_trace (c->check_struct (this));













 185   }



















 186 
 187   public:




 188   HBUINT16      versionZ;       /* Unused. */
 189   HBUINT16      length;         /* Length of the subtable (including this header). */
 190   HBUINT8       format;         /* Subtable format. */
 191   HBUINT8       coverage;       /* Coverage bits. */

 192   public:
 193   DEFINE_SIZE_STATIC (6);
 194 };
 195 
 196 struct KernOT : AAT::KerxTable<KernOT>
 197 {
 198   friend struct AAT::KerxTable<KernOT>;
 199 
 200   static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
 201   static constexpr unsigned minVersion = 0u;
 202 
 203   typedef KernOTSubTableHeader SubTableHeader;
 204   typedef SubTableHeader::Types Types;
 205   typedef KernSubTable<SubTableHeader> SubTable;
 206 
 207   protected:
 208   HBUINT16      version;        /* Version--0x0000u */
 209   HBUINT16      tableCount;     /* Number of subtables in the kerning table. */
 210   SubTable      firstSubTable;  /* Subtables. */
 211   public:
 212   DEFINE_SIZE_MIN (4);
 213 };
 214 
 215 
 216 struct KernAATSubTableHeader
 217 {
 218   static constexpr bool apple = true;
 219   typedef AAT::ObsoleteTypes Types;
 220 
 221   unsigned int tuple_count () const { return 0; }
 222   bool is_horizontal () const       { return !(coverage & Vertical); }
 223 
 224   enum Coverage
 225   {
 226     Vertical    = 0x80u,
 227     CrossStream = 0x40u,
 228     Variation   = 0x20u,





 229 
 230     /* Not supported: */
 231     Backwards   = 0x00u,
 232   };
 233 
 234   bool sanitize (hb_sanitize_context_t *c) const
 235   {
 236     TRACE_SANITIZE (this);
 237     return_trace (c->check_struct (this));
 238   }
 239 
 240   public:
 241   HBUINT32      length;         /* Length of the subtable (including this header). */
 242   HBUINT8       coverage;       /* Coverage bits. */
 243   HBUINT8       format;         /* Subtable format. */
 244   HBUINT16      tupleIndex;     /* The tuple index (used for variations fonts).
 245                                * This value specifies which tuple this subtable covers.
 246                                * Note: We don't implement. */
 247   public:
 248   DEFINE_SIZE_STATIC (8);
 249 };
 250 
 251 struct KernAAT : AAT::KerxTable<KernAAT>
 252 {
 253   friend struct AAT::KerxTable<KernAAT>;
 254 
 255   static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
 256   static constexpr unsigned minVersion = 0x00010000u;
 257 
 258   typedef KernAATSubTableHeader SubTableHeader;
 259   typedef SubTableHeader::Types Types;
 260   typedef KernSubTable<SubTableHeader> SubTable;
 261 
 262   protected:
 263   HBUINT32      version;        /* Version--0x00010000u */
 264   HBUINT32      tableCount;     /* Number of subtables in the kerning table. */
 265   SubTable      firstSubTable;  /* Subtables. */
 266   public:
 267   DEFINE_SIZE_MIN (8);
 268 };
 269 
 270 struct kern
 271 {
 272   static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
 273 
 274   bool has_data () const { return u.version32; }
 275   unsigned int get_type () const { return u.major; }
 276 
 277   bool has_state_machine () const
 278   {
 279     switch (get_type ()) {
 280     case 0: return u.ot.has_state_machine ();
 281     case 1: return u.aat.has_state_machine ();
 282     default:return false;
 283     }
 284   }
 285 
 286   bool has_cross_stream () const
 287   {
 288     switch (get_type ()) {
 289     case 0: return u.ot.has_cross_stream ();
 290     case 1: return u.aat.has_cross_stream ();
 291     default:return false;


 292     }
 293   }
 294 
 295   int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const


 296   {
 297     switch (get_type ()) {
 298     case 0: return u.ot.get_h_kerning (left, right);
 299     case 1: return u.aat.get_h_kerning (left, right);
 300     default:return 0;
 301     }



 302   }
 303 
 304   bool apply (AAT::hb_aat_apply_context_t *c) const
 305   { return dispatch (c); }
 306 
 307   template <typename context_t>
 308   typename context_t::return_t dispatch (context_t *c) const
 309   {
 310     unsigned int subtable_type = get_type ();
 311     TRACE_DISPATCH (this, subtable_type);
 312     switch (subtable_type) {
 313     case 0:     return_trace (c->dispatch (u.ot));
 314     case 1:     return_trace (c->dispatch (u.aat));
 315     default:    return_trace (c->default_return_value ());
 316     }
 317   }
 318 
 319   bool sanitize (hb_sanitize_context_t *c) const
 320   {
 321     TRACE_SANITIZE (this);
 322     if (!u.version32.sanitize (c)) return_trace (false);
 323     return_trace (dispatch (c));
 324   }
 325 
 326   protected:
 327   union {
 328   HBUINT32              version32;
 329   HBUINT16              major;
 330   KernOT                ot;
 331   KernAAT               aat;
 332   } u;
 333   public:
 334   DEFINE_SIZE_UNION (4, version32);
 335 };
 336 
 337 } /* namespace OT */
 338 
 339 
 340 #endif /* HB_OT_KERN_TABLE_HH */
< prev index next >