OLD | NEW |
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 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 font->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_) \ | |
233 do { \ | |
234 OTS_FAILURE_MSG(msg_ ", table discarded"); \ | |
235 font->gdef->data = 0; \ | |
236 font->gdef->length = 0; \ | |
237 } while (0) | |
238 | |
239 namespace ots { | 232 namespace ots { |
240 | 233 |
241 bool ots_gdef_parse(Font *font, const uint8_t *data, size_t length) { | 234 bool ots_gdef_parse(Font *font, const uint8_t *data, size_t length) { |
242 // Grab the number of glyphs in the font from the maxp table to check | 235 // Grab the number of glyphs in the font from the maxp table to check |
243 // GlyphIDs in GDEF table. | 236 // GlyphIDs in GDEF table. |
244 if (!font->maxp) { | 237 if (!font->maxp) { |
245 return OTS_FAILURE_MSG("No maxp table in font, needed by GDEF"); | 238 return OTS_FAILURE_MSG("No maxp table in font, needed by GDEF"); |
246 } | 239 } |
247 const uint16_t num_glyphs = font->maxp->num_glyphs; | 240 const uint16_t num_glyphs = font->maxp->num_glyphs; |
248 | 241 |
249 Buffer table(data, length); | 242 Buffer table(data, length); |
250 | 243 |
251 OpenTypeGDEF *gdef = new OpenTypeGDEF; | 244 OpenTypeGDEF *gdef = new OpenTypeGDEF; |
252 font->gdef = gdef; | 245 font->gdef = gdef; |
253 | 246 |
254 uint32_t version = 0; | 247 uint32_t version = 0; |
255 if (!table.ReadU32(&version)) { | 248 if (!table.ReadU32(&version)) { |
256 DROP_THIS_TABLE("Incomplete table"); | 249 return OTS_FAILURE_MSG("Incomplete table"); |
257 return true; | |
258 } | 250 } |
259 if (version < 0x00010000 || version == 0x00010001) { | 251 if (version < 0x00010000 || version == 0x00010001) { |
260 DROP_THIS_TABLE("Bad version"); | 252 return OTS_FAILURE_MSG("Bad version"); |
261 return true; | |
262 } | 253 } |
263 | 254 |
264 if (version >= 0x00010002) { | 255 if (version >= 0x00010002) { |
265 gdef->version_2 = true; | 256 gdef->version_2 = true; |
266 } | 257 } |
267 | 258 |
268 uint16_t offset_glyph_class_def = 0; | 259 uint16_t offset_glyph_class_def = 0; |
269 uint16_t offset_attach_list = 0; | 260 uint16_t offset_attach_list = 0; |
270 uint16_t offset_lig_caret_list = 0; | 261 uint16_t offset_lig_caret_list = 0; |
271 uint16_t offset_mark_attach_class_def = 0; | 262 uint16_t offset_mark_attach_class_def = 0; |
272 if (!table.ReadU16(&offset_glyph_class_def) || | 263 if (!table.ReadU16(&offset_glyph_class_def) || |
273 !table.ReadU16(&offset_attach_list) || | 264 !table.ReadU16(&offset_attach_list) || |
274 !table.ReadU16(&offset_lig_caret_list) || | 265 !table.ReadU16(&offset_lig_caret_list) || |
275 !table.ReadU16(&offset_mark_attach_class_def)) { | 266 !table.ReadU16(&offset_mark_attach_class_def)) { |
276 DROP_THIS_TABLE("Incomplete table"); | 267 return OTS_FAILURE_MSG("Incomplete table"); |
277 return true; | |
278 } | 268 } |
279 uint16_t offset_mark_glyph_sets_def = 0; | 269 uint16_t offset_mark_glyph_sets_def = 0; |
280 if (gdef->version_2) { | 270 if (gdef->version_2) { |
281 if (!table.ReadU16(&offset_mark_glyph_sets_def)) { | 271 if (!table.ReadU16(&offset_mark_glyph_sets_def)) { |
282 DROP_THIS_TABLE("Incomplete table"); | 272 return OTS_FAILURE_MSG("Incomplete table"); |
283 return true; | |
284 } | 273 } |
285 } | 274 } |
286 | 275 |
287 unsigned gdef_header_end = 4 + 4 * 2; | 276 unsigned gdef_header_end = 4 + 4 * 2; |
288 if (gdef->version_2) | 277 if (gdef->version_2) |
289 gdef_header_end += 2; | 278 gdef_header_end += 2; |
290 | 279 |
291 // Parse subtables | 280 // Parse subtables |
292 if (offset_glyph_class_def) { | 281 if (offset_glyph_class_def) { |
293 if (offset_glyph_class_def >= length || | 282 if (offset_glyph_class_def >= length || |
294 offset_glyph_class_def < gdef_header_end) { | 283 offset_glyph_class_def < gdef_header_end) { |
295 DROP_THIS_TABLE("Invalid offset to glyph classes"); | 284 return OTS_FAILURE_MSG("Invalid offset to glyph classes"); |
296 return true; | |
297 } | 285 } |
298 if (!ParseGlyphClassDefTable(font, data + offset_glyph_class_def, | 286 if (!ParseGlyphClassDefTable(font, data + offset_glyph_class_def, |
299 length - offset_glyph_class_def, | 287 length - offset_glyph_class_def, |
300 num_glyphs)) { | 288 num_glyphs)) { |
301 DROP_THIS_TABLE("Invalid glyph classes"); | 289 return OTS_FAILURE_MSG("Invalid glyph classes"); |
302 return true; | |
303 } | 290 } |
304 gdef->has_glyph_class_def = true; | 291 gdef->has_glyph_class_def = true; |
305 } | 292 } |
306 | 293 |
307 if (offset_attach_list) { | 294 if (offset_attach_list) { |
308 if (offset_attach_list >= length || | 295 if (offset_attach_list >= length || |
309 offset_attach_list < gdef_header_end) { | 296 offset_attach_list < gdef_header_end) { |
310 DROP_THIS_TABLE("Invalid offset to attachment list"); | 297 return OTS_FAILURE_MSG("Invalid offset to attachment list"); |
311 return true; | |
312 } | 298 } |
313 if (!ParseAttachListTable(font, data + offset_attach_list, | 299 if (!ParseAttachListTable(font, data + offset_attach_list, |
314 length - offset_attach_list, | 300 length - offset_attach_list, |
315 num_glyphs)) { | 301 num_glyphs)) { |
316 DROP_THIS_TABLE("Invalid attachment list"); | 302 return OTS_FAILURE_MSG("Invalid attachment list"); |
317 return true; | |
318 } | 303 } |
319 } | 304 } |
320 | 305 |
321 if (offset_lig_caret_list) { | 306 if (offset_lig_caret_list) { |
322 if (offset_lig_caret_list >= length || | 307 if (offset_lig_caret_list >= length || |
323 offset_lig_caret_list < gdef_header_end) { | 308 offset_lig_caret_list < gdef_header_end) { |
324 DROP_THIS_TABLE("Invalid offset to ligature caret list"); | 309 return OTS_FAILURE_MSG("Invalid offset to ligature caret list"); |
325 return true; | |
326 } | 310 } |
327 if (!ParseLigCaretListTable(font, data + offset_lig_caret_list, | 311 if (!ParseLigCaretListTable(font, data + offset_lig_caret_list, |
328 length - offset_lig_caret_list, | 312 length - offset_lig_caret_list, |
329 num_glyphs)) { | 313 num_glyphs)) { |
330 DROP_THIS_TABLE("Invalid ligature caret list"); | 314 return OTS_FAILURE_MSG("Invalid ligature caret list"); |
331 return true; | |
332 } | 315 } |
333 } | 316 } |
334 | 317 |
335 if (offset_mark_attach_class_def) { | 318 if (offset_mark_attach_class_def) { |
336 if (offset_mark_attach_class_def >= length || | 319 if (offset_mark_attach_class_def >= length || |
337 offset_mark_attach_class_def < gdef_header_end) { | 320 offset_mark_attach_class_def < gdef_header_end) { |
338 return OTS_FAILURE_MSG("Invalid offset to mark attachment list"); | 321 return OTS_FAILURE_MSG("Invalid offset to mark attachment list"); |
339 } | 322 } |
340 if (!ParseMarkAttachClassDefTable(font, | 323 if (!ParseMarkAttachClassDefTable(font, |
341 data + offset_mark_attach_class_def, | 324 data + offset_mark_attach_class_def, |
342 length - offset_mark_attach_class_def, | 325 length - offset_mark_attach_class_def, |
343 num_glyphs)) { | 326 num_glyphs)) { |
344 DROP_THIS_TABLE("Invalid mark attachment list"); | 327 return OTS_FAILURE_MSG("Invalid mark attachment list"); |
345 return true; | |
346 } | 328 } |
347 gdef->has_mark_attachment_class_def = true; | 329 gdef->has_mark_attachment_class_def = true; |
348 } | 330 } |
349 | 331 |
350 if (offset_mark_glyph_sets_def) { | 332 if (offset_mark_glyph_sets_def) { |
351 if (offset_mark_glyph_sets_def >= length || | 333 if (offset_mark_glyph_sets_def >= length || |
352 offset_mark_glyph_sets_def < gdef_header_end) { | 334 offset_mark_glyph_sets_def < gdef_header_end) { |
353 return OTS_FAILURE_MSG("invalid offset to mark glyph sets"); | 335 return OTS_FAILURE_MSG("invalid offset to mark glyph sets"); |
354 } | 336 } |
355 if (!ParseMarkGlyphSetsDefTable(font, | 337 if (!ParseMarkGlyphSetsDefTable(font, |
356 data + offset_mark_glyph_sets_def, | 338 data + offset_mark_glyph_sets_def, |
357 length - offset_mark_glyph_sets_def, | 339 length - offset_mark_glyph_sets_def, |
358 num_glyphs)) { | 340 num_glyphs)) { |
359 DROP_THIS_TABLE("Invalid mark glyph sets"); | 341 return OTS_FAILURE_MSG("Invalid mark glyph sets"); |
360 return true; | |
361 } | 342 } |
362 gdef->has_mark_glyph_sets_def = true; | 343 gdef->has_mark_glyph_sets_def = true; |
363 } | 344 } |
364 gdef->data = data; | 345 gdef->data = data; |
365 gdef->length = length; | 346 gdef->length = length; |
366 return true; | 347 return true; |
367 } | 348 } |
368 | 349 |
369 bool ots_gdef_should_serialise(Font *font) { | 350 bool ots_gdef_should_serialise(Font *font) { |
370 return font->gdef != NULL && font->gdef->data != NULL; | 351 return font->gdef != NULL && font->gdef->data != NULL; |
(...skipping 12 matching lines...) Expand all Loading... |
383 font->gdef_reused = true; | 364 font->gdef_reused = true; |
384 } | 365 } |
385 | 366 |
386 void ots_gdef_free(Font *font) { | 367 void ots_gdef_free(Font *font) { |
387 delete font->gdef; | 368 delete font->gdef; |
388 } | 369 } |
389 | 370 |
390 } // namespace ots | 371 } // namespace ots |
391 | 372 |
392 #undef TABLE_NAME | 373 #undef TABLE_NAME |
393 #undef DROP_THIS_TABLE | |
OLD | NEW |