src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-cbdt-table.hh
changeset 47216 71c04702a3d5
parent 43232 8e39ad39979f
child 48274 51772bf1fb0c
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     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   OffsetTo<IndexSubtable, ULONG> 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   OffsetTo<IndexSubtableArray, ULONG> 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   ArrayOf<BitmapSizeTable, ULONG> 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 */