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 |