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