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