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

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

Issue 935333002: Update from https://crrev.com/316786 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 10 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-common.cc ('k') | third_party/harfbuzz-ng/src/hb-ft.h » ('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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 return face_data; 133 return face_data;
134 } 134 }
135 135
136 136
137 /* 137 /*
138 * shaper font data 138 * shaper font data
139 */ 139 */
140 140
141 struct hb_coretext_shaper_font_data_t { 141 struct hb_coretext_shaper_font_data_t {
142 CTFontRef ct_font; 142 CTFontRef ct_font;
143 CGFloat x_mult, y_mult; /* From CT space to HB space. */
143 }; 144 };
144 145
145 hb_coretext_shaper_font_data_t * 146 hb_coretext_shaper_font_data_t *
146 _hb_coretext_shaper_font_data_create (hb_font_t *font) 147 _hb_coretext_shaper_font_data_create (hb_font_t *font)
147 { 148 {
148 if (unlikely (!hb_coretext_shaper_face_data_ensure (font->face))) return NULL; 149 if (unlikely (!hb_coretext_shaper_face_data_ensure (font->face))) return NULL;
149 150
150 hb_coretext_shaper_font_data_t *data = (hb_coretext_shaper_font_data_t *) call oc (1, sizeof (hb_coretext_shaper_font_data_t)); 151 hb_coretext_shaper_font_data_t *data = (hb_coretext_shaper_font_data_t *) call oc (1, sizeof (hb_coretext_shaper_font_data_t));
151 if (unlikely (!data)) 152 if (unlikely (!data))
152 return NULL; 153 return NULL;
153 154
154 hb_face_t *face = font->face; 155 hb_face_t *face = font->face;
155 hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); 156 hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
156 157
157 data->ct_font = CTFontCreateWithGraphicsFont (face_data, font->y_scale, NULL, NULL); 158 /* Choose a CoreText font size and calculate multipliers to convert to HarfBuz z space. */
159 CGFloat font_size = 36.; /* Default... */
160 /* No idea if the following is even a good idea. */
161 if (font->y_ppem)
162 font_size = font->y_ppem;
163
164 if (font_size < 0)
165 font_size = -font_size;
166 data->x_mult = (CGFloat) font->x_scale / font_size;
167 data->y_mult = (CGFloat) font->y_scale / font_size;
168 data->ct_font = CTFontCreateWithGraphicsFont (face_data, font_size, NULL, NULL );
158 if (unlikely (!data->ct_font)) { 169 if (unlikely (!data->ct_font)) {
159 DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed"); 170 DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed");
160 free (data); 171 free (data);
161 return NULL; 172 return NULL;
162 } 173 }
163 174
164 return data; 175 return data;
165 } 176 }
166 177
167 void 178 void
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 if (unlikely (!line)) 780 if (unlikely (!line))
770 FAIL ("CTTypesetterCreateLine failed"); 781 FAIL ("CTTypesetterCreateLine failed");
771 } 782 }
772 783
773 CFArrayRef glyph_runs = CTLineGetGlyphRuns (line); 784 CFArrayRef glyph_runs = CTLineGetGlyphRuns (line);
774 unsigned int num_runs = CFArrayGetCount (glyph_runs); 785 unsigned int num_runs = CFArrayGetCount (glyph_runs);
775 DEBUG_MSG (CORETEXT, NULL, "Num runs: %d", num_runs); 786 DEBUG_MSG (CORETEXT, NULL, "Num runs: %d", num_runs);
776 787
777 buffer->len = 0; 788 buffer->len = 0;
778 uint32_t status_and = ~0, status_or = 0; 789 uint32_t status_and = ~0, status_or = 0;
790 double advances_so_far = 0;
779 791
780 const CFRange range_all = CFRangeMake (0, 0); 792 const CFRange range_all = CFRangeMake (0, 0);
781 793
782 for (unsigned int i = 0; i < num_runs; i++) 794 for (unsigned int i = 0; i < num_runs; i++)
783 { 795 {
784 CTRunRef run = static_cast<CTRunRef>(CFArrayGetValueAtIndex (glyph_runs, i )); 796 CTRunRef run = static_cast<CTRunRef>(CFArrayGetValueAtIndex (glyph_runs, i ));
785 CTRunStatus run_status = CTRunGetStatus (run); 797 CTRunStatus run_status = CTRunGetStatus (run);
786 status_or |= run_status; 798 status_or |= run_status;
787 status_and &= run_status; 799 status_and &= run_status;
788 DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status); 800 DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status);
801 double run_advance = CTRunGetTypographicBounds (run, range_all, NULL, NULL , NULL);
802 if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
803 run_advance = -run_advance;
804 DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance);
789 805
790 /* CoreText does automatic font fallback (AKA "cascading") for characters 806 /* CoreText does automatic font fallback (AKA "cascading") for characters
791 * not supported by the requested font, and provides no way to turn it off , 807 * not supported by the requested font, and provides no way to turn it off ,
792 * so we must detect if the returned run uses a font other than the reques ted 808 * so we must detect if the returned run uses a font other than the reques ted
793 * one and fill in the buffer with .notdef glyphs instead of random glyph 809 * one and fill in the buffer with .notdef glyphs instead of random glyph
794 * indices from a different font. 810 * indices from a different font.
795 */ 811 */
796 CFDictionaryRef attributes = CTRunGetAttributes (run); 812 CFDictionaryRef attributes = CTRunGetAttributes (run);
797 CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attri butes, kCTFontAttributeName)); 813 CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attri butes, kCTFontAttributeName));
798 if (!CFEqual (run_ct_font, font_data->ct_font)) 814 if (!CFEqual (run_ct_font, font_data->ct_font))
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 } 869 }
854 if (!matched) 870 if (!matched)
855 { 871 {
856 CFRange range = CTRunGetStringRange (run); 872 CFRange range = CTRunGetStringRange (run);
857 DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld", 873 DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld",
858 range.location, range.location + range.length); 874 range.location, range.location + range.length);
859 if (!buffer->ensure_inplace (buffer->len + range.length)) 875 if (!buffer->ensure_inplace (buffer->len + range.length))
860 goto resize_and_retry; 876 goto resize_and_retry;
861 hb_glyph_info_t *info = buffer->info + buffer->len; 877 hb_glyph_info_t *info = buffer->info + buffer->len;
862 878
863 » CGGlyph notdef = 0; 879 » hb_codepoint_t notdef = 0;
864 » double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFo ntHorizontalOrientation, &notdef, NULL, 1); 880 » hb_direction_t dir = buffer->props.direction;
881 » hb_position_t x_advance, y_advance, x_offset, y_offset;
882 » hb_font_get_glyph_advance_for_direction (font, notdef, dir, &x_advance , &y_advance);
883 » hb_font_get_glyph_origin_for_direction (font, notdef, dir, &x_offset, &y_offset);
884 » hb_position_t advance = x_advance + y_advance;
885 » x_offset = -x_offset;
886 » y_offset = -y_offset;
865 887
866 unsigned int old_len = buffer->len; 888 unsigned int old_len = buffer->len;
867 for (CFIndex j = range.location; j < range.location + range.length; j+ +) 889 for (CFIndex j = range.location; j < range.location + range.length; j+ +)
868 { 890 {
869 UniChar ch = CFStringGetCharacterAtIndex (string_ref, j); 891 UniChar ch = CFStringGetCharacterAtIndex (string_ref, j);
870 if (hb_in_range<UniChar> (ch, 0xDC00u, 0xDFFFu) && range.location < j) 892 if (hb_in_range<UniChar> (ch, 0xDC00u, 0xDFFFu) && range.location < j)
871 { 893 {
872 ch = CFStringGetCharacterAtIndex (string_ref, j - 1); 894 ch = CFStringGetCharacterAtIndex (string_ref, j - 1);
873 if (hb_in_range<UniChar> (ch, 0xD800u, 0xDBFFu)) 895 if (hb_in_range<UniChar> (ch, 0xD800u, 0xDBFFu))
874 /* This is the second of a surrogate pair. Don't need .notdef 896 /* This is the second of a surrogate pair. Don't need .notdef
875 * for this one. */ 897 * for this one. */
876 continue; 898 continue;
877 } 899 }
900 if (buffer->unicode->is_default_ignorable (ch))
901 continue;
878 902
879 info->codepoint = notdef; 903 info->codepoint = notdef;
880 info->cluster = log_clusters[j]; 904 info->cluster = log_clusters[j];
881 905
882 info->mask = advance; 906 info->mask = advance;
883 » info->var1.u32 = 0; 907 » info->var1.u32 = x_offset;
884 » info->var2.u32 = 0; 908 » info->var2.u32 = y_offset;
885 909
886 info++; 910 info++;
887 buffer->len++; 911 buffer->len++;
888 } 912 }
889 if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) 913 if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
890 buffer->reverse_range (old_len, buffer->len); 914 buffer->reverse_range (old_len, buffer->len);
915 advances_so_far += run_advance;
891 continue; 916 continue;
892 } 917 }
893 } 918 }
894 919
895 unsigned int num_glyphs = CTRunGetGlyphCount (run); 920 unsigned int num_glyphs = CTRunGetGlyphCount (run);
896 if (num_glyphs == 0) 921 if (num_glyphs == 0)
897 continue; 922 continue;
898 923
899 if (!buffer->ensure_inplace (buffer->len + num_glyphs)) 924 if (!buffer->ensure_inplace (buffer->len + num_glyphs))
900 goto resize_and_retry; 925 goto resize_and_retry;
901 926
902 hb_glyph_info_t *run_info = buffer->info + buffer->len; 927 hb_glyph_info_t *run_info = buffer->info + buffer->len;
903 928
904 /* Testing used to indicate that CTRunGetGlyphsPtr, etc (almost?) always 929 /* Testing used to indicate that CTRunGetGlyphsPtr, etc (almost?) always
905 * succeed, and so copying data to our own buffer will be rare. Reports 930 * succeed, and so copying data to our own buffer will be rare. Reports
906 * have it that this changed in OS X 10.10 Yosemite, and NULL is returned 931 * have it that this changed in OS X 10.10 Yosemite, and NULL is returned
907 * frequently. At any rate, we can test that codepath by setting USE_PTR 932 * frequently. At any rate, we can test that codepath by setting USE_PTR
908 * to false. */ 933 * to false. */
909 934
910 #define USE_PTR true 935 #define USE_PTR true
911 936
912 #define SCRATCH_SAVE() \ 937 #define SCRATCH_SAVE() \
913 unsigned int scratch_size_saved = scratch_size; \ 938 unsigned int scratch_size_saved = scratch_size; \
914 hb_buffer_t::scratch_buffer_t *scratch_saved = scratch 939 hb_buffer_t::scratch_buffer_t *scratch_saved = scratch
915 940
916 #define SCRATCH_RESTORE() \ 941 #define SCRATCH_RESTORE() \
917 scratch_size = scratch_size_saved; \ 942 scratch_size = scratch_size_saved; \
918 scratch = scratch_saved; 943 scratch = scratch_saved;
919 944
920 { 945 { /* Setup glyphs */
921 SCRATCH_SAVE(); 946 SCRATCH_SAVE();
922 const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : NULL; 947 const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : NULL;
923 if (!glyphs) { 948 if (!glyphs) {
924 ALLOCATE_ARRAY (CGGlyph, glyph_buf, num_glyphs, goto resize_and_retry) ; 949 ALLOCATE_ARRAY (CGGlyph, glyph_buf, num_glyphs, goto resize_and_retry) ;
925 CTRunGetGlyphs (run, range_all, glyph_buf); 950 CTRunGetGlyphs (run, range_all, glyph_buf);
926 glyphs = glyph_buf; 951 glyphs = glyph_buf;
927 } 952 }
928 const CFIndex* string_indices = USE_PTR ? CTRunGetStringIndicesPtr (run) : NULL; 953 const CFIndex* string_indices = USE_PTR ? CTRunGetStringIndicesPtr (run) : NULL;
929 if (!string_indices) { 954 if (!string_indices) {
930 ALLOCATE_ARRAY (CFIndex, index_buf, num_glyphs, goto resize_and_retry) ; 955 ALLOCATE_ARRAY (CFIndex, index_buf, num_glyphs, goto resize_and_retry) ;
931 CTRunGetStringIndices (run, range_all, index_buf); 956 CTRunGetStringIndices (run, range_all, index_buf);
932 string_indices = index_buf; 957 string_indices = index_buf;
933 } 958 }
934 hb_glyph_info_t *info = run_info; 959 hb_glyph_info_t *info = run_info;
935 for (unsigned int j = 0; j < num_glyphs; j++) 960 for (unsigned int j = 0; j < num_glyphs; j++)
936 { 961 {
937 info->codepoint = glyphs[j]; 962 info->codepoint = glyphs[j];
938 info->cluster = log_clusters[string_indices[j]]; 963 info->cluster = log_clusters[string_indices[j]];
939 info++; 964 info++;
940 } 965 }
941 SCRATCH_RESTORE(); 966 SCRATCH_RESTORE();
942 } 967 }
943 { 968 {
969 /* Setup positions.
970 * Note that CoreText does not return advances for glyphs. As such,
971 * for all but last glyph, we use the delta position to next glyph as
972 * advance (in the advance direction only), and for last glyph we set
973 * whatever is needed to make the whole run's advance add up. */
944 SCRATCH_SAVE(); 974 SCRATCH_SAVE();
945 const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : NULL; 975 const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : NULL;
946 if (!positions) { 976 if (!positions) {
947 ALLOCATE_ARRAY (CGPoint, position_buf, num_glyphs, goto resize_and_ret ry); 977 ALLOCATE_ARRAY (CGPoint, position_buf, num_glyphs, goto resize_and_ret ry);
948 CTRunGetPositions (run, range_all, position_buf); 978 CTRunGetPositions (run, range_all, position_buf);
949 positions = position_buf; 979 positions = position_buf;
950 } 980 }
951 double run_advance = CTRunGetTypographicBounds (run, range_all, NULL, NU LL, NULL);
952 DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance);
953 hb_glyph_info_t *info = run_info; 981 hb_glyph_info_t *info = run_info;
982 CGFloat x_mult = font_data->x_mult, y_mult = font_data->y_mult;
954 if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) 983 if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
955 { 984 {
985 hb_position_t x_offset = (positions[0].x - advances_so_far) * x_mult;
956 for (unsigned int j = 0; j < num_glyphs; j++) 986 for (unsigned int j = 0; j < num_glyphs; j++)
957 { 987 {
958 » double advance = (j + 1 < num_glyphs ? positions[j + 1].x : position s[0].x + run_advance) - positions[j].x; 988 » double advance;
959 » info->mask = advance; 989 » if (likely (j + 1 < num_glyphs))
960 » info->var1.u32 = positions[0].x; /* Yes, zero. */ 990 » advance = positions[j + 1].x - positions[j].x;
961 » info->var2.u32 = positions[j].y; 991 » else /* last glyph */
992 » advance = run_advance - (positions[j].x - positions[0].x);
993 » info->mask = advance * x_mult;
994 » info->var1.u32 = x_offset;
995 » info->var2.u32 = positions[j].y * y_mult;
962 info++; 996 info++;
963 } 997 }
964 } 998 }
965 else 999 else
966 { 1000 {
967 » run_advance = -run_advance; 1001 » hb_position_t y_offset = (positions[0].y - advances_so_far) * y_mult;
968 for (unsigned int j = 0; j < num_glyphs; j++) 1002 for (unsigned int j = 0; j < num_glyphs; j++)
969 { 1003 {
970 » double advance = (j + 1 < num_glyphs ? positions[j + 1].y : position s[0].y + run_advance) - positions[j].y; 1004 » double advance;
971 » info->mask = advance; 1005 » if (likely (j + 1 < num_glyphs))
972 » info->var1.u32 = positions[j].x; 1006 » advance = positions[j + 1].y - positions[j].y;
973 » info->var2.u32 = positions[0].y; /* Yes, zero. */ 1007 » else /* last glyph */
1008 » advance = run_advance - (positions[j].y - positions[0].y);
1009 » info->mask = advance * y_mult;
1010 » info->var1.u32 = positions[j].x * x_mult;
1011 » info->var2.u32 = y_offset;
974 info++; 1012 info++;
975 } 1013 }
976 } 1014 }
977 SCRATCH_RESTORE(); 1015 SCRATCH_RESTORE();
1016 advances_so_far += run_advance;
978 } 1017 }
979 #undef SCRATCH_RESTORE 1018 #undef SCRATCH_RESTORE
980 #undef SCRATCH_SAVE 1019 #undef SCRATCH_SAVE
981 #undef USE_PTR 1020 #undef USE_PTR
982 #undef ALLOCATE_ARRAY 1021 #undef ALLOCATE_ARRAY
983 1022
984 buffer->len += num_glyphs; 1023 buffer->len += num_glyphs;
985 } 1024 }
986 1025
987 /* Make sure all runs had the expected direction. */ 1026 /* Make sure all runs had the expected direction. */
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 1185
1147 hb_bool_t 1186 hb_bool_t
1148 _hb_coretext_aat_shape (hb_shape_plan_t *shape_plan, 1187 _hb_coretext_aat_shape (hb_shape_plan_t *shape_plan,
1149 hb_font_t *font, 1188 hb_font_t *font,
1150 hb_buffer_t *buffer, 1189 hb_buffer_t *buffer,
1151 const hb_feature_t *features, 1190 const hb_feature_t *features,
1152 unsigned int num_features) 1191 unsigned int num_features)
1153 { 1192 {
1154 return _hb_coretext_shape (shape_plan, font, buffer, features, num_features); 1193 return _hb_coretext_shape (shape_plan, font, buffer, features, num_features);
1155 } 1194 }
OLDNEW
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-common.cc ('k') | third_party/harfbuzz-ng/src/hb-ft.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698