< prev index next >

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

Print this page


   1 /*
   2  * Copyright © 2016 Elie Roux <elie.roux@telecom-bretagne.eu>
   3  * Copyright © 2018  Google, Inc.

   4  *
   5  *  This is part of HarfBuzz, a text shaping library.
   6  *
   7  * Permission is hereby granted, without written agreement and without
   8  * license or royalty fees, to use, copy, modify, and distribute this
   9  * software and its documentation for any purpose, provided that the
  10  * above copyright notice and the following two paragraphs appear in
  11  * all copies of this software.
  12  *
  13  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
  14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
  15  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
  16  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  17  * DAMAGE.
  18  *
  19  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
  20  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  21  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  22  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
  23  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  24  *
  25  * Google Author(s): Behdad Esfahbod
  26  */
  27 
  28 #ifndef HB_OT_LAYOUT_BASE_TABLE_HH
  29 #define HB_OT_LAYOUT_BASE_TABLE_HH
  30 
  31 #include "hb-open-type-private.hh"
  32 #include "hb-ot-layout-common-private.hh"
  33 
  34 namespace OT {

  35 
  36 #define NOT_INDEXED   ((unsigned int) -1)
  37 
  38 /*
  39  * BASE -- Baseline
  40  * https://docs.microsoft.com/en-us/typography/opentype/spec/base
  41  */
  42 
  43 struct BaseCoordFormat1
  44 {
  45   inline int get_coord (void) const { return coordinate; }
  46 
  47   inline bool sanitize (hb_sanitize_context_t *c) const
  48   {
  49     TRACE_SANITIZE (this);
  50     return_trace (c->check_struct (this));
  51   }
  52 
  53   protected:
  54   HBUINT16      format;         /* Format identifier--format = 1 */
  55   HBINT16       coordinate;     /* X or Y value, in design units */
  56   public:
  57   DEFINE_SIZE_STATIC (4);
  58 };
  59 
  60 struct BaseCoordFormat2
  61 {
  62   inline int get_coord (void) const
  63   {
  64     /* TODO */
  65     return coordinate;
  66   }
  67 
  68   inline bool sanitize (hb_sanitize_context_t *c) const
  69   {
  70     TRACE_SANITIZE (this);
  71     return_trace (c->check_struct (this));
  72   }
  73 
  74   protected:
  75   HBUINT16      format;         /* Format identifier--format = 2 */
  76   HBINT16       coordinate;     /* X or Y value, in design units */
  77   GlyphID       referenceGlyph; /* Glyph ID of control glyph */
  78   HBUINT16      coordPoint;     /* Index of contour point on the
  79                                  * reference glyph */
  80   public:
  81   DEFINE_SIZE_STATIC (8);
  82 };
  83 
  84 struct BaseCoordFormat3
  85 {
  86   inline int get_coord (void) const


  87   {
  88     /* TODO */
  89     return coordinate;


  90   }
  91 
  92   inline bool sanitize (hb_sanitize_context_t *c) const

  93   {
  94     TRACE_SANITIZE (this);
  95     return_trace (c->check_struct (this) && deviceTable.sanitize (c, this));

  96   }
  97 
  98   protected:
  99   HBUINT16              format;         /* Format identifier--format = 3 */
 100   HBINT16               coordinate;     /* X or Y value, in design units */
 101   OffsetTo<Device>      deviceTable;    /* Offset to Device table for X or

 102                                          * Y value, from beginning of
 103                                          * BaseCoord table (may be NULL). */
 104   public:
 105   DEFINE_SIZE_STATIC (6);
 106 };
 107 
 108 struct BaseCoord
 109 {
 110   inline int get_coord (void) const


 111   {
 112     switch (u.format) {
 113     case 1: return u.format1.get_coord ();
 114     case 2: return u.format2.get_coord ();
 115     case 3: return u.format3.get_coord ();
 116     default:return 0;
 117     }
 118   }
 119 
 120   inline bool sanitize (hb_sanitize_context_t *c) const
 121   {
 122     TRACE_SANITIZE (this);
 123     if (!u.format.sanitize (c)) return_trace (false);
 124     switch (u.format) {
 125     case 1: return_trace (u.format1.sanitize (c));
 126     case 2: return_trace (u.format2.sanitize (c));
 127     case 3: return_trace (u.format3.sanitize (c));
 128     default:return_trace (false);
 129     }
 130   }
 131 
 132   protected:
 133   union {
 134     HBUINT16            format;
 135     BaseCoordFormat1    format1;
 136     BaseCoordFormat2    format2;
 137     BaseCoordFormat3    format3;
 138   } u;
 139   public:
 140   DEFINE_SIZE_UNION (2, format);
 141 };
 142 
 143 struct FeatMinMaxRecord
 144 {
 145   inline int get_min_value (void) const
 146   { return (this+minCoord).get_coord(); }
 147 
 148   inline int get_max_value (void) const
 149   { return (this+maxCoord).get_coord(); }



 150 
 151   inline const Tag &get_tag () const
 152   { return tag; }



 153 
 154   inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
 155   {
 156     TRACE_SANITIZE (this);
 157     return_trace (c->check_struct (this) &&
 158                   minCoord.sanitize (c, base) &&
 159                   maxCoord.sanitize (c, base));
 160   }
 161 
 162   protected:
 163   Tag                   tag;            /* 4-byte feature identification tag--must
 164                                          * match feature tag in FeatureList */
 165   OffsetTo<BaseCoord>   minCoord;       /* Offset to BaseCoord table that defines

 166                                          * the minimum extent value, from beginning
 167                                          * of MinMax table (may be NULL) */
 168   OffsetTo<BaseCoord>   maxCoord;       /* Offset to BaseCoord table that defines

 169                                          * the maximum extent value, from beginning
 170                                          * of MinMax table (may be NULL) */
 171   public:
 172   DEFINE_SIZE_STATIC (8);
 173 
 174 };
 175 
 176 struct MinMax
 177 {
 178   inline unsigned int get_feature_tag_index (Tag featureTableTag) const


 179   {
 180     /* TODO bsearch */
 181     unsigned int count = featMinMaxRecords.len;
 182     for (unsigned int i = 0; i < count; i++)






 183     {
 184       Tag tag = featMinMaxRecords[i].get_tag();
 185       int cmp = tag.cmp(featureTableTag);
 186       if (cmp == 0) return i;
 187       if (cmp > 0)  return NOT_INDEXED;
 188     }
 189     return NOT_INDEXED;
 190   }
 191 
 192   inline int get_min_value (unsigned int featureTableTagIndex) const
 193   {
 194     if (featureTableTagIndex == NOT_INDEXED)
 195       return (this+minCoord).get_coord();
 196     return featMinMaxRecords[featureTableTagIndex].get_min_value();
 197   }
 198 
 199   inline int get_max_value (unsigned int featureTableTagIndex) const
 200   {
 201     if (featureTableTagIndex == NOT_INDEXED)
 202       return (this+maxCoord).get_coord();
 203     return featMinMaxRecords[featureTableTagIndex].get_max_value();
 204   }
 205 
 206   inline bool sanitize (hb_sanitize_context_t *c) const
 207   {
 208     TRACE_SANITIZE (this);
 209     return_trace (c->check_struct (this) &&
 210                   minCoord.sanitize (c, this) &&
 211                   maxCoord.sanitize (c, this) &&
 212                   featMinMaxRecords.sanitize (c, this));
 213   }
 214 
 215   protected:
 216   OffsetTo<BaseCoord>   minCoord;       /* Offset to BaseCoord table that defines

 217                                          * minimum extent value, from the beginning
 218                                          * of MinMax table (may be NULL) */
 219   OffsetTo<BaseCoord>   maxCoord;       /* Offset to BaseCoord table that defines

 220                                          * maximum extent value, from the beginning
 221                                          * of MinMax table (may be NULL) */
 222   ArrayOf<FeatMinMaxRecord>
 223                 featMinMaxRecords;      /* Array of FeatMinMaxRecords, in alphabetical

 224                                          * order by featureTableTag */
 225   public:
 226   DEFINE_SIZE_ARRAY (6, featMinMaxRecords);
 227 };
 228 
 229 /* TODO... */
 230 struct BaseLangSysRecord
 231 {
 232   inline const Tag& get_tag(void) const
 233   { return baseLangSysTag; }
 234 
 235   inline unsigned int get_feature_tag_index (Tag featureTableTag) const
 236   { return (this+minMax).get_feature_tag_index(featureTableTag); }
 237 
 238   inline int get_min_value (unsigned int featureTableTagIndex) const
 239   { return (this+minMax).get_min_value(featureTableTagIndex); }
 240 
 241   inline int get_max_value (unsigned int featureTableTagIndex) const
 242   { return (this+minMax).get_max_value(featureTableTagIndex); }
 243 
 244   inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
 245   {
 246     TRACE_SANITIZE (this);
 247     return_trace (c->check_struct (this) &&
 248                   minMax.sanitize (c, base));
 249   }
 250 
 251   protected:
 252   Tag                   baseLangSysTag;
 253   OffsetTo<MinMax>      minMax;








 254   public:
 255   DEFINE_SIZE_STATIC (6);
 256 
 257 };
 258 
 259 struct BaseValues
 260 {
 261   inline unsigned int get_default_base_tag_index (void) const
 262   { return defaultIndex; }
 263 
 264   inline int get_base_coord (unsigned int baselineTagIndex) const
 265   {
 266     return (this+baseCoords[baselineTagIndex]).get_coord();




 267   }
 268 
 269   inline bool sanitize (hb_sanitize_context_t *c) const



 270   {
 271     TRACE_SANITIZE (this);
 272     return_trace (c->check_struct (this) &&
 273       defaultIndex <= baseCoordCount &&
 274       baseCoords.sanitize (c, this));
 275   }
 276 
 277   protected:
 278   Index                         defaultIndex;
 279   HBUINT16                      baseCoordCount;
 280   OffsetArrayOf<BaseCoord>      baseCoords;

 281   public:
 282   DEFINE_SIZE_ARRAY (6, baseCoords);
 283 
 284 };
 285 
 286 struct BaseScript {
 287 
 288   inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const
 289   {
 290     Tag tag;
 291     int cmp;
 292     for (unsigned int i = 0; i < baseLangSysCount; i++) {
 293       tag = baseLangSysRecords[i].get_tag();
 294       // taking advantage of alphabetical order
 295       cmp = tag.cmp(baseLangSysTag);
 296       if (cmp == 0) return i;
 297       if (cmp > 0)  return NOT_INDEXED;
 298     }
 299     return NOT_INDEXED;
 300   }
 301 
 302   inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const
 303   {
 304     if (baseLangSysIndex == NOT_INDEXED) {
 305       if (unlikely(defaultMinMax)) return NOT_INDEXED;
 306       return (this+defaultMinMax).get_feature_tag_index(featureTableTag);
 307     }
 308     if (unlikely(baseLangSysIndex >= baseLangSysCount)) return NOT_INDEXED;
 309     return baseLangSysRecords[baseLangSysIndex].get_feature_tag_index(featureTableTag);
 310   }
 311 
 312   inline int get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
 313   {
 314     if (baseLangSysIndex == NOT_INDEXED)
 315       return (this+defaultMinMax).get_min_value(featureTableTagIndex);
 316     return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex);
 317   }
 318 
 319   inline int get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
 320   {
 321     if (baseLangSysIndex == NOT_INDEXED)
 322       return (this+defaultMinMax).get_min_value(featureTableTagIndex);
 323     return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex);




 324   }
 325 
 326   inline unsigned int get_default_base_tag_index (void) const
 327   { return (this+baseValues).get_default_base_tag_index(); }
 328 
 329   inline int get_base_coord (unsigned int baselineTagIndex) const
 330   { return (this+baseValues).get_base_coord(baselineTagIndex); }
 331 
 332   inline bool sanitize (hb_sanitize_context_t *c) const
 333   {
 334     TRACE_SANITIZE (this);
 335     return_trace (c->check_struct (this) &&
 336       baseValues.sanitize (c, this) &&
 337       defaultMinMax.sanitize (c, this) &&
 338       baseLangSysRecords.sanitize (c, this));
 339   }
 340 
 341   protected:
 342   OffsetTo<BaseValues>        baseValues;
 343   OffsetTo<MinMax>            defaultMinMax;
 344   HBUINT16                      baseLangSysCount;
 345   ArrayOf<BaseLangSysRecord>  baseLangSysRecords;






 346 
 347   public:
 348     DEFINE_SIZE_ARRAY (8, baseLangSysRecords);
 349 };
 350 











 351 
 352 struct BaseScriptRecord {
 353 
 354   inline const Tag& get_tag (void) const
 355   { return baseScriptTag; }
 356 
 357   inline unsigned int get_default_base_tag_index(void) const
 358   { return (this+baseScript).get_default_base_tag_index(); }
 359 
 360   inline int get_base_coord(unsigned int baselineTagIndex) const
 361   { return (this+baseScript).get_base_coord(baselineTagIndex); }
 362 
 363   inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const
 364   { return (this+baseScript).get_lang_tag_index(baseLangSysTag); }
 365 
 366   inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const
 367   { return (this+baseScript).get_feature_tag_index(baseLangSysIndex, featureTableTag); }
 368 
 369   inline int get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
 370   { return (this+baseScript).get_max_value(baseLangSysIndex, featureTableTagIndex); }
 371 
 372   inline int get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
 373   { return (this+baseScript).get_min_value(baseLangSysIndex, featureTableTagIndex); }
 374 
 375   inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
 376   {
 377     TRACE_SANITIZE (this);
 378     return_trace (c->check_struct (this) &&
 379       baseScript != Null(OffsetTo<BaseScript>) &&
 380       baseScript.sanitize (c, base));
 381   }
 382 
 383   protected:
 384   Tag                   baseScriptTag;
 385   OffsetTo<BaseScript>  baseScript;


 386 
 387   public:
 388     DEFINE_SIZE_STATIC (6);
 389 };
 390 
 391 struct BaseScriptList {
 392 
 393   inline unsigned int get_base_script_index (Tag baseScriptTag) const
 394   {
 395     for (unsigned int i = 0; i < baseScriptCount; i++)
 396       if (baseScriptRecords[i].get_tag() == baseScriptTag)
 397         return i;
 398     return NOT_INDEXED;
 399   }
 400 
 401   inline unsigned int get_default_base_tag_index (unsigned int baseScriptIndex) const
 402   {
 403     if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED;
 404     return baseScriptRecords[baseScriptIndex].get_default_base_tag_index();
 405   }
 406 
 407   inline int get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
 408   {
 409     return baseScriptRecords[baseScriptIndex].get_base_coord(baselineTagIndex);
 410   }
 411 
 412   inline unsigned int get_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
 413   {
 414     if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED;
 415     return baseScriptRecords[baseScriptIndex].get_lang_tag_index(baseLangSysTag);
 416   }
 417 
 418   inline unsigned int get_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
 419   {
 420     if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED;
 421     return baseScriptRecords[baseScriptIndex].get_feature_tag_index(baseLangSysIndex, featureTableTag);



 422   }
 423 
 424   inline int get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const

 425   {
 426     return baseScriptRecords[baseScriptIndex].get_max_value(baseLangSysIndex, featureTableTagIndex);
 427   }
 428 
 429   inline int get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
 430   {
 431     return baseScriptRecords[baseScriptIndex].get_min_value(baseLangSysIndex, featureTableTagIndex);
 432   }
 433 
 434   inline bool sanitize (hb_sanitize_context_t *c) const
 435   {
 436     TRACE_SANITIZE (this);
 437     return_trace (c->check_struct (this) &&
 438       baseScriptRecords.sanitize (c, this));
 439   }
 440 
 441   protected:
 442   HBUINT16                    baseScriptCount;
 443   ArrayOf<BaseScriptRecord> baseScriptRecords;
 444 
 445   public:
 446   DEFINE_SIZE_ARRAY (4, baseScriptRecords);
 447 
 448 };
 449 
 450 struct BaseTagList
 451 {
 452 
 453   inline unsigned int get_tag_index(Tag baselineTag) const
 454   {
 455     for (unsigned int i = 0; i < baseTagCount; i++)
 456       if (baselineTags[i] == baselineTag)
 457         return i;
 458     return NOT_INDEXED;
 459   }
 460 
 461   inline bool sanitize (hb_sanitize_context_t *c) const
 462   {
 463     TRACE_SANITIZE (this);
 464     return_trace (c->check_struct (this));
 465   }
 466 
 467   protected:
 468   HBUINT16        baseTagCount;
 469   SortedArrayOf<Tag>  baselineTags;
 470 
 471   public:
 472   DEFINE_SIZE_ARRAY (4, baselineTags);
 473 };
 474 
 475 struct Axis
 476 {
 477 
 478   inline unsigned int get_base_tag_index(Tag baselineTag) const


 479   {
 480     if (unlikely(baseTagList == Null(OffsetTo<BaseTagList>))) return NOT_INDEXED;
 481     return (this+baseTagList).get_tag_index(baselineTag);
 482   }
 483 
 484   inline unsigned int get_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const
 485   {
 486     if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED;
 487     return (this+baseScriptList).get_default_base_tag_index(baseScriptIndex);
 488   }
 489 
 490   inline int get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
 491   {
 492     return (this+baseScriptList).get_base_coord(baseScriptIndex, baselineTagIndex);
 493   }
 494 
 495   inline unsigned int get_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
 496   {
 497     if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED;
 498     return (this+baseScriptList).get_lang_tag_index(baseScriptIndex, baseLangSysTag);
 499   }
 500 
 501   inline unsigned int get_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const




 502   {
 503     if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED;
 504     return (this+baseScriptList).get_feature_tag_index(baseScriptIndex, baseLangSysIndex, featureTableTag);
 505   }
 506 
 507   inline int get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
 508   {
 509     return (this+baseScriptList).get_max_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
 510   }
 511 
 512   inline int get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
 513   {
 514     return (this+baseScriptList).get_min_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
 515   }
 516 
 517   inline bool sanitize (hb_sanitize_context_t *c) const
 518   {
 519     TRACE_SANITIZE (this);
 520     return_trace (c->check_struct (this) &&
 521       baseTagList.sanitize (c, this) &&
 522       baseScriptList.sanitize (c, this));
 523   }
 524 
 525   protected:
 526   OffsetTo<BaseTagList>     baseTagList;
 527   OffsetTo<BaseScriptList>  baseScriptList;








 528 
 529   public:
 530   DEFINE_SIZE_STATIC (4);
 531 };
 532 
 533 struct BASE
 534 {
 535   static const hb_tag_t tableTag = HB_OT_TAG_BASE;
 536 
 537   inline bool has_vert_axis(void)
 538   { return vertAxis != Null(OffsetTo<Axis>); }
 539 
 540   inline bool has_horiz_axis(void)
 541   { return horizAxis != Null(OffsetTo<Axis>); }
 542 
 543   // horizontal axis base coords:

 544 
 545   inline unsigned int get_horiz_base_tag_index(Tag baselineTag) const





 546   {
 547     if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
 548     return (this+horizAxis).get_base_tag_index(baselineTag);
 549   }
 550 
 551   inline unsigned int get_horiz_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const
 552   {
 553     if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
 554     return (this+horizAxis).get_default_base_tag_index_for_script_index(baseScriptIndex);
 555   }
 556 
 557   inline int get_horiz_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const







 558   {
 559     return (this+horizAxis).get_base_coord(baseScriptIndex, baselineTagIndex);
 560   }
 561 
 562   // vertical axis base coords:
 563 
 564   inline unsigned int get_vert_base_tag_index(Tag baselineTag) const
 565   {
 566     if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
 567     return (this+vertAxis).get_base_tag_index(baselineTag);
 568   }
 569 
 570   inline unsigned int get_vert_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const
 571   {
 572     if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
 573     return (this+vertAxis).get_default_base_tag_index_for_script_index(baseScriptIndex);
 574   }
 575 
 576   inline int get_vert_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
 577   {
 578     return (this+vertAxis).get_base_coord(baseScriptIndex, baselineTagIndex);
 579   }
 580 
 581   // horizontal axis min/max coords:
 582 
 583   inline unsigned int get_horiz_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
 584   {
 585     if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
 586     return (this+horizAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag);
 587   }
 588 
 589   inline unsigned int get_horiz_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
 590   {
 591     if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
 592     return (this+horizAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag);
 593   }
 594 
 595   inline int get_horiz_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
 596   {
 597     return (this+horizAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
 598   }
 599 
 600   inline int get_horiz_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
 601   {
 602     return (this+horizAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
 603   }
 604 
 605     // vertical axis min/max coords:
 606 
 607   inline unsigned int get_vert_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
 608   {
 609     if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
 610     return (this+vertAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag);
 611   }
 612 
 613   inline unsigned int get_vert_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
 614   {
 615     if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED;
 616     return (this+vertAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag);
 617   }
 618 
 619   inline int get_vert_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
 620   {
 621     return (this+vertAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
 622   }
 623 
 624   inline int get_vert_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
 625   {
 626     return (this+vertAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
 627   }
 628 
 629   inline bool sanitize (hb_sanitize_context_t *c) const
 630   {
 631     TRACE_SANITIZE (this);
 632     return_trace (c->check_struct (this) &&
 633                   likely (version.major == 1) &&
 634                   horizAxis.sanitize (c, this) &&
 635                   vertAxis.sanitize (c, this) &&
 636                   (version.to_int () < 0x00010001u || varStore.sanitize (c, this)));
 637   }
 638 
 639   protected:
 640   FixedVersion<>  version;
 641   OffsetTo<Axis>  horizAxis;
 642   OffsetTo<Axis>  vertAxis;


 643   LOffsetTo<VariationStore>
 644                 varStore;               /* Offset to the table of Item Variation
 645                                          * Store--from beginning of BASE
 646                                          * header (may be NULL).  Introduced
 647                                          * in version 0x00010001. */
 648   public:
 649   DEFINE_SIZE_MIN (8);
 650 };
 651 
 652 
 653 } /* namespace OT */
 654 
 655 
 656 #endif /* HB_OT_LAYOUT_BASE_TABLE_HH */
   1 /*
   2  * Copyright © 2016 Elie Roux <elie.roux@telecom-bretagne.eu>
   3  * Copyright © 2018  Google, Inc.
   4  * Copyright © 2018  Ebrahim Byagowi
   5  *
   6  *  This is part of HarfBuzz, a text shaping library.
   7  *
   8  * Permission is hereby granted, without written agreement and without
   9  * license or royalty fees, to use, copy, modify, and distribute this
  10  * software and its documentation for any purpose, provided that the
  11  * above copyright notice and the following two paragraphs appear in
  12  * all copies of this software.
  13  *
  14  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
  15  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
  16  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
  17  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  18  * DAMAGE.
  19  *
  20  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
  21  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  22  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  23  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
  24  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  25  *
  26  * Google Author(s): Behdad Esfahbod
  27  */
  28 
  29 #ifndef HB_OT_LAYOUT_BASE_TABLE_HH
  30 #define HB_OT_LAYOUT_BASE_TABLE_HH
  31 
  32 #include "hb-open-type.hh"
  33 #include "hb-ot-layout-common.hh"
  34 
  35 /* To be removed */
  36 typedef hb_tag_t hb_ot_layout_baseline_t;
  37 
  38 namespace OT {
  39 
  40 /*
  41  * BASE -- Baseline
  42  * https://docs.microsoft.com/en-us/typography/opentype/spec/base
  43  */
  44 
  45 struct BaseCoordFormat1
  46 {
  47   hb_position_t get_coord () const { return coordinate; }
  48 
  49   bool sanitize (hb_sanitize_context_t *c) const
  50   {
  51     TRACE_SANITIZE (this);
  52     return_trace (likely (c->check_struct (this)));
  53   }
  54 
  55   protected:
  56   HBUINT16      format;         /* Format identifier--format = 1 */
  57   FWORD         coordinate;     /* X or Y value, in design units */
  58   public:
  59   DEFINE_SIZE_STATIC (4);
  60 };
  61 
  62 struct BaseCoordFormat2
  63 {
  64   hb_position_t get_coord () const
  65   {
  66     /* TODO */
  67     return coordinate;
  68   }
  69 
  70   bool sanitize (hb_sanitize_context_t *c) const
  71   {
  72     TRACE_SANITIZE (this);
  73     return_trace (c->check_struct (this));
  74   }
  75 
  76   protected:
  77   HBUINT16      format;         /* Format identifier--format = 2 */
  78   FWORD         coordinate;     /* X or Y value, in design units */
  79   GlyphID       referenceGlyph; /* Glyph ID of control glyph */
  80   HBUINT16      coordPoint;     /* Index of contour point on the
  81                                  * reference glyph */
  82   public:
  83   DEFINE_SIZE_STATIC (8);
  84 };
  85 
  86 struct BaseCoordFormat3
  87 {
  88   hb_position_t get_coord (hb_font_t *font,
  89                            const VariationStore &var_store,
  90                            hb_direction_t direction) const
  91   {
  92     const Device &device = this+deviceTable;
  93     return coordinate + (HB_DIRECTION_IS_VERTICAL (direction) ?
  94                          device.get_y_delta (font, var_store) :
  95                          device.get_x_delta (font, var_store));
  96   }
  97 
  98 
  99   bool sanitize (hb_sanitize_context_t *c) const
 100   {
 101     TRACE_SANITIZE (this);
 102     return_trace (likely (c->check_struct (this) &&
 103                           deviceTable.sanitize (c, this)));
 104   }
 105 
 106   protected:
 107   HBUINT16      format;         /* Format identifier--format = 3 */
 108   FWORD         coordinate;     /* X or Y value, in design units */
 109   OffsetTo<Device>
 110                 deviceTable;    /* Offset to Device table for X or
 111                                  * Y value, from beginning of
 112                                  * BaseCoord table (may be NULL). */
 113   public:
 114   DEFINE_SIZE_STATIC (6);
 115 };
 116 
 117 struct BaseCoord
 118 {
 119   hb_position_t get_coord (hb_font_t *font,
 120                            const VariationStore &var_store,
 121                            hb_direction_t direction) const
 122   {
 123     switch (u.format) {
 124     case 1: return u.format1.get_coord ();
 125     case 2: return u.format2.get_coord ();
 126     case 3: return u.format3.get_coord (font, var_store, direction);
 127     default:return 0;
 128     }
 129   }
 130 
 131   bool sanitize (hb_sanitize_context_t *c) const
 132   {
 133     TRACE_SANITIZE (this);
 134     if (unlikely (!u.format.sanitize (c))) return_trace (false);
 135     switch (u.format) {
 136     case 1: return_trace (u.format1.sanitize (c));
 137     case 2: return_trace (u.format2.sanitize (c));
 138     case 3: return_trace (u.format3.sanitize (c));
 139     default:return_trace (false);
 140     }
 141   }
 142 
 143   protected:
 144   union {
 145     HBUINT16            format;
 146     BaseCoordFormat1    format1;
 147     BaseCoordFormat2    format2;
 148     BaseCoordFormat3    format3;
 149   } u;
 150   public:
 151   DEFINE_SIZE_UNION (2, format);
 152 };
 153 
 154 struct FeatMinMaxRecord
 155 {
 156   static int cmp (const void *key_, const void *entry_)
 157   {
 158     hb_tag_t key = * (hb_tag_t *) key_;
 159     const FeatMinMaxRecord &entry = * (const FeatMinMaxRecord *) entry_;
 160     return key < (unsigned int) entry.tag ? -1 :
 161            key > (unsigned int) entry.tag ? 1 :
 162            0;
 163   }
 164 
 165   void get_min_max (const BaseCoord **min, const BaseCoord **max) const
 166   {
 167     if (likely (min)) *min = &(this+minCoord);
 168     if (likely (max)) *max = &(this+maxCoord);
 169   }
 170 
 171   bool sanitize (hb_sanitize_context_t *c, const void *base) const
 172   {
 173     TRACE_SANITIZE (this);
 174     return_trace (likely (c->check_struct (this) &&
 175                           minCoord.sanitize (c, this) &&
 176                           maxCoord.sanitize (c, this)));
 177   }
 178 
 179   protected:
 180   Tag           tag;            /* 4-byte feature identification tag--must
 181                                  * match feature tag in FeatureList */
 182   OffsetTo<BaseCoord>
 183                 minCoord;       /* Offset to BaseCoord table that defines
 184                                  * the minimum extent value, from beginning
 185                                  * of MinMax table (may be NULL) */
 186   OffsetTo<BaseCoord>
 187                 maxCoord;       /* Offset to BaseCoord table that defines
 188                                  * the maximum extent value, from beginning
 189                                  * of MinMax table (may be NULL) */
 190   public:
 191   DEFINE_SIZE_STATIC (8);
 192 
 193 };
 194 
 195 struct MinMax
 196 {
 197   void get_min_max (hb_tag_t          feature_tag,
 198                            const BaseCoord **min,
 199                            const BaseCoord **max) const
 200   {
 201     /* TODO Replace hb_bsearch() with .bsearch(). */
 202     const FeatMinMaxRecord *minMaxCoord = (const FeatMinMaxRecord *)
 203                                           hb_bsearch (&feature_tag, featMinMaxRecords.arrayZ,
 204                                                       featMinMaxRecords.len,
 205                                                       FeatMinMaxRecord::static_size,
 206                                                       FeatMinMaxRecord::cmp);
 207     if (minMaxCoord)
 208       minMaxCoord->get_min_max (min, max);
 209     else
 210     {
 211       if (likely (min)) *min = &(this+minCoord);
 212       if (likely (max)) *max = &(this+maxCoord);


 213     }















 214   }
 215 
 216   bool sanitize (hb_sanitize_context_t *c) const
 217   {
 218     TRACE_SANITIZE (this);
 219     return_trace (likely (c->check_struct (this) &&
 220                           minCoord.sanitize (c, this) &&
 221                           maxCoord.sanitize (c, this) &&
 222                           featMinMaxRecords.sanitize (c, this)));
 223   }
 224 
 225   protected:
 226   OffsetTo<BaseCoord>
 227                 minCoord;       /* Offset to BaseCoord table that defines
 228                                  * minimum extent value, from the beginning
 229                                  * of MinMax table (may be NULL) */
 230   OffsetTo<BaseCoord>
 231                 maxCoord;       /* Offset to BaseCoord table that defines
 232                                  * maximum extent value, from the beginning
 233                                  * of MinMax table (may be NULL) */
 234   SortedArrayOf<FeatMinMaxRecord>
 235                 featMinMaxRecords;
 236                                 /* Array of FeatMinMaxRecords, in alphabetical
 237                                  * order by featureTableTag */
 238   public:
 239   DEFINE_SIZE_ARRAY (6, featMinMaxRecords);
 240 };
 241 
 242 struct BaseValues

 243 {
 244   const BaseCoord &get_base_coord (int baseline_tag_index) const
 245   {
 246     if (baseline_tag_index == -1) baseline_tag_index = defaultIndex;
 247     return this+baseCoords[baseline_tag_index];
 248   }






 249 
 250   bool sanitize (hb_sanitize_context_t *c) const
 251   {
 252     TRACE_SANITIZE (this);
 253     return_trace (likely (c->check_struct (this) &&
 254                           baseCoords.sanitize (c, this)));
 255   }
 256 
 257   protected:
 258   Index         defaultIndex;   /* Index number of default baseline for this
 259                                  * script — equals index position of baseline tag
 260                                  * in baselineTags array of the BaseTagList */
 261   OffsetArrayOf<BaseCoord>
 262                 baseCoords;     /* Number of BaseCoord tables defined — should equal
 263                                  * baseTagCount in the BaseTagList
 264                                  *
 265                                  * Array of offsets to BaseCoord tables, from beginning of
 266                                  * BaseValues table — order matches baselineTags array in
 267                                  * the BaseTagList */
 268   public:
 269   DEFINE_SIZE_ARRAY (4, baseCoords);

 270 };
 271 
 272 struct BaseLangSysRecord
 273 {
 274   static int cmp (const void *key_, const void *entry_)



 275   {
 276     hb_tag_t key = * (hb_tag_t *) key_;
 277     const BaseLangSysRecord &entry = * (const BaseLangSysRecord *) entry_;
 278     return key < (unsigned int) entry.baseLangSysTag ? -1 :
 279            key > (unsigned int) entry.baseLangSysTag ? 1 :
 280            0;
 281   }
 282 
 283   const MinMax &get_min_max () const
 284   { return this+minMax; }
 285 
 286   bool sanitize (hb_sanitize_context_t *c, const void *base) const
 287   {
 288     TRACE_SANITIZE (this);
 289     return_trace (likely (c->check_struct (this) &&
 290                           minMax.sanitize (c, this)));

 291   }
 292 
 293   protected:
 294   Tag           baseLangSysTag; /* 4-byte language system identification tag */
 295   OffsetTo<MinMax>
 296                 minMax;         /* Offset to MinMax table, from beginning
 297                                  * of BaseScript table */
 298   public:
 299   DEFINE_SIZE_STATIC (6);

 300 };
 301 
 302 struct BaseScript
 303 {
 304   const MinMax &get_min_max (hb_tag_t language_tag) const































 305   {
 306     /* TODO Replace hb_bsearch() with .bsearch(). */
 307     const BaseLangSysRecord* record = (const BaseLangSysRecord *)
 308                                       hb_bsearch (&language_tag, baseLangSysRecords.arrayZ,
 309                                                   baseLangSysRecords.len,
 310                                                   BaseLangSysRecord::static_size,
 311                                                   BaseLangSysRecord::cmp);
 312     return record ? record->get_min_max () : this+defaultMinMax;
 313   }
 314 
 315   const BaseCoord &get_base_coord (int baseline_tag_index) const
 316   { return (this+baseValues).get_base_coord (baseline_tag_index); }
 317 
 318   bool is_empty () const { return !baseValues; }

 319 
 320   bool sanitize (hb_sanitize_context_t *c) const
 321   {
 322     TRACE_SANITIZE (this);
 323     return_trace (likely (c->check_struct (this) &&
 324                           baseValues.sanitize (c, this) &&
 325                           defaultMinMax.sanitize (c, this) &&
 326                           baseLangSysRecords.sanitize (c, this)));
 327   }
 328 
 329   protected:
 330   OffsetTo<BaseValues>
 331                 baseValues;     /* Offset to BaseValues table, from beginning
 332                                  * of BaseScript table (may be NULL) */
 333   OffsetTo<MinMax>
 334                 defaultMinMax;  /* Offset to MinMax table, from beginning of
 335                                  * BaseScript table (may be NULL) */
 336   SortedArrayOf<BaseLangSysRecord>
 337                 baseLangSysRecords;
 338                                 /* Number of BaseLangSysRecords
 339                                  * defined — may be zero (0) */
 340 
 341   public:
 342   DEFINE_SIZE_ARRAY (6, baseLangSysRecords);
 343 };
 344 
 345 struct BaseScriptList;
 346 struct BaseScriptRecord
 347 {
 348   static int cmp (const void *key_, const void *entry_)
 349   {
 350     hb_tag_t key = * (hb_tag_t *) key_;
 351     const BaseScriptRecord &entry = * (const BaseScriptRecord *) entry_;
 352     return key < (unsigned int) entry.baseScriptTag ? -1 :
 353            key > (unsigned int) entry.baseScriptTag ? 1 :
 354            0;
 355   }
 356 
 357   const BaseScript &get_base_script (const BaseScriptList *list) const
 358   { return list+baseScript; }




















 359 
 360   bool sanitize (hb_sanitize_context_t *c, const void *base) const
 361   {
 362     TRACE_SANITIZE (this);
 363     return_trace (likely (c->check_struct (this) &&
 364                           baseScript.sanitize (c, base)));

 365   }
 366 
 367   protected:
 368   Tag           baseScriptTag;  /* 4-byte script identification tag */
 369   OffsetTo<BaseScript>
 370                 baseScript;     /* Offset to BaseScript table, from beginning
 371                                  * of BaseScriptList */
 372 
 373   public:
 374   DEFINE_SIZE_STATIC (6);
 375 };
 376 
 377 struct BaseScriptList
 378 {
 379   const BaseScriptRecord *find_record (hb_tag_t script) const

























 380   {
 381     /* TODO Replace hb_bsearch() with .bsearch(). */
 382     return (const BaseScriptRecord *) hb_bsearch (&script, baseScriptRecords.arrayZ,
 383                                                   baseScriptRecords.len,
 384                                                   BaseScriptRecord::static_size,
 385                                                   BaseScriptRecord::cmp);
 386   }
 387 
 388   /* TODO: Or client should handle fallback? */
 389   const BaseScript &get_base_script (hb_tag_t script) const
 390   {
 391     const BaseScriptRecord *record = find_record (script);
 392     if (!record) record = find_record ((hb_script_t) HB_TAG ('D','F','L','T'));
 393 
 394     return record ? record->get_base_script (this) : Null (BaseScript);


 395   }
 396 
 397   bool sanitize (hb_sanitize_context_t *c) const
 398   {
 399     TRACE_SANITIZE (this);
 400     return_trace (c->check_struct (this) &&
 401                   baseScriptRecords.sanitize (c, this));
 402   }
 403 
 404   protected:
 405   SortedArrayOf<BaseScriptRecord>
 406                         baseScriptRecords;
 407 
 408   public:
 409   DEFINE_SIZE_ARRAY (2, baseScriptRecords);


























 410 };
 411 
 412 struct Axis
 413 {
 414   bool get_baseline (hb_ot_layout_baseline_t   baseline,
 415                             hb_tag_t                  script_tag,
 416                             hb_tag_t                  language_tag,
 417                             const BaseCoord         **coord) const
 418   {
 419     const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
 420     if (base_script.is_empty ()) return false;

 421 
 422     if (likely (coord)) *coord = &base_script.get_base_coord ((this+baseTagList).bsearch (baseline));









 423 
 424     return true;



 425   }
 426 
 427   bool get_min_max (hb_tag_t          script_tag,
 428                     hb_tag_t          language_tag,
 429                     hb_tag_t          feature_tag,
 430                     const BaseCoord **min_coord,
 431                     const BaseCoord **max_coord) const
 432   {
 433     const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
 434     if (base_script.is_empty ()) return false;

 435 
 436     base_script.get_min_max (language_tag).get_min_max (feature_tag, min_coord, max_coord);



 437 
 438     return true;


 439   }
 440 
 441   bool sanitize (hb_sanitize_context_t *c) const
 442   {
 443     TRACE_SANITIZE (this);
 444     return_trace (likely (c->check_struct (this) &&
 445                           (this+baseTagList).sanitize (c) &&
 446                           (this+baseScriptList).sanitize (c)));
 447   }
 448 
 449   protected:
 450   OffsetTo<SortedArrayOf<Tag> >
 451                 baseTagList;    /* Offset to BaseTagList table, from beginning
 452                                  * of Axis table (may be NULL)
 453                                  * Array of 4-byte baseline identification tags — must
 454                                  * be in alphabetical order */
 455   OffsetTo<BaseScriptList>
 456                 baseScriptList; /* Offset to BaseScriptList table, from beginning
 457                                  * of Axis table
 458                                  * Array of BaseScriptRecords, in alphabetical order
 459                                  * by baseScriptTag */
 460 
 461   public:
 462   DEFINE_SIZE_STATIC (4);
 463 };
 464 
 465 struct BASE
 466 {
 467   static constexpr hb_tag_t tableTag = HB_OT_TAG_BASE;



 468 
 469   const Axis &get_axis (hb_direction_t direction) const
 470   { return HB_DIRECTION_IS_VERTICAL (direction) ? this+vAxis : this+hAxis; }
 471 
 472   const VariationStore &get_var_store () const
 473   { return version.to_int () < 0x00010001u ? Null (VariationStore) : this+varStore; }
 474 
 475   bool get_baseline (hb_font_t               *font,
 476                      hb_ot_layout_baseline_t  baseline,
 477                      hb_direction_t           direction,
 478                      hb_tag_t                 script_tag,
 479                      hb_tag_t                 language_tag,
 480                      hb_position_t           *base) const
 481   {
 482     const BaseCoord *base_coord;
 483     if (!get_axis (direction).get_baseline (baseline, script_tag, language_tag, &base_coord))
 484       return false;
 485 
 486     if (likely (base && base_coord)) *base = base_coord->get_coord (font,
 487                                                                     get_var_store (),
 488                                                                     direction);
 489     return true;
 490   }
 491 
 492   /* TODO: Expose this separately sometime? */
 493   bool get_min_max (hb_font_t      *font,
 494                     hb_direction_t  direction,
 495                     hb_tag_t        script_tag,
 496                     hb_tag_t        language_tag,
 497                     hb_tag_t        feature_tag,
 498                     hb_position_t  *min,
 499                     hb_position_t  *max)
 500   {
 501     const BaseCoord *min_coord, *max_coord;
 502     if (!get_axis (direction).get_min_max (script_tag, language_tag, feature_tag,
 503                                            &min_coord, &max_coord))
 504       return false;































 505 
 506     const VariationStore &var_store = get_var_store ();
 507     if (likely (min && min_coord)) *min = min_coord->get_coord (font, var_store, direction);
 508     if (likely (max && max_coord)) *max = max_coord->get_coord (font, var_store, direction);
 509     return true;























 510   }
 511 
 512   bool sanitize (hb_sanitize_context_t *c) const





 513   {
 514     TRACE_SANITIZE (this);
 515     return_trace (likely (c->check_struct (this) &&
 516                           likely (version.major == 1) &&
 517                           hAxis.sanitize (c, this) &&
 518                           vAxis.sanitize (c, this) &&
 519                           (version.to_int () < 0x00010001u || varStore.sanitize (c, this))));
 520   }
 521 
 522   protected:
 523   FixedVersion<>version;        /* Version of the BASE table */
 524   OffsetTo<Axis>hAxis;          /* Offset to horizontal Axis table, from beginning
 525                                  * of BASE table (may be NULL) */
 526   OffsetTo<Axis>vAxis;          /* Offset to vertical Axis table, from beginning
 527                                  * of BASE table (may be NULL) */
 528   LOffsetTo<VariationStore>
 529                 varStore;       /* Offset to the table of Item Variation
 530                                  * Store--from beginning of BASE
 531                                  * header (may be NULL).  Introduced
 532                                  * in version 0x00010001. */
 533   public:
 534   DEFINE_SIZE_MIN (8);
 535 };
 536 
 537 
 538 } /* namespace OT */
 539 
 540 
 541 #endif /* HB_OT_LAYOUT_BASE_TABLE_HH */
< prev index next >