Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/harfbuzz/src/hb-open-file.hh @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* | |
| 2 * Copyright © 2007,2008,2009 Red Hat, Inc. | |
| 3 * Copyright © 2012 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 * Red Hat Author(s): Behdad Esfahbod | |
| 26 * Google Author(s): Behdad Esfahbod | |
| 27 */ | |
| 28 | |
| 29 #ifndef HB_OPEN_FILE_HH | |
| 30 #define HB_OPEN_FILE_HH | |
| 31 | |
| 32 #include "hb-open-type.hh" | |
| 33 #include "hb-ot-head-table.hh" | |
| 34 | |
| 35 | |
| 36 namespace OT { | |
| 37 | |
| 38 /* | |
| 39 * | |
| 40 * The OpenType Font File | |
| 41 * | |
| 42 */ | |
| 43 | |
| 44 | |
| 45 /* | |
| 46 * Organization of an OpenType Font | |
| 47 */ | |
| 48 | |
| 49 struct OpenTypeFontFile; | |
| 50 struct OpenTypeOffsetTable; | |
| 51 struct TTCHeader; | |
| 52 | |
| 53 | |
| 54 typedef struct TableRecord | |
| 55 { | |
| 56 int cmp (Tag t) const { return -t.cmp (tag); } | |
| 57 | |
| 58 HB_INTERNAL static int cmp (const void *pa, const void *pb) | |
| 59 { | |
| 60 const TableRecord *a = (const TableRecord *) pa; | |
| 61 const TableRecord *b = (const TableRecord *) pb; | |
| 62 return b->cmp (a->tag); | |
| 63 } | |
| 64 | |
| 65 bool sanitize (hb_sanitize_context_t *c) const | |
| 66 { | |
| 67 TRACE_SANITIZE (this); | |
| 68 return_trace (c->check_struct (this)); | |
| 69 } | |
| 70 | |
| 71 Tag tag; /* 4-byte identifier. */ | |
| 72 CheckSum checkSum; /* CheckSum for this table. */ | |
| 73 Offset32 offset; /* Offset from beginning of TrueType font | |
| 74 * file. */ | |
| 75 HBUINT32 length; /* Length of this table. */ | |
| 76 public: | |
| 77 DEFINE_SIZE_STATIC (16); | |
| 78 } OpenTypeTable; | |
| 79 | |
| 80 typedef struct OpenTypeOffsetTable | |
| 81 { | |
| 82 friend struct OpenTypeFontFile; | |
| 83 | |
| 84 unsigned int get_table_count () const { return tables.len; } | |
| 85 const TableRecord& get_table (unsigned int i) const | |
| 86 { return tables[i]; } | |
| 87 unsigned int get_table_tags (unsigned int start_offset, | |
| 88 unsigned int *table_count, /* IN/OUT */ | |
| 89 hb_tag_t *table_tags /* OUT */) const | |
| 90 { | |
| 91 if (table_count) | |
| 92 { | |
| 93 + tables.as_array ().sub_array (start_offset, table_count) | |
| 94 | hb_map (&TableRecord::tag) | |
| 95 | hb_sink (hb_array (table_tags, *table_count)) | |
| 96 ; | |
| 97 } | |
| 98 return tables.len; | |
| 99 } | |
| 100 bool find_table_index (hb_tag_t tag, unsigned int *table_index) const | |
| 101 { | |
| 102 Tag t; | |
| 103 t = tag; | |
| 104 /* Use lfind for small fonts; there are fonts that have unsorted table entries; | |
| 105 * those tend to work in other tools, so tolerate them. | |
| 106 * https://github.com/harfbuzz/harfbuzz/issues/3065 */ | |
| 107 if (tables.len < 16) | |
| 108 return tables.lfind (t, table_index, HB_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX); | |
| 109 else | |
| 110 return tables.bfind (t, table_index, HB_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX); | |
| 111 } | |
| 112 const TableRecord& get_table_by_tag (hb_tag_t tag) const | |
| 113 { | |
| 114 unsigned int table_index; | |
| 115 find_table_index (tag, &table_index); | |
| 116 return get_table (table_index); | |
| 117 } | |
| 118 | |
| 119 public: | |
| 120 | |
| 121 template <typename Iterator, | |
| 122 hb_requires ((hb_is_source_of<Iterator, hb_pair_t<hb_tag_t, hb_blob_t *>>::value))> | |
| 123 bool serialize (hb_serialize_context_t *c, | |
| 124 hb_tag_t sfnt_tag, | |
| 125 Iterator it) | |
| 126 { | |
| 127 TRACE_SERIALIZE (this); | |
| 128 /* Alloc 12 for the OTHeader. */ | |
| 129 if (unlikely (!c->extend_min (this))) return_trace (false); | |
| 130 /* Write sfntVersion (bytes 0..3). */ | |
| 131 sfnt_version = sfnt_tag; | |
| 132 /* Take space for numTables, searchRange, entrySelector, RangeShift | |
| 133 * and the TableRecords themselves. */ | |
| 134 unsigned num_items = it.len (); | |
| 135 if (unlikely (!tables.serialize (c, num_items))) return_trace (false); | |
| 136 | |
| 137 const char *dir_end = (const char *) c->head; | |
| 138 HBUINT32 *checksum_adjustment = nullptr; | |
| 139 | |
| 140 /* Write OffsetTables, alloc for and write actual table blobs. */ | |
| 141 unsigned i = 0; | |
| 142 for (hb_pair_t<hb_tag_t, hb_blob_t*> entry : it) | |
| 143 { | |
| 144 hb_blob_t *blob = entry.second; | |
| 145 unsigned len = blob->length; | |
| 146 | |
| 147 /* Allocate room for the table and copy it. */ | |
| 148 char *start = (char *) c->allocate_size<void> (len); | |
| 149 if (unlikely (!start)) return false; | |
| 150 | |
| 151 TableRecord &rec = tables.arrayZ[i]; | |
| 152 rec.tag = entry.first; | |
| 153 rec.length = len; | |
| 154 rec.offset = 0; | |
| 155 if (unlikely (!c->check_assign (rec.offset, | |
| 156 (unsigned) ((char *) start - (char *) this), | |
| 157 HB_SERIALIZE_ERROR_OFFSET_OVERFLOW))) | |
| 158 return_trace (false); | |
| 159 | |
| 160 if (likely (len)) | |
| 161 hb_memcpy (start, blob->data, len); | |
| 162 | |
| 163 /* 4-byte alignment. */ | |
| 164 c->align (4); | |
| 165 const char *end = (const char *) c->head; | |
| 166 | |
| 167 if (entry.first == HB_OT_TAG_head && | |
| 168 (unsigned) (end - start) >= head::static_size) | |
| 169 { | |
| 170 head *h = (head *) start; | |
| 171 checksum_adjustment = &h->checkSumAdjustment; | |
| 172 *checksum_adjustment = 0; | |
| 173 } | |
| 174 | |
| 175 rec.checkSum.set_for_data (start, end - start); | |
| 176 i++; | |
| 177 } | |
| 178 | |
| 179 tables.qsort (); | |
| 180 | |
| 181 if (checksum_adjustment) | |
| 182 { | |
| 183 CheckSum checksum; | |
| 184 | |
| 185 /* The following line is a slower version of the following block. */ | |
| 186 //checksum.set_for_data (this, (const char *) c->head - (const char *) this); | |
| 187 checksum.set_for_data (this, dir_end - (const char *) this); | |
| 188 for (unsigned int i = 0; i < num_items; i++) | |
| 189 { | |
| 190 TableRecord &rec = tables.arrayZ[i]; | |
| 191 checksum = checksum + rec.checkSum; | |
| 192 } | |
| 193 | |
| 194 *checksum_adjustment = 0xB1B0AFBAu - checksum; | |
| 195 } | |
| 196 | |
| 197 return_trace (true); | |
| 198 } | |
| 199 | |
| 200 bool sanitize (hb_sanitize_context_t *c) const | |
| 201 { | |
| 202 TRACE_SANITIZE (this); | |
| 203 return_trace (c->check_struct (this) && tables.sanitize (c)); | |
| 204 } | |
| 205 | |
| 206 protected: | |
| 207 Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */ | |
| 208 BinSearchArrayOf<TableRecord> | |
| 209 tables; | |
| 210 public: | |
| 211 DEFINE_SIZE_ARRAY (12, tables); | |
| 212 } OpenTypeFontFace; | |
| 213 | |
| 214 | |
| 215 /* | |
| 216 * TrueType Collections | |
| 217 */ | |
| 218 | |
| 219 struct TTCHeaderVersion1 | |
| 220 { | |
| 221 friend struct TTCHeader; | |
| 222 | |
| 223 unsigned int get_face_count () const { return table.len; } | |
| 224 const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; } | |
| 225 | |
| 226 bool sanitize (hb_sanitize_context_t *c) const | |
| 227 { | |
| 228 TRACE_SANITIZE (this); | |
| 229 return_trace (table.sanitize (c, this)); | |
| 230 } | |
| 231 | |
| 232 protected: | |
| 233 Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ | |
| 234 FixedVersion<>version; /* Version of the TTC Header (1.0), | |
| 235 * 0x00010000u */ | |
| 236 Array32Of<Offset32To<OpenTypeOffsetTable>> | |
| 237 table; /* Array of offsets to the OffsetTable for each font | |
| 238 * from the beginning of the file */ | |
| 239 public: | |
| 240 DEFINE_SIZE_ARRAY (12, table); | |
| 241 }; | |
| 242 | |
| 243 struct TTCHeader | |
| 244 { | |
| 245 friend struct OpenTypeFontFile; | |
| 246 | |
| 247 private: | |
| 248 | |
| 249 unsigned int get_face_count () const | |
| 250 { | |
| 251 switch (u.header.version.major) { | |
| 252 case 2: /* version 2 is compatible with version 1 */ | |
| 253 case 1: return u.version1.get_face_count (); | |
| 254 default:return 0; | |
| 255 } | |
| 256 } | |
| 257 const OpenTypeFontFace& get_face (unsigned int i) const | |
| 258 { | |
| 259 switch (u.header.version.major) { | |
| 260 case 2: /* version 2 is compatible with version 1 */ | |
| 261 case 1: return u.version1.get_face (i); | |
| 262 default:return Null (OpenTypeFontFace); | |
| 263 } | |
| 264 } | |
| 265 | |
| 266 bool sanitize (hb_sanitize_context_t *c) const | |
| 267 { | |
| 268 TRACE_SANITIZE (this); | |
| 269 if (unlikely (!u.header.version.sanitize (c))) return_trace (false); | |
| 270 switch (u.header.version.major) { | |
| 271 case 2: /* version 2 is compatible with version 1 */ | |
| 272 case 1: return_trace (u.version1.sanitize (c)); | |
| 273 default:return_trace (true); | |
| 274 } | |
| 275 } | |
| 276 | |
| 277 protected: | |
| 278 union { | |
| 279 struct { | |
| 280 Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ | |
| 281 FixedVersion<>version; /* Version of the TTC Header (1.0 or 2.0), | |
| 282 * 0x00010000u or 0x00020000u */ | |
| 283 } header; | |
| 284 TTCHeaderVersion1 version1; | |
| 285 } u; | |
| 286 }; | |
| 287 | |
| 288 /* | |
| 289 * Mac Resource Fork | |
| 290 * | |
| 291 * http://mirror.informatimago.com/next/developer.apple.com/documentation/mac/MoreToolbox/MoreToolbox-99.html | |
| 292 */ | |
| 293 | |
| 294 struct ResourceRecord | |
| 295 { | |
| 296 const OpenTypeFontFace & get_face (const void *data_base) const | |
| 297 { return * reinterpret_cast<const OpenTypeFontFace *> ((data_base+offset).arrayZ); } | |
| 298 | |
| 299 bool sanitize (hb_sanitize_context_t *c, | |
| 300 const void *data_base) const | |
| 301 { | |
| 302 TRACE_SANITIZE (this); | |
| 303 return_trace (c->check_struct (this) && | |
| 304 offset.sanitize (c, data_base) && | |
| 305 get_face (data_base).sanitize (c)); | |
| 306 } | |
| 307 | |
| 308 protected: | |
| 309 HBUINT16 id; /* Resource ID. */ | |
| 310 HBINT16 nameOffset; /* Offset from beginning of resource name list | |
| 311 * to resource name, -1 means there is none. */ | |
| 312 HBUINT8 attrs; /* Resource attributes */ | |
| 313 NNOffset24To<Array32Of<HBUINT8>> | |
| 314 offset; /* Offset from beginning of data block to | |
| 315 * data for this resource */ | |
| 316 HBUINT32 reserved; /* Reserved for handle to resource */ | |
| 317 public: | |
| 318 DEFINE_SIZE_STATIC (12); | |
| 319 }; | |
| 320 | |
| 321 #define HB_TAG_sfnt HB_TAG ('s','f','n','t') | |
| 322 | |
| 323 struct ResourceTypeRecord | |
| 324 { | |
| 325 unsigned int get_resource_count () const | |
| 326 { return tag == HB_TAG_sfnt ? resCountM1 + 1 : 0; } | |
| 327 | |
| 328 bool is_sfnt () const { return tag == HB_TAG_sfnt; } | |
| 329 | |
| 330 const ResourceRecord& get_resource_record (unsigned int i, | |
| 331 const void *type_base) const | |
| 332 { return (type_base+resourcesZ).as_array (get_resource_count ())[i]; } | |
| 333 | |
| 334 bool sanitize (hb_sanitize_context_t *c, | |
| 335 const void *type_base, | |
| 336 const void *data_base) const | |
| 337 { | |
| 338 TRACE_SANITIZE (this); | |
| 339 return_trace (c->check_struct (this) && | |
| 340 resourcesZ.sanitize (c, type_base, | |
| 341 get_resource_count (), | |
| 342 data_base)); | |
| 343 } | |
| 344 | |
| 345 protected: | |
| 346 Tag tag; /* Resource type. */ | |
| 347 HBUINT16 resCountM1; /* Number of resources minus 1. */ | |
| 348 NNOffset16To<UnsizedArrayOf<ResourceRecord>> | |
| 349 resourcesZ; /* Offset from beginning of resource type list | |
| 350 * to reference item list for this type. */ | |
| 351 public: | |
| 352 DEFINE_SIZE_STATIC (8); | |
| 353 }; | |
| 354 | |
| 355 struct ResourceMap | |
| 356 { | |
| 357 unsigned int get_face_count () const | |
| 358 { | |
| 359 unsigned int count = get_type_count (); | |
| 360 for (unsigned int i = 0; i < count; i++) | |
| 361 { | |
| 362 const ResourceTypeRecord& type = get_type_record (i); | |
| 363 if (type.is_sfnt ()) | |
| 364 return type.get_resource_count (); | |
| 365 } | |
| 366 return 0; | |
| 367 } | |
| 368 | |
| 369 const OpenTypeFontFace& get_face (unsigned int idx, | |
| 370 const void *data_base) const | |
| 371 { | |
| 372 unsigned int count = get_type_count (); | |
| 373 for (unsigned int i = 0; i < count; i++) | |
| 374 { | |
| 375 const ResourceTypeRecord& type = get_type_record (i); | |
| 376 /* The check for idx < count is here because ResourceRecord is NOT null-safe. | |
| 377 * Because an offset of 0 there does NOT mean null. */ | |
| 378 if (type.is_sfnt () && idx < type.get_resource_count ()) | |
| 379 return type.get_resource_record (idx, &(this+typeList)).get_face (data_base); | |
| 380 } | |
| 381 return Null (OpenTypeFontFace); | |
| 382 } | |
| 383 | |
| 384 bool sanitize (hb_sanitize_context_t *c, const void *data_base) const | |
| 385 { | |
| 386 TRACE_SANITIZE (this); | |
| 387 return_trace (c->check_struct (this) && | |
| 388 typeList.sanitize (c, this, | |
| 389 &(this+typeList), | |
| 390 data_base)); | |
| 391 } | |
| 392 | |
| 393 private: | |
| 394 unsigned int get_type_count () const { return (this+typeList).lenM1 + 1; } | |
| 395 | |
| 396 const ResourceTypeRecord& get_type_record (unsigned int i) const | |
| 397 { return (this+typeList)[i]; } | |
| 398 | |
| 399 protected: | |
| 400 HBUINT8 reserved0[16]; /* Reserved for copy of resource header */ | |
| 401 HBUINT32 reserved1; /* Reserved for handle to next resource map */ | |
| 402 HBUINT16 resreved2; /* Reserved for file reference number */ | |
| 403 HBUINT16 attrs; /* Resource fork attribute */ | |
| 404 NNOffset16To<ArrayOfM1<ResourceTypeRecord>> | |
| 405 typeList; /* Offset from beginning of map to | |
| 406 * resource type list */ | |
| 407 Offset16 nameList; /* Offset from beginning of map to | |
| 408 * resource name list */ | |
| 409 public: | |
| 410 DEFINE_SIZE_STATIC (28); | |
| 411 }; | |
| 412 | |
| 413 struct ResourceForkHeader | |
| 414 { | |
| 415 unsigned int get_face_count () const | |
| 416 { return (this+map).get_face_count (); } | |
| 417 | |
| 418 const OpenTypeFontFace& get_face (unsigned int idx, | |
| 419 unsigned int *base_offset = nullptr) const | |
| 420 { | |
| 421 const OpenTypeFontFace &face = (this+map).get_face (idx, &(this+data)); | |
| 422 if (base_offset) | |
| 423 *base_offset = (const char *) &face - (const char *) this; | |
| 424 return face; | |
| 425 } | |
| 426 | |
| 427 bool sanitize (hb_sanitize_context_t *c) const | |
| 428 { | |
| 429 TRACE_SANITIZE (this); | |
| 430 return_trace (c->check_struct (this) && | |
| 431 data.sanitize (c, this, dataLen) && | |
| 432 map.sanitize (c, this, &(this+data))); | |
| 433 } | |
| 434 | |
| 435 protected: | |
| 436 NNOffset32To<UnsizedArrayOf<HBUINT8>> | |
| 437 data; /* Offset from beginning of resource fork | |
| 438 * to resource data */ | |
| 439 NNOffset32To<ResourceMap > | |
| 440 map; /* Offset from beginning of resource fork | |
| 441 * to resource map */ | |
| 442 HBUINT32 dataLen; /* Length of resource data */ | |
| 443 HBUINT32 mapLen; /* Length of resource map */ | |
| 444 public: | |
| 445 DEFINE_SIZE_STATIC (16); | |
| 446 }; | |
| 447 | |
| 448 /* | |
| 449 * OpenType Font File | |
| 450 */ | |
| 451 | |
| 452 struct OpenTypeFontFile | |
| 453 { | |
| 454 enum { | |
| 455 CFFTag = HB_TAG ('O','T','T','O'), /* OpenType with Postscript outlines */ | |
| 456 TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 ), /* OpenType with TrueType outlines */ | |
| 457 TTCTag = HB_TAG ('t','t','c','f'), /* TrueType Collection */ | |
| 458 DFontTag = HB_TAG ( 0 , 0 , 1 , 0 ), /* DFont Mac Resource Fork */ | |
| 459 TrueTag = HB_TAG ('t','r','u','e'), /* Obsolete Apple TrueType */ | |
| 460 Typ1Tag = HB_TAG ('t','y','p','1') /* Obsolete Apple Type1 font in SFNT container */ | |
| 461 }; | |
| 462 | |
| 463 hb_tag_t get_tag () const { return u.tag; } | |
| 464 | |
| 465 unsigned int get_face_count () const | |
| 466 { | |
| 467 switch (u.tag) { | |
| 468 case CFFTag: /* All the non-collection tags */ | |
| 469 case TrueTag: | |
| 470 case Typ1Tag: | |
| 471 case TrueTypeTag: return 1; | |
| 472 case TTCTag: return u.ttcHeader.get_face_count (); | |
| 473 case DFontTag: return u.rfHeader.get_face_count (); | |
| 474 default: return 0; | |
| 475 } | |
| 476 } | |
| 477 const OpenTypeFontFace& get_face (unsigned int i, unsigned int *base_offset = nullptr) const | |
| 478 { | |
| 479 if (base_offset) | |
| 480 *base_offset = 0; | |
| 481 switch (u.tag) { | |
| 482 /* Note: for non-collection SFNT data we ignore index. This is because | |
| 483 * Apple dfont container is a container of SFNT's. So each SFNT is a | |
| 484 * non-TTC, but the index is more than zero. */ | |
| 485 case CFFTag: /* All the non-collection tags */ | |
| 486 case TrueTag: | |
| 487 case Typ1Tag: | |
| 488 case TrueTypeTag: return u.fontFace; | |
| 489 case TTCTag: return u.ttcHeader.get_face (i); | |
| 490 case DFontTag: return u.rfHeader.get_face (i, base_offset); | |
| 491 default: return Null (OpenTypeFontFace); | |
| 492 } | |
| 493 } | |
| 494 | |
| 495 template <typename Iterator, | |
| 496 hb_requires ((hb_is_source_of<Iterator, hb_pair_t<hb_tag_t, hb_blob_t *>>::value))> | |
| 497 bool serialize_single (hb_serialize_context_t *c, | |
| 498 hb_tag_t sfnt_tag, | |
| 499 Iterator items) | |
| 500 { | |
| 501 TRACE_SERIALIZE (this); | |
| 502 assert (sfnt_tag != TTCTag); | |
| 503 if (unlikely (!c->extend_min (this))) return_trace (false); | |
| 504 return_trace (u.fontFace.serialize (c, sfnt_tag, items)); | |
| 505 } | |
| 506 | |
| 507 bool sanitize (hb_sanitize_context_t *c) const | |
| 508 { | |
| 509 TRACE_SANITIZE (this); | |
| 510 if (unlikely (!u.tag.sanitize (c))) return_trace (false); | |
| 511 switch (u.tag) { | |
| 512 case CFFTag: /* All the non-collection tags */ | |
| 513 case TrueTag: | |
| 514 case Typ1Tag: | |
| 515 case TrueTypeTag: return_trace (u.fontFace.sanitize (c)); | |
| 516 case TTCTag: return_trace (u.ttcHeader.sanitize (c)); | |
| 517 case DFontTag: return_trace (u.rfHeader.sanitize (c)); | |
| 518 default: return_trace (true); | |
| 519 } | |
| 520 } | |
| 521 | |
| 522 protected: | |
| 523 union { | |
| 524 Tag tag; /* 4-byte identifier. */ | |
| 525 OpenTypeFontFace fontFace; | |
| 526 TTCHeader ttcHeader; | |
| 527 ResourceForkHeader rfHeader; | |
| 528 } u; | |
| 529 public: | |
| 530 DEFINE_SIZE_UNION (4, tag); | |
| 531 }; | |
| 532 | |
| 533 | |
| 534 } /* namespace OT */ | |
| 535 | |
| 536 | |
| 537 #endif /* HB_OPEN_FILE_HH */ |
