OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2012,2013 Mozilla Foundation. | 2 * Copyright © 2012,2013 Mozilla Foundation. |
3 * Copyright © 2012,2013 Google, Inc. | 3 * Copyright © 2012,2013 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 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 event->start = true; | 470 event->start = true; |
471 event->feature = feature; | 471 event->feature = feature; |
472 | 472 |
473 event = feature_events.push (); | 473 event = feature_events.push (); |
474 if (unlikely (!event)) | 474 if (unlikely (!event)) |
475 goto fail_features; | 475 goto fail_features; |
476 event->index = features[i].end; | 476 event->index = features[i].end; |
477 event->start = false; | 477 event->start = false; |
478 event->feature = feature; | 478 event->feature = feature; |
479 } | 479 } |
480 feature_events.sort (); | 480 feature_events.qsort (); |
481 /* Add a strategic final event. */ | 481 /* Add a strategic final event. */ |
482 { | 482 { |
483 active_feature_t feature; | 483 active_feature_t feature; |
484 feature.rec.feature = HB_TAG_NONE; | 484 feature.rec.feature = HB_TAG_NONE; |
485 feature.rec.setting = 0; | 485 feature.rec.setting = 0; |
486 feature.order = num_features + 1; | 486 feature.order = num_features + 1; |
487 | 487 |
488 feature_event_t *event = feature_events.push (); | 488 feature_event_t *event = feature_events.push (); |
489 if (unlikely (!event)) | 489 if (unlikely (!event)) |
490 goto fail_features; | 490 goto fail_features; |
491 event->index = 0; /* This value does magic. */ | 491 event->index = 0; /* This value does magic. */ |
492 event->start = false; | 492 event->start = false; |
493 event->feature = feature; | 493 event->feature = feature; |
494 } | 494 } |
495 | 495 |
496 /* Scan events and save features for each range. */ | 496 /* Scan events and save features for each range. */ |
497 hb_auto_array_t<active_feature_t> active_features; | 497 hb_auto_array_t<active_feature_t> active_features; |
498 unsigned int last_index = 0; | 498 unsigned int last_index = 0; |
499 for (unsigned int i = 0; i < feature_events.len; i++) | 499 for (unsigned int i = 0; i < feature_events.len; i++) |
500 { | 500 { |
501 feature_event_t *event = &feature_events[i]; | 501 feature_event_t *event = &feature_events[i]; |
502 | 502 |
503 if (event->index != last_index) | 503 if (event->index != last_index) |
504 { | 504 { |
505 /* Save a snapshot of active features and the range. */ | 505 /* Save a snapshot of active features and the range. */ |
506 range_record_t *range = range_records.push (); | 506 range_record_t *range = range_records.push (); |
507 if (unlikely (!range)) | 507 if (unlikely (!range)) |
508 goto fail_features; | 508 goto fail_features; |
509 | 509 |
510 unsigned int offset = feature_records.len; | |
511 | |
512 if (active_features.len) | 510 if (active_features.len) |
513 { | 511 { |
514 CFMutableArrayRef features_array = CFArrayCreateMutable(kCFAllocatorDe
fault, 0, &kCFTypeArrayCallBacks); | 512 CFMutableArrayRef features_array = CFArrayCreateMutable(kCFAllocatorDe
fault, 0, &kCFTypeArrayCallBacks); |
515 | 513 |
516 /* TODO sort and resolve conflicting features? */ | 514 /* TODO sort and resolve conflicting features? */ |
517 » /* active_features.sort (); */ | 515 » /* active_features.qsort (); */ |
518 for (unsigned int j = 0; j < active_features.len; j++) | 516 for (unsigned int j = 0; j < active_features.len; j++) |
519 { | 517 { |
520 CFStringRef keys[2] = { | 518 CFStringRef keys[2] = { |
521 kCTFontFeatureTypeIdentifierKey, | 519 kCTFontFeatureTypeIdentifierKey, |
522 kCTFontFeatureSelectorIdentifierKey | 520 kCTFontFeatureSelectorIdentifierKey |
523 }; | 521 }; |
524 CFNumberRef values[2] = { | 522 CFNumberRef values[2] = { |
525 CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_fea
tures[j].rec.feature), | 523 CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_fea
tures[j].rec.feature), |
526 CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_fea
tures[j].rec.setting) | 524 CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_fea
tures[j].rec.setting) |
527 }; | 525 }; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 } | 603 } |
606 | 604 |
607 #define utf16_index() var1.u32 | 605 #define utf16_index() var1.u32 |
608 | 606 |
609 ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2); | 607 ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2); |
610 | 608 |
611 unsigned int chars_len = 0; | 609 unsigned int chars_len = 0; |
612 for (unsigned int i = 0; i < buffer->len; i++) { | 610 for (unsigned int i = 0; i < buffer->len; i++) { |
613 hb_codepoint_t c = buffer->info[i].codepoint; | 611 hb_codepoint_t c = buffer->info[i].codepoint; |
614 buffer->info[i].utf16_index() = chars_len; | 612 buffer->info[i].utf16_index() = chars_len; |
615 if (likely (c < 0x10000)) | 613 if (likely (c <= 0xFFFFu)) |
616 pchars[chars_len++] = c; | 614 pchars[chars_len++] = c; |
617 else if (unlikely (c >= 0x110000)) | 615 else if (unlikely (c > 0x10FFFFu)) |
618 pchars[chars_len++] = 0xFFFD; | 616 pchars[chars_len++] = 0xFFFDu; |
619 else { | 617 else { |
620 pchars[chars_len++] = 0xD800 + ((c - 0x10000) >> 10); | 618 pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10); |
621 pchars[chars_len++] = 0xDC00 + ((c - 0x10000) & ((1 << 10) - 1)); | 619 pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1 << 10) - 1)); |
622 } | 620 } |
623 } | 621 } |
624 | 622 |
625 #undef utf16_index | 623 #undef utf16_index |
626 | 624 |
627 CFStringRef string_ref = CFStringCreateWithCharactersNoCopy (NULL, | 625 CFStringRef string_ref = CFStringCreateWithCharactersNoCopy (NULL, |
628 pchars, chars_len
, | 626 pchars, chars_len
, |
629 kCFAllocatorNull)
; | 627 kCFAllocatorNull)
; |
630 | 628 |
631 CFMutableAttributedStringRef attr_string = CFAttributedStringCreateMutable (NU
LL, chars_len); | 629 CFMutableAttributedStringRef attr_string = CFAttributedStringCreateMutable (NU
LL, chars_len); |
632 CFAttributedStringReplaceString (attr_string, CFRangeMake (0, 0), string_ref); | 630 CFAttributedStringReplaceString (attr_string, CFRangeMake (0, 0), string_ref); |
633 CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), | 631 CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), |
634 kCTFontAttributeName, font_data->ct_font); | 632 kCTFontAttributeName, font_data->ct_font); |
635 | 633 |
636 if (num_features) | 634 if (num_features) |
637 { | 635 { |
638 ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len); | 636 ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len); |
639 | 637 |
640 /* Need log_clusters to assign features. */ | 638 /* Need log_clusters to assign features. */ |
641 chars_len = 0; | 639 chars_len = 0; |
642 for (unsigned int i = 0; i < buffer->len; i++) | 640 for (unsigned int i = 0; i < buffer->len; i++) |
643 { | 641 { |
644 hb_codepoint_t c = buffer->info[i].codepoint; | 642 hb_codepoint_t c = buffer->info[i].codepoint; |
645 unsigned int cluster = buffer->info[i].cluster; | 643 unsigned int cluster = buffer->info[i].cluster; |
646 log_clusters[chars_len++] = cluster; | 644 log_clusters[chars_len++] = cluster; |
647 if (c >= 0x10000 && c < 0x110000) | 645 if (hb_in_range (c, 0x10000u, 0x10FFFFu)) |
648 log_clusters[chars_len++] = cluster; /* Surrogates. */ | 646 log_clusters[chars_len++] = cluster; /* Surrogates. */ |
649 } | 647 } |
650 | 648 |
651 unsigned int start = 0; | 649 unsigned int start = 0; |
652 range_record_t *last_range = &range_records[0]; | 650 range_record_t *last_range = &range_records[0]; |
653 for (unsigned int k = 0; k < chars_len; k++) | 651 for (unsigned int k = 0; k < chars_len; k++) |
654 { | 652 { |
655 range_record_t *range = last_range; | 653 range_record_t *range = last_range; |
656 while (log_clusters[k] < range->index_first) | 654 while (log_clusters[k] < range->index_first) |
657 range--; | 655 range--; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 if (buffer->in_error) | 707 if (buffer->in_error) |
710 FAIL ("Buffer resize failed"); | 708 FAIL ("Buffer resize failed"); |
711 hb_glyph_info_t *info = buffer->info + buffer->len; | 709 hb_glyph_info_t *info = buffer->info + buffer->len; |
712 | 710 |
713 CGGlyph notdef = 0; | 711 CGGlyph notdef = 0; |
714 double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFont
HorizontalOrientation, ¬def, NULL, 1); | 712 double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFont
HorizontalOrientation, ¬def, NULL, 1); |
715 | 713 |
716 for (CFIndex j = range.location; j < range.location + range.length; j++) | 714 for (CFIndex j = range.location; j < range.location + range.length; j++) |
717 { | 715 { |
718 UniChar ch = CFStringGetCharacterAtIndex (string_ref, j); | 716 UniChar ch = CFStringGetCharacterAtIndex (string_ref, j); |
719 » if (hb_in_range<UniChar> (ch, 0xDC00, 0xDFFF) && range.location < j) | 717 » if (hb_in_range<UniChar> (ch, 0xDC00u, 0xDFFFu) && range.location <
j) |
720 { | 718 { |
721 ch = CFStringGetCharacterAtIndex (string_ref, j - 1); | 719 ch = CFStringGetCharacterAtIndex (string_ref, j - 1); |
722 » if (hb_in_range<UniChar> (ch, 0xD800, 0xDBFF)) | 720 » if (hb_in_range<UniChar> (ch, 0xD800u, 0xDBFFu)) |
723 /* This is the second of a surrogate pair. Don't need .notdef | 721 /* This is the second of a surrogate pair. Don't need .notdef |
724 * for this one. */ | 722 * for this one. */ |
725 continue; | 723 continue; |
726 } | 724 } |
727 | 725 |
728 info->codepoint = notdef; | 726 info->codepoint = notdef; |
729 /* TODO We have to fixup clusters later. See vis_clusters in | 727 /* TODO We have to fixup clusters later. See vis_clusters in |
730 * hb-uniscribe.cc for example. */ | 728 * hb-uniscribe.cc for example. */ |
731 info->cluster = j; | 729 info->cluster = j; |
732 | 730 |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
936 | 934 |
937 hb_bool_t | 935 hb_bool_t |
938 _hb_coretext_aat_shape (hb_shape_plan_t *shape_plan, | 936 _hb_coretext_aat_shape (hb_shape_plan_t *shape_plan, |
939 hb_font_t *font, | 937 hb_font_t *font, |
940 hb_buffer_t *buffer, | 938 hb_buffer_t *buffer, |
941 const hb_feature_t *features, | 939 const hb_feature_t *features, |
942 unsigned int num_features) | 940 unsigned int num_features) |
943 { | 941 { |
944 return _hb_coretext_shape (shape_plan, font, buffer, features, num_features); | 942 return _hb_coretext_shape (shape_plan, font, buffer, features, num_features); |
945 } | 943 } |
OLD | NEW |