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 |