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