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 19 matching lines...) Expand all Loading... |
30 #define HB_OT_LAYOUT_COMMON_PRIVATE_HH | 30 #define HB_OT_LAYOUT_COMMON_PRIVATE_HH |
31 | 31 |
32 #include "hb-ot-layout-private.hh" | 32 #include "hb-ot-layout-private.hh" |
33 #include "hb-open-type-private.hh" | 33 #include "hb-open-type-private.hh" |
34 #include "hb-set-private.hh" | 34 #include "hb-set-private.hh" |
35 | 35 |
36 | 36 |
37 namespace OT { | 37 namespace OT { |
38 | 38 |
39 | 39 |
| 40 #define TRACE_DISPATCH(this, format) \ |
| 41 hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t
> trace \ |
| 42 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ |
| 43 "format %d", (int) format); |
| 44 |
| 45 |
40 #define NOT_COVERED ((unsigned int) -1) | 46 #define NOT_COVERED ((unsigned int) -1) |
41 #define MAX_NESTING_LEVEL 8 | 47 #define MAX_NESTING_LEVEL 8 |
42 #define MAX_CONTEXT_LENGTH 64 | 48 #define MAX_CONTEXT_LENGTH 64 |
43 | 49 |
44 | 50 |
45 | 51 |
46 /* | 52 /* |
47 * | 53 * |
48 * OpenType Layout Common Table Formats | 54 * OpenType Layout Common Table Formats |
49 * | 55 * |
50 */ | 56 */ |
51 | 57 |
52 | 58 |
53 /* | 59 /* |
54 * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList | 60 * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList |
55 */ | 61 */ |
56 | 62 |
57 template <typename Type> | 63 template <typename Type> |
58 struct Record | 64 struct Record |
59 { | 65 { |
60 inline int cmp (hb_tag_t a) const { | 66 inline int cmp (hb_tag_t a) const { |
61 return tag.cmp (a); | 67 return tag.cmp (a); |
62 } | 68 } |
63 | 69 |
64 struct sanitize_closure_t { | 70 struct sanitize_closure_t { |
65 hb_tag_t tag; | 71 hb_tag_t tag; |
66 void *list_base; | 72 const void *list_base; |
67 }; | 73 }; |
68 inline bool sanitize (hb_sanitize_context_t *c, void *base) { | 74 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const |
| 75 { |
69 TRACE_SANITIZE (this); | 76 TRACE_SANITIZE (this); |
70 const sanitize_closure_t closure = {tag, base}; | 77 const sanitize_closure_t closure = {tag, base}; |
71 return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base, &cl
osure)); | 78 return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base, &cl
osure)); |
72 } | 79 } |
73 | 80 |
74 Tag tag; /* 4-byte Tag identifier */ | 81 Tag tag; /* 4-byte Tag identifier */ |
75 OffsetTo<Type> | 82 OffsetTo<Type> |
76 offset; /* Offset from beginning of object holding | 83 offset; /* Offset from beginning of object holding |
77 * the Record */ | 84 * the Record */ |
78 public: | 85 public: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 } | 121 } |
115 } | 122 } |
116 }; | 123 }; |
117 | 124 |
118 template <typename Type> | 125 template <typename Type> |
119 struct RecordListOf : RecordArrayOf<Type> | 126 struct RecordListOf : RecordArrayOf<Type> |
120 { | 127 { |
121 inline const Type& operator [] (unsigned int i) const | 128 inline const Type& operator [] (unsigned int i) const |
122 { return this+RecordArrayOf<Type>::operator [](i).offset; } | 129 { return this+RecordArrayOf<Type>::operator [](i).offset; } |
123 | 130 |
124 inline bool sanitize (hb_sanitize_context_t *c) { | 131 inline bool sanitize (hb_sanitize_context_t *c) const |
| 132 { |
125 TRACE_SANITIZE (this); | 133 TRACE_SANITIZE (this); |
126 return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this)); | 134 return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this)); |
127 } | 135 } |
128 }; | 136 }; |
129 | 137 |
130 | 138 |
131 struct RangeRecord | 139 struct RangeRecord |
132 { | 140 { |
133 inline int cmp (hb_codepoint_t g) const { | 141 inline int cmp (hb_codepoint_t g) const { |
134 return g < start ? -1 : g <= end ? 0 : +1 ; | 142 return g < start ? -1 : g <= end ? 0 : +1 ; |
135 } | 143 } |
136 | 144 |
137 inline bool sanitize (hb_sanitize_context_t *c) { | 145 inline bool sanitize (hb_sanitize_context_t *c) const |
| 146 { |
138 TRACE_SANITIZE (this); | 147 TRACE_SANITIZE (this); |
139 return TRACE_RETURN (c->check_struct (this)); | 148 return TRACE_RETURN (c->check_struct (this)); |
140 } | 149 } |
141 | 150 |
142 inline bool intersects (const hb_set_t *glyphs) const { | 151 inline bool intersects (const hb_set_t *glyphs) const { |
143 return glyphs->intersects (start, end); | 152 return glyphs->intersects (start, end); |
144 } | 153 } |
145 | 154 |
146 template <typename set_t> | 155 template <typename set_t> |
147 inline void add_coverage (set_t *glyphs) const { | 156 inline void add_coverage (set_t *glyphs) const { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 | 201 |
193 inline bool has_required_feature (void) const { return reqFeatureIndex != 0xFF
FFu; } | 202 inline bool has_required_feature (void) const { return reqFeatureIndex != 0xFF
FFu; } |
194 inline unsigned int get_required_feature_index (void) const | 203 inline unsigned int get_required_feature_index (void) const |
195 { | 204 { |
196 if (reqFeatureIndex == 0xFFFFu) | 205 if (reqFeatureIndex == 0xFFFFu) |
197 return Index::NOT_FOUND_INDEX; | 206 return Index::NOT_FOUND_INDEX; |
198 return reqFeatureIndex;; | 207 return reqFeatureIndex;; |
199 } | 208 } |
200 | 209 |
201 inline bool sanitize (hb_sanitize_context_t *c, | 210 inline bool sanitize (hb_sanitize_context_t *c, |
202 » » » const Record<LangSys>::sanitize_closure_t * = NULL) { | 211 » » » const Record<LangSys>::sanitize_closure_t * = NULL) cons
t |
| 212 { |
203 TRACE_SANITIZE (this); | 213 TRACE_SANITIZE (this); |
204 return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c)); | 214 return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c)); |
205 } | 215 } |
206 | 216 |
207 Offset<> lookupOrderZ; /* = Null (reserved for an offset to a | 217 Offset<> lookupOrderZ; /* = Null (reserved for an offset to a |
208 * reordering table) */ | 218 * reordering table) */ |
209 USHORT reqFeatureIndex;/* Index of a feature required for this | 219 USHORT reqFeatureIndex;/* Index of a feature required for this |
210 * language system--if no required features | 220 * language system--if no required features |
211 * = 0xFFFFu */ | 221 * = 0xFFFFu */ |
212 IndexArray featureIndex; /* Array of indices into the FeatureList */ | 222 IndexArray featureIndex; /* Array of indices into the FeatureList */ |
(...skipping 18 matching lines...) Expand all Loading... |
231 if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys (); | 241 if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys (); |
232 return this+langSys[i].offset; | 242 return this+langSys[i].offset; |
233 } | 243 } |
234 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 |
235 { return langSys.find_index (tag, index); } | 245 { return langSys.find_index (tag, index); } |
236 | 246 |
237 inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; } | 247 inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; } |
238 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; } |
239 | 249 |
240 inline bool sanitize (hb_sanitize_context_t *c, | 250 inline bool sanitize (hb_sanitize_context_t *c, |
241 » » » const Record<Script>::sanitize_closure_t * = NULL) { | 251 » » » const Record<Script>::sanitize_closure_t * = NULL) const |
| 252 { |
242 TRACE_SANITIZE (this); | 253 TRACE_SANITIZE (this); |
243 return TRACE_RETURN (defaultLangSys.sanitize (c, this) && langSys.sanitize (
c, this)); | 254 return TRACE_RETURN (defaultLangSys.sanitize (c, this) && langSys.sanitize (
c, this)); |
244 } | 255 } |
245 | 256 |
246 protected: | 257 protected: |
247 OffsetTo<LangSys> | 258 OffsetTo<LangSys> |
248 defaultLangSys; /* Offset to DefaultLangSys table--from | 259 defaultLangSys; /* Offset to DefaultLangSys table--from |
249 * beginning of Script table--may be Null */ | 260 * beginning of Script table--may be Null */ |
250 RecordArrayOf<LangSys> | 261 RecordArrayOf<LangSys> |
251 langSys; /* Array of LangSysRecords--listed | 262 langSys; /* Array of LangSysRecords--listed |
252 * alphabetically by LangSysTag */ | 263 * alphabetically by LangSysTag */ |
253 public: | 264 public: |
254 DEFINE_SIZE_ARRAY (4, langSys); | 265 DEFINE_SIZE_ARRAY (4, langSys); |
255 }; | 266 }; |
256 | 267 |
257 typedef RecordListOf<Script> ScriptList; | 268 typedef RecordListOf<Script> ScriptList; |
258 | 269 |
259 | 270 |
260 /* http://www.microsoft.com/typography/otspec/features_pt.htm#size */ | 271 /* http://www.microsoft.com/typography/otspec/features_pt.htm#size */ |
261 struct FeatureParamsSize | 272 struct FeatureParamsSize |
262 { | 273 { |
263 inline bool sanitize (hb_sanitize_context_t *c) { | 274 inline bool sanitize (hb_sanitize_context_t *c) const |
| 275 { |
264 TRACE_SANITIZE (this); | 276 TRACE_SANITIZE (this); |
265 if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); | 277 if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); |
266 | 278 |
267 /* 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 |
268 * Adobe tools calculated the offset of the FeatureParams sutable from the | 280 * Adobe tools calculated the offset of the FeatureParams sutable from the |
269 * 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 |
270 * 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 |
271 * 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. |
272 * | 284 * |
273 * 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 : |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 USHORT rangeEnd; /* Small end of the recommended usage range | 376 USHORT rangeEnd; /* Small end of the recommended usage range |
365 (exclusive), stored in 720/inch units | 377 (exclusive), stored in 720/inch units |
366 * (decipoints). */ | 378 * (decipoints). */ |
367 public: | 379 public: |
368 DEFINE_SIZE_STATIC (10); | 380 DEFINE_SIZE_STATIC (10); |
369 }; | 381 }; |
370 | 382 |
371 /* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */ | 383 /* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */ |
372 struct FeatureParamsStylisticSet | 384 struct FeatureParamsStylisticSet |
373 { | 385 { |
374 inline bool sanitize (hb_sanitize_context_t *c) { | 386 inline bool sanitize (hb_sanitize_context_t *c) const |
| 387 { |
375 TRACE_SANITIZE (this); | 388 TRACE_SANITIZE (this); |
376 /* Right now minorVersion is at zero. Which means, any table supports | 389 /* Right now minorVersion is at zero. Which means, any table supports |
377 * the uiNameID field. */ | 390 * the uiNameID field. */ |
378 return TRACE_RETURN (c->check_struct (this)); | 391 return TRACE_RETURN (c->check_struct (this)); |
379 } | 392 } |
380 | 393 |
381 USHORT version; /* (set to 0): This corresponds to a “minor” | 394 USHORT version; /* (set to 0): This corresponds to a “minor” |
382 * version number. Additional data may be | 395 * version number. Additional data may be |
383 * added to the end of this Feature Parameters | 396 * added to the end of this Feature Parameters |
384 * table in the future. */ | 397 * table in the future. */ |
(...skipping 12 matching lines...) Expand all Loading... |
397 * fallback. The string should be kept to a | 410 * fallback. The string should be kept to a |
398 * minimal length to fit comfortably with | 411 * minimal length to fit comfortably with |
399 * different application interfaces. */ | 412 * different application interfaces. */ |
400 public: | 413 public: |
401 DEFINE_SIZE_STATIC (4); | 414 DEFINE_SIZE_STATIC (4); |
402 }; | 415 }; |
403 | 416 |
404 /* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */ | 417 /* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */ |
405 struct FeatureParamsCharacterVariants | 418 struct FeatureParamsCharacterVariants |
406 { | 419 { |
407 inline bool sanitize (hb_sanitize_context_t *c) { | 420 inline bool sanitize (hb_sanitize_context_t *c) const |
| 421 { |
408 TRACE_SANITIZE (this); | 422 TRACE_SANITIZE (this); |
409 return TRACE_RETURN (c->check_struct (this) && | 423 return TRACE_RETURN (c->check_struct (this) && |
410 characters.sanitize (c)); | 424 characters.sanitize (c)); |
411 } | 425 } |
412 | 426 |
413 USHORT format; /* Format number is set to 0. */ | 427 USHORT format; /* Format number is set to 0. */ |
414 USHORT featUILableNameID; /* The ‘name’ table name ID that | 428 USHORT featUILableNameID; /* The ‘name’ table name ID that |
415 * specifies a string (or strings, | 429 * specifies a string (or strings, |
416 * for multiple languages) for a | 430 * for multiple languages) for a |
417 * user-interface label for this | 431 * user-interface label for this |
(...skipping 19 matching lines...) Expand all Loading... |
437 characters; /* Array of the Unicode Scalar Value | 451 characters; /* Array of the Unicode Scalar Value |
438 * of the characters for which this | 452 * of the characters for which this |
439 * feature provides glyph variants. | 453 * feature provides glyph variants. |
440 * (May be zero.) */ | 454 * (May be zero.) */ |
441 public: | 455 public: |
442 DEFINE_SIZE_ARRAY (14, characters); | 456 DEFINE_SIZE_ARRAY (14, characters); |
443 }; | 457 }; |
444 | 458 |
445 struct FeatureParams | 459 struct FeatureParams |
446 { | 460 { |
447 inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) { | 461 inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) const |
| 462 { |
448 TRACE_SANITIZE (this); | 463 TRACE_SANITIZE (this); |
449 if (tag == HB_TAG ('s','i','z','e')) | 464 if (tag == HB_TAG ('s','i','z','e')) |
450 return TRACE_RETURN (u.size.sanitize (c)); | 465 return TRACE_RETURN (u.size.sanitize (c)); |
451 if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */ | 466 if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */ |
452 return TRACE_RETURN (u.stylisticSet.sanitize (c)); | 467 return TRACE_RETURN (u.stylisticSet.sanitize (c)); |
453 if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */ | 468 if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */ |
454 return TRACE_RETURN (u.characterVariants.sanitize (c)); | 469 return TRACE_RETURN (u.characterVariants.sanitize (c)); |
455 return TRACE_RETURN (true); | 470 return TRACE_RETURN (true); |
456 } | 471 } |
457 | 472 |
(...skipping 21 matching lines...) Expand all Loading... |
479 { return lookupIndex[i]; } | 494 { return lookupIndex[i]; } |
480 inline unsigned int get_lookup_indexes (unsigned int start_index, | 495 inline unsigned int get_lookup_indexes (unsigned int start_index, |
481 unsigned int *lookup_count /* IN/OUT *
/, | 496 unsigned int *lookup_count /* IN/OUT *
/, |
482 unsigned int *lookup_tags /* OUT */) c
onst | 497 unsigned int *lookup_tags /* OUT */) c
onst |
483 { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); } | 498 { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); } |
484 | 499 |
485 inline const FeatureParams &get_feature_params (void) const | 500 inline const FeatureParams &get_feature_params (void) const |
486 { return this+featureParams; } | 501 { return this+featureParams; } |
487 | 502 |
488 inline bool sanitize (hb_sanitize_context_t *c, | 503 inline bool sanitize (hb_sanitize_context_t *c, |
489 » » » const Record<Feature>::sanitize_closure_t *closure) { | 504 » » » const Record<Feature>::sanitize_closure_t *closure) cons
t |
| 505 { |
490 TRACE_SANITIZE (this); | 506 TRACE_SANITIZE (this); |
491 if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) | 507 if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) |
492 return TRACE_RETURN (false); | 508 return TRACE_RETURN (false); |
493 | 509 |
494 /* Some earlier versions of Adobe tools calculated the offset of the | 510 /* Some earlier versions of Adobe tools calculated the offset of the |
495 * FeatureParams subtable from the beginning of the FeatureList table! | 511 * FeatureParams subtable from the beginning of the FeatureList table! |
496 * | 512 * |
497 * If sanitizing "failed" for the FeatureParams subtable, try it with the | 513 * If sanitizing "failed" for the FeatureParams subtable, try it with the |
498 * alternative location. We would know sanitize "failed" if old value | 514 * alternative location. We would know sanitize "failed" if old value |
499 * of the offset was non-zero, but it's zeroed now. | 515 * of the offset was non-zero, but it's zeroed now. |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 MarkAttachmentType = 0xFF00u | 570 MarkAttachmentType = 0xFF00u |
555 }; | 571 }; |
556 public: | 572 public: |
557 DEFINE_SIZE_STATIC (2); | 573 DEFINE_SIZE_STATIC (2); |
558 }; | 574 }; |
559 | 575 |
560 struct Lookup | 576 struct Lookup |
561 { | 577 { |
562 inline unsigned int get_subtable_count (void) const { return subTable.len; } | 578 inline unsigned int get_subtable_count (void) const { return subTable.len; } |
563 | 579 |
| 580 template <typename SubTableType> |
| 581 inline const SubTableType& get_subtable (unsigned int i) const |
| 582 { return this+CastR<OffsetArrayOf<SubTableType> > (subTable)[i]; } |
| 583 |
| 584 template <typename SubTableType> |
| 585 inline const OffsetArrayOf<SubTableType>& get_subtables (void) const |
| 586 { return CastR<OffsetArrayOf<SubTableType> > (subTable); } |
| 587 template <typename SubTableType> |
| 588 inline OffsetArrayOf<SubTableType>& get_subtables (void) |
| 589 { return CastR<OffsetArrayOf<SubTableType> > (subTable); } |
| 590 |
564 inline unsigned int get_type (void) const { return lookupType; } | 591 inline unsigned int get_type (void) const { return lookupType; } |
565 | 592 |
566 /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and | 593 /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and |
567 * higher 16-bit is mark-filtering-set if the lookup uses one. | 594 * higher 16-bit is mark-filtering-set if the lookup uses one. |
568 * Not to be confused with glyph_props which is very similar. */ | 595 * Not to be confused with glyph_props which is very similar. */ |
569 inline uint32_t get_props (void) const | 596 inline uint32_t get_props (void) const |
570 { | 597 { |
571 unsigned int flag = lookupFlag; | 598 unsigned int flag = lookupFlag; |
572 if (unlikely (flag & LookupFlag::UseMarkFilteringSet)) | 599 if (unlikely (flag & LookupFlag::UseMarkFilteringSet)) |
573 { | 600 { |
574 const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); | 601 const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); |
575 flag += (markFilteringSet << 16); | 602 flag += (markFilteringSet << 16); |
576 } | 603 } |
577 return flag; | 604 return flag; |
578 } | 605 } |
579 | 606 |
| 607 template <typename SubTableType, typename context_t> |
| 608 inline typename context_t::return_t dispatch (context_t *c) const |
| 609 { |
| 610 unsigned int lookup_type = get_type (); |
| 611 TRACE_DISPATCH (this, lookup_type); |
| 612 unsigned int count = get_subtable_count (); |
| 613 for (unsigned int i = 0; i < count; i++) { |
| 614 typename context_t::return_t r = get_subtable<SubTableType> (i).dispatch (
c, lookup_type); |
| 615 if (c->stop_sublookup_iteration (r)) |
| 616 return TRACE_RETURN (r); |
| 617 } |
| 618 return TRACE_RETURN (c->default_return_value ()); |
| 619 } |
| 620 |
580 inline bool serialize (hb_serialize_context_t *c, | 621 inline bool serialize (hb_serialize_context_t *c, |
581 unsigned int lookup_type, | 622 unsigned int lookup_type, |
582 uint32_t lookup_props, | 623 uint32_t lookup_props, |
583 unsigned int num_subtables) | 624 unsigned int num_subtables) |
584 { | 625 { |
585 TRACE_SERIALIZE (this); | 626 TRACE_SERIALIZE (this); |
586 if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); | 627 if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); |
587 lookupType.set (lookup_type); | 628 lookupType.set (lookup_type); |
588 lookupFlag.set (lookup_props & 0xFFFFu); | 629 lookupFlag.set (lookup_props & 0xFFFFu); |
589 if (unlikely (!subTable.serialize (c, num_subtables))) return TRACE_RETURN (
false); | 630 if (unlikely (!subTable.serialize (c, num_subtables))) return TRACE_RETURN (
false); |
590 if (lookupFlag & LookupFlag::UseMarkFilteringSet) | 631 if (lookupFlag & LookupFlag::UseMarkFilteringSet) |
591 { | 632 { |
592 USHORT &markFilteringSet = StructAfter<USHORT> (subTable); | 633 USHORT &markFilteringSet = StructAfter<USHORT> (subTable); |
593 markFilteringSet.set (lookup_props >> 16); | 634 markFilteringSet.set (lookup_props >> 16); |
594 } | 635 } |
595 return TRACE_RETURN (true); | 636 return TRACE_RETURN (true); |
596 } | 637 } |
597 | 638 |
598 inline bool sanitize (hb_sanitize_context_t *c) { | 639 inline bool sanitize (hb_sanitize_context_t *c) const |
| 640 { |
599 TRACE_SANITIZE (this); | 641 TRACE_SANITIZE (this); |
600 /* Real sanitize of the subtables is done by GSUB/GPOS/... */ | 642 /* Real sanitize of the subtables is done by GSUB/GPOS/... */ |
601 if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN
(false); | 643 if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN
(false); |
602 if (lookupFlag & LookupFlag::UseMarkFilteringSet) | 644 if (lookupFlag & LookupFlag::UseMarkFilteringSet) |
603 { | 645 { |
604 USHORT &markFilteringSet = StructAfter<USHORT> (subTable); | 646 const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); |
605 if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false); | 647 if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false); |
606 } | 648 } |
607 return TRACE_RETURN (true); | 649 return TRACE_RETURN (true); |
608 } | 650 } |
609 | 651 |
| 652 private: |
610 USHORT lookupType; /* Different enumerations for GSUB and G
POS */ | 653 USHORT lookupType; /* Different enumerations for GSUB and G
POS */ |
611 USHORT lookupFlag; /* Lookup qualifiers */ | 654 USHORT lookupFlag; /* Lookup qualifiers */ |
612 ArrayOf<Offset<> > | 655 ArrayOf<Offset<> > |
613 subTable; /* Array of SubTables */ | 656 subTable; /* Array of SubTables */ |
614 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 |
615 * structure. This field is only present
if bit | 658 * structure. This field is only present
if bit |
616 * UseMarkFilteringSet of lookup flags i
s set. */ | 659 * UseMarkFilteringSet of lookup flags i
s set. */ |
617 public: | 660 public: |
618 DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX); | 661 DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX); |
619 }; | 662 }; |
(...skipping 24 matching lines...) Expand all Loading... |
644 TRACE_SERIALIZE (this); | 687 TRACE_SERIALIZE (this); |
645 if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); | 688 if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); |
646 glyphArray.len.set (num_glyphs); | 689 glyphArray.len.set (num_glyphs); |
647 if (unlikely (!c->extend (glyphArray))) return TRACE_RETURN (false); | 690 if (unlikely (!c->extend (glyphArray))) return TRACE_RETURN (false); |
648 for (unsigned int i = 0; i < num_glyphs; i++) | 691 for (unsigned int i = 0; i < num_glyphs; i++) |
649 glyphArray[i] = glyphs[i]; | 692 glyphArray[i] = glyphs[i]; |
650 glyphs.advance (num_glyphs); | 693 glyphs.advance (num_glyphs); |
651 return TRACE_RETURN (true); | 694 return TRACE_RETURN (true); |
652 } | 695 } |
653 | 696 |
654 inline bool sanitize (hb_sanitize_context_t *c) { | 697 inline bool sanitize (hb_sanitize_context_t *c) const |
| 698 { |
655 TRACE_SANITIZE (this); | 699 TRACE_SANITIZE (this); |
656 return TRACE_RETURN (glyphArray.sanitize (c)); | 700 return TRACE_RETURN (glyphArray.sanitize (c)); |
657 } | 701 } |
658 | 702 |
659 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 { |
660 return glyphs->has (glyphArray[index]); | 704 return glyphs->has (glyphArray[index]); |
661 } | 705 } |
662 | 706 |
663 template <typename set_t> | 707 template <typename set_t> |
664 inline void add_coverage (set_t *glyphs) const { | 708 inline void add_coverage (set_t *glyphs) const { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 rangeRecord[range].start = glyphs[i]; | 774 rangeRecord[range].start = glyphs[i]; |
731 rangeRecord[range].value.set (i); | 775 rangeRecord[range].value.set (i); |
732 rangeRecord[range].end = glyphs[i]; | 776 rangeRecord[range].end = glyphs[i]; |
733 } else { | 777 } else { |
734 rangeRecord[range].end = glyphs[i]; | 778 rangeRecord[range].end = glyphs[i]; |
735 } | 779 } |
736 glyphs.advance (num_glyphs); | 780 glyphs.advance (num_glyphs); |
737 return TRACE_RETURN (true); | 781 return TRACE_RETURN (true); |
738 } | 782 } |
739 | 783 |
740 inline bool sanitize (hb_sanitize_context_t *c) { | 784 inline bool sanitize (hb_sanitize_context_t *c) const |
| 785 { |
741 TRACE_SANITIZE (this); | 786 TRACE_SANITIZE (this); |
742 return TRACE_RETURN (rangeRecord.sanitize (c)); | 787 return TRACE_RETURN (rangeRecord.sanitize (c)); |
743 } | 788 } |
744 | 789 |
745 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 { |
746 unsigned int i; | 791 unsigned int i; |
747 unsigned int count = rangeRecord.len; | 792 unsigned int count = rangeRecord.len; |
748 for (i = 0; i < count; i++) { | 793 for (i = 0; i < count; i++) { |
749 const RangeRecord &range = rangeRecord[i]; | 794 const RangeRecord &range = rangeRecord[i]; |
750 if (range.value <= index && | 795 if (range.value <= index && |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 if (glyphs[i - 1] + 1 != glyphs[i]) | 870 if (glyphs[i - 1] + 1 != glyphs[i]) |
826 num_ranges++; | 871 num_ranges++; |
827 u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2); | 872 u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2); |
828 switch (u.format) { | 873 switch (u.format) { |
829 case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, num_glyphs)); | 874 case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, num_glyphs)); |
830 case 2: return TRACE_RETURN (u.format2.serialize (c, glyphs, num_glyphs)); | 875 case 2: return TRACE_RETURN (u.format2.serialize (c, glyphs, num_glyphs)); |
831 default:return TRACE_RETURN (false); | 876 default:return TRACE_RETURN (false); |
832 } | 877 } |
833 } | 878 } |
834 | 879 |
835 inline bool sanitize (hb_sanitize_context_t *c) { | 880 inline bool sanitize (hb_sanitize_context_t *c) const |
| 881 { |
836 TRACE_SANITIZE (this); | 882 TRACE_SANITIZE (this); |
837 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | 883 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
838 switch (u.format) { | 884 switch (u.format) { |
839 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | 885 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
840 case 2: return TRACE_RETURN (u.format2.sanitize (c)); | 886 case 2: return TRACE_RETURN (u.format2.sanitize (c)); |
841 default:return TRACE_RETURN (true); | 887 default:return TRACE_RETURN (true); |
842 } | 888 } |
843 } | 889 } |
844 | 890 |
845 inline bool intersects (const hb_set_t *glyphs) const { | 891 inline bool intersects (const hb_set_t *glyphs) const { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
931 * Class Definition Table | 977 * Class Definition Table |
932 */ | 978 */ |
933 | 979 |
934 struct ClassDefFormat1 | 980 struct ClassDefFormat1 |
935 { | 981 { |
936 friend struct ClassDef; | 982 friend struct ClassDef; |
937 | 983 |
938 private: | 984 private: |
939 inline unsigned int get_class (hb_codepoint_t glyph_id) const | 985 inline unsigned int get_class (hb_codepoint_t glyph_id) const |
940 { | 986 { |
941 if (unlikely ((unsigned int) (glyph_id - startGlyph) < classValue.len)) | 987 unsigned int i = (unsigned int) (glyph_id - startGlyph); |
942 return classValue[glyph_id - startGlyph]; | 988 if (unlikely (i < classValue.len)) |
| 989 return classValue[i]; |
943 return 0; | 990 return 0; |
944 } | 991 } |
945 | 992 |
946 inline bool sanitize (hb_sanitize_context_t *c) { | 993 inline bool sanitize (hb_sanitize_context_t *c) const |
| 994 { |
947 TRACE_SANITIZE (this); | 995 TRACE_SANITIZE (this); |
948 return TRACE_RETURN (c->check_struct (this) && classValue.sanitize (c)); | 996 return TRACE_RETURN (c->check_struct (this) && classValue.sanitize (c)); |
949 } | 997 } |
950 | 998 |
951 template <typename set_t> | 999 template <typename set_t> |
952 inline void add_class (set_t *glyphs, unsigned int klass) const { | 1000 inline void add_class (set_t *glyphs, unsigned int klass) const { |
953 unsigned int count = classValue.len; | 1001 unsigned int count = classValue.len; |
954 for (unsigned int i = 0; i < count; i++) | 1002 for (unsigned int i = 0; i < count; i++) |
955 if (classValue[i] == klass) | 1003 if (classValue[i] == klass) |
956 glyphs->add (startGlyph + i); | 1004 glyphs->add (startGlyph + i); |
(...skipping 30 matching lines...) Expand all Loading... |
987 }; | 1035 }; |
988 | 1036 |
989 struct ClassDefFormat2 | 1037 struct ClassDefFormat2 |
990 { | 1038 { |
991 friend struct ClassDef; | 1039 friend struct ClassDef; |
992 | 1040 |
993 private: | 1041 private: |
994 inline unsigned int get_class (hb_codepoint_t glyph_id) const | 1042 inline unsigned int get_class (hb_codepoint_t glyph_id) const |
995 { | 1043 { |
996 int i = rangeRecord.bsearch (glyph_id); | 1044 int i = rangeRecord.bsearch (glyph_id); |
997 if (i != -1) | 1045 if (unlikely (i != -1)) |
998 return rangeRecord[i].value; | 1046 return rangeRecord[i].value; |
999 return 0; | 1047 return 0; |
1000 } | 1048 } |
1001 | 1049 |
1002 inline bool sanitize (hb_sanitize_context_t *c) { | 1050 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1051 { |
1003 TRACE_SANITIZE (this); | 1052 TRACE_SANITIZE (this); |
1004 return TRACE_RETURN (rangeRecord.sanitize (c)); | 1053 return TRACE_RETURN (rangeRecord.sanitize (c)); |
1005 } | 1054 } |
1006 | 1055 |
1007 template <typename set_t> | 1056 template <typename set_t> |
1008 inline void add_class (set_t *glyphs, unsigned int klass) const { | 1057 inline void add_class (set_t *glyphs, unsigned int klass) const { |
1009 unsigned int count = rangeRecord.len; | 1058 unsigned int count = rangeRecord.len; |
1010 for (unsigned int i = 0; i < count; i++) | 1059 for (unsigned int i = 0; i < count; i++) |
1011 if (rangeRecord[i].value == klass) | 1060 if (rangeRecord[i].value == klass) |
1012 rangeRecord[i].add_coverage (glyphs); | 1061 rangeRecord[i].add_coverage (glyphs); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1049 { | 1098 { |
1050 inline unsigned int get_class (hb_codepoint_t glyph_id) const | 1099 inline unsigned int get_class (hb_codepoint_t glyph_id) const |
1051 { | 1100 { |
1052 switch (u.format) { | 1101 switch (u.format) { |
1053 case 1: return u.format1.get_class(glyph_id); | 1102 case 1: return u.format1.get_class(glyph_id); |
1054 case 2: return u.format2.get_class(glyph_id); | 1103 case 2: return u.format2.get_class(glyph_id); |
1055 default:return 0; | 1104 default:return 0; |
1056 } | 1105 } |
1057 } | 1106 } |
1058 | 1107 |
1059 inline bool sanitize (hb_sanitize_context_t *c) { | 1108 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1109 { |
1060 TRACE_SANITIZE (this); | 1110 TRACE_SANITIZE (this); |
1061 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | 1111 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
1062 switch (u.format) { | 1112 switch (u.format) { |
1063 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | 1113 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
1064 case 2: return TRACE_RETURN (u.format2.sanitize (c)); | 1114 case 2: return TRACE_RETURN (u.format2.sanitize (c)); |
1065 default:return TRACE_RETURN (true); | 1115 default:return TRACE_RETURN (true); |
1066 } | 1116 } |
1067 } | 1117 } |
1068 | 1118 |
1069 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 { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1141 return delta; | 1191 return delta; |
1142 } | 1192 } |
1143 | 1193 |
1144 inline unsigned int get_size (void) const | 1194 inline unsigned int get_size (void) const |
1145 { | 1195 { |
1146 unsigned int f = deltaFormat; | 1196 unsigned int f = deltaFormat; |
1147 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; |
1148 return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); | 1198 return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); |
1149 } | 1199 } |
1150 | 1200 |
1151 inline bool sanitize (hb_sanitize_context_t *c) { | 1201 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1202 { |
1152 TRACE_SANITIZE (this); | 1203 TRACE_SANITIZE (this); |
1153 return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->g
et_size ())); | 1204 return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->g
et_size ())); |
1154 } | 1205 } |
1155 | 1206 |
1156 protected: | 1207 protected: |
1157 USHORT startSize; /* Smallest size to correct--in ppem */ | 1208 USHORT startSize; /* Smallest size to correct--in ppem */ |
1158 USHORT endSize; /* Largest size to correct--in ppem */ | 1209 USHORT endSize; /* Largest size to correct--in ppem */ |
1159 USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2
, or 3 | 1210 USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2
, or 3 |
1160 * 1 Signed 2-bit value, 8 values per
uint16 | 1211 * 1 Signed 2-bit value, 8 values per
uint16 |
1161 * 2 Signed 4-bit value, 4 values per
uint16 | 1212 * 2 Signed 4-bit value, 4 values per
uint16 |
1162 * 3 Signed 8-bit value, 2 values per
uint16 | 1213 * 3 Signed 8-bit value, 2 values per
uint16 |
1163 */ | 1214 */ |
1164 USHORT deltaValue[VAR]; /* Array of compressed data */ | 1215 USHORT deltaValue[VAR]; /* Array of compressed data */ |
1165 public: | 1216 public: |
1166 DEFINE_SIZE_ARRAY (6, deltaValue); | 1217 DEFINE_SIZE_ARRAY (6, deltaValue); |
1167 }; | 1218 }; |
1168 | 1219 |
1169 | 1220 |
1170 } /* namespace OT */ | 1221 } /* namespace OT */ |
1171 | 1222 |
1172 | 1223 |
1173 #endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */ | 1224 #endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */ |
OLD | NEW |