Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright  2016  Google, Inc.
      3  *
      4  *  This is part of HarfBuzz, a text shaping library.
      5  *
      6  * Permission is hereby granted, without written agreement and without
      7  * license or royalty fees, to use, copy, modify, and distribute this
      8  * software and its documentation for any purpose, provided that the
      9  * above copyright notice and the following two paragraphs appear in
     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): Seigo Nonaka
     25  */
     26 
     27 #ifndef HB_OT_CBDT_TABLE_HH
     28 #define HB_OT_CBDT_TABLE_HH
     29 
     30 #include "hb-open-type-private.hh"
     31 
     32 namespace OT {
     33 
     34 struct SmallGlyphMetrics
     35 {
     36   inline bool sanitize (hb_sanitize_context_t *c) const
     37   {
     38     TRACE_SANITIZE (this);
     39     return_trace (c->check_struct (this));
     40   }
     41 
     42   inline void get_extents (hb_glyph_extents_t *extents) const
     43   {
     44     extents->x_bearing = bearingX;
     45     extents->y_bearing = bearingY;
     46     extents->width = width;
     47     extents->height = -height;
     48   }
     49 
     50   BYTE height;
     51   BYTE width;
     52   CHAR bearingX;
     53   CHAR bearingY;
     54   BYTE advance;
     55 
     56   DEFINE_SIZE_STATIC(5);
     57 };
     58 
     59 struct BigGlyphMetrics : SmallGlyphMetrics
     60 {
     61   CHAR vertBearingX;
     62   CHAR vertBearingY;
     63   BYTE vertAdvance;
     64 
     65   DEFINE_SIZE_STATIC(8);
     66 };
     67 
     68 struct SBitLineMetrics
     69 {
     70   inline bool sanitize (hb_sanitize_context_t *c) const
     71   {
     72     TRACE_SANITIZE (this);
     73     return_trace (c->check_struct (this));
     74   }
     75 
     76   CHAR ascender;
     77   CHAR decender;
     78   BYTE widthMax;
     79   CHAR caretSlopeNumerator;
     80   CHAR caretSlopeDenominator;
     81   CHAR caretOffset;
     82   CHAR minOriginSB;
     83   CHAR minAdvanceSB;
     84   CHAR maxBeforeBL;
     85   CHAR minAfterBL;
     86   CHAR padding1;
     87   CHAR padding2;
     88 
     89   DEFINE_SIZE_STATIC(12);
     90 };
     91 
     92 
     93 /*
     94  * Index Subtables.
     95  */
     96 
     97 struct IndexSubtableHeader
     98 {
     99   inline bool sanitize (hb_sanitize_context_t *c) const
    100   {
    101     TRACE_SANITIZE (this);
    102     return_trace (c->check_struct (this));
    103   }
    104 
    105   USHORT indexFormat;
    106   USHORT imageFormat;
    107   ULONG imageDataOffset;
    108 
    109   DEFINE_SIZE_STATIC(8);
    110 };
    111 
    112 template <typename OffsetType>
    113 struct IndexSubtableFormat1Or3
    114 {
    115   inline bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
    116   {
    117     TRACE_SANITIZE (this);
    118     return_trace (c->check_struct (this) &&
    119 		  c->check_array (offsetArrayZ, offsetArrayZ[0].static_size, glyph_count + 1));
    120   }
    121 
    122   bool get_image_data (unsigned int idx,
    123 		       unsigned int *offset,
    124 		       unsigned int *length) const
    125   {
    126     if (unlikely (offsetArrayZ[idx + 1] <= offsetArrayZ[idx]))
    127       return false;
    128 
    129     *offset = header.imageDataOffset + offsetArrayZ[idx];
    130     *length = offsetArrayZ[idx + 1] - offsetArrayZ[idx];
    131     return true;
    132   }
    133 
    134   IndexSubtableHeader header;
    135   Offset<OffsetType> offsetArrayZ[VAR];
    136 
    137   DEFINE_SIZE_ARRAY(8, offsetArrayZ);
    138 };
    139 
    140 struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<ULONG> {};
    141 struct IndexSubtableFormat3 : IndexSubtableFormat1Or3<USHORT> {};
    142 
    143 struct IndexSubtable
    144 {
    145   inline bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
    146   {
    147     TRACE_SANITIZE (this);
    148     if (!u.header.sanitize (c)) return_trace (false);
    149     switch (u.header.indexFormat) {
    150     case 1: return_trace (u.format1.sanitize (c, glyph_count));
    151     case 3: return_trace (u.format3.sanitize (c, glyph_count));
    152     default:return_trace (true);
    153     }
    154   }
    155 
    156   inline bool get_extents (hb_glyph_extents_t *extents) const
    157   {
    158     switch (u.header.indexFormat) {
    159     case 2: case 5: /* TODO */
    160     case 1: case 3: case 4: /* Variable-metrics formats do not have metrics here. */
    161     default:return (false);
    162     }
    163   }
    164 
    165   bool get_image_data (unsigned int idx,
    166 		       unsigned int *offset,
    167 		       unsigned int *length,
    168 		       unsigned int *format) const
    169   {
    170     *format = u.header.imageFormat;
    171     switch (u.header.indexFormat) {
    172     case 1: return u.format1.get_image_data (idx, offset, length);
    173     case 3: return u.format3.get_image_data (idx, offset, length);
    174     default: return false;
    175     }
    176   }
    177 
    178   protected:
    179   union {
    180   IndexSubtableHeader	header;
    181   IndexSubtableFormat1	format1;
    182   IndexSubtableFormat3	format3;
    183   /* TODO: Format 2, 4, 5. */
    184   } u;
    185   public:
    186   DEFINE_SIZE_UNION (8, header);
    187 };
    188 
    189 struct IndexSubtableRecord
    190 {
    191   inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
    192   {
    193     TRACE_SANITIZE (this);
    194     return_trace (c->check_struct (this) &&
    195 		  firstGlyphIndex <= lastGlyphIndex &&
    196 		  offsetToSubtable.sanitize (c, this, lastGlyphIndex - firstGlyphIndex + 1));
    197   }
    198 
    199   inline bool get_extents (hb_glyph_extents_t *extents) const
    200   {
    201     return (this+offsetToSubtable).get_extents (extents);
    202   }
    203 
    204   bool get_image_data (unsigned int gid,
    205 		       unsigned int *offset,
    206 		       unsigned int *length,
    207 		       unsigned int *format) const
    208   {
    209     if (gid < firstGlyphIndex || gid > lastGlyphIndex)
    210     {
    211       return false;
    212     }
    213     return (this+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
    214 						   offset, length, format);
    215   }
    216 
    217   USHORT firstGlyphIndex;
    218   USHORT lastGlyphIndex;
    219   LOffsetTo<IndexSubtable> offsetToSubtable;
    220 
    221   DEFINE_SIZE_STATIC(8);
    222 };
    223 
    224 struct IndexSubtableArray
    225 {
    226   inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
    227   {
    228     TRACE_SANITIZE (this);
    229     if (unlikely (!c->check_array (&indexSubtablesZ, indexSubtablesZ[0].static_size, count)))
    230       return_trace (false);
    231     for (unsigned int i = 0; i < count; i++)
    232       if (unlikely (!indexSubtablesZ[i].sanitize (c, this)))
    233 	return_trace (false);
    234     return_trace (true);
    235   }
    236 
    237   public:
    238   const IndexSubtableRecord* find_table (hb_codepoint_t glyph, unsigned int numTables) const
    239   {
    240     for (unsigned int i = 0; i < numTables; ++i)
    241     {
    242       unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex;
    243       unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex;
    244       if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) {
    245         return &indexSubtablesZ[i];
    246       }
    247     }
    248     return NULL;
    249   }
    250 
    251   protected:
    252   IndexSubtableRecord indexSubtablesZ[VAR];
    253 
    254   public:
    255   DEFINE_SIZE_ARRAY(0, indexSubtablesZ);
    256 };
    257 
    258 struct BitmapSizeTable
    259 {
    260   friend struct CBLC;
    261 
    262   inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
    263   {
    264     TRACE_SANITIZE (this);
    265     return_trace (c->check_struct (this) &&
    266 		  indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) &&
    267 		  c->check_range (&(base+indexSubtableArrayOffset), indexTablesSize) &&
    268 		  horizontal.sanitize (c) &&
    269 		  vertical.sanitize (c));
    270   }
    271 
    272   const IndexSubtableRecord *find_table (hb_codepoint_t glyph, const void *base) const
    273   {
    274     return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables);
    275   }
    276 
    277   protected:
    278   LOffsetTo<IndexSubtableArray> indexSubtableArrayOffset;
    279   ULONG indexTablesSize;
    280   ULONG numberOfIndexSubtables;
    281   ULONG colorRef;
    282   SBitLineMetrics horizontal;
    283   SBitLineMetrics vertical;
    284   USHORT startGlyphIndex;
    285   USHORT endGlyphIndex;
    286   BYTE ppemX;
    287   BYTE ppemY;
    288   BYTE bitDepth;
    289   CHAR flags;
    290 
    291 public:
    292   DEFINE_SIZE_STATIC(48);
    293 };
    294 
    295 
    296 /*
    297  * Glyph Bitmap Data Formats.
    298  */
    299 
    300 struct GlyphBitmapDataFormat17
    301 {
    302   SmallGlyphMetrics glyphMetrics;
    303   ULONG dataLen;
    304   BYTE dataZ[VAR];
    305 
    306   DEFINE_SIZE_ARRAY(9, dataZ);
    307 };
    308 
    309 
    310 /*
    311  * CBLC -- Color Bitmap Location Table
    312  */
    313 
    314 #define HB_OT_TAG_CBLC HB_TAG('C','B','L','C')
    315 
    316 struct CBLC
    317 {
    318   static const hb_tag_t tableTag = HB_OT_TAG_CBLC;
    319 
    320   inline bool sanitize (hb_sanitize_context_t *c) const
    321   {
    322     TRACE_SANITIZE (this);
    323     return_trace (c->check_struct (this) &&
    324 		  likely (version.major == 2 || version.major == 3) &&
    325 		  sizeTables.sanitize (c, this));
    326   }
    327 
    328   public:
    329   const IndexSubtableRecord *find_table (hb_codepoint_t glyph,
    330 					 unsigned int *x_ppem, unsigned int *y_ppem) const
    331   {
    332     /* TODO: Make it possible to select strike. */
    333 
    334     unsigned int count = sizeTables.len;
    335     for (uint32_t i = 0; i < count; ++i)
    336     {
    337       unsigned int startGlyphIndex = sizeTables.array[i].startGlyphIndex;
    338       unsigned int endGlyphIndex = sizeTables.array[i].endGlyphIndex;
    339       if (startGlyphIndex <= glyph && glyph <= endGlyphIndex)
    340       {
    341 	*x_ppem = sizeTables[i].ppemX;
    342 	*y_ppem = sizeTables[i].ppemY;
    343 	return sizeTables[i].find_table (glyph, this);
    344       }
    345     }
    346 
    347     return NULL;
    348   }
    349 
    350   protected:
    351   FixedVersion<>		version;
    352   LArrayOf<BitmapSizeTable>	sizeTables;
    353 
    354   public:
    355   DEFINE_SIZE_ARRAY(8, sizeTables);
    356 };
    357 
    358 /*
    359  * CBDT -- Color Bitmap Data Table
    360  */
    361 #define HB_OT_TAG_CBDT HB_TAG('C','B','D','T')
    362 
    363 struct CBDT
    364 {
    365   static const hb_tag_t tableTag = HB_OT_TAG_CBDT;
    366 
    367   inline bool sanitize (hb_sanitize_context_t *c) const
    368   {
    369     TRACE_SANITIZE (this);
    370     return_trace (c->check_struct (this) &&
    371 		  likely (version.major == 2 || version.major == 3));
    372   }
    373 
    374   protected:
    375   FixedVersion<>version;
    376   BYTE dataZ[VAR];
    377 
    378   public:
    379   DEFINE_SIZE_ARRAY(4, dataZ);
    380 };
    381 
    382 } /* namespace OT */
    383 
    384 #endif /* HB_OT_CBDT_TABLE_HH */
    385