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_PRIVATE_HH
30#define HB_OPEN_FILE_PRIVATE_HH
31
32#include "hb-open-type-private.hh"
33
34
35namespace OT {
36
37
38/*
39 *
40 * The OpenType Font File
41 *
42 */
43
44
45/*
46 * Organization of an OpenType Font
47 */
48
49struct OpenTypeFontFile;
50struct OffsetTable;
51struct TTCHeader;
52
53
54typedef struct TableRecord
55{
56 int cmp (Tag t) const
57 { return t.cmp (a: tag); }
58
59 inline bool sanitize (hb_sanitize_context_t *c) const
60 {
61 TRACE_SANITIZE (this);
62 return_trace (c->check_struct (this));
63 }
64
65 Tag tag; /* 4-byte identifier. */
66 CheckSum checkSum; /* CheckSum for this table. */
67 UINT32 offset; /* Offset from beginning of TrueType font
68 * file. */
69 UINT32 length; /* Length of this table. */
70 public:
71 DEFINE_SIZE_STATIC (16);
72} OpenTypeTable;
73
74typedef struct OffsetTable
75{
76 friend struct OpenTypeFontFile;
77
78 inline unsigned int get_table_count (void) const
79 { return tables.len; }
80 inline const TableRecord& get_table (unsigned int i) const
81 {
82 return tables[i];
83 }
84 inline unsigned int get_table_tags (unsigned int start_offset,
85 unsigned int *table_count, /* IN/OUT */
86 hb_tag_t *table_tags /* OUT */) const
87 {
88 if (table_count)
89 {
90 if (start_offset >= tables.len)
91 *table_count = 0;
92 else
93 *table_count = MIN<unsigned int> (a: *table_count, b: tables.len - start_offset);
94
95 const TableRecord *sub_tables = tables.array + start_offset;
96 unsigned int count = *table_count;
97 for (unsigned int i = 0; i < count; i++)
98 table_tags[i] = sub_tables[i].tag;
99 }
100 return tables.len;
101 }
102 inline bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
103 {
104 Tag t;
105 t.set (tag);
106 /* Linear-search for small tables to work around fonts with unsorted
107 * table list. */
108 int i = tables.len < 64 ? tables.lsearch (x: t) : tables.bsearch (x: t);
109 if (table_index)
110 *table_index = i == -1 ? Index::NOT_FOUND_INDEX : (unsigned int) i;
111 return i != -1;
112 }
113 inline const TableRecord& get_table_by_tag (hb_tag_t tag) const
114 {
115 unsigned int table_index;
116 find_table_index (tag, table_index: &table_index);
117 return get_table (i: table_index);
118 }
119
120 public:
121 inline bool sanitize (hb_sanitize_context_t *c) const
122 {
123 TRACE_SANITIZE (this);
124 return_trace (c->check_struct (this) && tables.sanitize (c));
125 }
126
127 protected:
128 Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */
129 BinSearchArrayOf<TableRecord>
130 tables;
131 public:
132 DEFINE_SIZE_ARRAY (12, tables);
133} OpenTypeFontFace;
134
135
136/*
137 * TrueType Collections
138 */
139
140struct TTCHeaderVersion1
141{
142 friend struct TTCHeader;
143
144 inline unsigned int get_face_count (void) const { return table.len; }
145 inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
146
147 inline bool sanitize (hb_sanitize_context_t *c) const
148 {
149 TRACE_SANITIZE (this);
150 return_trace (table.sanitize (c, this));
151 }
152
153 protected:
154 Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
155 FixedVersion<>version; /* Version of the TTC Header (1.0),
156 * 0x00010000u */
157 ArrayOf<LOffsetTo<OffsetTable>, UINT32>
158 table; /* Array of offsets to the OffsetTable for each font
159 * from the beginning of the file */
160 public:
161 DEFINE_SIZE_ARRAY (12, table);
162};
163
164struct TTCHeader
165{
166 friend struct OpenTypeFontFile;
167
168 private:
169
170 inline unsigned int get_face_count (void) const
171 {
172 switch (u.header.version.major) {
173 case 2: /* version 2 is compatible with version 1 */
174 case 1: return u.version1.get_face_count ();
175 default:return 0;
176 }
177 }
178 inline const OpenTypeFontFace& get_face (unsigned int i) const
179 {
180 switch (u.header.version.major) {
181 case 2: /* version 2 is compatible with version 1 */
182 case 1: return u.version1.get_face (i);
183 default:return Null(OpenTypeFontFace);
184 }
185 }
186
187 inline bool sanitize (hb_sanitize_context_t *c) const
188 {
189 TRACE_SANITIZE (this);
190 if (unlikely (!u.header.version.sanitize (c))) return_trace (false);
191 switch (u.header.version.major) {
192 case 2: /* version 2 is compatible with version 1 */
193 case 1: return_trace (u.version1.sanitize (c));
194 default:return_trace (true);
195 }
196 }
197
198 protected:
199 union {
200 struct {
201 Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
202 FixedVersion<>version; /* Version of the TTC Header (1.0 or 2.0),
203 * 0x00010000u or 0x00020000u */
204 } header;
205 TTCHeaderVersion1 version1;
206 } u;
207};
208
209
210/*
211 * OpenType Font File
212 */
213
214struct OpenTypeFontFile
215{
216 static const hb_tag_t tableTag = HB_TAG ('_','_','_','_'); /* Sanitizer needs this. */
217
218 static const hb_tag_t CFFTag = HB_TAG ('O','T','T','O'); /* OpenType with Postscript outlines */
219 static const hb_tag_t TrueTypeTag = HB_TAG ( 0 , 1 , 0 , 0 ); /* OpenType with TrueType outlines */
220 static const hb_tag_t TTCTag = HB_TAG ('t','t','c','f'); /* TrueType Collection */
221 static const hb_tag_t TrueTag = HB_TAG ('t','r','u','e'); /* Obsolete Apple TrueType */
222 static const hb_tag_t Typ1Tag = HB_TAG ('t','y','p','1'); /* Obsolete Apple Type1 font in SFNT container */
223
224 inline hb_tag_t get_tag (void) const { return u.tag; }
225
226 inline unsigned int get_face_count (void) const
227 {
228 switch (u.tag) {
229 case CFFTag: /* All the non-collection tags */
230 case TrueTag:
231 case Typ1Tag:
232 case TrueTypeTag: return 1;
233 case TTCTag: return u.ttcHeader.get_face_count ();
234 default: return 0;
235 }
236 }
237 inline const OpenTypeFontFace& get_face (unsigned int i) const
238 {
239 switch (u.tag) {
240 /* Note: for non-collection SFNT data we ignore index. This is because
241 * Apple dfont container is a container of SFNT's. So each SFNT is a
242 * non-TTC, but the index is more than zero. */
243 case CFFTag: /* All the non-collection tags */
244 case TrueTag:
245 case Typ1Tag:
246 case TrueTypeTag: return u.fontFace;
247 case TTCTag: return u.ttcHeader.get_face (i);
248 default: return Null(OpenTypeFontFace);
249 }
250 }
251
252 inline bool sanitize (hb_sanitize_context_t *c) const
253 {
254 TRACE_SANITIZE (this);
255 if (unlikely (!u.tag.sanitize (c))) return_trace (false);
256 switch (u.tag) {
257 case CFFTag: /* All the non-collection tags */
258 case TrueTag:
259 case Typ1Tag:
260 case TrueTypeTag: return_trace (u.fontFace.sanitize (c));
261 case TTCTag: return_trace (u.ttcHeader.sanitize (c));
262 default: return_trace (true);
263 }
264 }
265
266 protected:
267 union {
268 Tag tag; /* 4-byte identifier. */
269 OpenTypeFontFace fontFace;
270 TTCHeader ttcHeader;
271 } u;
272 public:
273 DEFINE_SIZE_UNION (4, tag);
274};
275
276
277} /* namespace OT */
278
279
280#endif /* HB_OPEN_FILE_PRIVATE_HH */
281

source code of qtbase/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh