blob: ac027520d02c7b656acbcd02758fd9ca54e29754 [file] [log] [blame]
Behdad Esfahbod2098a022009-08-02 19:57:00 -04001/*
Behdad Esfahbod2409d5f2011-04-21 17:14:28 -04002 * Copyright © 2007,2008,2009 Red Hat, Inc.
Behdad Esfahbod0ab8c862012-05-11 01:25:34 +02003 * Copyright © 2012 Google, Inc.
Behdad Esfahbod2098a022009-08-02 19:57:00 -04004 *
Behdad Esfahbodc755cb32010-04-22 00:11:43 -04005 * This is part of HarfBuzz, a text shaping library.
Behdad Esfahbod2098a022009-08-02 19:57:00 -04006 *
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
Behdad Esfahbod0ab8c862012-05-11 01:25:34 +020026 * Google Author(s): Behdad Esfahbod
Behdad Esfahbod2098a022009-08-02 19:57:00 -040027 */
28
Behdad Esfahbod5f5b24f2009-08-02 20:03:12 -040029#ifndef HB_OPEN_FILE_PRIVATE_HH
30#define HB_OPEN_FILE_PRIVATE_HH
Behdad Esfahbod2098a022009-08-02 19:57:00 -040031
Behdad Esfahbod7edb4302009-08-04 22:06:57 -040032#include "hb-open-type-private.hh"
Behdad Esfahboddc5c7922018-02-23 16:42:06 -080033#include "hb-ot-head-table.hh"
Behdad Esfahbod2098a022009-08-02 19:57:00 -040034
Behdad Esfahbodacdba3f2010-07-23 15:11:18 -040035
Behdad Esfahbod7c8e8442012-08-28 17:57:49 -040036namespace OT {
37
Behdad Esfahbod2098a022009-08-02 19:57:00 -040038
39/*
40 *
41 * The OpenType Font File
42 *
43 */
44
45
46/*
47 * Organization of an OpenType Font
48 */
49
50struct OpenTypeFontFile;
51struct OffsetTable;
52struct TTCHeader;
53
Behdad Esfahbod569da922010-05-10 16:38:32 -040054
Behdad Esfahbod22c53762010-12-14 23:51:29 -050055typedef struct TableRecord
Behdad Esfahbod2098a022009-08-02 19:57:00 -040056{
Behdad Esfahbod6c04dcb2017-10-31 20:11:00 -060057 int cmp (Tag t) const
Garret Rieger8e614ad2018-02-20 17:36:54 -080058 { return -t.cmp (tag); }
Behdad Esfahbod6c04dcb2017-10-31 20:11:00 -060059
Behdad Esfahbodc479a592018-02-07 21:13:10 -060060 static int cmp (const void *pa, const void *pb)
61 {
62 const TableRecord *a = (const TableRecord *) pa;
63 const TableRecord *b = (const TableRecord *) pb;
64 return b->cmp (a->tag);
65 }
66
Behdad Esfahbodde2118e2015-02-17 17:27:44 +030067 inline bool sanitize (hb_sanitize_context_t *c) const
68 {
Behdad Esfahbodbe218c62012-11-23 15:32:14 -050069 TRACE_SANITIZE (this);
Behdad Esfahbodb4715902015-09-29 14:57:02 +010070 return_trace (c->check_struct (this));
Behdad Esfahbodb508e5c2009-08-04 15:07:24 -040071 }
72
Behdad Esfahbod2098a022009-08-02 19:57:00 -040073 Tag tag; /* 4-byte identifier. */
74 CheckSum checkSum; /* CheckSum for this table. */
Behdad Esfahbodc479a592018-02-07 21:13:10 -060075 Offset32 offset; /* Offset from beginning of TrueType font
Behdad Esfahbod2098a022009-08-02 19:57:00 -040076 * file. */
Behdad Esfahbodc9acab32018-02-07 17:12:55 -060077 HBUINT32 length; /* Length of this table. */
Behdad Esfahbod569da922010-05-10 16:38:32 -040078 public:
79 DEFINE_SIZE_STATIC (16);
Behdad Esfahbod2098a022009-08-02 19:57:00 -040080} OpenTypeTable;
Behdad Esfahbod2098a022009-08-02 19:57:00 -040081
82typedef struct OffsetTable
83{
84 friend struct OpenTypeFontFile;
Behdad Esfahbod2098a022009-08-02 19:57:00 -040085
Behdad Esfahbodbff3c0f2009-08-07 19:46:30 -040086 inline unsigned int get_table_count (void) const
Behdad Esfahbodb0e33da2017-10-31 20:05:37 -060087 { return tables.len; }
Behdad Esfahbod22c53762010-12-14 23:51:29 -050088 inline const TableRecord& get_table (unsigned int i) const
Behdad Esfahbodbff3c0f2009-08-07 19:46:30 -040089 {
Behdad Esfahbod22c53762010-12-14 23:51:29 -050090 return tables[i];
Behdad Esfahbodbff3c0f2009-08-07 19:46:30 -040091 }
Behdad Esfahbodc9acab32018-02-07 17:12:55 -060092 inline unsigned int get_table_tags (unsigned int start_offset,
Behdad Esfahbod94b3caf2017-10-11 17:22:44 +020093 unsigned int *table_count, /* IN/OUT */
94 hb_tag_t *table_tags /* OUT */) const
95 {
96 if (table_count)
97 {
Behdad Esfahbodb0e33da2017-10-31 20:05:37 -060098 if (start_offset >= tables.len)
Behdad Esfahbod94b3caf2017-10-11 17:22:44 +020099 *table_count = 0;
100 else
ebraminio102f5ea2017-11-01 02:10:18 -0700101 *table_count = MIN<unsigned int> (*table_count, tables.len - start_offset);
Behdad Esfahbod94b3caf2017-10-11 17:22:44 +0200102
Behdad Esfahbodb0e33da2017-10-31 20:05:37 -0600103 const TableRecord *sub_tables = tables.array + start_offset;
Behdad Esfahbod94b3caf2017-10-11 17:22:44 +0200104 unsigned int count = *table_count;
105 for (unsigned int i = 0; i < count; i++)
106 table_tags[i] = sub_tables[i].tag;
107 }
Behdad Esfahbodb0e33da2017-10-31 20:05:37 -0600108 return tables.len;
Behdad Esfahbod94b3caf2017-10-11 17:22:44 +0200109 }
Behdad Esfahbodbff3c0f2009-08-07 19:46:30 -0400110 inline bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
111 {
Behdad Esfahbodffd321a2010-04-21 00:14:12 -0400112 Tag t;
113 t.set (tag);
Behdad Esfahbod6c04dcb2017-10-31 20:11:00 -0600114 /* Linear-search for small tables to work around fonts with unsorted
115 * table list. */
116 int i = tables.len < 64 ? tables.lsearch (t) : tables.bsearch (t);
117 if (table_index)
118 *table_index = i == -1 ? Index::NOT_FOUND_INDEX : (unsigned int) i;
119 return i != -1;
Behdad Esfahbodbff3c0f2009-08-07 19:46:30 -0400120 }
Behdad Esfahbod22c53762010-12-14 23:51:29 -0500121 inline const TableRecord& get_table_by_tag (hb_tag_t tag) const
Behdad Esfahbodbff3c0f2009-08-07 19:46:30 -0400122 {
123 unsigned int table_index;
124 find_table_index (tag, &table_index);
125 return get_table (table_index);
126 }
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400127
Behdad Esfahbodb508e5c2009-08-04 15:07:24 -0400128 public:
Behdad Esfahbodc479a592018-02-07 21:13:10 -0600129
130 inline bool serialize (hb_serialize_context_t *c,
131 hb_tag_t sfnt_tag,
132 Supplier<hb_tag_t> &tags,
133 Supplier<hb_blob_t *> &blobs,
134 unsigned int table_count)
135 {
136 TRACE_SERIALIZE (this);
Behdad Esfahbodec2538c2018-02-23 15:51:26 -0800137 /* Alloc 12 for the OTHeader. */
Behdad Esfahbodc479a592018-02-07 21:13:10 -0600138 if (unlikely (!c->extend_min (*this))) return_trace (false);
Behdad Esfahboddc5c7922018-02-23 16:42:06 -0800139 /* Write sfntVersion (bytes 0..3). */
Behdad Esfahbodc479a592018-02-07 21:13:10 -0600140 sfnt_version.set (sfnt_tag);
Behdad Esfahbodec2538c2018-02-23 15:51:26 -0800141 /* Take space for numTables, searchRange, entrySelector, RangeShift
Behdad Esfahboddc5c7922018-02-23 16:42:06 -0800142 * and the TableRecords themselves. */
Behdad Esfahbodc479a592018-02-07 21:13:10 -0600143 if (unlikely (!tables.serialize (c, table_count))) return_trace (false);
Behdad Esfahbod941bbd92018-02-07 21:49:01 -0600144
Behdad Esfahboddc5c7922018-02-23 16:42:06 -0800145 const char *dir_end = (const char *) c->head;
146 HBUINT32 *checksum_adjustment = nullptr;
147
Behdad Esfahbodec2538c2018-02-23 15:51:26 -0800148 /* Write OffsetTables, alloc for and write actual table blobs. */
Behdad Esfahbodc479a592018-02-07 21:13:10 -0600149 for (unsigned int i = 0; i < table_count; i++)
150 {
151 TableRecord &rec = tables.array[i];
152 hb_blob_t *blob = blobs[i];
Behdad Esfahbod941bbd92018-02-07 21:49:01 -0600153 rec.tag.set (tags[i]);
Behdad Esfahbodc479a592018-02-07 21:13:10 -0600154 rec.length.set (hb_blob_get_length (blob));
Behdad Esfahbodc479a592018-02-07 21:13:10 -0600155 rec.offset.serialize (c, this);
Behdad Esfahboddc5c7922018-02-23 16:42:06 -0800156
157 /* Allocate room for the table and copy it. */
158 char *start = (char *) c->allocate_size<void> (rec.length);
159 if (unlikely (!start)) {return false;}
160
161 memcpy (start, hb_blob_get_data (blob, nullptr), rec.length);
162
Behdad Esfahbodec2538c2018-02-23 15:51:26 -0800163 /* 4-byte allignment. */
Behdad Esfahbodc479a592018-02-07 21:13:10 -0600164 if (rec.length % 4)
Behdad Esfahboddc5c7922018-02-23 16:42:06 -0800165 c->allocate_size<void> (4 - rec.length % 4);
Behdad Esfahbodec2538c2018-02-23 15:51:26 -0800166 const char *end = (const char *) c->head;
Behdad Esfahboddc5c7922018-02-23 16:42:06 -0800167
168 if (tags[i] == HB_OT_TAG_head && end - start >= head::static_size)
169 {
170 head *h = (head *) start;
171 checksum_adjustment = &h->checkSumAdjustment;
172 checksum_adjustment->set (0);
173 }
174
Behdad Esfahbodec2538c2018-02-23 15:51:26 -0800175 rec.checkSum.set_for_data (start, end - start);
Behdad Esfahbodc479a592018-02-07 21:13:10 -0600176 }
Behdad Esfahbod71130a22018-02-10 13:15:57 -0600177 tags += table_count;
178 blobs += table_count;
Behdad Esfahbod941bbd92018-02-07 21:49:01 -0600179
Behdad Esfahbodc479a592018-02-07 21:13:10 -0600180 tables.qsort ();
Behdad Esfahboddc5c7922018-02-23 16:42:06 -0800181
182 if (checksum_adjustment)
183 {
184 CheckSum checksum;
185
186 /* The following line is a slower version of the following block. */
187 //checksum.set_for_data (this, (const char *) c->head - (const char *) this);
188 checksum.set_for_data (this, dir_end - (const char *) this);
189 for (unsigned int i = 0; i < table_count; i++)
190 {
191 TableRecord &rec = tables.array[i];
192 checksum.set (checksum + rec.checkSum);
193 }
194
195 checksum_adjustment->set (0xB1B0AFBAu - checksum);
196 }
197
Behdad Esfahbodc479a592018-02-07 21:13:10 -0600198 return_trace (true);
199 }
200
Behdad Esfahbodde2118e2015-02-17 17:27:44 +0300201 inline bool sanitize (hb_sanitize_context_t *c) const
202 {
Behdad Esfahbodbe218c62012-11-23 15:32:14 -0500203 TRACE_SANITIZE (this);
Behdad Esfahbodb0e33da2017-10-31 20:05:37 -0600204 return_trace (c->check_struct (this) && tables.sanitize (c));
Behdad Esfahbodb508e5c2009-08-04 15:07:24 -0400205 }
206
Behdad Esfahbodec8d2492012-07-24 15:40:37 -0400207 protected:
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400208 Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */
Behdad Esfahbodb0e33da2017-10-31 20:05:37 -0600209 BinSearchArrayOf<TableRecord>
210 tables;
Behdad Esfahbod569da922010-05-10 16:38:32 -0400211 public:
Behdad Esfahbod22c53762010-12-14 23:51:29 -0500212 DEFINE_SIZE_ARRAY (12, tables);
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400213} OpenTypeFontFace;
Behdad Esfahbod569da922010-05-10 16:38:32 -0400214
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400215
216/*
217 * TrueType Collections
218 */
219
Behdad Esfahbodae4190c2010-04-23 12:33:02 -0400220struct TTCHeaderVersion1
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400221{
Behdad Esfahbodae4190c2010-04-23 12:33:02 -0400222 friend struct TTCHeader;
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400223
Behdad Esfahbod20b035d2009-08-10 19:00:36 -0400224 inline unsigned int get_face_count (void) const { return table.len; }
Behdad Esfahboddf3f5052010-04-22 14:11:33 -0400225 inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
Behdad Esfahbodb508e5c2009-08-04 15:07:24 -0400226
Behdad Esfahbodde2118e2015-02-17 17:27:44 +0300227 inline bool sanitize (hb_sanitize_context_t *c) const
228 {
Behdad Esfahbodbe218c62012-11-23 15:32:14 -0500229 TRACE_SANITIZE (this);
Behdad Esfahbodb4715902015-09-29 14:57:02 +0100230 return_trace (table.sanitize (c, this));
Behdad Esfahbodb508e5c2009-08-04 15:07:24 -0400231 }
232
Behdad Esfahbodec8d2492012-07-24 15:40:37 -0400233 protected:
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400234 Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
Behdad Esfahbod9a13ed42016-02-22 11:44:45 +0900235 FixedVersion<>version; /* Version of the TTC Header (1.0),
Behdad Esfahbod76271002014-07-11 14:54:42 -0400236 * 0x00010000u */
Behdad Esfahbod6b191782018-01-10 03:07:30 +0100237 ArrayOf<LOffsetTo<OffsetTable>, HBUINT32>
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400238 table; /* Array of offsets to the OffsetTable for each font
239 * from the beginning of the file */
Behdad Esfahbodb3651232010-05-10 16:57:29 -0400240 public:
Behdad Esfahbod0eb9fc62010-05-10 19:01:17 -0400241 DEFINE_SIZE_ARRAY (12, table);
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400242};
Behdad Esfahbodae4190c2010-04-23 12:33:02 -0400243
244struct TTCHeader
245{
246 friend struct OpenTypeFontFile;
247
248 private:
249
250 inline unsigned int get_face_count (void) const
251 {
Behdad Esfahbod4f28fbd2011-05-31 12:33:11 -0400252 switch (u.header.version.major) {
Behdad Esfahbodae4190c2010-04-23 12:33:02 -0400253 case 2: /* version 2 is compatible with version 1 */
Behdad Esfahboddacebca2010-05-10 19:45:41 -0400254 case 1: return u.version1.get_face_count ();
Behdad Esfahbodae4190c2010-04-23 12:33:02 -0400255 default:return 0;
256 }
257 }
258 inline const OpenTypeFontFace& get_face (unsigned int i) const
259 {
Behdad Esfahbod4f28fbd2011-05-31 12:33:11 -0400260 switch (u.header.version.major) {
Behdad Esfahbodae4190c2010-04-23 12:33:02 -0400261 case 2: /* version 2 is compatible with version 1 */
Behdad Esfahboddacebca2010-05-10 19:45:41 -0400262 case 1: return u.version1.get_face (i);
Behdad Esfahbod1aa46662010-04-23 13:32:03 -0400263 default:return Null(OpenTypeFontFace);
Behdad Esfahbodae4190c2010-04-23 12:33:02 -0400264 }
265 }
266
Behdad Esfahbodde2118e2015-02-17 17:27:44 +0300267 inline bool sanitize (hb_sanitize_context_t *c) const
268 {
Behdad Esfahbodbe218c62012-11-23 15:32:14 -0500269 TRACE_SANITIZE (this);
Behdad Esfahbodb4715902015-09-29 14:57:02 +0100270 if (unlikely (!u.header.version.sanitize (c))) return_trace (false);
Behdad Esfahbod4f28fbd2011-05-31 12:33:11 -0400271 switch (u.header.version.major) {
Behdad Esfahbodae4190c2010-04-23 12:33:02 -0400272 case 2: /* version 2 is compatible with version 1 */
Behdad Esfahbodb4715902015-09-29 14:57:02 +0100273 case 1: return_trace (u.version1.sanitize (c));
274 default:return_trace (true);
Behdad Esfahbodae4190c2010-04-23 12:33:02 -0400275 }
276 }
277
Behdad Esfahbodec8d2492012-07-24 15:40:37 -0400278 protected:
Behdad Esfahbodae4190c2010-04-23 12:33:02 -0400279 union {
280 struct {
281 Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
Behdad Esfahbod9a13ed42016-02-22 11:44:45 +0900282 FixedVersion<>version; /* Version of the TTC Header (1.0 or 2.0),
Behdad Esfahbod76271002014-07-11 14:54:42 -0400283 * 0x00010000u or 0x00020000u */
Behdad Esfahbodae4190c2010-04-23 12:33:02 -0400284 } header;
Behdad Esfahboddacebca2010-05-10 19:45:41 -0400285 TTCHeaderVersion1 version1;
Behdad Esfahbodae4190c2010-04-23 12:33:02 -0400286 } u;
287};
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400288
289
290/*
291 * OpenType Font File
292 */
293
294struct OpenTypeFontFile
295{
Behdad Esfahbod153beeb2014-12-12 19:46:09 -0800296 static const hb_tag_t tableTag = HB_TAG ('_','_','_','_'); /* Sanitizer needs this. */
297
Ebrahim Byagowi2a236062018-03-23 18:37:01 +0430298 enum {
299 CFFTag = HB_TAG ('O','T','T','O'), /* OpenType with Postscript outlines */
300 TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 ), /* OpenType with TrueType outlines */
301 TTCTag = HB_TAG ('t','t','c','f'), /* TrueType Collection */
302 TrueTag = HB_TAG ('t','r','u','e'), /* Obsolete Apple TrueType */
303 Typ1Tag = HB_TAG ('t','y','p','1') /* Obsolete Apple Type1 font in SFNT container */
304 };
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400305
Behdad Esfahbod1aa46662010-04-23 13:32:03 -0400306 inline hb_tag_t get_tag (void) const { return u.tag; }
307
Behdad Esfahbod20b035d2009-08-10 19:00:36 -0400308 inline unsigned int get_face_count (void) const
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400309 {
Behdad Esfahbod1aa46662010-04-23 13:32:03 -0400310 switch (u.tag) {
311 case CFFTag: /* All the non-collection tags */
Jeff Muizelaar4ce578e2010-05-03 15:03:53 -0400312 case TrueTag:
313 case Typ1Tag:
Behdad Esfahbod1aa46662010-04-23 13:32:03 -0400314 case TrueTypeTag: return 1;
Behdad Esfahboddacebca2010-05-10 19:45:41 -0400315 case TTCTag: return u.ttcHeader.get_face_count ();
Behdad Esfahbod1aa46662010-04-23 13:32:03 -0400316 default: return 0;
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400317 }
318 }
Behdad Esfahbod20b035d2009-08-10 19:00:36 -0400319 inline const OpenTypeFontFace& get_face (unsigned int i) const
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400320 {
Behdad Esfahbod1aa46662010-04-23 13:32:03 -0400321 switch (u.tag) {
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400322 /* Note: for non-collection SFNT data we ignore index. This is because
323 * Apple dfont container is a container of SFNT's. So each SFNT is a
324 * non-TTC, but the index is more than zero. */
Behdad Esfahbod1aa46662010-04-23 13:32:03 -0400325 case CFFTag: /* All the non-collection tags */
Jeff Muizelaar4ce578e2010-05-03 15:03:53 -0400326 case TrueTag:
327 case Typ1Tag:
Behdad Esfahboddacebca2010-05-10 19:45:41 -0400328 case TrueTypeTag: return u.fontFace;
329 case TTCTag: return u.ttcHeader.get_face (i);
Behdad Esfahbod1aa46662010-04-23 13:32:03 -0400330 default: return Null(OpenTypeFontFace);
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400331 }
332 }
333
Behdad Esfahbodc479a592018-02-07 21:13:10 -0600334 inline bool serialize_single (hb_serialize_context_t *c,
335 hb_tag_t sfnt_tag,
336 Supplier<hb_tag_t> &tags,
337 Supplier<hb_blob_t *> &blobs,
338 unsigned int table_count)
339 {
340 TRACE_SERIALIZE (this);
341 assert (sfnt_tag != TTCTag);
342 if (unlikely (!c->extend_min (*this))) return_trace (false);
343 return_trace (u.fontFace.serialize (c, sfnt_tag, tags, blobs, table_count));
344 }
345
Behdad Esfahbodde2118e2015-02-17 17:27:44 +0300346 inline bool sanitize (hb_sanitize_context_t *c) const
347 {
Behdad Esfahbodbe218c62012-11-23 15:32:14 -0500348 TRACE_SANITIZE (this);
Behdad Esfahbodb4715902015-09-29 14:57:02 +0100349 if (unlikely (!u.tag.sanitize (c))) return_trace (false);
Behdad Esfahbod1aa46662010-04-23 13:32:03 -0400350 switch (u.tag) {
351 case CFFTag: /* All the non-collection tags */
Jeff Muizelaar4ce578e2010-05-03 15:03:53 -0400352 case TrueTag:
353 case Typ1Tag:
Behdad Esfahbodb4715902015-09-29 14:57:02 +0100354 case TrueTypeTag: return_trace (u.fontFace.sanitize (c));
355 case TTCTag: return_trace (u.ttcHeader.sanitize (c));
356 default: return_trace (true);
Behdad Esfahbodb508e5c2009-08-04 15:07:24 -0400357 }
358 }
359
Behdad Esfahbodec8d2492012-07-24 15:40:37 -0400360 protected:
Behdad Esfahbod1aa46662010-04-23 13:32:03 -0400361 union {
362 Tag tag; /* 4-byte identifier. */
Behdad Esfahboddacebca2010-05-10 19:45:41 -0400363 OpenTypeFontFace fontFace;
364 TTCHeader ttcHeader;
Behdad Esfahbod1aa46662010-04-23 13:32:03 -0400365 } u;
Behdad Esfahboddacebca2010-05-10 19:45:41 -0400366 public:
367 DEFINE_SIZE_UNION (4, tag);
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400368};
Behdad Esfahbod2098a022009-08-02 19:57:00 -0400369
370
Behdad Esfahbod7d52e662012-11-16 18:49:54 -0800371} /* namespace OT */
Behdad Esfahbod7c8e8442012-08-28 17:57:49 -0400372
Behdad Esfahbodacdba3f2010-07-23 15:11:18 -0400373
Behdad Esfahbod5f5b24f2009-08-02 20:03:12 -0400374#endif /* HB_OPEN_FILE_PRIVATE_HH */