OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2011,2012 Google, Inc. | 2 * Copyright © 2011,2012 Google, Inc. |
3 * | 3 * |
4 * This is part of HarfBuzz, a text shaping library. | 4 * This is part of HarfBuzz, a text shaping library. |
5 * | 5 * |
6 * Permission is hereby granted, without written agreement and without | 6 * Permission is hereby granted, without written agreement and without |
7 * license or royalty fees, to use, copy, modify, and distribute this | 7 * license or royalty fees, to use, copy, modify, and distribute this |
8 * software and its documentation for any purpose, provided that the | 8 * software and its documentation for any purpose, provided that the |
9 * above copyright notice and the following two paragraphs appear in | 9 * above copyright notice and the following two paragraphs appear in |
10 * all copies of this software. | 10 * all copies of this software. |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "hb-ot-layout-gsubgpos-private.hh" | 28 #include "hb-ot-layout-gsubgpos-private.hh" |
29 | 29 |
30 static unsigned int | 30 static unsigned int |
31 recategorize_combining_class (hb_codepoint_t u, | 31 recategorize_combining_class (hb_codepoint_t u, |
32 unsigned int klass) | 32 unsigned int klass) |
33 { | 33 { |
34 if (klass >= 200) | 34 if (klass >= 200) |
35 return klass; | 35 return klass; |
36 | 36 |
37 /* Thai / Lao need some per-character work. */ | 37 /* Thai / Lao need some per-character work. */ |
38 if ((u & ~0xFF) == 0x0E00) | 38 if ((u & ~0xFF) == 0x0E00u) |
39 { | 39 { |
40 if (unlikely (klass == 0)) | 40 if (unlikely (klass == 0)) |
41 { | 41 { |
42 switch (u) | 42 switch (u) |
43 { | 43 { |
44 case 0x0E31: | 44 case 0x0E31u: |
45 case 0x0E34: | 45 case 0x0E34u: |
46 case 0x0E35: | 46 case 0x0E35u: |
47 case 0x0E36: | 47 case 0x0E36u: |
48 case 0x0E37: | 48 case 0x0E37u: |
49 case 0x0E47: | 49 case 0x0E47u: |
50 case 0x0E4C: | 50 case 0x0E4Cu: |
51 case 0x0E4D: | 51 case 0x0E4Du: |
52 case 0x0E4E: | 52 case 0x0E4Eu: |
53 klass = HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT; | 53 klass = HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT; |
54 break; | 54 break; |
55 | 55 |
56 case 0x0EB1: | 56 case 0x0EB1u: |
57 case 0x0EB4: | 57 case 0x0EB4u: |
58 case 0x0EB5: | 58 case 0x0EB5u: |
59 case 0x0EB6: | 59 case 0x0EB6u: |
60 case 0x0EB7: | 60 case 0x0EB7u: |
61 case 0x0EBB: | 61 case 0x0EBBu: |
62 case 0x0ECC: | 62 case 0x0ECCu: |
63 case 0x0ECD: | 63 case 0x0ECDu: |
64 klass = HB_UNICODE_COMBINING_CLASS_ABOVE; | 64 klass = HB_UNICODE_COMBINING_CLASS_ABOVE; |
65 break; | 65 break; |
66 | 66 |
67 case 0x0EBC: | 67 case 0x0EBCu: |
68 klass = HB_UNICODE_COMBINING_CLASS_BELOW; | 68 klass = HB_UNICODE_COMBINING_CLASS_BELOW; |
69 break; | 69 break; |
70 } | 70 } |
71 } else { | 71 } else { |
72 /* Thai virama is below-right */ | 72 /* Thai virama is below-right */ |
73 if (u == 0x0E3A) | 73 if (u == 0x0E3Au) |
74 klass = HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT; | 74 klass = HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT; |
75 } | 75 } |
76 } | 76 } |
77 | 77 |
78 switch (klass) | 78 switch (klass) |
79 { | 79 { |
80 | 80 |
81 /* Hebrew */ | 81 /* Hebrew */ |
82 | 82 |
83 case HB_MODIFIED_COMBINING_CLASS_CCC10: /* sheva */ | 83 case HB_MODIFIED_COMBINING_CLASS_CCC10: /* sheva */ |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 | 160 |
161 return klass; | 161 return klass; |
162 } | 162 } |
163 | 163 |
164 void | 164 void |
165 _hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *pla
n HB_UNUSED, | 165 _hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *pla
n HB_UNUSED, |
166 hb_font_t *font HB_UNUSED, | 166 hb_font_t *font HB_UNUSED, |
167 hb_buffer_t *buffer) | 167 hb_buffer_t *buffer) |
168 { | 168 { |
169 unsigned int count = buffer->len; | 169 unsigned int count = buffer->len; |
| 170 hb_glyph_info_t *info = buffer->info; |
170 for (unsigned int i = 0; i < count; i++) | 171 for (unsigned int i = 0; i < count; i++) |
171 if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GEN
ERAL_CATEGORY_NON_SPACING_MARK) { | 172 if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CAT
EGORY_NON_SPACING_MARK) { |
172 unsigned int combining_class = _hb_glyph_info_get_modified_combining_class
(&buffer->info[i]); | 173 unsigned int combining_class = _hb_glyph_info_get_modified_combining_class
(&info[i]); |
173 combining_class = recategorize_combining_class (buffer->info[i].codepoint,
combining_class); | 174 combining_class = recategorize_combining_class (info[i].codepoint, combini
ng_class); |
174 _hb_glyph_info_set_modified_combining_class (&buffer->info[i], combining_c
lass); | 175 _hb_glyph_info_set_modified_combining_class (&info[i], combining_class); |
175 } | 176 } |
176 } | 177 } |
177 | 178 |
178 | 179 |
179 static void | 180 static void |
180 zero_mark_advances (hb_buffer_t *buffer, | 181 zero_mark_advances (hb_buffer_t *buffer, |
181 unsigned int start, | 182 unsigned int start, |
182 unsigned int end) | 183 unsigned int end) |
183 { | 184 { |
| 185 hb_glyph_info_t *info = buffer->info; |
184 for (unsigned int i = start; i < end; i++) | 186 for (unsigned int i = start; i < end; i++) |
185 if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GEN
ERAL_CATEGORY_NON_SPACING_MARK) | 187 if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CAT
EGORY_NON_SPACING_MARK) |
186 { | 188 { |
187 buffer->pos[i].x_advance = 0; | 189 buffer->pos[i].x_advance = 0; |
188 buffer->pos[i].y_advance = 0; | 190 buffer->pos[i].y_advance = 0; |
189 } | 191 } |
190 } | 192 } |
191 | 193 |
192 static inline void | 194 static inline void |
193 position_mark (const hb_ot_shape_plan_t *plan, | 195 position_mark (const hb_ot_shape_plan_t *plan, |
194 hb_font_t *font, | 196 hb_font_t *font, |
195 hb_buffer_t *buffer, | 197 hb_buffer_t *buffer, |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 hb_position_t x_offset = 0, y_offset = 0; | 322 hb_position_t x_offset = 0, y_offset = 0; |
321 if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) { | 323 if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) { |
322 x_offset -= buffer->pos[base].x_advance; | 324 x_offset -= buffer->pos[base].x_advance; |
323 y_offset -= buffer->pos[base].y_advance; | 325 y_offset -= buffer->pos[base].y_advance; |
324 } | 326 } |
325 | 327 |
326 hb_glyph_extents_t component_extents = base_extents; | 328 hb_glyph_extents_t component_extents = base_extents; |
327 unsigned int last_lig_component = (unsigned int) -1; | 329 unsigned int last_lig_component = (unsigned int) -1; |
328 unsigned int last_combining_class = 255; | 330 unsigned int last_combining_class = 255; |
329 hb_glyph_extents_t cluster_extents = base_extents; /* Initialization is just t
o shut gcc up. */ | 331 hb_glyph_extents_t cluster_extents = base_extents; /* Initialization is just t
o shut gcc up. */ |
| 332 hb_glyph_info_t *info = buffer->info; |
330 for (unsigned int i = base + 1; i < end; i++) | 333 for (unsigned int i = base + 1; i < end; i++) |
331 if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i])) | 334 if (_hb_glyph_info_get_modified_combining_class (&info[i])) |
332 { | 335 { |
333 if (num_lig_components > 1) { | 336 if (num_lig_components > 1) { |
334 » unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[i]); | 337 » unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&info[i]); |
335 » unsigned int this_lig_component = _hb_glyph_info_get_lig_comp (&buffer->
info[i]) - 1; | 338 » unsigned int this_lig_component = _hb_glyph_info_get_lig_comp (&info[i])
- 1; |
336 /* Conditions for attaching to the last component. */ | 339 /* Conditions for attaching to the last component. */ |
337 if (!lig_id || lig_id != this_lig_id || this_lig_component >= num_lig_co
mponents) | 340 if (!lig_id || lig_id != this_lig_id || this_lig_component >= num_lig_co
mponents) |
338 this_lig_component = num_lig_components - 1; | 341 this_lig_component = num_lig_components - 1; |
339 if (last_lig_component != this_lig_component) | 342 if (last_lig_component != this_lig_component) |
340 { | 343 { |
341 last_lig_component = this_lig_component; | 344 last_lig_component = this_lig_component; |
342 last_combining_class = 255; | 345 last_combining_class = 255; |
343 component_extents = base_extents; | 346 component_extents = base_extents; |
344 if (unlikely (horiz_dir == HB_DIRECTION_INVALID)) { | 347 if (unlikely (horiz_dir == HB_DIRECTION_INVALID)) { |
345 if (HB_DIRECTION_IS_HORIZONTAL (plan->props.direction)) | 348 if (HB_DIRECTION_IS_HORIZONTAL (plan->props.direction)) |
346 horiz_dir = plan->props.direction; | 349 horiz_dir = plan->props.direction; |
347 else | 350 else |
348 horiz_dir = hb_script_get_horizontal_direction (plan->props.script
); | 351 horiz_dir = hb_script_get_horizontal_direction (plan->props.script
); |
349 } | 352 } |
350 if (horiz_dir == HB_DIRECTION_LTR) | 353 if (horiz_dir == HB_DIRECTION_LTR) |
351 component_extents.x_bearing += (this_lig_component * component_exten
ts.width) / num_lig_components; | 354 component_extents.x_bearing += (this_lig_component * component_exten
ts.width) / num_lig_components; |
352 else | 355 else |
353 component_extents.x_bearing += ((num_lig_components - 1 - this_lig_c
omponent) * component_extents.width) / num_lig_components; | 356 component_extents.x_bearing += ((num_lig_components - 1 - this_lig_c
omponent) * component_extents.width) / num_lig_components; |
354 component_extents.width /= num_lig_components; | 357 component_extents.width /= num_lig_components; |
355 } | 358 } |
356 } | 359 } |
357 | 360 |
358 unsigned int this_combining_class = _hb_glyph_info_get_modified_combining_
class (&buffer->info[i]); | 361 unsigned int this_combining_class = _hb_glyph_info_get_modified_combining_
class (&info[i]); |
359 if (last_combining_class != this_combining_class) | 362 if (last_combining_class != this_combining_class) |
360 { | 363 { |
361 last_combining_class = this_combining_class; | 364 last_combining_class = this_combining_class; |
362 cluster_extents = component_extents; | 365 cluster_extents = component_extents; |
363 } | 366 } |
364 | 367 |
365 position_mark (plan, font, buffer, cluster_extents, i, this_combining_clas
s); | 368 position_mark (plan, font, buffer, cluster_extents, i, this_combining_clas
s); |
366 | 369 |
367 buffer->pos[i].x_advance = 0; | 370 buffer->pos[i].x_advance = 0; |
368 buffer->pos[i].y_advance = 0; | 371 buffer->pos[i].y_advance = 0; |
(...skipping 15 matching lines...) Expand all Loading... |
384 position_cluster (const hb_ot_shape_plan_t *plan, | 387 position_cluster (const hb_ot_shape_plan_t *plan, |
385 hb_font_t *font, | 388 hb_font_t *font, |
386 hb_buffer_t *buffer, | 389 hb_buffer_t *buffer, |
387 unsigned int start, | 390 unsigned int start, |
388 unsigned int end) | 391 unsigned int end) |
389 { | 392 { |
390 if (end - start < 2) | 393 if (end - start < 2) |
391 return; | 394 return; |
392 | 395 |
393 /* Find the base glyph */ | 396 /* Find the base glyph */ |
| 397 hb_glyph_info_t *info = buffer->info; |
394 for (unsigned int i = start; i < end; i++) | 398 for (unsigned int i = start; i < end; i++) |
395 if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_categor
y (&buffer->info[i]))) | 399 if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_categor
y (&info[i]))) |
396 { | 400 { |
397 /* Find mark glyphs */ | 401 /* Find mark glyphs */ |
398 unsigned int j; | 402 unsigned int j; |
399 for (j = i + 1; j < end; j++) | 403 for (j = i + 1; j < end; j++) |
400 » if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_cat
egory (&buffer->info[j]))) | 404 » if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_cat
egory (&info[j]))) |
401 break; | 405 break; |
402 | 406 |
403 position_around_base (plan, font, buffer, i, j); | 407 position_around_base (plan, font, buffer, i, j); |
404 | 408 |
405 i = j - 1; | 409 i = j - 1; |
406 } | 410 } |
407 } | 411 } |
408 | 412 |
409 void | 413 void |
410 _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan, | 414 _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan, |
(...skipping 14 matching lines...) Expand all Loading... |
425 | 429 |
426 | 430 |
427 /* Performs old-style TrueType kerning. */ | 431 /* Performs old-style TrueType kerning. */ |
428 void | 432 void |
429 _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, | 433 _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, |
430 hb_font_t *font, | 434 hb_font_t *font, |
431 hb_buffer_t *buffer) | 435 hb_buffer_t *buffer) |
432 { | 436 { |
433 if (!plan->has_kern) return; | 437 if (!plan->has_kern) return; |
434 | 438 |
435 unsigned int count = buffer->len; | |
436 | |
437 OT::hb_apply_context_t c (1, font, buffer); | 439 OT::hb_apply_context_t c (1, font, buffer); |
438 c.set_lookup_mask (plan->kern_mask); | 440 c.set_lookup_mask (plan->kern_mask); |
439 c.set_lookup_props (OT::LookupFlag::IgnoreMarks); | 441 c.set_lookup_props (OT::LookupFlag::IgnoreMarks); |
440 | 442 |
| 443 unsigned int count = buffer->len; |
441 hb_glyph_info_t *info = buffer->info; | 444 hb_glyph_info_t *info = buffer->info; |
442 hb_glyph_position_t *pos = buffer->pos; | 445 hb_glyph_position_t *pos = buffer->pos; |
443 | |
444 for (unsigned int idx = 0; idx < count;) | 446 for (unsigned int idx = 0; idx < count;) |
445 { | 447 { |
446 OT::hb_apply_context_t::skipping_forward_iterator_t skippy_iter (&c, idx, 1)
; | 448 OT::hb_apply_context_t::skipping_forward_iterator_t skippy_iter (&c, idx, 1)
; |
447 if (!skippy_iter.next ()) | 449 if (!skippy_iter.next ()) |
448 { | 450 { |
449 idx++; | 451 idx++; |
450 continue; | 452 continue; |
451 } | 453 } |
452 | 454 |
453 hb_position_t x_kern, y_kern; | 455 hb_position_t x_kern, y_kern; |
(...skipping 16 matching lines...) Expand all Loading... |
470 hb_position_t kern1 = y_kern >> 1; | 472 hb_position_t kern1 = y_kern >> 1; |
471 hb_position_t kern2 = y_kern - kern1; | 473 hb_position_t kern2 = y_kern - kern1; |
472 pos[idx].y_advance += kern1; | 474 pos[idx].y_advance += kern1; |
473 pos[skippy_iter.idx].y_advance += kern2; | 475 pos[skippy_iter.idx].y_advance += kern2; |
474 pos[skippy_iter.idx].y_offset += kern2; | 476 pos[skippy_iter.idx].y_offset += kern2; |
475 } | 477 } |
476 | 478 |
477 idx = skippy_iter.idx; | 479 idx = skippy_iter.idx; |
478 } | 480 } |
479 } | 481 } |
OLD | NEW |