Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(713)

Side by Side Diff: third_party/harfbuzz-ng/src/hb-coretext.cc

Issue 205003003: Update harfbuzz-ng to 0.9.27 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: w/missing files Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-coretext.h ('k') | third_party/harfbuzz-ng/src/hb-face.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 19 matching lines...) Expand all
30 #include "hb-shaper-impl-private.hh" 30 #include "hb-shaper-impl-private.hh"
31 31
32 #include "hb-coretext.h" 32 #include "hb-coretext.h"
33 33
34 34
35 #ifndef HB_DEBUG_CORETEXT 35 #ifndef HB_DEBUG_CORETEXT
36 #define HB_DEBUG_CORETEXT (HB_DEBUG+0) 36 #define HB_DEBUG_CORETEXT (HB_DEBUG+0)
37 #endif 37 #endif
38 38
39 39
40 static void
41 release_table_data (void *user_data)
42 {
43 CFDataRef cf_data = reinterpret_cast<CFDataRef> (user_data);
44 CFRelease(cf_data);
45 }
46
47 static hb_blob_t *
48 reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
49 {
50 CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data);
51 CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag);
52 if (unlikely (!cf_data))
53 return NULL;
54
55 const char *data = reinterpret_cast<const char*> (CFDataGetBytePtr (cf_data));
56 const size_t length = CFDataGetLength (cf_data);
57 if (!data || !length)
58 return NULL;
59
60 return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY,
61 reinterpret_cast<void *> (const_cast<__CFData *> (cf_da ta)),
62 release_table_data);
63 }
64
65 hb_face_t *
66 hb_coretext_face_create (CGFontRef cg_font)
67 {
68 return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), (hb _destroy_func_t) CGFontRelease);
69 }
70
71
40 HB_SHAPER_DATA_ENSURE_DECLARE(coretext, face) 72 HB_SHAPER_DATA_ENSURE_DECLARE(coretext, face)
41 HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font) 73 HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font)
42 74
43 75
44 /* 76 /*
45 * shaper face data 77 * shaper face data
46 */ 78 */
47 79
48 struct hb_coretext_shaper_face_data_t { 80 struct hb_coretext_shaper_face_data_t {
49 CGFontRef cg_font; 81 CGFontRef cg_font;
50 }; 82 };
51 83
52 static void 84 static void
53 release_data (void *info, const void *data, size_t size) 85 release_data (void *info, const void *data, size_t size)
54 { 86 {
55 assert (hb_blob_get_length ((hb_blob_t *) info) == size && 87 assert (hb_blob_get_length ((hb_blob_t *) info) == size &&
56 hb_blob_get_data ((hb_blob_t *) info, NULL) == data); 88 hb_blob_get_data ((hb_blob_t *) info, NULL) == data);
57 89
58 hb_blob_destroy ((hb_blob_t *) info); 90 hb_blob_destroy ((hb_blob_t *) info);
59 } 91 }
60 92
61 hb_coretext_shaper_face_data_t * 93 hb_coretext_shaper_face_data_t *
62 _hb_coretext_shaper_face_data_create (hb_face_t *face) 94 _hb_coretext_shaper_face_data_create (hb_face_t *face)
63 { 95 {
64 hb_coretext_shaper_face_data_t *data = (hb_coretext_shaper_face_data_t *) call oc (1, sizeof (hb_coretext_shaper_face_data_t)); 96 hb_coretext_shaper_face_data_t *data = (hb_coretext_shaper_face_data_t *) call oc (1, sizeof (hb_coretext_shaper_face_data_t));
65 if (unlikely (!data)) 97 if (unlikely (!data))
66 return NULL; 98 return NULL;
67 99
68 hb_blob_t *blob = hb_face_reference_blob (face); 100 if (face->destroy == (hb_destroy_func_t) CGFontRelease)
69 unsigned int blob_length; 101 {
70 const char *blob_data = hb_blob_get_data (blob, &blob_length); 102 data->cg_font = CGFontRetain ((CGFontRef) face->user_data);
71 if (unlikely (!blob_length)) 103 }
72 DEBUG_MSG (CORETEXT, face, "Face has empty blob"); 104 else
105 {
106 hb_blob_t *blob = hb_face_reference_blob (face);
107 unsigned int blob_length;
108 const char *blob_data = hb_blob_get_data (blob, &blob_length);
109 if (unlikely (!blob_length))
110 DEBUG_MSG (CORETEXT, face, "Face has empty blob");
73 111
74 CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, bl ob_length, &release_data); 112 CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data);
75 data->cg_font = CGFontCreateWithDataProvider (provider); 113 data->cg_font = CGFontCreateWithDataProvider (provider);
76 CGDataProviderRelease (provider); 114 CGDataProviderRelease (provider);
115 }
77 116
78 if (unlikely (!data->cg_font)) { 117 if (unlikely (!data->cg_font)) {
79 DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed"); 118 DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed");
80 free (data); 119 free (data);
81 return NULL; 120 return NULL;
82 } 121 }
83 122
84 return data; 123 return data;
85 } 124 }
86 125
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 } 426 }
388 427
389 hb_bool_t 428 hb_bool_t
390 _hb_coretext_shape (hb_shape_plan_t *shape_plan, 429 _hb_coretext_shape (hb_shape_plan_t *shape_plan,
391 hb_font_t *font, 430 hb_font_t *font,
392 hb_buffer_t *buffer, 431 hb_buffer_t *buffer,
393 const hb_feature_t *features, 432 const hb_feature_t *features,
394 unsigned int num_features) 433 unsigned int num_features)
395 { 434 {
396 hb_face_t *face = font->face; 435 hb_face_t *face = font->face;
436 hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
397 hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); 437 hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
398 438
399 /* 439 /*
400 * Set up features. 440 * Set up features.
401 * (copied + modified from code from hb-uniscribe.cc) 441 * (copied + modified from code from hb-uniscribe.cc)
402 */ 442 */
403 hb_auto_array_t<feature_record_t> feature_records; 443 hb_auto_array_t<feature_record_t> feature_records;
404 hb_auto_array_t<range_record_t> range_records; 444 hb_auto_array_t<range_record_t> range_records;
405 if (num_features) 445 if (num_features)
406 { 446 {
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 } 623 }
584 624
585 #undef utf16_index 625 #undef utf16_index
586 626
587 CFStringRef string_ref = CFStringCreateWithCharactersNoCopy (NULL, 627 CFStringRef string_ref = CFStringCreateWithCharactersNoCopy (NULL,
588 pchars, chars_len , 628 pchars, chars_len ,
589 kCFAllocatorNull) ; 629 kCFAllocatorNull) ;
590 630
591 CFMutableAttributedStringRef attr_string = CFAttributedStringCreateMutable (NU LL, chars_len); 631 CFMutableAttributedStringRef attr_string = CFAttributedStringCreateMutable (NU LL, chars_len);
592 CFAttributedStringReplaceString (attr_string, CFRangeMake (0, 0), string_ref); 632 CFAttributedStringReplaceString (attr_string, CFRangeMake (0, 0), string_ref);
593 CFRelease (string_ref);
594 CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), 633 CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
595 kCTFontAttributeName, font_data->ct_font); 634 kCTFontAttributeName, font_data->ct_font);
596 635
597 if (num_features) 636 if (num_features)
598 { 637 {
599 ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len); 638 ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len);
600 639
601 /* Need log_clusters to assign features. */ 640 /* Need log_clusters to assign features. */
602 chars_len = 0; 641 chars_len = 0;
603 for (unsigned int i = 0; i < buffer->len; i++) 642 for (unsigned int i = 0; i < buffer->len; i++)
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 CTLineRef line = CTLineCreateWithAttributedString (attr_string); 680 CTLineRef line = CTLineCreateWithAttributedString (attr_string);
642 CFRelease (attr_string); 681 CFRelease (attr_string);
643 682
644 CFArrayRef glyph_runs = CTLineGetGlyphRuns (line); 683 CFArrayRef glyph_runs = CTLineGetGlyphRuns (line);
645 unsigned int num_runs = CFArrayGetCount (glyph_runs); 684 unsigned int num_runs = CFArrayGetCount (glyph_runs);
646 685
647 buffer->len = 0; 686 buffer->len = 0;
648 687
649 const CFRange range_all = CFRangeMake (0, 0); 688 const CFRange range_all = CFRangeMake (0, 0);
650 689
651 for (unsigned int i = 0; i < num_runs; i++) { 690 for (unsigned int i = 0; i < num_runs; i++)
691 {
652 CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex (glyph_runs, i); 692 CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex (glyph_runs, i);
653 693
694 /* CoreText does automatic font fallback (AKA "cascading") for characters
695 * not supported by the requested font, and provides no way to turn it off,
696 * so we detect if the returned run uses a font other than the requested
697 * one and fill in the buffer with .notdef glyphs instead of random glyph
698 * indices from a different font.
699 */
700 CFDictionaryRef attributes = CTRunGetAttributes (run);
701 CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attribu tes, kCTFontAttributeName));
702 CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
703 if (!CFEqual (run_cg_font, face_data->cg_font))
704 {
705 CFRelease (run_cg_font);
706
707 CFRange range = CTRunGetStringRange (run);
708 buffer->ensure (buffer->len + range.length);
709 if (buffer->in_error)
710 FAIL ("Buffer resize failed");
711 hb_glyph_info_t *info = buffer->info + buffer->len;
712
713 CGGlyph notdef = 0;
714 double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFont HorizontalOrientation, &notdef, NULL, 1);
715
716 for (CFIndex j = range.location; j < range.location + range.length; j++)
717 {
718 UniChar ch = CFStringGetCharacterAtIndex (string_ref, j);
719 if (hb_in_range<UniChar> (ch, 0xDC00, 0xDFFF) && range.location < j)
720 {
721 ch = CFStringGetCharacterAtIndex (string_ref, j - 1);
722 if (hb_in_range<UniChar> (ch, 0xD800, 0xDBFF))
723 /* This is the second of a surrogate pair. Don't need .notdef
724 * for this one. */
725 continue;
726 }
727
728 info->codepoint = notdef;
729 /* TODO We have to fixup clusters later. See vis_clusters in
730 * hb-uniscribe.cc for example. */
731 info->cluster = j;
732
733 info->mask = advance;
734 info->var1.u32 = 0;
735 info->var2.u32 = 0;
736
737 info++;
738 buffer->len++;
739 }
740 continue;
741 }
742 CFRelease (run_cg_font);
743
654 unsigned int num_glyphs = CTRunGetGlyphCount (run); 744 unsigned int num_glyphs = CTRunGetGlyphCount (run);
655 if (num_glyphs == 0) 745 if (num_glyphs == 0)
656 continue; 746 continue;
657 747
658 buffer->ensure (buffer->len + num_glyphs); 748 buffer->ensure (buffer->len + num_glyphs);
659 749
660 scratch = buffer->get_scratch_buffer (&scratch_size); 750 scratch = buffer->get_scratch_buffer (&scratch_size);
661 751
662 /* Testing indicates that CTRunGetGlyphsPtr, etc (almost?) always 752 /* Testing indicates that CTRunGetGlyphsPtr, etc (almost?) always
663 * succeed, and so copying data to our own buffer will be rare. */ 753 * succeed, and so copying data to our own buffer will be rare. */
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 if (buffer->info[j - 1].cluster < curr_cluster) 837 if (buffer->info[j - 1].cluster < curr_cluster)
748 buffer->info[j - 1].cluster = curr_cluster; 838 buffer->info[j - 1].cluster = curr_cluster;
749 else 839 else
750 break; 840 break;
751 } 841 }
752 } 842 }
753 prev_cluster = curr_cluster; 843 prev_cluster = curr_cluster;
754 } 844 }
755 } 845 }
756 846
847 CFRelease (string_ref);
757 CFRelease (line); 848 CFRelease (line);
758 849
759 return true; 850 return true;
760 } 851 }
852
853
854 /*
855 * AAT shaper
856 */
857
858 HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, face)
859 HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, font)
860
861
862 /*
863 * shaper face data
864 */
865
866 struct hb_coretext_aat_shaper_face_data_t {};
867
868 hb_coretext_aat_shaper_face_data_t *
869 _hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
870 {
871 hb_blob_t *mort_blob = face->reference_table (HB_CORETEXT_TAG_MORT);
872 /* Umm, we just reference the table to check whether it exists.
873 * Maybe add better API for this? */
874 if (!hb_blob_get_length (mort_blob))
875 {
876 hb_blob_destroy (mort_blob);
877 mort_blob = face->reference_table (HB_CORETEXT_TAG_MORX);
878 if (!hb_blob_get_length (mort_blob))
879 {
880 hb_blob_destroy (mort_blob);
881 return NULL;
882 }
883 }
884 hb_blob_destroy (mort_blob);
885
886 return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_shaper_fa ce_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL;
887 }
888
889 void
890 _hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_shaper_face_data_t *d ata HB_UNUSED)
891 {
892 }
893
894
895 /*
896 * shaper font data
897 */
898
899 struct hb_coretext_aat_shaper_font_data_t {};
900
901 hb_coretext_aat_shaper_font_data_t *
902 _hb_coretext_aat_shaper_font_data_create (hb_font_t *font)
903 {
904 return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_shaper_fo nt_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL;
905 }
906
907 void
908 _hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_shaper_font_data_t *d ata HB_UNUSED)
909 {
910 }
911
912
913 /*
914 * shaper shape_plan data
915 */
916
917 struct hb_coretext_aat_shaper_shape_plan_data_t {};
918
919 hb_coretext_aat_shaper_shape_plan_data_t *
920 _hb_coretext_aat_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan H B_UNUSED,
921 const hb_feature_t *user_features H B_UNUSED,
922 unsigned int num_user_featur es HB_UNUSED)
923 {
924 return (hb_coretext_aat_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
925 }
926
927 void
928 _hb_coretext_aat_shaper_shape_plan_data_destroy (hb_coretext_aat_shaper_shape_pl an_data_t *data HB_UNUSED)
929 {
930 }
931
932
933 /*
934 * shaper
935 */
936
937 hb_bool_t
938 _hb_coretext_aat_shape (hb_shape_plan_t *shape_plan,
939 hb_font_t *font,
940 hb_buffer_t *buffer,
941 const hb_feature_t *features,
942 unsigned int num_features)
943 {
944 return _hb_coretext_shape (shape_plan, font, buffer, features, num_features);
945 }
OLDNEW
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-coretext.h ('k') | third_party/harfbuzz-ng/src/hb-face.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698