OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2007,2008,2009 Red Hat, Inc. | 2 * Copyright © 2007,2008,2009 Red Hat, Inc. |
3 * Copyright © 2010,2012 Google, Inc. | 3 * Copyright © 2010,2012 Google, Inc. |
4 * | 4 * |
5 * This is part of HarfBuzz, a text shaping library. | 5 * This is part of HarfBuzz, a text shaping library. |
6 * | 6 * |
7 * Permission is hereby granted, without written agreement and without | 7 * Permission is hereby granted, without written agreement and without |
8 * license or royalty fees, to use, copy, modify, and distribute this | 8 * license or royalty fees, to use, copy, modify, and distribute this |
9 * software and its documentation for any purpose, provided that the | 9 * software and its documentation for any purpose, provided that the |
10 * above copyright notice and the following two paragraphs appear in | 10 * above copyright notice and the following two paragraphs appear in |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 } | 68 } |
69 | 69 |
70 struct sanitize_closure_t { | 70 struct sanitize_closure_t { |
71 hb_tag_t tag; | 71 hb_tag_t tag; |
72 const void *list_base; | 72 const void *list_base; |
73 }; | 73 }; |
74 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const | 74 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const |
75 { | 75 { |
76 TRACE_SANITIZE (this); | 76 TRACE_SANITIZE (this); |
77 const sanitize_closure_t closure = {tag, base}; | 77 const sanitize_closure_t closure = {tag, base}; |
78 return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base, &cl
osure)); | 78 return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure))
; |
79 } | 79 } |
80 | 80 |
81 Tag tag; /* 4-byte Tag identifier */ | 81 Tag tag; /* 4-byte Tag identifier */ |
82 OffsetTo<Type> | 82 OffsetTo<Type> |
83 offset; /* Offset from beginning of object holding | 83 offset; /* Offset from beginning of object holding |
84 * the Record */ | 84 * the Record */ |
85 public: | 85 public: |
86 DEFINE_SIZE_STATIC (6); | 86 DEFINE_SIZE_STATIC (6); |
87 }; | 87 }; |
88 | 88 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 | 124 |
125 template <typename Type> | 125 template <typename Type> |
126 struct RecordListOf : RecordArrayOf<Type> | 126 struct RecordListOf : RecordArrayOf<Type> |
127 { | 127 { |
128 inline const Type& operator [] (unsigned int i) const | 128 inline const Type& operator [] (unsigned int i) const |
129 { return this+RecordArrayOf<Type>::operator [](i).offset; } | 129 { return this+RecordArrayOf<Type>::operator [](i).offset; } |
130 | 130 |
131 inline bool sanitize (hb_sanitize_context_t *c) const | 131 inline bool sanitize (hb_sanitize_context_t *c) const |
132 { | 132 { |
133 TRACE_SANITIZE (this); | 133 TRACE_SANITIZE (this); |
134 return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this)); | 134 return_trace (RecordArrayOf<Type>::sanitize (c, this)); |
135 } | 135 } |
136 }; | 136 }; |
137 | 137 |
138 | 138 |
139 struct RangeRecord | 139 struct RangeRecord |
140 { | 140 { |
141 inline int cmp (hb_codepoint_t g) const { | 141 inline int cmp (hb_codepoint_t g) const { |
142 return g < start ? -1 : g <= end ? 0 : +1 ; | 142 return g < start ? -1 : g <= end ? 0 : +1 ; |
143 } | 143 } |
144 | 144 |
145 inline bool sanitize (hb_sanitize_context_t *c) const | 145 inline bool sanitize (hb_sanitize_context_t *c) const |
146 { | 146 { |
147 TRACE_SANITIZE (this); | 147 TRACE_SANITIZE (this); |
148 return TRACE_RETURN (c->check_struct (this)); | 148 return_trace (c->check_struct (this)); |
149 } | 149 } |
150 | 150 |
151 inline bool intersects (const hb_set_t *glyphs) const { | 151 inline bool intersects (const hb_set_t *glyphs) const { |
152 return glyphs->intersects (start, end); | 152 return glyphs->intersects (start, end); |
153 } | 153 } |
154 | 154 |
155 template <typename set_t> | 155 template <typename set_t> |
156 inline void add_coverage (set_t *glyphs) const { | 156 inline void add_coverage (set_t *glyphs) const { |
157 glyphs->add_range (start, end); | 157 glyphs->add_range (start, end); |
158 } | 158 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 { | 204 { |
205 if (reqFeatureIndex == 0xFFFFu) | 205 if (reqFeatureIndex == 0xFFFFu) |
206 return Index::NOT_FOUND_INDEX; | 206 return Index::NOT_FOUND_INDEX; |
207 return reqFeatureIndex;; | 207 return reqFeatureIndex;; |
208 } | 208 } |
209 | 209 |
210 inline bool sanitize (hb_sanitize_context_t *c, | 210 inline bool sanitize (hb_sanitize_context_t *c, |
211 const Record<LangSys>::sanitize_closure_t * = NULL) cons
t | 211 const Record<LangSys>::sanitize_closure_t * = NULL) cons
t |
212 { | 212 { |
213 TRACE_SANITIZE (this); | 213 TRACE_SANITIZE (this); |
214 return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c)); | 214 return_trace (c->check_struct (this) && featureIndex.sanitize (c)); |
215 } | 215 } |
216 | 216 |
217 Offset<> lookupOrderZ; /* = Null (reserved for an offset to a | 217 Offset<> lookupOrderZ; /* = Null (reserved for an offset to a |
218 * reordering table) */ | 218 * reordering table) */ |
219 USHORT reqFeatureIndex;/* Index of a feature required for this | 219 USHORT reqFeatureIndex;/* Index of a feature required for this |
220 * language system--if no required features | 220 * language system--if no required features |
221 * = 0xFFFFu */ | 221 * = 0xFFFFu */ |
222 IndexArray featureIndex; /* Array of indices into the FeatureList */ | 222 IndexArray featureIndex; /* Array of indices into the FeatureList */ |
223 public: | 223 public: |
224 DEFINE_SIZE_ARRAY (6, featureIndex); | 224 DEFINE_SIZE_ARRAY (6, featureIndex); |
(...skipping 19 matching lines...) Expand all Loading... |
244 inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const | 244 inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const |
245 { return langSys.find_index (tag, index); } | 245 { return langSys.find_index (tag, index); } |
246 | 246 |
247 inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; } | 247 inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; } |
248 inline const LangSys& get_default_lang_sys (void) const { return this+defaultL
angSys; } | 248 inline const LangSys& get_default_lang_sys (void) const { return this+defaultL
angSys; } |
249 | 249 |
250 inline bool sanitize (hb_sanitize_context_t *c, | 250 inline bool sanitize (hb_sanitize_context_t *c, |
251 const Record<Script>::sanitize_closure_t * = NULL) const | 251 const Record<Script>::sanitize_closure_t * = NULL) const |
252 { | 252 { |
253 TRACE_SANITIZE (this); | 253 TRACE_SANITIZE (this); |
254 return TRACE_RETURN (defaultLangSys.sanitize (c, this) && langSys.sanitize (
c, this)); | 254 return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this
)); |
255 } | 255 } |
256 | 256 |
257 protected: | 257 protected: |
258 OffsetTo<LangSys> | 258 OffsetTo<LangSys> |
259 defaultLangSys; /* Offset to DefaultLangSys table--from | 259 defaultLangSys; /* Offset to DefaultLangSys table--from |
260 * beginning of Script table--may be Null */ | 260 * beginning of Script table--may be Null */ |
261 RecordArrayOf<LangSys> | 261 RecordArrayOf<LangSys> |
262 langSys; /* Array of LangSysRecords--listed | 262 langSys; /* Array of LangSysRecords--listed |
263 * alphabetically by LangSysTag */ | 263 * alphabetically by LangSysTag */ |
264 public: | 264 public: |
265 DEFINE_SIZE_ARRAY (4, langSys); | 265 DEFINE_SIZE_ARRAY (4, langSys); |
266 }; | 266 }; |
267 | 267 |
268 typedef RecordListOf<Script> ScriptList; | 268 typedef RecordListOf<Script> ScriptList; |
269 | 269 |
270 | 270 |
271 /* http://www.microsoft.com/typography/otspec/features_pt.htm#size */ | 271 /* http://www.microsoft.com/typography/otspec/features_pt.htm#size */ |
272 struct FeatureParamsSize | 272 struct FeatureParamsSize |
273 { | 273 { |
274 inline bool sanitize (hb_sanitize_context_t *c) const | 274 inline bool sanitize (hb_sanitize_context_t *c) const |
275 { | 275 { |
276 TRACE_SANITIZE (this); | 276 TRACE_SANITIZE (this); |
277 if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); | 277 if (unlikely (!c->check_struct (this))) return_trace (false); |
278 | 278 |
279 /* This subtable has some "history", if you will. Some earlier versions of | 279 /* This subtable has some "history", if you will. Some earlier versions of |
280 * Adobe tools calculated the offset of the FeatureParams sutable from the | 280 * Adobe tools calculated the offset of the FeatureParams sutable from the |
281 * beginning of the FeatureList table! Now, that is dealt with in the | 281 * beginning of the FeatureList table! Now, that is dealt with in the |
282 * Feature implementation. But we still need to be able to tell junk from | 282 * Feature implementation. But we still need to be able to tell junk from |
283 * real data. Note: We don't check that the nameID actually exists. | 283 * real data. Note: We don't check that the nameID actually exists. |
284 * | 284 * |
285 * Read Roberts wrote on 9/15/06 on opentype-list@indx.co.uk : | 285 * Read Roberts wrote on 9/15/06 on opentype-list@indx.co.uk : |
286 * | 286 * |
287 * Yes, it is correct that a new version of the AFDKO (version 2.0) will be | 287 * Yes, it is correct that a new version of the AFDKO (version 2.0) will be |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 * "range end" <= "range start" or | 319 * "range end" <= "range start" or |
320 * "menu name ID" < 256 or | 320 * "menu name ID" < 256 or |
321 * "menu name ID" > 32767 or | 321 * "menu name ID" > 32767 or |
322 * menu name ID is not a name ID which is actually in the name table) | 322 * menu name ID is not a name ID which is actually in the name table) |
323 * fails test | 323 * fails test |
324 * Else | 324 * Else |
325 * passes test. | 325 * passes test. |
326 */ | 326 */ |
327 | 327 |
328 if (!designSize) | 328 if (!designSize) |
329 return TRACE_RETURN (false); | 329 return_trace (false); |
330 else if (subfamilyID == 0 && | 330 else if (subfamilyID == 0 && |
331 subfamilyNameID == 0 && | 331 subfamilyNameID == 0 && |
332 rangeStart == 0 && | 332 rangeStart == 0 && |
333 rangeEnd == 0) | 333 rangeEnd == 0) |
334 return TRACE_RETURN (true); | 334 return_trace (true); |
335 else if (designSize < rangeStart || | 335 else if (designSize < rangeStart || |
336 designSize > rangeEnd || | 336 designSize > rangeEnd || |
337 subfamilyNameID < 256 || | 337 subfamilyNameID < 256 || |
338 subfamilyNameID > 32767) | 338 subfamilyNameID > 32767) |
339 return TRACE_RETURN (false); | 339 return_trace (false); |
340 else | 340 else |
341 return TRACE_RETURN (true); | 341 return_trace (true); |
342 } | 342 } |
343 | 343 |
344 USHORT designSize; /* Represents the design size in 720/inch | 344 USHORT designSize; /* Represents the design size in 720/inch |
345 * units (decipoints). The design size entry | 345 * units (decipoints). The design size entry |
346 * must be non-zero. When there is a design | 346 * must be non-zero. When there is a design |
347 * size but no recommended size range, the | 347 * size but no recommended size range, the |
348 * rest of the array will consist of zeros. */ | 348 * rest of the array will consist of zeros. */ |
349 USHORT subfamilyID; /* Has no independent meaning, but serves | 349 USHORT subfamilyID; /* Has no independent meaning, but serves |
350 * as an identifier that associates fonts | 350 * as an identifier that associates fonts |
351 * in a subfamily. All fonts which share a | 351 * in a subfamily. All fonts which share a |
(...skipping 29 matching lines...) Expand all Loading... |
381 }; | 381 }; |
382 | 382 |
383 /* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */ | 383 /* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */ |
384 struct FeatureParamsStylisticSet | 384 struct FeatureParamsStylisticSet |
385 { | 385 { |
386 inline bool sanitize (hb_sanitize_context_t *c) const | 386 inline bool sanitize (hb_sanitize_context_t *c) const |
387 { | 387 { |
388 TRACE_SANITIZE (this); | 388 TRACE_SANITIZE (this); |
389 /* Right now minorVersion is at zero. Which means, any table supports | 389 /* Right now minorVersion is at zero. Which means, any table supports |
390 * the uiNameID field. */ | 390 * the uiNameID field. */ |
391 return TRACE_RETURN (c->check_struct (this)); | 391 return_trace (c->check_struct (this)); |
392 } | 392 } |
393 | 393 |
394 USHORT version; /* (set to 0): This corresponds to a “minor” | 394 USHORT version; /* (set to 0): This corresponds to a “minor” |
395 * version number. Additional data may be | 395 * version number. Additional data may be |
396 * added to the end of this Feature Parameters | 396 * added to the end of this Feature Parameters |
397 * table in the future. */ | 397 * table in the future. */ |
398 | 398 |
399 USHORT uiNameID; /* The 'name' table name ID that specifies a | 399 USHORT uiNameID; /* The 'name' table name ID that specifies a |
400 * string (or strings, for multiple languages) | 400 * string (or strings, for multiple languages) |
401 * for a user-interface label for this | 401 * for a user-interface label for this |
(...skipping 11 matching lines...) Expand all Loading... |
413 public: | 413 public: |
414 DEFINE_SIZE_STATIC (4); | 414 DEFINE_SIZE_STATIC (4); |
415 }; | 415 }; |
416 | 416 |
417 /* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */ | 417 /* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */ |
418 struct FeatureParamsCharacterVariants | 418 struct FeatureParamsCharacterVariants |
419 { | 419 { |
420 inline bool sanitize (hb_sanitize_context_t *c) const | 420 inline bool sanitize (hb_sanitize_context_t *c) const |
421 { | 421 { |
422 TRACE_SANITIZE (this); | 422 TRACE_SANITIZE (this); |
423 return TRACE_RETURN (c->check_struct (this) && | 423 return_trace (c->check_struct (this) && |
424 » » » characters.sanitize (c)); | 424 » » characters.sanitize (c)); |
425 } | 425 } |
426 | 426 |
427 USHORT format; /* Format number is set to 0. */ | 427 USHORT format; /* Format number is set to 0. */ |
428 USHORT featUILableNameID; /* The ‘name’ table name ID that | 428 USHORT featUILableNameID; /* The ‘name’ table name ID that |
429 * specifies a string (or strings, | 429 * specifies a string (or strings, |
430 * for multiple languages) for a | 430 * for multiple languages) for a |
431 * user-interface label for this | 431 * user-interface label for this |
432 * feature. (May be NULL.) */ | 432 * feature. (May be NULL.) */ |
433 USHORT featUITooltipTextNameID;/* The ‘name’ table name ID that | 433 USHORT featUITooltipTextNameID;/* The ‘name’ table name ID that |
434 * specifies a string (or strings, | 434 * specifies a string (or strings, |
(...skipping 20 matching lines...) Expand all Loading... |
455 public: | 455 public: |
456 DEFINE_SIZE_ARRAY (14, characters); | 456 DEFINE_SIZE_ARRAY (14, characters); |
457 }; | 457 }; |
458 | 458 |
459 struct FeatureParams | 459 struct FeatureParams |
460 { | 460 { |
461 inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) const | 461 inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) const |
462 { | 462 { |
463 TRACE_SANITIZE (this); | 463 TRACE_SANITIZE (this); |
464 if (tag == HB_TAG ('s','i','z','e')) | 464 if (tag == HB_TAG ('s','i','z','e')) |
465 return TRACE_RETURN (u.size.sanitize (c)); | 465 return_trace (u.size.sanitize (c)); |
466 if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */ | 466 if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */ |
467 return TRACE_RETURN (u.stylisticSet.sanitize (c)); | 467 return_trace (u.stylisticSet.sanitize (c)); |
468 if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */ | 468 if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */ |
469 return TRACE_RETURN (u.characterVariants.sanitize (c)); | 469 return_trace (u.characterVariants.sanitize (c)); |
470 return TRACE_RETURN (true); | 470 return_trace (true); |
471 } | 471 } |
472 | 472 |
473 inline const FeatureParamsSize& get_size_params (hb_tag_t tag) const | 473 inline const FeatureParamsSize& get_size_params (hb_tag_t tag) const |
474 { | 474 { |
475 if (tag == HB_TAG ('s','i','z','e')) | 475 if (tag == HB_TAG ('s','i','z','e')) |
476 return u.size; | 476 return u.size; |
477 return Null(FeatureParamsSize); | 477 return Null(FeatureParamsSize); |
478 } | 478 } |
479 | 479 |
480 private: | 480 private: |
(...skipping 17 matching lines...) Expand all Loading... |
498 { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); } | 498 { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); } |
499 | 499 |
500 inline const FeatureParams &get_feature_params (void) const | 500 inline const FeatureParams &get_feature_params (void) const |
501 { return this+featureParams; } | 501 { return this+featureParams; } |
502 | 502 |
503 inline bool sanitize (hb_sanitize_context_t *c, | 503 inline bool sanitize (hb_sanitize_context_t *c, |
504 const Record<Feature>::sanitize_closure_t *closure) cons
t | 504 const Record<Feature>::sanitize_closure_t *closure) cons
t |
505 { | 505 { |
506 TRACE_SANITIZE (this); | 506 TRACE_SANITIZE (this); |
507 if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) | 507 if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) |
508 return TRACE_RETURN (false); | 508 return_trace (false); |
509 | 509 |
510 /* Some earlier versions of Adobe tools calculated the offset of the | 510 /* Some earlier versions of Adobe tools calculated the offset of the |
511 * FeatureParams subtable from the beginning of the FeatureList table! | 511 * FeatureParams subtable from the beginning of the FeatureList table! |
512 * | 512 * |
513 * If sanitizing "failed" for the FeatureParams subtable, try it with the | 513 * If sanitizing "failed" for the FeatureParams subtable, try it with the |
514 * alternative location. We would know sanitize "failed" if old value | 514 * alternative location. We would know sanitize "failed" if old value |
515 * of the offset was non-zero, but it's zeroed now. | 515 * of the offset was non-zero, but it's zeroed now. |
516 * | 516 * |
517 * Only do this for the 'size' feature, since at the time of the faulty | 517 * Only do this for the 'size' feature, since at the time of the faulty |
518 * Adobe tools, only the 'size' feature had FeatureParams defined. | 518 * Adobe tools, only the 'size' feature had FeatureParams defined. |
519 */ | 519 */ |
520 | 520 |
521 OffsetTo<FeatureParams> orig_offset = featureParams; | 521 OffsetTo<FeatureParams> orig_offset = featureParams; |
522 if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_
TAG_NONE))) | 522 if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_
TAG_NONE))) |
523 return TRACE_RETURN (false); | 523 return_trace (false); |
524 | 524 |
525 if (likely (orig_offset.is_null ())) | 525 if (likely (orig_offset.is_null ())) |
526 return TRACE_RETURN (true); | 526 return_trace (true); |
527 | 527 |
528 if (featureParams == 0 && closure && | 528 if (featureParams == 0 && closure && |
529 closure->tag == HB_TAG ('s','i','z','e') && | 529 closure->tag == HB_TAG ('s','i','z','e') && |
530 closure->list_base && closure->list_base < this) | 530 closure->list_base && closure->list_base < this) |
531 { | 531 { |
532 unsigned int new_offset_int = (unsigned int) orig_offset - | 532 unsigned int new_offset_int = (unsigned int) orig_offset - |
533 (((char *) this) - ((char *) closure->list_b
ase)); | 533 (((char *) this) - ((char *) closure->list_b
ase)); |
534 | 534 |
535 OffsetTo<FeatureParams> new_offset; | 535 OffsetTo<FeatureParams> new_offset; |
536 /* Check that it did not overflow. */ | 536 /* Check that it did not overflow. */ |
537 new_offset.set (new_offset_int); | 537 new_offset.set (new_offset_int); |
538 if (new_offset == new_offset_int && | 538 if (new_offset == new_offset_int && |
539 c->try_set (&featureParams, new_offset) && | 539 c->try_set (&featureParams, new_offset) && |
540 !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE
)) | 540 !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE
)) |
541 » return TRACE_RETURN (false); | 541 » return_trace (false); |
542 } | 542 } |
543 | 543 |
544 return TRACE_RETURN (true); | 544 return_trace (true); |
545 } | 545 } |
546 | 546 |
547 OffsetTo<FeatureParams> | 547 OffsetTo<FeatureParams> |
548 featureParams; /* Offset to Feature Parameters table (if one | 548 featureParams; /* Offset to Feature Parameters table (if one |
549 * has been defined for the feature), relative | 549 * has been defined for the feature), relative |
550 * to the beginning of the Feature Table; = Null | 550 * to the beginning of the Feature Table; = Null |
551 * if not required */ | 551 * if not required */ |
552 IndexArray lookupIndex; /* Array of LookupList indices */ | 552 IndexArray lookupIndex; /* Array of LookupList indices */ |
553 public: | 553 public: |
554 DEFINE_SIZE_ARRAY (4, lookupIndex); | 554 DEFINE_SIZE_ARRAY (4, lookupIndex); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 | 606 |
607 template <typename SubTableType, typename context_t> | 607 template <typename SubTableType, typename context_t> |
608 inline typename context_t::return_t dispatch (context_t *c) const | 608 inline typename context_t::return_t dispatch (context_t *c) const |
609 { | 609 { |
610 unsigned int lookup_type = get_type (); | 610 unsigned int lookup_type = get_type (); |
611 TRACE_DISPATCH (this, lookup_type); | 611 TRACE_DISPATCH (this, lookup_type); |
612 unsigned int count = get_subtable_count (); | 612 unsigned int count = get_subtable_count (); |
613 for (unsigned int i = 0; i < count; i++) { | 613 for (unsigned int i = 0; i < count; i++) { |
614 typename context_t::return_t r = get_subtable<SubTableType> (i).dispatch (
c, lookup_type); | 614 typename context_t::return_t r = get_subtable<SubTableType> (i).dispatch (
c, lookup_type); |
615 if (c->stop_sublookup_iteration (r)) | 615 if (c->stop_sublookup_iteration (r)) |
616 return TRACE_RETURN (r); | 616 return_trace (r); |
617 } | 617 } |
618 return TRACE_RETURN (c->default_return_value ()); | 618 return_trace (c->default_return_value ()); |
619 } | 619 } |
620 | 620 |
621 inline bool serialize (hb_serialize_context_t *c, | 621 inline bool serialize (hb_serialize_context_t *c, |
622 unsigned int lookup_type, | 622 unsigned int lookup_type, |
623 uint32_t lookup_props, | 623 uint32_t lookup_props, |
624 unsigned int num_subtables) | 624 unsigned int num_subtables) |
625 { | 625 { |
626 TRACE_SERIALIZE (this); | 626 TRACE_SERIALIZE (this); |
627 if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); | 627 if (unlikely (!c->extend_min (*this))) return_trace (false); |
628 lookupType.set (lookup_type); | 628 lookupType.set (lookup_type); |
629 lookupFlag.set (lookup_props & 0xFFFFu); | 629 lookupFlag.set (lookup_props & 0xFFFFu); |
630 if (unlikely (!subTable.serialize (c, num_subtables))) return TRACE_RETURN (
false); | 630 if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false); |
631 if (lookupFlag & LookupFlag::UseMarkFilteringSet) | 631 if (lookupFlag & LookupFlag::UseMarkFilteringSet) |
632 { | 632 { |
633 USHORT &markFilteringSet = StructAfter<USHORT> (subTable); | 633 USHORT &markFilteringSet = StructAfter<USHORT> (subTable); |
634 markFilteringSet.set (lookup_props >> 16); | 634 markFilteringSet.set (lookup_props >> 16); |
635 } | 635 } |
636 return TRACE_RETURN (true); | 636 return_trace (true); |
637 } | 637 } |
638 | 638 |
639 inline bool sanitize (hb_sanitize_context_t *c) const | 639 inline bool sanitize (hb_sanitize_context_t *c) const |
640 { | 640 { |
641 TRACE_SANITIZE (this); | 641 TRACE_SANITIZE (this); |
642 /* Real sanitize of the subtables is done by GSUB/GPOS/... */ | 642 /* Real sanitize of the subtables is done by GSUB/GPOS/... */ |
643 if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN
(false); | 643 if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false)
; |
644 if (lookupFlag & LookupFlag::UseMarkFilteringSet) | 644 if (lookupFlag & LookupFlag::UseMarkFilteringSet) |
645 { | 645 { |
646 const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); | 646 const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); |
647 if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false); | 647 if (!markFilteringSet.sanitize (c)) return_trace (false); |
648 } | 648 } |
649 return TRACE_RETURN (true); | 649 return_trace (true); |
650 } | 650 } |
651 | 651 |
652 private: | 652 private: |
653 USHORT lookupType; /* Different enumerations for GSUB and G
POS */ | 653 USHORT lookupType; /* Different enumerations for GSUB and G
POS */ |
654 USHORT lookupFlag; /* Lookup qualifiers */ | 654 USHORT lookupFlag; /* Lookup qualifiers */ |
655 ArrayOf<Offset<> > | 655 ArrayOf<Offset<> > |
656 subTable; /* Array of SubTables */ | 656 subTable; /* Array of SubTables */ |
657 USHORT markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph s
ets | 657 USHORT markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph s
ets |
658 * structure. This field is only present
if bit | 658 * structure. This field is only present
if bit |
659 * UseMarkFilteringSet of lookup flags i
s set. */ | 659 * UseMarkFilteringSet of lookup flags i
s set. */ |
(...skipping 18 matching lines...) Expand all Loading... |
678 int i = glyphArray.bsearch (glyph_id); | 678 int i = glyphArray.bsearch (glyph_id); |
679 ASSERT_STATIC (((unsigned int) -1) == NOT_COVERED); | 679 ASSERT_STATIC (((unsigned int) -1) == NOT_COVERED); |
680 return i; | 680 return i; |
681 } | 681 } |
682 | 682 |
683 inline bool serialize (hb_serialize_context_t *c, | 683 inline bool serialize (hb_serialize_context_t *c, |
684 Supplier<GlyphID> &glyphs, | 684 Supplier<GlyphID> &glyphs, |
685 unsigned int num_glyphs) | 685 unsigned int num_glyphs) |
686 { | 686 { |
687 TRACE_SERIALIZE (this); | 687 TRACE_SERIALIZE (this); |
688 if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); | 688 if (unlikely (!c->extend_min (*this))) return_trace (false); |
689 glyphArray.len.set (num_glyphs); | 689 glyphArray.len.set (num_glyphs); |
690 if (unlikely (!c->extend (glyphArray))) return TRACE_RETURN (false); | 690 if (unlikely (!c->extend (glyphArray))) return_trace (false); |
691 for (unsigned int i = 0; i < num_glyphs; i++) | 691 for (unsigned int i = 0; i < num_glyphs; i++) |
692 glyphArray[i] = glyphs[i]; | 692 glyphArray[i] = glyphs[i]; |
693 glyphs.advance (num_glyphs); | 693 glyphs.advance (num_glyphs); |
694 return TRACE_RETURN (true); | 694 return_trace (true); |
695 } | 695 } |
696 | 696 |
697 inline bool sanitize (hb_sanitize_context_t *c) const | 697 inline bool sanitize (hb_sanitize_context_t *c) const |
698 { | 698 { |
699 TRACE_SANITIZE (this); | 699 TRACE_SANITIZE (this); |
700 return TRACE_RETURN (glyphArray.sanitize (c)); | 700 return_trace (glyphArray.sanitize (c)); |
701 } | 701 } |
702 | 702 |
703 inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) c
onst { | 703 inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) c
onst { |
704 return glyphs->has (glyphArray[index]); | 704 return glyphs->has (glyphArray[index]); |
705 } | 705 } |
706 | 706 |
707 template <typename set_t> | 707 template <typename set_t> |
708 inline void add_coverage (set_t *glyphs) const { | 708 inline void add_coverage (set_t *glyphs) const { |
709 unsigned int count = glyphArray.len; | 709 unsigned int count = glyphArray.len; |
710 for (unsigned int i = 0; i < count; i++) | 710 for (unsigned int i = 0; i < count; i++) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 return (unsigned int) range.value + (glyph_id - range.start); | 747 return (unsigned int) range.value + (glyph_id - range.start); |
748 } | 748 } |
749 return NOT_COVERED; | 749 return NOT_COVERED; |
750 } | 750 } |
751 | 751 |
752 inline bool serialize (hb_serialize_context_t *c, | 752 inline bool serialize (hb_serialize_context_t *c, |
753 Supplier<GlyphID> &glyphs, | 753 Supplier<GlyphID> &glyphs, |
754 unsigned int num_glyphs) | 754 unsigned int num_glyphs) |
755 { | 755 { |
756 TRACE_SERIALIZE (this); | 756 TRACE_SERIALIZE (this); |
757 if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); | 757 if (unlikely (!c->extend_min (*this))) return_trace (false); |
758 | 758 |
759 if (unlikely (!num_glyphs)) return TRACE_RETURN (true); | 759 if (unlikely (!num_glyphs)) return_trace (true); |
760 | 760 |
761 unsigned int num_ranges = 1; | 761 unsigned int num_ranges = 1; |
762 for (unsigned int i = 1; i < num_glyphs; i++) | 762 for (unsigned int i = 1; i < num_glyphs; i++) |
763 if (glyphs[i - 1] + 1 != glyphs[i]) | 763 if (glyphs[i - 1] + 1 != glyphs[i]) |
764 num_ranges++; | 764 num_ranges++; |
765 rangeRecord.len.set (num_ranges); | 765 rangeRecord.len.set (num_ranges); |
766 if (unlikely (!c->extend (rangeRecord))) return TRACE_RETURN (false); | 766 if (unlikely (!c->extend (rangeRecord))) return_trace (false); |
767 | 767 |
768 unsigned int range = 0; | 768 unsigned int range = 0; |
769 rangeRecord[range].start = glyphs[0]; | 769 rangeRecord[range].start = glyphs[0]; |
770 rangeRecord[range].value.set (0); | 770 rangeRecord[range].value.set (0); |
771 for (unsigned int i = 1; i < num_glyphs; i++) | 771 for (unsigned int i = 1; i < num_glyphs; i++) |
772 if (glyphs[i - 1] + 1 != glyphs[i]) { | 772 if (glyphs[i - 1] + 1 != glyphs[i]) { |
773 range++; | 773 range++; |
774 rangeRecord[range].start = glyphs[i]; | 774 rangeRecord[range].start = glyphs[i]; |
775 rangeRecord[range].value.set (i); | 775 rangeRecord[range].value.set (i); |
776 rangeRecord[range].end = glyphs[i]; | 776 rangeRecord[range].end = glyphs[i]; |
777 } else { | 777 } else { |
778 rangeRecord[range].end = glyphs[i]; | 778 rangeRecord[range].end = glyphs[i]; |
779 } | 779 } |
780 glyphs.advance (num_glyphs); | 780 glyphs.advance (num_glyphs); |
781 return TRACE_RETURN (true); | 781 return_trace (true); |
782 } | 782 } |
783 | 783 |
784 inline bool sanitize (hb_sanitize_context_t *c) const | 784 inline bool sanitize (hb_sanitize_context_t *c) const |
785 { | 785 { |
786 TRACE_SANITIZE (this); | 786 TRACE_SANITIZE (this); |
787 return TRACE_RETURN (rangeRecord.sanitize (c)); | 787 return_trace (rangeRecord.sanitize (c)); |
788 } | 788 } |
789 | 789 |
790 inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) c
onst { | 790 inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) c
onst { |
791 unsigned int i; | 791 unsigned int i; |
792 unsigned int count = rangeRecord.len; | 792 unsigned int count = rangeRecord.len; |
793 for (i = 0; i < count; i++) { | 793 for (i = 0; i < count; i++) { |
794 const RangeRecord &range = rangeRecord[i]; | 794 const RangeRecord &range = rangeRecord[i]; |
795 if (range.value <= index && | 795 if (range.value <= index && |
796 index < (unsigned int) range.value + (range.end - range.start) && | 796 index < (unsigned int) range.value + (range.end - range.start) && |
797 range.intersects (glyphs)) | 797 range.intersects (glyphs)) |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
857 case 2: return u.format2.get_coverage(glyph_id); | 857 case 2: return u.format2.get_coverage(glyph_id); |
858 default:return NOT_COVERED; | 858 default:return NOT_COVERED; |
859 } | 859 } |
860 } | 860 } |
861 | 861 |
862 inline bool serialize (hb_serialize_context_t *c, | 862 inline bool serialize (hb_serialize_context_t *c, |
863 Supplier<GlyphID> &glyphs, | 863 Supplier<GlyphID> &glyphs, |
864 unsigned int num_glyphs) | 864 unsigned int num_glyphs) |
865 { | 865 { |
866 TRACE_SERIALIZE (this); | 866 TRACE_SERIALIZE (this); |
867 if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); | 867 if (unlikely (!c->extend_min (*this))) return_trace (false); |
868 unsigned int num_ranges = 1; | 868 unsigned int num_ranges = 1; |
869 for (unsigned int i = 1; i < num_glyphs; i++) | 869 for (unsigned int i = 1; i < num_glyphs; i++) |
870 if (glyphs[i - 1] + 1 != glyphs[i]) | 870 if (glyphs[i - 1] + 1 != glyphs[i]) |
871 num_ranges++; | 871 num_ranges++; |
872 u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2); | 872 u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2); |
873 switch (u.format) { | 873 switch (u.format) { |
874 case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, num_glyphs)); | 874 case 1: return_trace (u.format1.serialize (c, glyphs, num_glyphs)); |
875 case 2: return TRACE_RETURN (u.format2.serialize (c, glyphs, num_glyphs)); | 875 case 2: return_trace (u.format2.serialize (c, glyphs, num_glyphs)); |
876 default:return TRACE_RETURN (false); | 876 default:return_trace (false); |
877 } | 877 } |
878 } | 878 } |
879 | 879 |
880 inline bool sanitize (hb_sanitize_context_t *c) const | 880 inline bool sanitize (hb_sanitize_context_t *c) const |
881 { | 881 { |
882 TRACE_SANITIZE (this); | 882 TRACE_SANITIZE (this); |
883 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | 883 if (!u.format.sanitize (c)) return_trace (false); |
884 switch (u.format) { | 884 switch (u.format) { |
885 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | 885 case 1: return_trace (u.format1.sanitize (c)); |
886 case 2: return TRACE_RETURN (u.format2.sanitize (c)); | 886 case 2: return_trace (u.format2.sanitize (c)); |
887 default:return TRACE_RETURN (true); | 887 default:return_trace (true); |
888 } | 888 } |
889 } | 889 } |
890 | 890 |
891 inline bool intersects (const hb_set_t *glyphs) const { | 891 inline bool intersects (const hb_set_t *glyphs) const { |
892 /* TODO speed this up */ | 892 /* TODO speed this up */ |
893 Coverage::Iter iter; | 893 Coverage::Iter iter; |
894 for (iter.init (*this); iter.more (); iter.next ()) { | 894 for (iter.init (*this); iter.more (); iter.next ()) { |
895 if (glyphs->has (iter.get_glyph ())) | 895 if (glyphs->has (iter.get_glyph ())) |
896 return true; | 896 return true; |
897 } | 897 } |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
986 { | 986 { |
987 unsigned int i = (unsigned int) (glyph_id - startGlyph); | 987 unsigned int i = (unsigned int) (glyph_id - startGlyph); |
988 if (unlikely (i < classValue.len)) | 988 if (unlikely (i < classValue.len)) |
989 return classValue[i]; | 989 return classValue[i]; |
990 return 0; | 990 return 0; |
991 } | 991 } |
992 | 992 |
993 inline bool sanitize (hb_sanitize_context_t *c) const | 993 inline bool sanitize (hb_sanitize_context_t *c) const |
994 { | 994 { |
995 TRACE_SANITIZE (this); | 995 TRACE_SANITIZE (this); |
996 return TRACE_RETURN (c->check_struct (this) && classValue.sanitize (c)); | 996 return_trace (c->check_struct (this) && classValue.sanitize (c)); |
997 } | 997 } |
998 | 998 |
999 template <typename set_t> | 999 template <typename set_t> |
1000 inline void add_class (set_t *glyphs, unsigned int klass) const { | 1000 inline void add_class (set_t *glyphs, unsigned int klass) const { |
1001 unsigned int count = classValue.len; | 1001 unsigned int count = classValue.len; |
1002 for (unsigned int i = 0; i < count; i++) | 1002 for (unsigned int i = 0; i < count; i++) |
1003 if (classValue[i] == klass) | 1003 if (classValue[i] == klass) |
1004 glyphs->add (startGlyph + i); | 1004 glyphs->add (startGlyph + i); |
1005 } | 1005 } |
1006 | 1006 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1043 { | 1043 { |
1044 int i = rangeRecord.bsearch (glyph_id); | 1044 int i = rangeRecord.bsearch (glyph_id); |
1045 if (unlikely (i != -1)) | 1045 if (unlikely (i != -1)) |
1046 return rangeRecord[i].value; | 1046 return rangeRecord[i].value; |
1047 return 0; | 1047 return 0; |
1048 } | 1048 } |
1049 | 1049 |
1050 inline bool sanitize (hb_sanitize_context_t *c) const | 1050 inline bool sanitize (hb_sanitize_context_t *c) const |
1051 { | 1051 { |
1052 TRACE_SANITIZE (this); | 1052 TRACE_SANITIZE (this); |
1053 return TRACE_RETURN (rangeRecord.sanitize (c)); | 1053 return_trace (rangeRecord.sanitize (c)); |
1054 } | 1054 } |
1055 | 1055 |
1056 template <typename set_t> | 1056 template <typename set_t> |
1057 inline void add_class (set_t *glyphs, unsigned int klass) const { | 1057 inline void add_class (set_t *glyphs, unsigned int klass) const { |
1058 unsigned int count = rangeRecord.len; | 1058 unsigned int count = rangeRecord.len; |
1059 for (unsigned int i = 0; i < count; i++) | 1059 for (unsigned int i = 0; i < count; i++) |
1060 if (rangeRecord[i].value == klass) | 1060 if (rangeRecord[i].value == klass) |
1061 rangeRecord[i].add_coverage (glyphs); | 1061 rangeRecord[i].add_coverage (glyphs); |
1062 } | 1062 } |
1063 | 1063 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1101 switch (u.format) { | 1101 switch (u.format) { |
1102 case 1: return u.format1.get_class(glyph_id); | 1102 case 1: return u.format1.get_class(glyph_id); |
1103 case 2: return u.format2.get_class(glyph_id); | 1103 case 2: return u.format2.get_class(glyph_id); |
1104 default:return 0; | 1104 default:return 0; |
1105 } | 1105 } |
1106 } | 1106 } |
1107 | 1107 |
1108 inline bool sanitize (hb_sanitize_context_t *c) const | 1108 inline bool sanitize (hb_sanitize_context_t *c) const |
1109 { | 1109 { |
1110 TRACE_SANITIZE (this); | 1110 TRACE_SANITIZE (this); |
1111 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | 1111 if (!u.format.sanitize (c)) return_trace (false); |
1112 switch (u.format) { | 1112 switch (u.format) { |
1113 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | 1113 case 1: return_trace (u.format1.sanitize (c)); |
1114 case 2: return TRACE_RETURN (u.format2.sanitize (c)); | 1114 case 2: return_trace (u.format2.sanitize (c)); |
1115 default:return TRACE_RETURN (true); | 1115 default:return_trace (true); |
1116 } | 1116 } |
1117 } | 1117 } |
1118 | 1118 |
1119 inline void add_class (hb_set_t *glyphs, unsigned int klass) const { | 1119 inline void add_class (hb_set_t *glyphs, unsigned int klass) const { |
1120 switch (u.format) { | 1120 switch (u.format) { |
1121 case 1: u.format1.add_class (glyphs, klass); return; | 1121 case 1: u.format1.add_class (glyphs, klass); return; |
1122 case 2: u.format2.add_class (glyphs, klass); return; | 1122 case 2: u.format2.add_class (glyphs, klass); return; |
1123 default:return; | 1123 default:return; |
1124 } | 1124 } |
1125 } | 1125 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1194 inline unsigned int get_size (void) const | 1194 inline unsigned int get_size (void) const |
1195 { | 1195 { |
1196 unsigned int f = deltaFormat; | 1196 unsigned int f = deltaFormat; |
1197 if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::sta
tic_size; | 1197 if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::sta
tic_size; |
1198 return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); | 1198 return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); |
1199 } | 1199 } |
1200 | 1200 |
1201 inline bool sanitize (hb_sanitize_context_t *c) const | 1201 inline bool sanitize (hb_sanitize_context_t *c) const |
1202 { | 1202 { |
1203 TRACE_SANITIZE (this); | 1203 TRACE_SANITIZE (this); |
1204 return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->g
et_size ())); | 1204 return_trace (c->check_struct (this) && c->check_range (this, this->get_size
())); |
1205 } | 1205 } |
1206 | 1206 |
1207 protected: | 1207 protected: |
1208 USHORT startSize; /* Smallest size to correct--in ppem */ | 1208 USHORT startSize; /* Smallest size to correct--in ppem */ |
1209 USHORT endSize; /* Largest size to correct--in ppem */ | 1209 USHORT endSize; /* Largest size to correct--in ppem */ |
1210 USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2
, or 3 | 1210 USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2
, or 3 |
1211 * 1 Signed 2-bit value, 8 values per
uint16 | 1211 * 1 Signed 2-bit value, 8 values per
uint16 |
1212 * 2 Signed 4-bit value, 4 values per
uint16 | 1212 * 2 Signed 4-bit value, 4 values per
uint16 |
1213 * 3 Signed 8-bit value, 2 values per
uint16 | 1213 * 3 Signed 8-bit value, 2 values per
uint16 |
1214 */ | 1214 */ |
1215 USHORT deltaValue[VAR]; /* Array of compressed data */ | 1215 USHORT deltaValue[VAR]; /* Array of compressed data */ |
1216 public: | 1216 public: |
1217 DEFINE_SIZE_ARRAY (6, deltaValue); | 1217 DEFINE_SIZE_ARRAY (6, deltaValue); |
1218 }; | 1218 }; |
1219 | 1219 |
1220 | 1220 |
1221 } /* namespace OT */ | 1221 } /* namespace OT */ |
1222 | 1222 |
1223 | 1223 |
1224 #endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */ | 1224 #endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */ |
OLD | NEW |