| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 2007,2008,2009 Red Hat, Inc. | 2 * Copyright © 2007,2008,2009 Red Hat, Inc. |
| 3 * Copyright © 2012,2013 Google, Inc. | 3 * Copyright © 2012,2013 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 hb_ot_layout_table_find_feature (hb_face_t *face, | 42 hb_ot_layout_table_find_feature (hb_face_t *face, |
| 43 hb_tag_t table_tag, | 43 hb_tag_t table_tag, |
| 44 hb_tag_t feature_tag, | 44 hb_tag_t feature_tag, |
| 45 unsigned int *feature_index); | 45 unsigned int *feature_index); |
| 46 | 46 |
| 47 | 47 |
| 48 /* | 48 /* |
| 49 * GDEF | 49 * GDEF |
| 50 */ | 50 */ |
| 51 | 51 |
| 52 typedef enum | 52 enum hb_ot_layout_glyph_props_flags_t |
| 53 { | 53 { |
| 54 /* The following three match LookupFlags::Ignore* numbers. */ | 54 /* The following three match LookupFlags::Ignore* numbers. */ |
| 55 HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 0x02u, | 55 HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 0x02u, |
| 56 HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE = 0x04u, | 56 HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE = 0x04u, |
| 57 HB_OT_LAYOUT_GLYPH_PROPS_MARK = 0x08u, | 57 HB_OT_LAYOUT_GLYPH_PROPS_MARK = 0x08u, |
| 58 | 58 |
| 59 /* The following are used internally; not derived from GDEF. */ | 59 /* The following are used internally; not derived from GDEF. */ |
| 60 HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED = 0x10u, | 60 HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED = 0x10u, |
| 61 HB_OT_LAYOUT_GLYPH_PROPS_LIGATED = 0x20u, | 61 HB_OT_LAYOUT_GLYPH_PROPS_LIGATED = 0x20u, |
| 62 HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED = 0x40u, | 62 HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED = 0x40u, |
| 63 | 63 |
| 64 HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED | | 64 HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED | |
| 65 HB_OT_LAYOUT_GLYPH_PROPS_LIGATED | | 65 HB_OT_LAYOUT_GLYPH_PROPS_LIGATED | |
| 66 HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED | 66 HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED |
| 67 } hb_ot_layout_glyph_class_mask_t; | 67 }; |
| 68 HB_MARK_AS_FLAG_T (hb_ot_layout_glyph_props_flags_t); |
| 68 | 69 |
| 69 | 70 |
| 70 /* | 71 /* |
| 71 * GSUB/GPOS | 72 * GSUB/GPOS |
| 72 */ | 73 */ |
| 73 | 74 |
| 74 HB_INTERNAL hb_bool_t | 75 HB_INTERNAL hb_bool_t |
| 75 hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face, | 76 hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face, |
| 76 unsigned int lookup_index, | 77 unsigned int lookup_index, |
| 77 const hb_codepoint_t *glyphs, | 78 const hb_codepoint_t *glyphs, |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 | 174 |
| 174 | 175 |
| 175 #define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot) | 176 #define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot) |
| 176 | 177 |
| 177 | 178 |
| 178 /* | 179 /* |
| 179 * Buffer var routines. | 180 * Buffer var routines. |
| 180 */ | 181 */ |
| 181 | 182 |
| 182 /* buffer var allocations, used during the entire shaping process */ | 183 /* buffer var allocations, used during the entire shaping process */ |
| 183 #define unicode_props0()» var2.u8[0] | 184 #define unicode_props()»» var2.u16[0] |
| 184 #define unicode_props1()» var2.u8[1] | |
| 185 | 185 |
| 186 /* buffer var allocations, used during the GSUB/GPOS processing */ | 186 /* buffer var allocations, used during the GSUB/GPOS processing */ |
| 187 #define glyph_props() var1.u16[0] /* GDEF glyph properties */ | 187 #define glyph_props() var1.u16[0] /* GDEF glyph properties */ |
| 188 #define lig_props() var1.u8[2] /* GSUB/GPOS ligature tracking */ | 188 #define lig_props() var1.u8[2] /* GSUB/GPOS ligature tracking */ |
| 189 #define syllable() var1.u8[3] /* GSUB/GPOS shaping boundaries */ | 189 #define syllable() var1.u8[3] /* GSUB/GPOS shaping boundaries */ |
| 190 | 190 |
| 191 | 191 |
| 192 /* loop over syllables */ | 192 /* loop over syllables */ |
| 193 | 193 |
| 194 #define foreach_syllable(buffer, start, end) \ | 194 #define foreach_syllable(buffer, start, end) \ |
| (...skipping 12 matching lines...) Expand all Loading... |
| 207 unsigned int syllable = info[start].syllable(); | 207 unsigned int syllable = info[start].syllable(); |
| 208 while (++start < count && syllable == info[start].syllable()) | 208 while (++start < count && syllable == info[start].syllable()) |
| 209 ; | 209 ; |
| 210 | 210 |
| 211 return start; | 211 return start; |
| 212 } | 212 } |
| 213 | 213 |
| 214 | 214 |
| 215 /* unicode_props */ | 215 /* unicode_props */ |
| 216 | 216 |
| 217 enum { | 217 /* Design: |
| 218 MASK0_ZWJ = 0x20u, | 218 * unicode_props() is a two-byte number. The low byte includes: |
| 219 MASK0_ZWNJ = 0x40u, | 219 * - General_Category: 5 bits. |
| 220 MASK0_IGNORABLE = 0x80u, | 220 * - A bit each for: |
| 221 MASK0_GEN_CAT = 0x1Fu | 221 * * Is it Default_Ignorable(); we have a modified Default_Ignorable(). |
| 222 * * Is it U+200D ZWJ? |
| 223 * * Is it U+200C ZWNJ? |
| 224 * |
| 225 * The high-byte has different meanings, switched by the Gen-Cat: |
| 226 * - For Mn,Mc,Me: the modified Combining_Class. |
| 227 * - For Ws: index of which space character this is, if space fallback |
| 228 * is needed, ie. we don't set this by default, only if asked to. |
| 229 * |
| 230 * If needed, we can use the ZWJ/ZWNJ to use the high byte as well, |
| 231 * freeing two more bits. |
| 232 */ |
| 233 |
| 234 enum hb_unicode_props_flags_t { |
| 235 UPROPS_MASK_ZWJ = 0x20u, |
| 236 UPROPS_MASK_ZWNJ = 0x40u, |
| 237 UPROPS_MASK_IGNORABLE = 0x80u, |
| 238 UPROPS_MASK_GEN_CAT = 0x1Fu |
| 222 }; | 239 }; |
| 240 HB_MARK_AS_FLAG_T (hb_unicode_props_flags_t); |
| 223 | 241 |
| 224 static inline void | 242 static inline void |
| 225 _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *uni
code) | 243 _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) |
| 226 { | 244 { |
| 227 /* XXX This shouldn't be inlined, or at least not while is_default_ignorable()
is inline. */ | 245 hb_unicode_funcs_t *unicode = buffer->unicode; |
| 228 info->unicode_props0() = ((unsigned int) unicode->general_category (info->code
point)) | | 246 unsigned int u = info->codepoint; |
| 229 » » » (unicode->is_default_ignorable (info->codepoint) ? MA
SK0_IGNORABLE : 0) | | 247 unsigned int gen_cat = (unsigned int) unicode->general_category (u); |
| 230 » » » (info->codepoint == 0x200Cu ? MASK0_ZWNJ : 0) | | 248 unsigned int props = gen_cat; |
| 231 » » » (info->codepoint == 0x200Du ? MASK0_ZWJ : 0); | 249 |
| 232 info->unicode_props1() = unicode->modified_combining_class (info->codepoint); | 250 if (u >= 0x80) |
| 251 { |
| 252 buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII; |
| 253 if (unlikely (unicode->is_default_ignorable (u))) |
| 254 { |
| 255 buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES; |
| 256 props |= UPROPS_MASK_IGNORABLE; |
| 257 if (u == 0x200Cu) props |= UPROPS_MASK_ZWNJ; |
| 258 if (u == 0x200Du) props |= UPROPS_MASK_ZWJ; |
| 259 } |
| 260 else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK (gen_ca
t))) |
| 261 { |
| 262 /* Only Mn and Mc can have non-zero ccc: |
| 263 * http://www.unicode.org/policies/stability_policy.html#Property_Value |
| 264 * """ |
| 265 * Canonical_Combining_Class, General_Category |
| 266 * All characters other than those with General_Category property values |
| 267 * Spacing_Mark (Mc) and Nonspacing_Mark (Mn) have the Canonical_Combining
_Class |
| 268 * property value 0. |
| 269 * 1.1.5+ |
| 270 * """ |
| 271 * |
| 272 * Also, all Mn's that are Default_Ignorable, have ccc=0, hence |
| 273 * the "else if". |
| 274 */ |
| 275 props |= unicode->modified_combining_class (info->codepoint)<<8; |
| 276 } |
| 277 } |
| 278 |
| 279 info->unicode_props() = props; |
| 233 } | 280 } |
| 234 | 281 |
| 235 static inline void | 282 static inline void |
| 236 _hb_glyph_info_set_general_category (hb_glyph_info_t *info, | 283 _hb_glyph_info_set_general_category (hb_glyph_info_t *info, |
| 237 hb_unicode_general_category_t gen_cat) | 284 hb_unicode_general_category_t gen_cat) |
| 238 { | 285 { |
| 239 info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) &
~MASK0_GEN_CAT); | 286 /* Clears top-byte. */ |
| 287 info->unicode_props() = (unsigned int) gen_cat | (info->unicode_props() & (0xF
F & ~UPROPS_MASK_GEN_CAT)); |
| 240 } | 288 } |
| 241 | 289 |
| 242 static inline hb_unicode_general_category_t | 290 static inline hb_unicode_general_category_t |
| 243 _hb_glyph_info_get_general_category (const hb_glyph_info_t *info) | 291 _hb_glyph_info_get_general_category (const hb_glyph_info_t *info) |
| 244 { | 292 { |
| 245 return (hb_unicode_general_category_t) (info->unicode_props0() & MASK0_GEN_CAT
); | 293 return (hb_unicode_general_category_t) (info->unicode_props() & UPROPS_MASK_GE
N_CAT); |
| 246 } | 294 } |
| 247 | 295 |
| 296 static inline bool |
| 297 _hb_glyph_info_is_unicode_mark (const hb_glyph_info_t *info) |
| 298 { |
| 299 return HB_UNICODE_GENERAL_CATEGORY_IS_MARK (info->unicode_props() & UPROPS_MAS
K_GEN_CAT); |
| 300 } |
| 248 static inline void | 301 static inline void |
| 249 _hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, | 302 _hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, |
| 250 unsigned int modified_class) | 303 unsigned int modified_class) |
| 251 { | 304 { |
| 252 info->unicode_props1() = modified_class; | 305 if (unlikely (!_hb_glyph_info_is_unicode_mark (info))) |
| 306 return; |
| 307 info->unicode_props() = (modified_class<<8) | (info->unicode_props() & 0xFF); |
| 253 } | 308 } |
| 254 | |
| 255 static inline unsigned int | 309 static inline unsigned int |
| 256 _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info) | 310 _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info) |
| 257 { | 311 { |
| 258 return info->unicode_props1(); | 312 return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0; |
| 313 } |
| 314 |
| 315 static inline bool |
| 316 _hb_glyph_info_is_unicode_space (const hb_glyph_info_t *info) |
| 317 { |
| 318 return _hb_glyph_info_get_general_category (info) == |
| 319 » HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR; |
| 320 } |
| 321 static inline void |
| 322 _hb_glyph_info_set_unicode_space_fallback_type (hb_glyph_info_t *info, hb_unicod
e_funcs_t::space_t s) |
| 323 { |
| 324 if (unlikely (!_hb_glyph_info_is_unicode_space (info))) |
| 325 return; |
| 326 info->unicode_props() = (((unsigned int) s)<<8) | (info->unicode_props() & 0xF
F); |
| 327 } |
| 328 static inline hb_unicode_funcs_t::space_t |
| 329 _hb_glyph_info_get_unicode_space_fallback_type (const hb_glyph_info_t *info) |
| 330 { |
| 331 return _hb_glyph_info_is_unicode_space (info) ? |
| 332 » (hb_unicode_funcs_t::space_t) (info->unicode_props()>>8) : |
| 333 » hb_unicode_funcs_t::NOT_SPACE; |
| 259 } | 334 } |
| 260 | 335 |
| 261 static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info); | 336 static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info); |
| 262 | 337 |
| 263 static inline hb_bool_t | 338 static inline hb_bool_t |
| 264 _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) | 339 _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) |
| 265 { | 340 { |
| 266 return (info->unicode_props0() & MASK0_IGNORABLE) && !_hb_glyph_info_ligated (
info); | 341 return (info->unicode_props() & UPROPS_MASK_IGNORABLE) && !_hb_glyph_info_liga
ted (info); |
| 267 } | 342 } |
| 268 | 343 |
| 269 static inline hb_bool_t | 344 static inline hb_bool_t |
| 270 _hb_glyph_info_is_zwnj (const hb_glyph_info_t *info) | 345 _hb_glyph_info_is_zwnj (const hb_glyph_info_t *info) |
| 271 { | 346 { |
| 272 return !!(info->unicode_props0() & MASK0_ZWNJ); | 347 return !!(info->unicode_props() & UPROPS_MASK_ZWNJ); |
| 273 } | 348 } |
| 274 | 349 |
| 275 static inline hb_bool_t | 350 static inline hb_bool_t |
| 276 _hb_glyph_info_is_zwj (const hb_glyph_info_t *info) | 351 _hb_glyph_info_is_zwj (const hb_glyph_info_t *info) |
| 277 { | 352 { |
| 278 return !!(info->unicode_props0() & MASK0_ZWJ); | 353 return !!(info->unicode_props() & UPROPS_MASK_ZWJ); |
| 279 } | 354 } |
| 280 | 355 |
| 281 static inline void | 356 static inline void |
| 282 _hb_glyph_info_flip_joiners (hb_glyph_info_t *info) | 357 _hb_glyph_info_flip_joiners (hb_glyph_info_t *info) |
| 283 { | 358 { |
| 284 info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ; | 359 info->unicode_props() ^= UPROPS_MASK_ZWNJ | UPROPS_MASK_ZWJ; |
| 285 } | 360 } |
| 286 | 361 |
| 287 /* lig_props: aka lig_id / lig_comp | 362 /* lig_props: aka lig_id / lig_comp |
| 288 * | 363 * |
| 289 * When a ligature is formed: | 364 * When a ligature is formed: |
| 290 * | 365 * |
| 291 * - The ligature glyph and any marks in between all the same newly allocated | 366 * - The ligature glyph and any marks in between all the same newly allocated |
| 292 * lig_id, | 367 * lig_id, |
| 293 * - The ligature glyph will get lig_num_comps set to the number of components | 368 * - The ligature glyph will get lig_num_comps set to the number of components |
| 294 * - The marks get lig_comp > 0, reflecting which component of the ligature | 369 * - The marks get lig_comp > 0, reflecting which component of the ligature |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 HB_OT_LAYOUT_GLYPH_PROPS_LIGATED | | 523 HB_OT_LAYOUT_GLYPH_PROPS_LIGATED | |
| 449 HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED); | 524 HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED); |
| 450 } | 525 } |
| 451 | 526 |
| 452 | 527 |
| 453 /* Allocation / deallocation. */ | 528 /* Allocation / deallocation. */ |
| 454 | 529 |
| 455 static inline void | 530 static inline void |
| 456 _hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer) | 531 _hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer) |
| 457 { | 532 { |
| 458 HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props0); | 533 HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props); |
| 459 HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props1); | |
| 460 } | 534 } |
| 461 | 535 |
| 462 static inline void | 536 static inline void |
| 463 _hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer) | 537 _hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer) |
| 464 { | 538 { |
| 465 HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props0); | 539 HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props); |
| 466 HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props1); | |
| 467 } | 540 } |
| 468 | 541 |
| 469 static inline void | 542 static inline void |
| 470 _hb_buffer_assert_unicode_vars (hb_buffer_t *buffer) | 543 _hb_buffer_assert_unicode_vars (hb_buffer_t *buffer) |
| 471 { | 544 { |
| 472 HB_BUFFER_ASSERT_VAR (buffer, unicode_props0); | 545 HB_BUFFER_ASSERT_VAR (buffer, unicode_props); |
| 473 HB_BUFFER_ASSERT_VAR (buffer, unicode_props1); | |
| 474 } | 546 } |
| 475 | 547 |
| 476 static inline void | 548 static inline void |
| 477 _hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer) | 549 _hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer) |
| 478 { | 550 { |
| 479 HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props); | 551 HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props); |
| 480 HB_BUFFER_ALLOCATE_VAR (buffer, lig_props); | 552 HB_BUFFER_ALLOCATE_VAR (buffer, lig_props); |
| 481 HB_BUFFER_ALLOCATE_VAR (buffer, syllable); | 553 HB_BUFFER_ALLOCATE_VAR (buffer, syllable); |
| 482 } | 554 } |
| 483 | 555 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 498 } | 570 } |
| 499 | 571 |
| 500 /* Make sure no one directly touches our props... */ | 572 /* Make sure no one directly touches our props... */ |
| 501 #undef unicode_props0 | 573 #undef unicode_props0 |
| 502 #undef unicode_props1 | 574 #undef unicode_props1 |
| 503 #undef lig_props | 575 #undef lig_props |
| 504 #undef glyph_props | 576 #undef glyph_props |
| 505 | 577 |
| 506 | 578 |
| 507 #endif /* HB_OT_LAYOUT_PRIVATE_HH */ | 579 #endif /* HB_OT_LAYOUT_PRIVATE_HH */ |
| OLD | NEW |