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

Side by Side Diff: third_party/ots/src/gdef.cc

Issue 1252363005: Update OTS to revision a7a3b94 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 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
« no previous file with comments | « third_party/ots/src/gasp.cc ('k') | third_party/ots/src/glyf.cc » ('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"
(...skipping 10 matching lines...) Expand all
21 21
22 // The maximum class value in class definition tables. 22 // The maximum class value in class definition tables.
23 const uint16_t kMaxClassDefValue = 0xFFFF; 23 const uint16_t kMaxClassDefValue = 0xFFFF;
24 // The maximum class value in the glyph class definision table. 24 // The maximum class value in the glyph class definision table.
25 const uint16_t kMaxGlyphClassDefValue = 4; 25 const uint16_t kMaxGlyphClassDefValue = 4;
26 // The maximum format number of caret value tables. 26 // The maximum format number of caret value tables.
27 // 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
28 // ParseLigCaretListTable() for the reason. 28 // ParseLigCaretListTable() for the reason.
29 const uint16_t kMaxCaretValueFormat = 2; 29 const uint16_t kMaxCaretValueFormat = 2;
30 30
31 bool ParseGlyphClassDefTable(ots::OpenTypeFile *file, const uint8_t *data, 31 bool ParseGlyphClassDefTable(ots::Font *font, const uint8_t *data,
32 size_t length, const uint16_t num_glyphs) { 32 size_t length, const uint16_t num_glyphs) {
33 return ots::ParseClassDefTable(file, data, length, num_glyphs, 33 return ots::ParseClassDefTable(font, data, length, num_glyphs,
34 kMaxGlyphClassDefValue); 34 kMaxGlyphClassDefValue);
35 } 35 }
36 36
37 bool ParseAttachListTable(ots::OpenTypeFile *file, const uint8_t *data, 37 bool ParseAttachListTable(ots::Font *font, const uint8_t *data,
38 size_t length, const uint16_t num_glyphs) { 38 size_t length, const uint16_t num_glyphs) {
39 ots::Buffer subtable(data, length); 39 ots::Buffer subtable(data, length);
40 40
41 uint16_t offset_coverage = 0; 41 uint16_t offset_coverage = 0;
42 uint16_t glyph_count = 0; 42 uint16_t glyph_count = 0;
43 if (!subtable.ReadU16(&offset_coverage) || 43 if (!subtable.ReadU16(&offset_coverage) ||
44 !subtable.ReadU16(&glyph_count)) { 44 !subtable.ReadU16(&glyph_count)) {
45 return OTS_FAILURE_MSG("Failed to read gdef header"); 45 return OTS_FAILURE_MSG("Failed to read gdef header");
46 } 46 }
47 const unsigned attach_points_end = 47 const unsigned attach_points_end =
(...skipping 15 matching lines...) Expand all
63 if (!subtable.ReadU16(&attach_points[i])) { 63 if (!subtable.ReadU16(&attach_points[i])) {
64 return OTS_FAILURE_MSG("Can't read attachment point %d", i); 64 return OTS_FAILURE_MSG("Can't read attachment point %d", i);
65 } 65 }
66 if (attach_points[i] >= length || 66 if (attach_points[i] >= length ||
67 attach_points[i] < attach_points_end) { 67 attach_points[i] < attach_points_end) {
68 return OTS_FAILURE_MSG("Bad attachment point %d of %d", i, attach_points[i ]); 68 return OTS_FAILURE_MSG("Bad attachment point %d of %d", i, attach_points[i ]);
69 } 69 }
70 } 70 }
71 71
72 // Parse coverage table 72 // Parse coverage table
73 if (!ots::ParseCoverageTable(file, data + offset_coverage, 73 if (!ots::ParseCoverageTable(font, data + offset_coverage,
74 length - offset_coverage, num_glyphs)) { 74 length - offset_coverage, num_glyphs)) {
75 return OTS_FAILURE_MSG("Bad coverage table"); 75 return OTS_FAILURE_MSG("Bad coverage table");
76 } 76 }
77 77
78 // Parse attach point table 78 // Parse attach point table
79 for (unsigned i = 0; i < attach_points.size(); ++i) { 79 for (unsigned i = 0; i < attach_points.size(); ++i) {
80 subtable.set_offset(attach_points[i]); 80 subtable.set_offset(attach_points[i]);
81 uint16_t point_count = 0; 81 uint16_t point_count = 0;
82 if (!subtable.ReadU16(&point_count)) { 82 if (!subtable.ReadU16(&point_count)) {
83 return OTS_FAILURE_MSG("Can't read point count %d", i); 83 return OTS_FAILURE_MSG("Can't read point count %d", i);
(...skipping 11 matching lines...) Expand all
95 if (last_point_index != 0 && last_point_index >= point_index) { 95 if (last_point_index != 0 && last_point_index >= point_index) {
96 return OTS_FAILURE_MSG("bad contour indeces: %u >= %u", 96 return OTS_FAILURE_MSG("bad contour indeces: %u >= %u",
97 last_point_index, point_index); 97 last_point_index, point_index);
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::Font *font, 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_MSG("Can't read caret structure"); 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;
(...skipping 13 matching lines...) Expand all
129 for (unsigned i = 0; i < lig_glyph_count; ++i) { 129 for (unsigned i = 0; i < lig_glyph_count; ++i) {
130 if (!subtable.ReadU16(&lig_glyphs[i])) { 130 if (!subtable.ReadU16(&lig_glyphs[i])) {
131 return OTS_FAILURE_MSG("Can't read ligature glyph location %d", i); 131 return OTS_FAILURE_MSG("Can't read ligature glyph location %d", i);
132 } 132 }
133 if (lig_glyphs[i] >= length || lig_glyphs[i] < lig_glyphs_end) { 133 if (lig_glyphs[i] >= length || lig_glyphs[i] < lig_glyphs_end) {
134 return OTS_FAILURE_MSG("Bad ligature glyph location %d in glyph %d", lig_g lyphs[i], i); 134 return OTS_FAILURE_MSG("Bad ligature glyph location %d in glyph %d", lig_g lyphs[i], i);
135 } 135 }
136 } 136 }
137 137
138 // Parse coverage table 138 // Parse coverage table
139 if (!ots::ParseCoverageTable(file, data + offset_coverage, 139 if (!ots::ParseCoverageTable(font, data + offset_coverage,
140 length - offset_coverage, num_glyphs)) { 140 length - offset_coverage, num_glyphs)) {
141 return OTS_FAILURE_MSG("Can't parse caret coverage table"); 141 return OTS_FAILURE_MSG("Can't parse caret coverage table");
142 } 142 }
143 143
144 // Parse ligature glyph table 144 // Parse ligature glyph table
145 for (unsigned i = 0; i < lig_glyphs.size(); ++i) { 145 for (unsigned i = 0; i < lig_glyphs.size(); ++i) {
146 subtable.set_offset(lig_glyphs[i]); 146 subtable.set_offset(lig_glyphs[i]);
147 uint16_t caret_count = 0; 147 uint16_t caret_count = 0;
148 if (!subtable.ReadU16(&caret_count)) { 148 if (!subtable.ReadU16(&caret_count)) {
149 return OTS_FAILURE_MSG("Can't read caret count for glyph %d", i); 149 return OTS_FAILURE_MSG("Can't read caret count for glyph %d", i);
(...skipping 30 matching lines...) Expand all
180 // CaretValueFormats contain a 2-byte field which could be 180 // CaretValueFormats contain a 2-byte field which could be
181 // arbitrary value. 181 // arbitrary value.
182 if (!subtable.Skip(2)) { 182 if (!subtable.Skip(2)) {
183 return OTS_FAILURE_MSG("Bad caret value table structure %d in glyph %d", j, i); 183 return OTS_FAILURE_MSG("Bad caret value table structure %d in glyph %d", j, i);
184 } 184 }
185 } 185 }
186 } 186 }
187 return true; 187 return true;
188 } 188 }
189 189
190 bool ParseMarkAttachClassDefTable(ots::OpenTypeFile *file, const uint8_t *data, 190 bool ParseMarkAttachClassDefTable(ots::Font *font, const uint8_t *data,
191 size_t length, const uint16_t num_glyphs) { 191 size_t length, const uint16_t num_glyphs) {
192 return ots::ParseClassDefTable(file, data, length, num_glyphs, kMaxClassDefVal ue); 192 return ots::ParseClassDefTable(font, data, length, num_glyphs, kMaxClassDefVal ue);
193 } 193 }
194 194
195 bool ParseMarkGlyphSetsDefTable(ots::OpenTypeFile *file, const uint8_t *data, 195 bool ParseMarkGlyphSetsDefTable(ots::Font *font, const uint8_t *data,
196 size_t length, const uint16_t num_glyphs) { 196 size_t length, const uint16_t num_glyphs) {
197 ots::Buffer subtable(data, length); 197 ots::Buffer subtable(data, length);
198 uint16_t format = 0; 198 uint16_t format = 0;
199 uint16_t mark_set_count = 0; 199 uint16_t mark_set_count = 0;
200 if (!subtable.ReadU16(&format) || 200 if (!subtable.ReadU16(&format) ||
201 !subtable.ReadU16(&mark_set_count)) { 201 !subtable.ReadU16(&mark_set_count)) {
202 return OTS_FAILURE_MSG("Can' read mark glyph table structure"); 202 return OTS_FAILURE_MSG("Can' read mark glyph table structure");
203 } 203 }
204 if (format != 1) { 204 if (format != 1) {
205 return OTS_FAILURE_MSG("bad mark glyph set table format: %u", format); 205 return OTS_FAILURE_MSG("bad mark glyph set table format: %u", format);
206 } 206 }
207 207
208 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;
209 if (mark_sets_end > std::numeric_limits<uint16_t>::max()) { 209 if (mark_sets_end > std::numeric_limits<uint16_t>::max()) {
210 return OTS_FAILURE_MSG("Bad mark_set %d", mark_sets_end); 210 return OTS_FAILURE_MSG("Bad mark_set %d", mark_sets_end);
211 } 211 }
212 for (unsigned i = 0; i < mark_set_count; ++i) { 212 for (unsigned i = 0; i < mark_set_count; ++i) {
213 uint32_t offset_coverage = 0; 213 uint32_t offset_coverage = 0;
214 if (!subtable.ReadU32(&offset_coverage)) { 214 if (!subtable.ReadU32(&offset_coverage)) {
215 return OTS_FAILURE_MSG("Can't read covrage location for mark set %d", i); 215 return OTS_FAILURE_MSG("Can't read covrage location for mark set %d", i);
216 } 216 }
217 if (offset_coverage >= length || 217 if (offset_coverage >= length ||
218 offset_coverage < mark_sets_end) { 218 offset_coverage < mark_sets_end) {
219 return OTS_FAILURE_MSG("Bad coverage location %d for mark set %d", offset_ coverage, i); 219 return OTS_FAILURE_MSG("Bad coverage location %d for mark set %d", offset_ coverage, i);
220 } 220 }
221 if (!ots::ParseCoverageTable(file, data + offset_coverage, 221 if (!ots::ParseCoverageTable(font, data + offset_coverage,
222 length - offset_coverage, num_glyphs)) { 222 length - offset_coverage, num_glyphs)) {
223 return OTS_FAILURE_MSG("Failed to parse coverage table for mark set %d", i ); 223 return OTS_FAILURE_MSG("Failed to parse coverage table for mark set %d", i );
224 } 224 }
225 } 225 }
226 file->gdef->num_mark_glyph_sets = mark_set_count; 226 font->gdef->num_mark_glyph_sets = mark_set_count;
227 return true; 227 return true;
228 } 228 }
229 229
230 } // namespace 230 } // namespace
231 231
232 #define DROP_THIS_TABLE(msg_) \ 232 #define DROP_THIS_TABLE(msg_) \
233 do { \ 233 do { \
234 OTS_FAILURE_MSG(msg_ ", table discarded"); \ 234 OTS_FAILURE_MSG(msg_ ", table discarded"); \
235 file->gdef->data = 0; \ 235 font->gdef->data = 0; \
236 file->gdef->length = 0; \ 236 font->gdef->length = 0; \
237 } while (0) 237 } while (0)
238 238
239 namespace ots { 239 namespace ots {
240 240
241 bool ots_gdef_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { 241 bool ots_gdef_parse(Font *font, const uint8_t *data, size_t length) {
242 // Grab the number of glyphs in the file from the maxp table to check 242 // Grab the number of glyphs in the font from the maxp table to check
243 // GlyphIDs in GDEF table. 243 // GlyphIDs in GDEF table.
244 if (!file->maxp) { 244 if (!font->maxp) {
245 return OTS_FAILURE_MSG("No maxp table in font, needed by GDEF"); 245 return OTS_FAILURE_MSG("No maxp table in font, needed by GDEF");
246 } 246 }
247 const uint16_t num_glyphs = file->maxp->num_glyphs; 247 const uint16_t num_glyphs = font->maxp->num_glyphs;
248 248
249 Buffer table(data, length); 249 Buffer table(data, length);
250 250
251 OpenTypeGDEF *gdef = new OpenTypeGDEF; 251 OpenTypeGDEF *gdef = new OpenTypeGDEF;
252 file->gdef = gdef; 252 font->gdef = gdef;
253 253
254 uint32_t version = 0; 254 uint32_t version = 0;
255 if (!table.ReadU32(&version)) { 255 if (!table.ReadU32(&version)) {
256 DROP_THIS_TABLE("Incomplete table"); 256 DROP_THIS_TABLE("Incomplete table");
257 return true; 257 return true;
258 } 258 }
259 if (version < 0x00010000 || version == 0x00010001) { 259 if (version < 0x00010000 || version == 0x00010001) {
260 DROP_THIS_TABLE("Bad version"); 260 DROP_THIS_TABLE("Bad version");
261 return true; 261 return true;
262 } 262 }
(...skipping 25 matching lines...) Expand all
288 if (gdef->version_2) 288 if (gdef->version_2)
289 gdef_header_end += 2; 289 gdef_header_end += 2;
290 290
291 // Parse subtables 291 // Parse subtables
292 if (offset_glyph_class_def) { 292 if (offset_glyph_class_def) {
293 if (offset_glyph_class_def >= length || 293 if (offset_glyph_class_def >= length ||
294 offset_glyph_class_def < gdef_header_end) { 294 offset_glyph_class_def < gdef_header_end) {
295 DROP_THIS_TABLE("Invalid offset to glyph classes"); 295 DROP_THIS_TABLE("Invalid offset to glyph classes");
296 return true; 296 return true;
297 } 297 }
298 if (!ParseGlyphClassDefTable(file, data + offset_glyph_class_def, 298 if (!ParseGlyphClassDefTable(font, data + offset_glyph_class_def,
299 length - offset_glyph_class_def, 299 length - offset_glyph_class_def,
300 num_glyphs)) { 300 num_glyphs)) {
301 DROP_THIS_TABLE("Invalid glyph classes"); 301 DROP_THIS_TABLE("Invalid glyph classes");
302 return true; 302 return true;
303 } 303 }
304 gdef->has_glyph_class_def = true; 304 gdef->has_glyph_class_def = true;
305 } 305 }
306 306
307 if (offset_attach_list) { 307 if (offset_attach_list) {
308 if (offset_attach_list >= length || 308 if (offset_attach_list >= length ||
309 offset_attach_list < gdef_header_end) { 309 offset_attach_list < gdef_header_end) {
310 DROP_THIS_TABLE("Invalid offset to attachment list"); 310 DROP_THIS_TABLE("Invalid offset to attachment list");
311 return true; 311 return true;
312 } 312 }
313 if (!ParseAttachListTable(file, data + offset_attach_list, 313 if (!ParseAttachListTable(font, data + offset_attach_list,
314 length - offset_attach_list, 314 length - offset_attach_list,
315 num_glyphs)) { 315 num_glyphs)) {
316 DROP_THIS_TABLE("Invalid attachment list"); 316 DROP_THIS_TABLE("Invalid attachment list");
317 return true; 317 return true;
318 } 318 }
319 } 319 }
320 320
321 if (offset_lig_caret_list) { 321 if (offset_lig_caret_list) {
322 if (offset_lig_caret_list >= length || 322 if (offset_lig_caret_list >= length ||
323 offset_lig_caret_list < gdef_header_end) { 323 offset_lig_caret_list < gdef_header_end) {
324 DROP_THIS_TABLE("Invalid offset to ligature caret list"); 324 DROP_THIS_TABLE("Invalid offset to ligature caret list");
325 return true; 325 return true;
326 } 326 }
327 if (!ParseLigCaretListTable(file, data + offset_lig_caret_list, 327 if (!ParseLigCaretListTable(font, data + offset_lig_caret_list,
328 length - offset_lig_caret_list, 328 length - offset_lig_caret_list,
329 num_glyphs)) { 329 num_glyphs)) {
330 DROP_THIS_TABLE("Invalid ligature caret list"); 330 DROP_THIS_TABLE("Invalid ligature caret list");
331 return true; 331 return true;
332 } 332 }
333 } 333 }
334 334
335 if (offset_mark_attach_class_def) { 335 if (offset_mark_attach_class_def) {
336 if (offset_mark_attach_class_def >= length || 336 if (offset_mark_attach_class_def >= length ||
337 offset_mark_attach_class_def < gdef_header_end) { 337 offset_mark_attach_class_def < gdef_header_end) {
338 return OTS_FAILURE_MSG("Invalid offset to mark attachment list"); 338 return OTS_FAILURE_MSG("Invalid offset to mark attachment list");
339 } 339 }
340 if (!ParseMarkAttachClassDefTable(file, 340 if (!ParseMarkAttachClassDefTable(font,
341 data + offset_mark_attach_class_def, 341 data + offset_mark_attach_class_def,
342 length - offset_mark_attach_class_def, 342 length - offset_mark_attach_class_def,
343 num_glyphs)) { 343 num_glyphs)) {
344 DROP_THIS_TABLE("Invalid mark attachment list"); 344 DROP_THIS_TABLE("Invalid mark attachment list");
345 return true; 345 return true;
346 } 346 }
347 gdef->has_mark_attachment_class_def = true; 347 gdef->has_mark_attachment_class_def = true;
348 } 348 }
349 349
350 if (offset_mark_glyph_sets_def) { 350 if (offset_mark_glyph_sets_def) {
351 if (offset_mark_glyph_sets_def >= length || 351 if (offset_mark_glyph_sets_def >= length ||
352 offset_mark_glyph_sets_def < gdef_header_end) { 352 offset_mark_glyph_sets_def < gdef_header_end) {
353 return OTS_FAILURE_MSG("invalid offset to mark glyph sets"); 353 return OTS_FAILURE_MSG("invalid offset to mark glyph sets");
354 } 354 }
355 if (!ParseMarkGlyphSetsDefTable(file, 355 if (!ParseMarkGlyphSetsDefTable(font,
356 data + offset_mark_glyph_sets_def, 356 data + offset_mark_glyph_sets_def,
357 length - offset_mark_glyph_sets_def, 357 length - offset_mark_glyph_sets_def,
358 num_glyphs)) { 358 num_glyphs)) {
359 DROP_THIS_TABLE("Invalid mark glyph sets"); 359 DROP_THIS_TABLE("Invalid mark glyph sets");
360 return true; 360 return true;
361 } 361 }
362 gdef->has_mark_glyph_sets_def = true; 362 gdef->has_mark_glyph_sets_def = true;
363 } 363 }
364 gdef->data = data; 364 gdef->data = data;
365 gdef->length = length; 365 gdef->length = length;
366 return true; 366 return true;
367 } 367 }
368 368
369 bool ots_gdef_should_serialise(OpenTypeFile *file) { 369 bool ots_gdef_should_serialise(Font *font) {
370 return file->gdef != NULL && file->gdef->data != NULL; 370 return font->gdef != NULL && font->gdef->data != NULL;
371 } 371 }
372 372
373 bool ots_gdef_serialise(OTSStream *out, OpenTypeFile *file) { 373 bool ots_gdef_serialise(OTSStream *out, Font *font) {
374 if (!out->Write(file->gdef->data, file->gdef->length)) { 374 if (!out->Write(font->gdef->data, font->gdef->length)) {
375 return OTS_FAILURE_MSG("Failed to write GDEF table"); 375 return OTS_FAILURE_MSG("Failed to write GDEF table");
376 } 376 }
377 377
378 return true; 378 return true;
379 } 379 }
380 380
381 void ots_gdef_free(OpenTypeFile *file) { 381 void ots_gdef_reuse(Font *font, Font *other) {
382 delete file->gdef; 382 font->gdef = other->gdef;
383 font->gdef_reused = true;
384 }
385
386 void ots_gdef_free(Font *font) {
387 delete font->gdef;
383 } 388 }
384 389
385 } // namespace ots 390 } // namespace ots
386 391
387 #undef TABLE_NAME 392 #undef TABLE_NAME
388 #undef DROP_THIS_TABLE 393 #undef DROP_THIS_TABLE
OLDNEW
« no previous file with comments | « third_party/ots/src/gasp.cc ('k') | third_party/ots/src/glyf.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698