| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 2009,2010 Red Hat, Inc. | 2 * Copyright © 2009,2010 Red Hat, Inc. |
| 3 * Copyright © 2010,2011,2012 Google, Inc. | 3 * Copyright © 2010,2011,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_shaper_face_data_t hb_ot_layout_t | 30 #define hb_ot_shaper_face_data_t hb_ot_layout_t |
| 31 #define hb_ot_shaper_shape_plan_data_t hb_ot_shape_plan_t | 31 #define hb_ot_shaper_shape_plan_data_t hb_ot_shape_plan_t |
| 32 #include "hb-shaper-impl-private.hh" | 32 #include "hb-shaper-impl-private.hh" |
| 33 | 33 |
| 34 #include "hb-ot-shape-private.hh" | 34 #include "hb-ot-shape-private.hh" |
| 35 #include "hb-ot-shape-complex-private.hh" | 35 #include "hb-ot-shape-complex-private.hh" |
| 36 #include "hb-ot-shape-fallback-private.hh" | 36 #include "hb-ot-shape-fallback-private.hh" |
| 37 #include "hb-ot-shape-normalize-private.hh" | 37 #include "hb-ot-shape-normalize-private.hh" |
| 38 | 38 |
| 39 #include "hb-ot-layout-private.hh" | 39 #include "hb-ot-layout-private.hh" |
| 40 #include "hb-unicode-private.hh" |
| 40 #include "hb-set-private.hh" | 41 #include "hb-set-private.hh" |
| 41 | 42 |
| 42 | 43 |
| 43 static hb_tag_t common_features[] = { | 44 static hb_tag_t common_features[] = { |
| 44 HB_TAG('c','c','m','p'), | 45 HB_TAG('c','c','m','p'), |
| 45 HB_TAG('l','i','g','a'), | 46 HB_TAG('l','i','g','a'), |
| 46 HB_TAG('l','o','c','l'), | 47 HB_TAG('l','o','c','l'), |
| 47 HB_TAG('m','a','r','k'), | 48 HB_TAG('m','a','r','k'), |
| 48 HB_TAG('m','k','m','k'), | 49 HB_TAG('m','k','m','k'), |
| 49 HB_TAG('r','l','i','g'), | 50 HB_TAG('r','l','i','g'), |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 | 220 |
| 220 /* Main shaper */ | 221 /* Main shaper */ |
| 221 | 222 |
| 222 | 223 |
| 223 /* Prepare */ | 224 /* Prepare */ |
| 224 | 225 |
| 225 static void | 226 static void |
| 226 hb_set_unicode_props (hb_buffer_t *buffer) | 227 hb_set_unicode_props (hb_buffer_t *buffer) |
| 227 { | 228 { |
| 228 unsigned int count = buffer->len; | 229 unsigned int count = buffer->len; |
| 230 hb_glyph_info_t *info = buffer->info; |
| 229 for (unsigned int i = 0; i < count; i++) | 231 for (unsigned int i = 0; i < count; i++) |
| 230 _hb_glyph_info_set_unicode_props (&buffer->info[i], buffer->unicode); | 232 _hb_glyph_info_set_unicode_props (&info[i], buffer->unicode); |
| 231 } | 233 } |
| 232 | 234 |
| 233 static void | 235 static void |
| 234 hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) | 236 hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) |
| 235 { | 237 { |
| 236 if (!(buffer->flags & HB_BUFFER_FLAG_BOT) || | 238 if (!(buffer->flags & HB_BUFFER_FLAG_BOT) || |
| 237 _hb_glyph_info_get_general_category (&buffer->info[0]) != | 239 _hb_glyph_info_get_general_category (&buffer->info[0]) != |
| 238 HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | 240 HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) |
| 239 return; | 241 return; |
| 240 | 242 |
| 241 if (!font->has_glyph (0x25CC)) | 243 if (!font->has_glyph (0x25CCu)) |
| 242 return; | 244 return; |
| 243 | 245 |
| 244 hb_glyph_info_t dottedcircle; | 246 hb_glyph_info_t dottedcircle; |
| 245 dottedcircle.codepoint = 0x25CC; | 247 dottedcircle.codepoint = 0x25CCu; |
| 246 _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode); | 248 _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode); |
| 247 | 249 |
| 248 buffer->clear_output (); | 250 buffer->clear_output (); |
| 249 | 251 |
| 250 buffer->idx = 0; | 252 buffer->idx = 0; |
| 251 hb_glyph_info_t info = dottedcircle; | 253 hb_glyph_info_t info = dottedcircle; |
| 252 info.cluster = buffer->cur().cluster; | 254 info.cluster = buffer->cur().cluster; |
| 253 info.mask = buffer->cur().mask; | 255 info.mask = buffer->cur().mask; |
| 254 buffer->output_info (info); | 256 buffer->output_info (info); |
| 255 while (buffer->idx < buffer->len) | 257 while (buffer->idx < buffer->len) |
| 256 buffer->next_glyph (); | 258 buffer->next_glyph (); |
| 257 | 259 |
| 258 buffer->swap_buffers (); | 260 buffer->swap_buffers (); |
| 259 } | 261 } |
| 260 | 262 |
| 261 static void | 263 static void |
| 262 hb_form_clusters (hb_buffer_t *buffer) | 264 hb_form_clusters (hb_buffer_t *buffer) |
| 263 { | 265 { |
| 264 unsigned int count = buffer->len; | 266 unsigned int count = buffer->len; |
| 267 hb_glyph_info_t *info = buffer->info; |
| 265 for (unsigned int i = 1; i < count; i++) | 268 for (unsigned int i = 1; i < count; i++) |
| 266 if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category
(&buffer->info[i]))) | 269 if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category
(&info[i]))) |
| 267 buffer->merge_clusters (i - 1, i + 1); | 270 buffer->merge_clusters (i - 1, i + 1); |
| 268 } | 271 } |
| 269 | 272 |
| 270 static void | 273 static void |
| 271 hb_ensure_native_direction (hb_buffer_t *buffer) | 274 hb_ensure_native_direction (hb_buffer_t *buffer) |
| 272 { | 275 { |
| 273 hb_direction_t direction = buffer->props.direction; | 276 hb_direction_t direction = buffer->props.direction; |
| 274 | 277 |
| 275 /* TODO vertical: | 278 /* TODO vertical: |
| 276 * The only BTT vertical script is Ogham, but it's not clear to me whether Ope
nType | 279 * The only BTT vertical script is Ogham, but it's not clear to me whether Ope
nType |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 if (!c->plan->has_frac) | 317 if (!c->plan->has_frac) |
| 315 return; | 318 return; |
| 316 | 319 |
| 317 hb_buffer_t *buffer = c->buffer; | 320 hb_buffer_t *buffer = c->buffer; |
| 318 | 321 |
| 319 /* TODO look in pre/post context text also. */ | 322 /* TODO look in pre/post context text also. */ |
| 320 unsigned int count = buffer->len; | 323 unsigned int count = buffer->len; |
| 321 hb_glyph_info_t *info = buffer->info; | 324 hb_glyph_info_t *info = buffer->info; |
| 322 for (unsigned int i = 0; i < count; i++) | 325 for (unsigned int i = 0; i < count; i++) |
| 323 { | 326 { |
| 324 if (info[i].codepoint == 0x2044) /* FRACTION SLASH */ | 327 if (info[i].codepoint == 0x2044u) /* FRACTION SLASH */ |
| 325 { | 328 { |
| 326 unsigned int start = i, end = i + 1; | 329 unsigned int start = i, end = i + 1; |
| 327 while (start && | 330 while (start && |
| 328 _hb_glyph_info_get_general_category (&info[start - 1]) == | 331 _hb_glyph_info_get_general_category (&info[start - 1]) == |
| 329 HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) | 332 HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) |
| 330 start--; | 333 start--; |
| 331 while (end < count && | 334 while (end < count && |
| 332 _hb_glyph_info_get_general_category (&info[end]) == | 335 _hb_glyph_info_get_general_category (&info[end]) == |
| 333 HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) | 336 HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) |
| 334 end++; | 337 end++; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 buffer->set_masks (feature->value << shift, mask, feature->start, feature-
>end); | 377 buffer->set_masks (feature->value << shift, mask, feature->start, feature-
>end); |
| 375 } | 378 } |
| 376 } | 379 } |
| 377 } | 380 } |
| 378 | 381 |
| 379 static inline void | 382 static inline void |
| 380 hb_ot_map_glyphs_fast (hb_buffer_t *buffer) | 383 hb_ot_map_glyphs_fast (hb_buffer_t *buffer) |
| 381 { | 384 { |
| 382 /* Normalization process sets up glyph_index(), we just copy it. */ | 385 /* Normalization process sets up glyph_index(), we just copy it. */ |
| 383 unsigned int count = buffer->len; | 386 unsigned int count = buffer->len; |
| 387 hb_glyph_info_t *info = buffer->info; |
| 384 for (unsigned int i = 0; i < count; i++) | 388 for (unsigned int i = 0; i < count; i++) |
| 385 buffer->info[i].codepoint = buffer->info[i].glyph_index(); | 389 info[i].codepoint = info[i].glyph_index(); |
| 386 } | 390 } |
| 387 | 391 |
| 388 static inline void | 392 static inline void |
| 389 hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) | 393 hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) |
| 390 { | 394 { |
| 391 unsigned int count = c->buffer->len; | 395 unsigned int count = c->buffer->len; |
| 392 hb_glyph_info_t *info = c->buffer->info; | 396 hb_glyph_info_t *info = c->buffer->info; |
| 393 for (unsigned int i = 0; i < count; i++) | 397 for (unsigned int i = 0; i < count; i++) |
| 394 _hb_glyph_info_set_glyph_props (&info[i], | 398 { |
| 395 » » » » _hb_glyph_info_get_general_category (&info[i
]) | 399 hb_ot_layout_glyph_class_mask_t klass; |
| 396 » » » » == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_M
ARK ? | 400 |
| 397 » » » » HB_OT_LAYOUT_GLYPH_PROPS_MARK : | 401 /* Never mark default-ignorables as marks. |
| 398 » » » » HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH); | 402 * They won't get in the way of lookups anyway, |
| 403 * but having them as mark will cause them to be skipped |
| 404 * over if the lookup-flag says so, but at least for the |
| 405 * Mongolian variation selectors, looks like Uniscribe |
| 406 * marks them as non-mark. Some Mongolian fonts without |
| 407 * GDEF rely on this. Another notable character that |
| 408 * this applies to is COMBINING GRAPHEME JOINER. */ |
| 409 klass = (_hb_glyph_info_get_general_category (&info[i]) != |
| 410 » HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK || |
| 411 » _hb_glyph_info_is_default_ignorable (&info[i])) ? |
| 412 » HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : |
| 413 » HB_OT_LAYOUT_GLYPH_PROPS_MARK; |
| 414 _hb_glyph_info_set_glyph_props (&info[i], klass); |
| 415 } |
| 399 } | 416 } |
| 400 | 417 |
| 401 static inline void | 418 static inline void |
| 402 hb_ot_substitute_default (hb_ot_shape_context_t *c) | 419 hb_ot_substitute_default (hb_ot_shape_context_t *c) |
| 403 { | 420 { |
| 404 hb_buffer_t *buffer = c->buffer; | 421 hb_buffer_t *buffer = c->buffer; |
| 405 | 422 |
| 406 if (c->plan->shaper->preprocess_text) | 423 if (c->plan->shaper->preprocess_text) |
| 407 c->plan->shaper->preprocess_text (c->plan, buffer, c->font); | 424 c->plan->shaper->preprocess_text (c->plan, buffer, c->font); |
| 408 | 425 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 static inline void | 462 static inline void |
| 446 hb_ot_substitute (hb_ot_shape_context_t *c) | 463 hb_ot_substitute (hb_ot_shape_context_t *c) |
| 447 { | 464 { |
| 448 hb_ot_substitute_default (c); | 465 hb_ot_substitute_default (c); |
| 449 hb_ot_substitute_complex (c); | 466 hb_ot_substitute_complex (c); |
| 450 } | 467 } |
| 451 | 468 |
| 452 /* Position */ | 469 /* Position */ |
| 453 | 470 |
| 454 static inline void | 471 static inline void |
| 455 zero_mark_widths_by_unicode (hb_buffer_t *buffer) | 472 adjust_mark_offsets (hb_glyph_position_t *pos) |
| 473 { |
| 474 pos->x_offset -= pos->x_advance; |
| 475 pos->y_offset -= pos->y_advance; |
| 476 } |
| 477 |
| 478 static inline void |
| 479 zero_mark_width (hb_glyph_position_t *pos) |
| 480 { |
| 481 pos->x_advance = 0; |
| 482 pos->y_advance = 0; |
| 483 } |
| 484 |
| 485 static inline void |
| 486 zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets) |
| 456 { | 487 { |
| 457 unsigned int count = buffer->len; | 488 unsigned int count = buffer->len; |
| 489 hb_glyph_info_t *info = buffer->info; |
| 458 for (unsigned int i = 0; i < count; i++) | 490 for (unsigned int i = 0; i < count; i++) |
| 459 if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GEN
ERAL_CATEGORY_NON_SPACING_MARK) | 491 if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CAT
EGORY_NON_SPACING_MARK) |
| 460 { | 492 { |
| 461 buffer->pos[i].x_advance = 0; | 493 if (adjust_offsets) |
| 462 buffer->pos[i].y_advance = 0; | 494 adjust_mark_offsets (&buffer->pos[i]); |
| 495 zero_mark_width (&buffer->pos[i]); |
| 463 } | 496 } |
| 464 } | 497 } |
| 465 | 498 |
| 466 static inline void | 499 static inline void |
| 467 zero_mark_widths_by_gdef (hb_buffer_t *buffer) | 500 zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets) |
| 468 { | 501 { |
| 469 unsigned int count = buffer->len; | 502 unsigned int count = buffer->len; |
| 503 hb_glyph_info_t *info = buffer->info; |
| 470 for (unsigned int i = 0; i < count; i++) | 504 for (unsigned int i = 0; i < count; i++) |
| 471 if (_hb_glyph_info_is_mark (&buffer->info[i])) | 505 if (_hb_glyph_info_is_mark (&info[i])) |
| 472 { | 506 { |
| 473 buffer->pos[i].x_advance = 0; | 507 if (adjust_offsets) |
| 474 buffer->pos[i].y_advance = 0; | 508 adjust_mark_offsets (&buffer->pos[i]); |
| 509 zero_mark_width (&buffer->pos[i]); |
| 475 } | 510 } |
| 476 } | 511 } |
| 477 | 512 |
| 478 static inline void | 513 static inline void |
| 479 hb_ot_position_default (hb_ot_shape_context_t *c) | 514 hb_ot_position_default (hb_ot_shape_context_t *c) |
| 480 { | 515 { |
| 481 hb_direction_t direction = c->buffer->props.direction; | 516 hb_direction_t direction = c->buffer->props.direction; |
| 482 unsigned int count = c->buffer->len; | 517 unsigned int count = c->buffer->len; |
| 483 hb_glyph_info_t *info = c->buffer->info; | 518 hb_glyph_info_t *info = c->buffer->info; |
| 484 hb_glyph_position_t *pos = c->buffer->pos; | 519 hb_glyph_position_t *pos = c->buffer->pos; |
| 485 for (unsigned int i = 0; i < count; i++) | 520 for (unsigned int i = 0; i < count; i++) |
| 486 { | 521 { |
| 487 c->font->get_glyph_advance_for_direction (info[i].codepoint, | 522 c->font->get_glyph_advance_for_direction (info[i].codepoint, |
| 488 direction, | 523 direction, |
| 489 &pos[i].x_advance, | 524 &pos[i].x_advance, |
| 490 &pos[i].y_advance); | 525 &pos[i].y_advance); |
| 491 c->font->subtract_glyph_origin_for_direction (info[i].codepoint, | 526 c->font->subtract_glyph_origin_for_direction (info[i].codepoint, |
| 492 direction, | 527 direction, |
| 493 &pos[i].x_offset, | 528 &pos[i].x_offset, |
| 494 &pos[i].y_offset); | 529 &pos[i].y_offset); |
| 495 | 530 |
| 496 } | 531 } |
| 497 } | 532 } |
| 498 | 533 |
| 499 static inline bool | 534 static inline bool |
| 500 hb_ot_position_complex (hb_ot_shape_context_t *c) | 535 hb_ot_position_complex (hb_ot_shape_context_t *c) |
| 501 { | 536 { |
| 502 bool ret = false; | 537 bool ret = false; |
| 503 unsigned int count = c->buffer->len; | 538 unsigned int count = c->buffer->len; |
| 539 bool has_positioning = hb_ot_layout_has_positioning (c->face); |
| 540 /* If the font has no GPOS, AND, no fallback positioning will |
| 541 * happen, AND, direction is forward, then when zeroing mark |
| 542 * widths, we shift the mark with it, such that the mark |
| 543 * is positioned hanging over the previous glyph. When |
| 544 * direction is backward we don't shift and it will end up |
| 545 * hanging over the next glyph after the final reordering. |
| 546 * If fallback positinoing happens or GPOS is present, we don't |
| 547 * care. |
| 548 */ |
| 549 bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallb
ack_position || |
| 550 HB_DIRECTION_IS_BACKWARD (c->buffer->prop
s.direction)); |
| 504 | 551 |
| 505 switch (c->plan->shaper->zero_width_marks) | 552 switch (c->plan->shaper->zero_width_marks) |
| 506 { | 553 { |
| 507 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: | 554 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: |
| 508 zero_mark_widths_by_gdef (c->buffer); | 555 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); |
| 509 break; | 556 break; |
| 510 | 557 |
| 511 /* Not currently used for any shaper: | 558 /* Not currently used for any shaper: |
| 512 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: | 559 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: |
| 513 zero_mark_widths_by_unicode (c->buffer); | 560 zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing); |
| 514 break; | 561 break; |
| 515 */ | 562 */ |
| 516 | 563 |
| 517 default: | 564 default: |
| 518 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: | 565 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: |
| 519 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: | 566 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: |
| 520 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: | 567 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: |
| 521 break; | 568 break; |
| 522 } | 569 } |
| 523 | 570 |
| 524 if (hb_ot_layout_has_positioning (c->face)) | 571 if (has_positioning) |
| 525 { | 572 { |
| 526 hb_glyph_info_t *info = c->buffer->info; | 573 hb_glyph_info_t *info = c->buffer->info; |
| 527 hb_glyph_position_t *pos = c->buffer->pos; | 574 hb_glyph_position_t *pos = c->buffer->pos; |
| 528 | 575 |
| 529 /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */ | 576 /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */ |
| 530 | 577 |
| 531 for (unsigned int i = 0; i < count; i++) { | 578 for (unsigned int i = 0; i < count; i++) { |
| 532 c->font->add_glyph_origin_for_direction (info[i].codepoint, | 579 c->font->add_glyph_origin_for_direction (info[i].codepoint, |
| 533 HB_DIRECTION_LTR, | 580 HB_DIRECTION_LTR, |
| 534 &pos[i].x_offset, | 581 &pos[i].x_offset, |
| 535 &pos[i].y_offset); | 582 &pos[i].y_offset); |
| 536 } | 583 } |
| 537 | 584 |
| 538 c->plan->position (c->font, c->buffer); | 585 c->plan->position (c->font, c->buffer); |
| 539 | 586 |
| 540 for (unsigned int i = 0; i < count; i++) { | 587 for (unsigned int i = 0; i < count; i++) { |
| 541 c->font->subtract_glyph_origin_for_direction (info[i].codepoint, | 588 c->font->subtract_glyph_origin_for_direction (info[i].codepoint, |
| 542 HB_DIRECTION_LTR, | 589 HB_DIRECTION_LTR, |
| 543 &pos[i].x_offset, | 590 &pos[i].x_offset, |
| 544 &pos[i].y_offset); | 591 &pos[i].y_offset); |
| 545 } | 592 } |
| 546 | 593 |
| 547 ret = true; | 594 ret = true; |
| 548 } | 595 } |
| 549 | 596 |
| 550 switch (c->plan->shaper->zero_width_marks) | 597 switch (c->plan->shaper->zero_width_marks) |
| 551 { | 598 { |
| 552 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: | 599 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: |
| 553 zero_mark_widths_by_unicode (c->buffer); | 600 zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing); |
| 554 break; | 601 break; |
| 555 | 602 |
| 556 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: | 603 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: |
| 557 zero_mark_widths_by_gdef (c->buffer); | 604 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); |
| 558 break; | 605 break; |
| 559 | 606 |
| 560 default: | 607 default: |
| 561 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: | 608 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: |
| 562 //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: | 609 //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: |
| 563 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: | 610 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: |
| 564 break; | 611 break; |
| 565 } | 612 } |
| 566 | 613 |
| 567 return ret; | 614 return ret; |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 724 { | 771 { |
| 725 hb_ot_shape_plan_t plan; | 772 hb_ot_shape_plan_t plan; |
| 726 | 773 |
| 727 const char *shapers[] = {"ot", NULL}; | 774 const char *shapers[] = {"ot", NULL}; |
| 728 hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer
->props, | 775 hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer
->props, |
| 729 features, num_featu
res, shapers); | 776 features, num_featu
res, shapers); |
| 730 | 777 |
| 731 bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_
DIRECTION_RTL; | 778 bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_
DIRECTION_RTL; |
| 732 | 779 |
| 733 unsigned int count = buffer->len; | 780 unsigned int count = buffer->len; |
| 781 hb_glyph_info_t *info = buffer->info; |
| 734 for (unsigned int i = 0; i < count; i++) | 782 for (unsigned int i = 0; i < count; i++) |
| 735 add_char (font, buffer->unicode, mirror, buffer->info[i].codepoint, glyphs); | 783 add_char (font, buffer->unicode, mirror, info[i].codepoint, glyphs); |
| 736 | 784 |
| 737 hb_set_t lookups; | 785 hb_set_t lookups; |
| 738 lookups.init (); | 786 lookups.init (); |
| 739 hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, &lookups); | 787 hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, &lookups); |
| 740 | 788 |
| 741 /* And find transitive closure. */ | 789 /* And find transitive closure. */ |
| 742 hb_set_t copy; | 790 hb_set_t copy; |
| 743 copy.init (); | 791 copy.init (); |
| 744 do { | 792 do { |
| 745 copy.set (glyphs); | 793 copy.set (glyphs); |
| 746 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index)
;) | 794 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index)
;) |
| 747 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); | 795 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); |
| 748 } while (!copy.is_equal (glyphs)); | 796 } while (!copy.is_equal (glyphs)); |
| 749 | 797 |
| 750 hb_shape_plan_destroy (shape_plan); | 798 hb_shape_plan_destroy (shape_plan); |
| 751 } | 799 } |
| OLD | NEW |