| 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 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 | 221 |
| 222 | 222 |
| 223 /* Prepare */ | 223 /* Prepare */ |
| 224 | 224 |
| 225 static void | 225 static void |
| 226 hb_set_unicode_props (hb_buffer_t *buffer) | 226 hb_set_unicode_props (hb_buffer_t *buffer) |
| 227 { | 227 { |
| 228 unsigned int count = buffer->len; | 228 unsigned int count = buffer->len; |
| 229 hb_glyph_info_t *info = buffer->info; | 229 hb_glyph_info_t *info = buffer->info; |
| 230 for (unsigned int i = 0; i < count; i++) | 230 for (unsigned int i = 0; i < count; i++) |
| 231 _hb_glyph_info_set_unicode_props (&info[i], buffer->unicode); | 231 _hb_glyph_info_set_unicode_props (&info[i], buffer); |
| 232 } | 232 } |
| 233 | 233 |
| 234 static void | 234 static void |
| 235 hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) | 235 hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) |
| 236 { | 236 { |
| 237 if (!(buffer->flags & HB_BUFFER_FLAG_BOT) || | 237 if (!(buffer->flags & HB_BUFFER_FLAG_BOT) || |
| 238 buffer->context_len[0] || | 238 buffer->context_len[0] || |
| 239 _hb_glyph_info_get_general_category (&buffer->info[0]) != | 239 _hb_glyph_info_get_general_category (&buffer->info[0]) != |
| 240 HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | 240 HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) |
| 241 return; | 241 return; |
| 242 | 242 |
| 243 if (!font->has_glyph (0x25CCu)) | 243 if (!font->has_glyph (0x25CCu)) |
| 244 return; | 244 return; |
| 245 | 245 |
| 246 hb_glyph_info_t dottedcircle = {0}; | 246 hb_glyph_info_t dottedcircle = {0}; |
| 247 dottedcircle.codepoint = 0x25CCu; | 247 dottedcircle.codepoint = 0x25CCu; |
| 248 _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode); | 248 _hb_glyph_info_set_unicode_props (&dottedcircle, buffer); |
| 249 | 249 |
| 250 buffer->clear_output (); | 250 buffer->clear_output (); |
| 251 | 251 |
| 252 buffer->idx = 0; | 252 buffer->idx = 0; |
| 253 hb_glyph_info_t info = dottedcircle; | 253 hb_glyph_info_t info = dottedcircle; |
| 254 info.cluster = buffer->cur().cluster; | 254 info.cluster = buffer->cur().cluster; |
| 255 info.mask = buffer->cur().mask; | 255 info.mask = buffer->cur().mask; |
| 256 buffer->output_info (info); | 256 buffer->output_info (info); |
| 257 while (buffer->idx < buffer->len) | 257 while (buffer->idx < buffer->len && !buffer->in_error) |
| 258 buffer->next_glyph (); | 258 buffer->next_glyph (); |
| 259 | 259 |
| 260 buffer->swap_buffers (); | 260 buffer->swap_buffers (); |
| 261 } | 261 } |
| 262 | 262 |
| 263 static void | 263 static void |
| 264 hb_form_clusters (hb_buffer_t *buffer) | 264 hb_form_clusters (hb_buffer_t *buffer) |
| 265 { | 265 { |
| 266 if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) | 266 if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) || |
| 267 buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) |
| 267 return; | 268 return; |
| 268 | 269 |
| 269 /* Loop duplicated in hb_ensure_native_direction(). */ | 270 /* Loop duplicated in hb_ensure_native_direction(). */ |
| 270 unsigned int base = 0; | 271 unsigned int base = 0; |
| 271 unsigned int count = buffer->len; | 272 unsigned int count = buffer->len; |
| 272 hb_glyph_info_t *info = buffer->info; | 273 hb_glyph_info_t *info = buffer->info; |
| 273 for (unsigned int i = 1; i < count; i++) | 274 for (unsigned int i = 1; i < count; i++) |
| 274 { | 275 { |
| 275 if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general
_category (&info[i])))) | 276 if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general
_category (&info[i])))) |
| 276 { | 277 { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 if (likely (codepoint == info[i].codepoint || !c->font->has_glyph (codepoint
))) | 340 if (likely (codepoint == info[i].codepoint || !c->font->has_glyph (codepoint
))) |
| 340 info[i].mask |= rtlm_mask; | 341 info[i].mask |= rtlm_mask; |
| 341 else | 342 else |
| 342 info[i].codepoint = codepoint; | 343 info[i].codepoint = codepoint; |
| 343 } | 344 } |
| 344 } | 345 } |
| 345 | 346 |
| 346 static inline void | 347 static inline void |
| 347 hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c) | 348 hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c) |
| 348 { | 349 { |
| 349 if (!c->plan->has_frac) | 350 if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) || |
| 351 !c->plan->has_frac) |
| 350 return; | 352 return; |
| 351 | 353 |
| 352 hb_buffer_t *buffer = c->buffer; | 354 hb_buffer_t *buffer = c->buffer; |
| 353 | 355 |
| 354 /* TODO look in pre/post context text also. */ | 356 /* TODO look in pre/post context text also. */ |
| 355 unsigned int count = buffer->len; | 357 unsigned int count = buffer->len; |
| 356 hb_glyph_info_t *info = buffer->info; | 358 hb_glyph_info_t *info = buffer->info; |
| 357 for (unsigned int i = 0; i < count; i++) | 359 for (unsigned int i = 0; i < count; i++) |
| 358 { | 360 { |
| 359 if (info[i].codepoint == 0x2044u) /* FRACTION SLASH */ | 361 if (info[i].codepoint == 0x2044u) /* FRACTION SLASH */ |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 buffer->set_masks (feature->value << shift, mask, feature->start, feature-
>end); | 411 buffer->set_masks (feature->value << shift, mask, feature->start, feature-
>end); |
| 410 } | 412 } |
| 411 } | 413 } |
| 412 } | 414 } |
| 413 | 415 |
| 414 static void | 416 static void |
| 415 hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c) | 417 hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c) |
| 416 { | 418 { |
| 417 hb_buffer_t *buffer = c->buffer; | 419 hb_buffer_t *buffer = c->buffer; |
| 418 | 420 |
| 419 if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) | 421 if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) |
| |
| 422 (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)) |
| 420 return; | 423 return; |
| 421 | 424 |
| 422 unsigned int count = buffer->len; | 425 unsigned int count = buffer->len; |
| 423 hb_glyph_info_t *info = buffer->info; | 426 hb_glyph_info_t *info = buffer->info; |
| 424 hb_glyph_position_t *pos = buffer->pos; | 427 hb_glyph_position_t *pos = buffer->pos; |
| 425 unsigned int i = 0; | 428 unsigned int i = 0; |
| 426 for (i = 0; i < count; i++) | 429 for (i = 0; i < count; i++) |
| 427 if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) | 430 if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) |
| 428 pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset =
0; | 431 pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset =
0; |
| 429 } | 432 } |
| 430 | 433 |
| 431 static void | 434 static void |
| 432 hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) | 435 hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) |
| 433 { | 436 { |
| 434 hb_buffer_t *buffer = c->buffer; | 437 hb_buffer_t *buffer = c->buffer; |
| 435 | 438 |
| 436 if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) | 439 if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) |
| |
| 440 (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)) |
| 437 return; | 441 return; |
| 438 | 442 |
| 439 unsigned int count = buffer->len; | 443 unsigned int count = buffer->len; |
| 440 hb_glyph_info_t *info = buffer->info; | 444 hb_glyph_info_t *info = buffer->info; |
| 441 hb_glyph_position_t *pos = buffer->pos; | 445 hb_glyph_position_t *pos = buffer->pos; |
| 442 unsigned int i = 0; | 446 unsigned int i = 0; |
| 443 for (i = 0; i < count; i++) | 447 for (i = 0; i < count; i++) |
| 444 { | 448 { |
| 445 if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) | 449 if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) |
| 446 break; | 450 break; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS; | 522 buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS; |
| 519 } | 523 } |
| 520 | 524 |
| 521 static inline void | 525 static inline void |
| 522 hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) | 526 hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) |
| 523 { | 527 { |
| 524 unsigned int count = c->buffer->len; | 528 unsigned int count = c->buffer->len; |
| 525 hb_glyph_info_t *info = c->buffer->info; | 529 hb_glyph_info_t *info = c->buffer->info; |
| 526 for (unsigned int i = 0; i < count; i++) | 530 for (unsigned int i = 0; i < count; i++) |
| 527 { | 531 { |
| 528 hb_ot_layout_glyph_class_mask_t klass; | 532 hb_ot_layout_glyph_props_flags_t klass; |
| 529 | 533 |
| 530 /* Never mark default-ignorables as marks. | 534 /* Never mark default-ignorables as marks. |
| 531 * They won't get in the way of lookups anyway, | 535 * They won't get in the way of lookups anyway, |
| 532 * but having them as mark will cause them to be skipped | 536 * but having them as mark will cause them to be skipped |
| 533 * over if the lookup-flag says so, but at least for the | 537 * over if the lookup-flag says so, but at least for the |
| 534 * Mongolian variation selectors, looks like Uniscribe | 538 * Mongolian variation selectors, looks like Uniscribe |
| 535 * marks them as non-mark. Some Mongolian fonts without | 539 * marks them as non-mark. Some Mongolian fonts without |
| 536 * GDEF rely on this. Another notable character that | 540 * GDEF rely on this. Another notable character that |
| 537 * this applies to is COMBINING GRAPHEME JOINER. */ | 541 * this applies to is COMBINING GRAPHEME JOINER. */ |
| 538 klass = (_hb_glyph_info_get_general_category (&info[i]) != | 542 klass = (_hb_glyph_info_get_general_category (&info[i]) != |
| 539 HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK || | 543 HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK || |
| 540 _hb_glyph_info_is_default_ignorable (&info[i])) ? | 544 _hb_glyph_info_is_default_ignorable (&info[i])) ? |
| 541 HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : | 545 HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : |
| 542 HB_OT_LAYOUT_GLYPH_PROPS_MARK; | 546 HB_OT_LAYOUT_GLYPH_PROPS_MARK; |
| 543 _hb_glyph_info_set_glyph_props (&info[i], klass); | 547 _hb_glyph_info_set_glyph_props (&info[i], klass); |
| 544 } | 548 } |
| 545 } | 549 } |
| 546 | 550 |
| 547 static inline void | 551 static inline void |
| 548 hb_ot_substitute_default (hb_ot_shape_context_t *c) | 552 hb_ot_substitute_default (hb_ot_shape_context_t *c) |
| 549 { | 553 { |
| 550 hb_buffer_t *buffer = c->buffer; | 554 hb_buffer_t *buffer = c->buffer; |
| 551 | 555 |
| 552 if (c->plan->shaper->preprocess_text) | |
| 553 c->plan->shaper->preprocess_text (c->plan, buffer, c->font); | |
| 554 | |
| 555 hb_ot_shape_initialize_masks (c); | 556 hb_ot_shape_initialize_masks (c); |
| 556 | 557 |
| 557 hb_ot_mirror_chars (c); | 558 hb_ot_mirror_chars (c); |
| 558 | 559 |
| 559 HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); | 560 HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); |
| 560 | 561 |
| 561 _hb_ot_shape_normalize (c->plan, buffer, c->font); | 562 _hb_ot_shape_normalize (c->plan, buffer, c->font); |
| 562 | 563 |
| 563 hb_ot_shape_setup_masks (c); | 564 hb_ot_shape_setup_masks (c); |
| 564 | 565 |
| 565 /* This is unfortunate to go here, but necessary... */ | 566 /* This is unfortunate to go here, but necessary... */ |
| 566 if (!hb_ot_layout_has_positioning (c->face)) | 567 if (!hb_ot_layout_has_positioning (c->face)) |
| 567 _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer)
; | 568 _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer)
; |
| 568 | 569 |
| 569 hb_ot_map_glyphs_fast (buffer); | 570 hb_ot_map_glyphs_fast (buffer); |
| 570 | 571 |
| 571 HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index); | 572 HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index); |
| 572 } | 573 } |
| 573 | 574 |
| 574 static inline void | 575 static inline void |
| 575 hb_ot_substitute_complex (hb_ot_shape_context_t *c) | 576 hb_ot_substitute_complex (hb_ot_shape_context_t *c) |
| 576 { | 577 { |
| 577 hb_buffer_t *buffer = c->buffer; | 578 hb_buffer_t *buffer = c->buffer; |
| 578 | 579 |
| 579 _hb_buffer_allocate_gsubgpos_vars (buffer); | |
| 580 hb_ot_layout_substitute_start (c->font, buffer); | 580 hb_ot_layout_substitute_start (c->font, buffer); |
| 581 | 581 |
| 582 if (!hb_ot_layout_has_glyph_classes (c->face)) | 582 if (!hb_ot_layout_has_glyph_classes (c->face)) |
| 583 hb_synthesize_glyph_classes (c); | 583 hb_synthesize_glyph_classes (c); |
| 584 | 584 |
| 585 c->plan->substitute (c->font, buffer); | 585 c->plan->substitute (c->font, buffer); |
| 586 | 586 |
| 587 hb_ot_layout_substitute_finish (c->font, buffer); | 587 hb_ot_layout_substitute_finish (c->font, buffer); |
| 588 | 588 |
| 589 return; | 589 return; |
| 590 } | 590 } |
| 591 | 591 |
| 592 static inline void | 592 static inline void |
| 593 hb_ot_substitute (hb_ot_shape_context_t *c) | 593 hb_ot_substitute (hb_ot_shape_context_t *c) |
| 594 { | 594 { |
| 595 hb_ot_substitute_default (c); | 595 hb_ot_substitute_default (c); |
| 596 |
| 597 _hb_buffer_allocate_gsubgpos_vars (c->buffer); |
| 598 |
| 596 hb_ot_substitute_complex (c); | 599 hb_ot_substitute_complex (c); |
| 597 } | 600 } |
| 598 | 601 |
| 599 /* Position */ | 602 /* Position */ |
| 600 | 603 |
| 601 static inline void | 604 static inline void |
| 602 adjust_mark_offsets (hb_glyph_position_t *pos) | 605 adjust_mark_offsets (hb_glyph_position_t *pos) |
| 603 { | 606 { |
| 604 pos->x_offset -= pos->x_advance; | 607 pos->x_offset -= pos->x_advance; |
| 605 pos->y_offset -= pos->y_advance; | 608 pos->y_offset -= pos->y_advance; |
| 606 } | 609 } |
| 607 | 610 |
| 608 static inline void | 611 static inline void |
| 609 zero_mark_width (hb_glyph_position_t *pos) | 612 zero_mark_width (hb_glyph_position_t *pos) |
| 610 { | 613 { |
| 611 pos->x_advance = 0; | 614 pos->x_advance = 0; |
| 612 pos->y_advance = 0; | 615 pos->y_advance = 0; |
| 613 } | 616 } |
| 614 | 617 |
| 615 static inline void | 618 static inline void |
| 616 zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets) | 619 zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets) |
| 617 { | 620 { |
| 621 if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) |
| 622 return; |
| 623 |
| 618 unsigned int count = buffer->len; | 624 unsigned int count = buffer->len; |
| 619 hb_glyph_info_t *info = buffer->info; | 625 hb_glyph_info_t *info = buffer->info; |
| 620 for (unsigned int i = 0; i < count; i++) | 626 for (unsigned int i = 0; i < count; i++) |
| 621 if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CAT
EGORY_NON_SPACING_MARK) | 627 if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CAT
EGORY_NON_SPACING_MARK) |
| 622 { | 628 { |
| 623 if (adjust_offsets) | 629 if (adjust_offsets) |
| 624 adjust_mark_offsets (&buffer->pos[i]); | 630 adjust_mark_offsets (&buffer->pos[i]); |
| 625 zero_mark_width (&buffer->pos[i]); | 631 zero_mark_width (&buffer->pos[i]); |
| 626 } | 632 } |
| 627 } | 633 } |
| 628 | 634 |
| 629 static inline void | 635 static inline void |
| 630 zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets) | 636 zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets) |
| 631 { | 637 { |
| 638 /* This one is a hack; Technically GDEF can mark ASCII glyphs as marks, but we
don't listen. */ |
| 639 if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) |
| 640 return; |
| 641 |
| 632 unsigned int count = buffer->len; | 642 unsigned int count = buffer->len; |
| 633 hb_glyph_info_t *info = buffer->info; | 643 hb_glyph_info_t *info = buffer->info; |
| 634 for (unsigned int i = 0; i < count; i++) | 644 for (unsigned int i = 0; i < count; i++) |
| 635 if (_hb_glyph_info_is_mark (&info[i])) | 645 if (_hb_glyph_info_is_mark (&info[i])) |
| 636 { | 646 { |
| 637 if (adjust_offsets) | 647 if (adjust_offsets) |
| 638 adjust_mark_offsets (&buffer->pos[i]); | 648 adjust_mark_offsets (&buffer->pos[i]); |
| 639 zero_mark_width (&buffer->pos[i]); | 649 zero_mark_width (&buffer->pos[i]); |
| 640 } | 650 } |
| 641 } | 651 } |
| 642 | 652 |
| 643 static inline void | 653 static inline void |
| 644 hb_ot_position_default (hb_ot_shape_context_t *c) | 654 hb_ot_position_default (hb_ot_shape_context_t *c) |
| 645 { | 655 { |
| 646 hb_direction_t direction = c->buffer->props.direction; | 656 hb_direction_t direction = c->buffer->props.direction; |
| 647 unsigned int count = c->buffer->len; | 657 unsigned int count = c->buffer->len; |
| 648 hb_glyph_info_t *info = c->buffer->info; | 658 hb_glyph_info_t *info = c->buffer->info; |
| 649 hb_glyph_position_t *pos = c->buffer->pos; | 659 hb_glyph_position_t *pos = c->buffer->pos; |
| 650 for (unsigned int i = 0; i < count; i++) | 660 |
| 661 if (HB_DIRECTION_IS_HORIZONTAL (direction)) |
| 651 { | 662 { |
| 652 c->font->get_glyph_advance_for_direction (info[i].codepoint, | 663 for (unsigned int i = 0; i < count; i++) |
| 653 » » » » » direction, | 664 pos[i].x_advance = c->font->get_glyph_h_advance (info[i].codepoint); |
| 654 » » » » » &pos[i].x_advance, | 665 if (c->font->has_glyph_h_origin_func ()) |
| 655 » » » » » &pos[i].y_advance); | 666 for (unsigned int i = 0; i < count; i++) |
| 656 c->font->subtract_glyph_origin_for_direction (info[i].codepoint, | 667 » c->font->subtract_glyph_h_origin (info[i].codepoint, |
| 657 » » » » » » direction, | 668 » » » » » &pos[i].x_offset, |
| 658 » » » » » » &pos[i].x_offset, | 669 » » » » » &pos[i].y_offset); |
| 659 » » » » » » &pos[i].y_offset); | |
| 660 | |
| 661 } | 670 } |
| 671 else |
| 672 { |
| 673 for (unsigned int i = 0; i < count; i++) |
| 674 pos[i].y_advance = c->font->get_glyph_v_advance (info[i].codepoint); |
| 675 if (c->font->has_glyph_v_origin_func ()) |
| 676 for (unsigned int i = 0; i < count; i++) |
| 677 c->font->subtract_glyph_v_origin (info[i].codepoint, |
| 678 &pos[i].x_offset, |
| 679 &pos[i].y_offset); |
| 680 } |
| 681 if (c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK) |
| 682 _hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer); |
| 662 } | 683 } |
| 663 | 684 |
| 664 static inline bool | 685 static inline bool |
| 665 hb_ot_position_complex (hb_ot_shape_context_t *c) | 686 hb_ot_position_complex (hb_ot_shape_context_t *c) |
| 666 { | 687 { |
| 667 bool ret = false; | 688 bool ret = false; |
| 668 unsigned int count = c->buffer->len; | 689 unsigned int count = c->buffer->len; |
| 669 bool has_positioning = hb_ot_layout_has_positioning (c->face); | 690 bool has_positioning = hb_ot_layout_has_positioning (c->face); |
| 670 /* If the font has no GPOS, AND, no fallback positioning will | 691 /* If the font has no GPOS, AND, no fallback positioning will |
| 671 * happen, AND, direction is forward, then when zeroing mark | 692 * happen, AND, direction is forward, then when zeroing mark |
| (...skipping 24 matching lines...) Expand all Loading... |
| 696 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: | 717 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: |
| 697 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: | 718 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: |
| 698 break; | 719 break; |
| 699 } | 720 } |
| 700 | 721 |
| 701 if (has_positioning) | 722 if (has_positioning) |
| 702 { | 723 { |
| 703 hb_glyph_info_t *info = c->buffer->info; | 724 hb_glyph_info_t *info = c->buffer->info; |
| 704 hb_glyph_position_t *pos = c->buffer->pos; | 725 hb_glyph_position_t *pos = c->buffer->pos; |
| 705 | 726 |
| 706 /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */ | 727 /* Change glyph origin to what GPOS expects (horizontal), apply GPOS, change
it back. */ |
| 707 | 728 |
| 708 for (unsigned int i = 0; i < count; i++) { | 729 if (c->font->has_glyph_h_origin_func ()) |
| 709 c->font->add_glyph_origin_for_direction (info[i].codepoint, | 730 for (unsigned int i = 0; i < count; i++) |
| 710 » » » » » HB_DIRECTION_LTR, | 731 » c->font->add_glyph_h_origin (info[i].codepoint, |
| 711 » » » » » &pos[i].x_offset, | 732 » » » » &pos[i].x_offset, |
| 712 » » » » » &pos[i].y_offset); | 733 » » » » &pos[i].y_offset); |
| 713 } | |
| 714 | 734 |
| 715 c->plan->position (c->font, c->buffer); | 735 c->plan->position (c->font, c->buffer); |
| 716 | 736 |
| 717 for (unsigned int i = 0; i < count; i++) { | 737 if (c->font->has_glyph_h_origin_func ()) |
| 718 c->font->subtract_glyph_origin_for_direction (info[i].codepoint, | 738 for (unsigned int i = 0; i < count; i++) |
| 719 » » » » » » HB_DIRECTION_LTR, | 739 » c->font->subtract_glyph_h_origin (info[i].codepoint, |
| 720 » » » » » » &pos[i].x_offset, | 740 » » » » » &pos[i].x_offset, |
| 721 » » » » » » &pos[i].y_offset); | 741 » » » » » &pos[i].y_offset); |
| 722 } | |
| 723 | 742 |
| 724 ret = true; | 743 ret = true; |
| 725 } | 744 } |
| 726 | 745 |
| 727 switch (c->plan->shaper->zero_width_marks) | 746 switch (c->plan->shaper->zero_width_marks) |
| 728 { | 747 { |
| 729 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: | 748 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: |
| 730 zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing); | 749 zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing); |
| 731 break; | 750 break; |
| 732 | 751 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 _hb_buffer_deallocate_gsubgpos_vars (c->buffer); | 790 _hb_buffer_deallocate_gsubgpos_vars (c->buffer); |
| 772 } | 791 } |
| 773 | 792 |
| 774 | 793 |
| 775 /* Pull it all together! */ | 794 /* Pull it all together! */ |
| 776 | 795 |
| 777 static void | 796 static void |
| 778 hb_ot_shape_internal (hb_ot_shape_context_t *c) | 797 hb_ot_shape_internal (hb_ot_shape_context_t *c) |
| 779 { | 798 { |
| 780 c->buffer->deallocate_var_all (); | 799 c->buffer->deallocate_var_all (); |
| 800 c->buffer->scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; |
| 801 if (likely (!_hb_unsigned_int_mul_overflows (c->buffer->len, HB_BUFFER_MAX_EXP
ANSION_FACTOR))) |
| 802 { |
| 803 c->buffer->max_len = MAX (c->buffer->len * HB_BUFFER_MAX_EXPANSION_FACTOR, |
| 804 (unsigned) HB_BUFFER_MAX_LEN_MIN); |
| 805 } |
| 781 | 806 |
| 782 /* Save the original direction, we use it later. */ | 807 /* Save the original direction, we use it later. */ |
| 783 c->target_direction = c->buffer->props.direction; | 808 c->target_direction = c->buffer->props.direction; |
| 784 | 809 |
| 785 _hb_buffer_allocate_unicode_vars (c->buffer); | 810 _hb_buffer_allocate_unicode_vars (c->buffer); |
| 786 | 811 |
| 787 c->buffer->clear_output (); | 812 c->buffer->clear_output (); |
| 788 | 813 |
| 789 hb_set_unicode_props (c->buffer); | 814 hb_set_unicode_props (c->buffer); |
| 790 hb_insert_dotted_circle (c->buffer, c->font); | 815 hb_insert_dotted_circle (c->buffer, c->font); |
| 791 hb_form_clusters (c->buffer); | 816 hb_form_clusters (c->buffer); |
| 792 | 817 |
| 793 hb_ensure_native_direction (c->buffer); | 818 hb_ensure_native_direction (c->buffer); |
| 794 | 819 |
| 820 if (c->plan->shaper->preprocess_text) |
| 821 c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font); |
| 822 |
| 795 hb_ot_substitute (c); | 823 hb_ot_substitute (c); |
| 796 hb_ot_position (c); | 824 hb_ot_position (c); |
| 797 | 825 |
| 798 hb_ot_hide_default_ignorables (c); | 826 hb_ot_hide_default_ignorables (c); |
| 799 | 827 |
| 828 if (c->plan->shaper->postprocess_glyphs) |
| 829 c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font); |
| 830 |
| 800 _hb_buffer_deallocate_unicode_vars (c->buffer); | 831 _hb_buffer_deallocate_unicode_vars (c->buffer); |
| 801 | 832 |
| 802 c->buffer->props.direction = c->target_direction; | 833 c->buffer->props.direction = c->target_direction; |
| 803 | 834 |
| 835 c->buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT; |
| 804 c->buffer->deallocate_var_all (); | 836 c->buffer->deallocate_var_all (); |
| 805 } | 837 } |
| 806 | 838 |
| 807 | 839 |
| 808 hb_bool_t | 840 hb_bool_t |
| 809 _hb_ot_shape (hb_shape_plan_t *shape_plan, | 841 _hb_ot_shape (hb_shape_plan_t *shape_plan, |
| 810 hb_font_t *font, | 842 hb_font_t *font, |
| 811 hb_buffer_t *buffer, | 843 hb_buffer_t *buffer, |
| 812 const hb_feature_t *features, | 844 const hb_feature_t *features, |
| 813 unsigned int num_features) | 845 unsigned int num_features) |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 hb_set_t copy; | 915 hb_set_t copy; |
| 884 copy.init (); | 916 copy.init (); |
| 885 do { | 917 do { |
| 886 copy.set (glyphs); | 918 copy.set (glyphs); |
| 887 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index)
;) | 919 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index)
;) |
| 888 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); | 920 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); |
| 889 } while (!copy.is_equal (glyphs)); | 921 } while (!copy.is_equal (glyphs)); |
| 890 | 922 |
| 891 hb_shape_plan_destroy (shape_plan); | 923 hb_shape_plan_destroy (shape_plan); |
| 892 } | 924 } |
| OLD | NEW |