| OLD | NEW |
| (Empty) | |
| 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) cons
t |
| 116 { |
| 117 TRACE_SANITIZE (this); |
| 118 return_trace (c->check_struct (this) && |
| 119 c->check_array (offsetArrayZ, offsetArrayZ[0].static_size, gly
ph_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) cons
t |
| 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 - firstGlyp
hIndex + 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_s
ize, 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 numT
ables) 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, numberOfIndexSubta
bles) && |
| 267 c->check_range (&(base+indexSubtableArrayOffset), indexTablesS
ize) && |
| 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, numberOfIndexSubta
bles); |
| 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_p
pem) 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 */ |
| OLD | NEW |