| 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 |