Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(602)

Side by Side Diff: src/gdef.cc

Issue 658573004: Updating to new OTS repo from https://github.com/khaledhosny/ots.git (Closed) Base URL: https://chromium.googlesource.com/external/ots@master
Patch Set: Adding Colored Emoji changes from external/git repo Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« .gitmodules ('K') | « src/gasp.cc ('k') | src/glyf.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gdef.h" 5 #include "gdef.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <vector> 8 #include <vector>
9 9
10 #include "gpos.h" 10 #include "gpos.h"
11 #include "gsub.h" 11 #include "gsub.h"
12 #include "layout.h" 12 #include "layout.h"
13 #include "maxp.h" 13 #include "maxp.h"
14 14
15 // GDEF - The Glyph Definition Table 15 // GDEF - The Glyph Definition Table
16 // http://www.microsoft.com/typography/otspec/gdef.htm 16 // http://www.microsoft.com/typography/otspec/gdef.htm
17 17
18 #define TABLE_NAME "GDEF"
19
18 namespace { 20 namespace {
19 21
20 // The maximum class value in class definition tables. 22 // The maximum class value in class definition tables.
21 const uint16_t kMaxClassDefValue = 0xFFFF; 23 const uint16_t kMaxClassDefValue = 0xFFFF;
22 // The maximum class value in the glyph class definision table. 24 // The maximum class value in the glyph class definision table.
23 const uint16_t kMaxGlyphClassDefValue = 4; 25 const uint16_t kMaxGlyphClassDefValue = 4;
24 // The maximum format number of caret value tables. 26 // The maximum format number of caret value tables.
25 // We don't support format 3 for now. See the comment in 27 // We don't support format 3 for now. See the comment in
26 // ParseLigCaretListTable() for the reason. 28 // ParseLigCaretListTable() for the reason.
27 const uint16_t kMaxCaretValueFormat = 2; 29 const uint16_t kMaxCaretValueFormat = 2;
28 30
29 bool ParseGlyphClassDefTable(ots::OpenTypeFile *file, const uint8_t *data, 31 bool ParseGlyphClassDefTable(ots::OpenTypeFile *file, const uint8_t *data,
30 size_t length, const uint16_t num_glyphs) { 32 size_t length, const uint16_t num_glyphs) {
31 return ots::ParseClassDefTable(data, length, num_glyphs, 33 return ots::ParseClassDefTable(file, data, length, num_glyphs,
32 kMaxGlyphClassDefValue); 34 kMaxGlyphClassDefValue);
33 } 35 }
34 36
35 bool ParseAttachListTable(ots::OpenTypeFile *file, const uint8_t *data, 37 bool ParseAttachListTable(ots::OpenTypeFile *file, const uint8_t *data,
36 size_t length, const uint16_t num_glyphs) { 38 size_t length, const uint16_t num_glyphs) {
37 ots::Buffer subtable(data, length); 39 ots::Buffer subtable(data, length);
38 40
39 uint16_t offset_coverage = 0; 41 uint16_t offset_coverage = 0;
40 uint16_t glyph_count = 0; 42 uint16_t glyph_count = 0;
41 if (!subtable.ReadU16(&offset_coverage) || 43 if (!subtable.ReadU16(&offset_coverage) ||
42 !subtable.ReadU16(&glyph_count)) { 44 !subtable.ReadU16(&glyph_count)) {
43 return OTS_FAILURE(); 45 return OTS_FAILURE_MSG("Failed to read gdef header");
44 } 46 }
45 const unsigned attach_points_end = 47 const unsigned attach_points_end =
46 2 * static_cast<unsigned>(glyph_count) + 4; 48 2 * static_cast<unsigned>(glyph_count) + 4;
47 if (attach_points_end > std::numeric_limits<uint16_t>::max()) { 49 if (attach_points_end > std::numeric_limits<uint16_t>::max()) {
48 return OTS_FAILURE(); 50 return OTS_FAILURE_MSG("Bad glyph count in gdef");
49 } 51 }
50 if (offset_coverage == 0 || offset_coverage >= length || 52 if (offset_coverage == 0 || offset_coverage >= length ||
51 offset_coverage < attach_points_end) { 53 offset_coverage < attach_points_end) {
52 return OTS_FAILURE(); 54 return OTS_FAILURE_MSG("Bad coverage offset %d", offset_coverage);
53 } 55 }
54 if (glyph_count > num_glyphs) { 56 if (glyph_count > num_glyphs) {
55 OTS_WARNING("bad glyph count: %u", glyph_count); 57 return OTS_FAILURE_MSG("Bad glyph count %u", glyph_count);
56 return OTS_FAILURE();
57 } 58 }
58 59
59 std::vector<uint16_t> attach_points; 60 std::vector<uint16_t> attach_points;
60 attach_points.resize(glyph_count); 61 attach_points.resize(glyph_count);
61 for (unsigned i = 0; i < glyph_count; ++i) { 62 for (unsigned i = 0; i < glyph_count; ++i) {
62 if (!subtable.ReadU16(&attach_points[i])) { 63 if (!subtable.ReadU16(&attach_points[i])) {
63 return OTS_FAILURE(); 64 return OTS_FAILURE_MSG("Can't read attachment point %d", i);
64 } 65 }
65 if (attach_points[i] >= length || 66 if (attach_points[i] >= length ||
66 attach_points[i] < attach_points_end) { 67 attach_points[i] < attach_points_end) {
67 return OTS_FAILURE(); 68 return OTS_FAILURE_MSG("Bad attachment point %d of %d", i, attach_points[i ]);
68 } 69 }
69 } 70 }
70 71
71 // Parse coverage table 72 // Parse coverage table
72 if (!ots::ParseCoverageTable(data + offset_coverage, 73 if (!ots::ParseCoverageTable(file, data + offset_coverage,
73 length - offset_coverage, num_glyphs)) { 74 length - offset_coverage, num_glyphs)) {
74 return OTS_FAILURE(); 75 return OTS_FAILURE_MSG("Bad coverage table");
75 } 76 }
76 77
77 // Parse attach point table 78 // Parse attach point table
78 for (unsigned i = 0; i < attach_points.size(); ++i) { 79 for (unsigned i = 0; i < attach_points.size(); ++i) {
79 subtable.set_offset(attach_points[i]); 80 subtable.set_offset(attach_points[i]);
80 uint16_t point_count = 0; 81 uint16_t point_count = 0;
81 if (!subtable.ReadU16(&point_count)) { 82 if (!subtable.ReadU16(&point_count)) {
82 return OTS_FAILURE(); 83 return OTS_FAILURE_MSG("Can't read point count %d", i);
83 } 84 }
84 if (point_count == 0) { 85 if (point_count == 0) {
85 return OTS_FAILURE(); 86 return OTS_FAILURE_MSG("zero point count %d", i);
86 } 87 }
87 uint16_t last_point_index = 0; 88 uint16_t last_point_index = 0;
88 uint16_t point_index = 0; 89 uint16_t point_index = 0;
89 for (unsigned j = 0; j < point_count; ++j) { 90 for (unsigned j = 0; j < point_count; ++j) {
90 if (!subtable.ReadU16(&point_index)) { 91 if (!subtable.ReadU16(&point_index)) {
91 return OTS_FAILURE(); 92 return OTS_FAILURE_MSG("Can't read point index %d in point %d", j, i);
92 } 93 }
93 // Contour point indeces are in increasing numerical order 94 // Contour point indeces are in increasing numerical order
94 if (last_point_index != 0 && last_point_index >= point_index) { 95 if (last_point_index != 0 && last_point_index >= point_index) {
95 OTS_WARNING("bad contour indeces: %u >= %u", 96 return OTS_FAILURE_MSG("bad contour indeces: %u >= %u",
96 last_point_index, point_index); 97 last_point_index, point_index);
97 return OTS_FAILURE();
98 } 98 }
99 last_point_index = point_index; 99 last_point_index = point_index;
100 } 100 }
101 } 101 }
102 return true; 102 return true;
103 } 103 }
104 104
105 bool ParseLigCaretListTable(ots::OpenTypeFile *file, const uint8_t *data, 105 bool ParseLigCaretListTable(ots::OpenTypeFile *file, const uint8_t *data,
106 size_t length, const uint16_t num_glyphs) { 106 size_t length, const uint16_t num_glyphs) {
107 ots::Buffer subtable(data, length); 107 ots::Buffer subtable(data, length);
108 uint16_t offset_coverage = 0; 108 uint16_t offset_coverage = 0;
109 uint16_t lig_glyph_count = 0; 109 uint16_t lig_glyph_count = 0;
110 if (!subtable.ReadU16(&offset_coverage) || 110 if (!subtable.ReadU16(&offset_coverage) ||
111 !subtable.ReadU16(&lig_glyph_count)) { 111 !subtable.ReadU16(&lig_glyph_count)) {
112 return OTS_FAILURE(); 112 return OTS_FAILURE_MSG("Can't read caret structure");
113 } 113 }
114 const unsigned lig_glyphs_end = 114 const unsigned lig_glyphs_end =
115 2 * static_cast<unsigned>(lig_glyph_count) + 4; 115 2 * static_cast<unsigned>(lig_glyph_count) + 4;
116 if (lig_glyphs_end > std::numeric_limits<uint16_t>::max()) { 116 if (lig_glyphs_end > std::numeric_limits<uint16_t>::max()) {
117 return OTS_FAILURE(); 117 return OTS_FAILURE_MSG("Bad caret structure");
118 } 118 }
119 if (offset_coverage == 0 || offset_coverage >= length || 119 if (offset_coverage == 0 || offset_coverage >= length ||
120 offset_coverage < lig_glyphs_end) { 120 offset_coverage < lig_glyphs_end) {
121 return OTS_FAILURE(); 121 return OTS_FAILURE_MSG("Bad caret coverate offset %d", offset_coverage);
122 } 122 }
123 if (lig_glyph_count > num_glyphs) { 123 if (lig_glyph_count > num_glyphs) {
124 OTS_WARNING("bad ligature glyph count: %u", lig_glyph_count); 124 return OTS_FAILURE_MSG("bad ligature glyph count: %u", lig_glyph_count);
125 return OTS_FAILURE();
126 } 125 }
127 126
128 std::vector<uint16_t> lig_glyphs; 127 std::vector<uint16_t> lig_glyphs;
129 lig_glyphs.resize(lig_glyph_count); 128 lig_glyphs.resize(lig_glyph_count);
130 for (unsigned i = 0; i < lig_glyph_count; ++i) { 129 for (unsigned i = 0; i < lig_glyph_count; ++i) {
131 if (!subtable.ReadU16(&lig_glyphs[i])) { 130 if (!subtable.ReadU16(&lig_glyphs[i])) {
132 return OTS_FAILURE(); 131 return OTS_FAILURE_MSG("Can't read ligature glyph location %d", i);
133 } 132 }
134 if (lig_glyphs[i] >= length || lig_glyphs[i] < lig_glyphs_end) { 133 if (lig_glyphs[i] >= length || lig_glyphs[i] < lig_glyphs_end) {
135 return OTS_FAILURE(); 134 return OTS_FAILURE_MSG("Bad ligature glyph location %d in glyph %d", lig_g lyphs[i], i);
136 } 135 }
137 } 136 }
138 137
139 // Parse coverage table 138 // Parse coverage table
140 if (!ots::ParseCoverageTable(data + offset_coverage, 139 if (!ots::ParseCoverageTable(file, data + offset_coverage,
141 length - offset_coverage, num_glyphs)) { 140 length - offset_coverage, num_glyphs)) {
142 return OTS_FAILURE(); 141 return OTS_FAILURE_MSG("Can't parse caret coverage table");
143 } 142 }
144 143
145 // Parse ligature glyph table 144 // Parse ligature glyph table
146 for (unsigned i = 0; i < lig_glyphs.size(); ++i) { 145 for (unsigned i = 0; i < lig_glyphs.size(); ++i) {
147 subtable.set_offset(lig_glyphs[i]); 146 subtable.set_offset(lig_glyphs[i]);
148 uint16_t caret_count = 0; 147 uint16_t caret_count = 0;
149 if (!subtable.ReadU16(&caret_count)) { 148 if (!subtable.ReadU16(&caret_count)) {
150 return OTS_FAILURE(); 149 return OTS_FAILURE_MSG("Can't read caret count for glyph %d", i);
151 } 150 }
152 if (caret_count == 0) { 151 if (caret_count == 0) {
153 OTS_WARNING("bad caret value count: %u", caret_count); 152 return OTS_FAILURE_MSG("bad caret value count: %u", caret_count);
154 return OTS_FAILURE();
155 } 153 }
156 154
157 std::vector<uint16_t> caret_values; 155 std::vector<uint16_t> caret_value_offsets;
158 caret_values.resize(caret_count); 156 caret_value_offsets.resize(caret_count);
159 uint16_t last_offset_caret = 0; 157 unsigned caret_value_offsets_end = 2 * static_cast<unsigned>(caret_count) + 2;
160 unsigned caret_values_end = 2 * static_cast<unsigned>(caret_count) + 2;
161 for (unsigned j = 0; j < caret_count; ++j) { 158 for (unsigned j = 0; j < caret_count; ++j) {
162 if (!subtable.ReadU16(&caret_values[j])) { 159 if (!subtable.ReadU16(&caret_value_offsets[j])) {
163 return OTS_FAILURE(); 160 return OTS_FAILURE_MSG("Can't read caret offset %d for glyph %d", j, i);
164 } 161 }
165 if (caret_values[j] >= length || caret_values[j] < caret_values_end) { 162 if (caret_value_offsets[j] >= length || caret_value_offsets[j] < caret_val ue_offsets_end) {
166 return OTS_FAILURE(); 163 return OTS_FAILURE_MSG("Bad caret offset %d for caret %d glyph %d", care t_value_offsets[j], j, i);
167 } 164 }
168 // Caret offsets are in increasing coordinate order
169 if (last_offset_caret != 0 && last_offset_caret >= caret_values[j]) {
170 OTS_WARNING("offset isn't in increasing coordinate order: %u >= %u",
171 last_offset_caret, caret_values[j]);
172 return OTS_FAILURE();
173 }
174 last_offset_caret = caret_values[j];
175 } 165 }
176 166
177 // Parse caret values table 167 // Parse caret values table
178 for (unsigned j = 0; j < caret_count; ++j) { 168 for (unsigned j = 0; j < caret_count; ++j) {
179 subtable.set_offset(lig_glyphs[i] + caret_values[j]); 169 subtable.set_offset(lig_glyphs[i] + caret_value_offsets[j]);
180 uint16_t caret_format = 0; 170 uint16_t caret_format = 0;
181 if (!subtable.ReadU16(&caret_format)) { 171 if (!subtable.ReadU16(&caret_format)) {
182 return OTS_FAILURE(); 172 return OTS_FAILURE_MSG("Can't read caret values table %d in glyph %d", j , i);
183 } 173 }
184 // TODO(bashi): We only support caret value format 1 and 2 for now 174 // TODO(bashi): We only support caret value format 1 and 2 for now
185 // because there are no fonts which contain caret value format 3 175 // because there are no fonts which contain caret value format 3
186 // as far as we investigated. 176 // as far as we investigated.
187 if (caret_format == 0 || caret_format > kMaxCaretValueFormat) { 177 if (caret_format == 0 || caret_format > kMaxCaretValueFormat) {
188 OTS_WARNING("bad caret value format: %u", caret_format); 178 return OTS_FAILURE_MSG("bad caret value format: %u", caret_format);
189 return OTS_FAILURE();
190 } 179 }
191 // CaretValueFormats contain a 2-byte field which could be 180 // CaretValueFormats contain a 2-byte field which could be
192 // arbitrary value. 181 // arbitrary value.
193 if (!subtable.Skip(2)) { 182 if (!subtable.Skip(2)) {
194 return OTS_FAILURE(); 183 return OTS_FAILURE_MSG("Bad caret value table structure %d in glyph %d", j, i);
195 } 184 }
196 } 185 }
197 } 186 }
198 return true; 187 return true;
199 } 188 }
200 189
201 bool ParseMarkAttachClassDefTable(ots::OpenTypeFile *file, const uint8_t *data, 190 bool ParseMarkAttachClassDefTable(ots::OpenTypeFile *file, const uint8_t *data,
202 size_t length, const uint16_t num_glyphs) { 191 size_t length, const uint16_t num_glyphs) {
203 return ots::ParseClassDefTable(data, length, num_glyphs, kMaxClassDefValue); 192 return ots::ParseClassDefTable(file, data, length, num_glyphs, kMaxClassDefVal ue);
204 } 193 }
205 194
206 bool ParseMarkGlyphSetsDefTable(ots::OpenTypeFile *file, const uint8_t *data, 195 bool ParseMarkGlyphSetsDefTable(ots::OpenTypeFile *file, const uint8_t *data,
207 size_t length, const uint16_t num_glyphs) { 196 size_t length, const uint16_t num_glyphs) {
208 ots::Buffer subtable(data, length); 197 ots::Buffer subtable(data, length);
209 uint16_t format = 0; 198 uint16_t format = 0;
210 uint16_t mark_set_count = 0; 199 uint16_t mark_set_count = 0;
211 if (!subtable.ReadU16(&format) || 200 if (!subtable.ReadU16(&format) ||
212 !subtable.ReadU16(&mark_set_count)) { 201 !subtable.ReadU16(&mark_set_count)) {
213 return OTS_FAILURE(); 202 return OTS_FAILURE_MSG("Can' read mark glyph table structure");
214 } 203 }
215 if (format != 1) { 204 if (format != 1) {
216 OTS_WARNING("bad mark glyph set table format: %u", format); 205 return OTS_FAILURE_MSG("bad mark glyph set table format: %u", format);
217 return OTS_FAILURE();
218 } 206 }
219 207
220 const unsigned mark_sets_end = 2 * static_cast<unsigned>(mark_set_count) + 4; 208 const unsigned mark_sets_end = 2 * static_cast<unsigned>(mark_set_count) + 4;
221 if (mark_sets_end > std::numeric_limits<uint16_t>::max()) { 209 if (mark_sets_end > std::numeric_limits<uint16_t>::max()) {
222 return OTS_FAILURE(); 210 return OTS_FAILURE_MSG("Bad mark_set %d", mark_sets_end);
223 } 211 }
224 for (unsigned i = 0; i < mark_set_count; ++i) { 212 for (unsigned i = 0; i < mark_set_count; ++i) {
225 uint32_t offset_coverage = 0; 213 uint32_t offset_coverage = 0;
226 if (!subtable.ReadU32(&offset_coverage)) { 214 if (!subtable.ReadU32(&offset_coverage)) {
227 return OTS_FAILURE(); 215 return OTS_FAILURE_MSG("Can't read covrage location for mark set %d", i);
228 } 216 }
229 if (offset_coverage >= length || 217 if (offset_coverage >= length ||
230 offset_coverage < mark_sets_end) { 218 offset_coverage < mark_sets_end) {
231 return OTS_FAILURE(); 219 return OTS_FAILURE_MSG("Bad coverage location %d for mark set %d", offset_ coverage, i);
232 } 220 }
233 if (!ots::ParseCoverageTable(data + offset_coverage, 221 if (!ots::ParseCoverageTable(file, data + offset_coverage,
234 length - offset_coverage, num_glyphs)) { 222 length - offset_coverage, num_glyphs)) {
235 return OTS_FAILURE(); 223 return OTS_FAILURE_MSG("Failed to parse coverage table for mark set %d", i );
236 } 224 }
237 } 225 }
238 file->gdef->num_mark_glyph_sets = mark_set_count; 226 file->gdef->num_mark_glyph_sets = mark_set_count;
239 return true; 227 return true;
240 } 228 }
241 229
242 } // namespace 230 } // namespace
243 231
244 #define DROP_THIS_TABLE \ 232 #define DROP_THIS_TABLE(msg_) \
245 do { file->gdef->data = 0; file->gdef->length = 0; } while (0) 233 do { \
234 file->gdef->data = 0; \
235 file->gdef->length = 0; \
236 OTS_FAILURE_MSG(msg_ ", table discarded"); \
237 } while (0)
246 238
247 namespace ots { 239 namespace ots {
248 240
249 bool ots_gdef_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { 241 bool ots_gdef_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
250 // Grab the number of glyphs in the file from the maxp table to check 242 // Grab the number of glyphs in the file from the maxp table to check
251 // GlyphIDs in GDEF table. 243 // GlyphIDs in GDEF table.
252 if (!file->maxp) { 244 if (!file->maxp) {
253 return OTS_FAILURE(); 245 return OTS_FAILURE_MSG("No maxp table in font, needed by GDEF");
254 } 246 }
255 const uint16_t num_glyphs = file->maxp->num_glyphs; 247 const uint16_t num_glyphs = file->maxp->num_glyphs;
256 248
257 Buffer table(data, length); 249 Buffer table(data, length);
258 250
259 OpenTypeGDEF *gdef = new OpenTypeGDEF; 251 OpenTypeGDEF *gdef = new OpenTypeGDEF;
260 file->gdef = gdef; 252 file->gdef = gdef;
261 253
262 uint32_t version = 0; 254 uint32_t version = 0;
263 if (!table.ReadU32(&version)) { 255 if (!table.ReadU32(&version)) {
264 return OTS_FAILURE(); 256 DROP_THIS_TABLE("Incomplete table");
257 return true;
265 } 258 }
266 if (version < 0x00010000 || version == 0x00010001) { 259 if (version < 0x00010000 || version == 0x00010001) {
267 OTS_WARNING("bad GDEF version"); 260 DROP_THIS_TABLE("Bad version");
268 DROP_THIS_TABLE;
269 return true; 261 return true;
270 } 262 }
271 263
272 if (version >= 0x00010002) { 264 if (version >= 0x00010002) {
273 gdef->version_2 = true; 265 gdef->version_2 = true;
274 } 266 }
275 267
276 uint16_t offset_glyph_class_def = 0; 268 uint16_t offset_glyph_class_def = 0;
277 uint16_t offset_attach_list = 0; 269 uint16_t offset_attach_list = 0;
278 uint16_t offset_lig_caret_list = 0; 270 uint16_t offset_lig_caret_list = 0;
279 uint16_t offset_mark_attach_class_def = 0; 271 uint16_t offset_mark_attach_class_def = 0;
280 if (!table.ReadU16(&offset_glyph_class_def) || 272 if (!table.ReadU16(&offset_glyph_class_def) ||
281 !table.ReadU16(&offset_attach_list) || 273 !table.ReadU16(&offset_attach_list) ||
282 !table.ReadU16(&offset_lig_caret_list) || 274 !table.ReadU16(&offset_lig_caret_list) ||
283 !table.ReadU16(&offset_mark_attach_class_def)) { 275 !table.ReadU16(&offset_mark_attach_class_def)) {
284 return OTS_FAILURE(); 276 DROP_THIS_TABLE("Incomplete table");
277 return true;
285 } 278 }
286 uint16_t offset_mark_glyph_sets_def = 0; 279 uint16_t offset_mark_glyph_sets_def = 0;
287 if (gdef->version_2) { 280 if (gdef->version_2) {
288 if (!table.ReadU16(&offset_mark_glyph_sets_def)) { 281 if (!table.ReadU16(&offset_mark_glyph_sets_def)) {
289 return OTS_FAILURE(); 282 DROP_THIS_TABLE("Incomplete table");
283 return true;
290 } 284 }
291 } 285 }
292 286
293 unsigned gdef_header_end = 4 + 4 * 2; 287 unsigned gdef_header_end = 4 + 4 * 2;
294 if (gdef->version_2) 288 if (gdef->version_2)
295 gdef_header_end += 2; 289 gdef_header_end += 2;
296 290
297 // Parse subtables 291 // Parse subtables
298 if (offset_glyph_class_def) { 292 if (offset_glyph_class_def) {
299 if (offset_glyph_class_def >= length || 293 if (offset_glyph_class_def >= length ||
300 offset_glyph_class_def < gdef_header_end) { 294 offset_glyph_class_def < gdef_header_end) {
301 return OTS_FAILURE(); 295 DROP_THIS_TABLE("Invalid offset to glyph classes");
296 return true;
302 } 297 }
303 if (!ParseGlyphClassDefTable(file, data + offset_glyph_class_def, 298 if (!ParseGlyphClassDefTable(file, data + offset_glyph_class_def,
304 length - offset_glyph_class_def, 299 length - offset_glyph_class_def,
305 num_glyphs)) { 300 num_glyphs)) {
306 DROP_THIS_TABLE; 301 DROP_THIS_TABLE("Invalid glyph classes");
307 return true; 302 return true;
308 } 303 }
309 gdef->has_glyph_class_def = true; 304 gdef->has_glyph_class_def = true;
310 } 305 }
311 306
312 if (offset_attach_list) { 307 if (offset_attach_list) {
313 if (offset_attach_list >= length || 308 if (offset_attach_list >= length ||
314 offset_attach_list < gdef_header_end) { 309 offset_attach_list < gdef_header_end) {
315 return OTS_FAILURE(); 310 DROP_THIS_TABLE("Invalid offset to attachment list");
311 return true;
316 } 312 }
317 if (!ParseAttachListTable(file, data + offset_attach_list, 313 if (!ParseAttachListTable(file, data + offset_attach_list,
318 length - offset_attach_list, 314 length - offset_attach_list,
319 num_glyphs)) { 315 num_glyphs)) {
320 DROP_THIS_TABLE; 316 DROP_THIS_TABLE("Invalid attachment list");
321 return true; 317 return true;
322 } 318 }
323 } 319 }
324 320
325 if (offset_lig_caret_list) { 321 if (offset_lig_caret_list) {
326 if (offset_lig_caret_list >= length || 322 if (offset_lig_caret_list >= length ||
327 offset_lig_caret_list < gdef_header_end) { 323 offset_lig_caret_list < gdef_header_end) {
328 return OTS_FAILURE(); 324 DROP_THIS_TABLE("Invalid offset to ligature caret list");
325 return true;
329 } 326 }
330 if (!ParseLigCaretListTable(file, data + offset_lig_caret_list, 327 if (!ParseLigCaretListTable(file, data + offset_lig_caret_list,
331 length - offset_lig_caret_list, 328 length - offset_lig_caret_list,
332 num_glyphs)) { 329 num_glyphs)) {
333 DROP_THIS_TABLE; 330 DROP_THIS_TABLE("Invalid ligature caret list");
334 return true; 331 return true;
335 } 332 }
336 } 333 }
337 334
338 if (offset_mark_attach_class_def) { 335 if (offset_mark_attach_class_def) {
339 if (offset_mark_attach_class_def >= length || 336 if (offset_mark_attach_class_def >= length ||
340 offset_mark_attach_class_def < gdef_header_end) { 337 offset_mark_attach_class_def < gdef_header_end) {
341 return OTS_FAILURE(); 338 return OTS_FAILURE_MSG("Invalid offset to mark attachment list");
342 } 339 }
343 if (!ParseMarkAttachClassDefTable(file, 340 if (!ParseMarkAttachClassDefTable(file,
344 data + offset_mark_attach_class_def, 341 data + offset_mark_attach_class_def,
345 length - offset_mark_attach_class_def, 342 length - offset_mark_attach_class_def,
346 num_glyphs)) { 343 num_glyphs)) {
347 DROP_THIS_TABLE; 344 DROP_THIS_TABLE("Invalid mark attachment list");
348 return true; 345 return true;
349 } 346 }
350 gdef->has_mark_attachment_class_def = true; 347 gdef->has_mark_attachment_class_def = true;
351 } 348 }
352 349
353 if (offset_mark_glyph_sets_def) { 350 if (offset_mark_glyph_sets_def) {
354 if (offset_mark_glyph_sets_def >= length || 351 if (offset_mark_glyph_sets_def >= length ||
355 offset_mark_glyph_sets_def < gdef_header_end) { 352 offset_mark_glyph_sets_def < gdef_header_end) {
356 return OTS_FAILURE(); 353 return OTS_FAILURE_MSG("invalid offset to mark glyph sets");
357 } 354 }
358 if (!ParseMarkGlyphSetsDefTable(file, 355 if (!ParseMarkGlyphSetsDefTable(file,
359 data + offset_mark_glyph_sets_def, 356 data + offset_mark_glyph_sets_def,
360 length - offset_mark_glyph_sets_def, 357 length - offset_mark_glyph_sets_def,
361 num_glyphs)) { 358 num_glyphs)) {
362 DROP_THIS_TABLE; 359 DROP_THIS_TABLE("Invalid mark glyph sets");
363 return true; 360 return true;
364 } 361 }
365 gdef->has_mark_glyph_sets_def = true; 362 gdef->has_mark_glyph_sets_def = true;
366 } 363 }
367 gdef->data = data; 364 gdef->data = data;
368 gdef->length = length; 365 gdef->length = length;
369 return true; 366 return true;
370 } 367 }
371 368
372 bool ots_gdef_should_serialise(OpenTypeFile *file) { 369 bool ots_gdef_should_serialise(OpenTypeFile *file) {
373 const bool needed_tables_dropped = 370 return file->gdef != NULL && file->gdef->data != NULL;
374 (file->gsub && file->gsub->data == NULL) ||
375 (file->gpos && file->gpos->data == NULL);
376 return file->gdef != NULL && file->gdef->data != NULL &&
377 !needed_tables_dropped;
378 } 371 }
379 372
380 bool ots_gdef_serialise(OTSStream *out, OpenTypeFile *file) { 373 bool ots_gdef_serialise(OTSStream *out, OpenTypeFile *file) {
381 if (!out->Write(file->gdef->data, file->gdef->length)) { 374 if (!out->Write(file->gdef->data, file->gdef->length)) {
382 return OTS_FAILURE(); 375 return OTS_FAILURE_MSG("Failed to write GDEF table");
383 } 376 }
384 377
385 return true; 378 return true;
386 } 379 }
387 380
388 void ots_gdef_free(OpenTypeFile *file) { 381 void ots_gdef_free(OpenTypeFile *file) {
389 delete file->gdef; 382 delete file->gdef;
390 } 383 }
391 384
392 } // namespace ots 385 } // namespace ots
393 386
387 #undef TABLE_NAME
388 #undef DROP_THIS_TABLE
OLDNEW
« .gitmodules ('K') | « src/gasp.cc ('k') | src/glyf.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698