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

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

Issue 1723043002: Roll HarfBuzz to 1.2.1 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Include upstream ebd7431f824 Created 4 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-directwrite.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
11 * all copies of this software. 11 * all copies of this software.
12 * 12 *
13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17 * DAMAGE. 17 * DAMAGE.
18 * 18 *
19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
22 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24 * 24 *
25 * Mozilla Author(s): Jonathan Kew 25 * Mozilla Author(s): Jonathan Kew
26 * Google Author(s): Behdad Esfahbod 26 * Google Author(s): Behdad Esfahbod
27 */ 27 */
28 28
29 #define HB_SHAPER coretext 29 #define HB_SHAPER coretext
30 #define hb_coretext_shaper_face_data_t CGFont
31 #include "hb-shaper-impl-private.hh" 30 #include "hb-shaper-impl-private.hh"
32 31
33 #include "hb-coretext.h" 32 #include "hb-coretext.h"
34 33
35 34
36 #ifndef HB_DEBUG_CORETEXT 35 #ifndef HB_DEBUG_CORETEXT
37 #define HB_DEBUG_CORETEXT (HB_DEBUG+0) 36 #define HB_DEBUG_CORETEXT (HB_DEBUG+0)
38 #endif 37 #endif
39 38
40 39
(...skipping 30 matching lines...) Expand all
71 70
72 71
73 HB_SHAPER_DATA_ENSURE_DECLARE(coretext, face) 72 HB_SHAPER_DATA_ENSURE_DECLARE(coretext, face)
74 HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font) 73 HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font)
75 74
76 75
77 /* 76 /*
78 * shaper face data 77 * shaper face data
79 */ 78 */
80 79
80 static CTFontDescriptorRef
81 get_last_resort_font_desc (void)
82 {
83 // TODO Handle allocation failures?
84 CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize (CFSTR ("LastResort"), 0);
85 CFArrayRef cascade_list = CFArrayCreate (kCFAllocatorDefault,
86 (const void **) &last_resort,
87 1,
88 &kCFTypeArrayCallBacks);
89 CFRelease (last_resort);
90 CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault,
91 (const void **) &kCTFontCasca deListAttribute,
92 (const void **) &cascade_list ,
93 1,
94 &kCFTypeDictionaryKeyCallBack s,
95 &kCFTypeDictionaryValueCallBa cks);
96 CFRelease (cascade_list);
97
98 CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attribut es);
99 CFRelease (attributes);
100 return font_desc;
101 }
102
81 static void 103 static void
82 release_data (void *info, const void *data, size_t size) 104 release_data (void *info, const void *data, size_t size)
83 { 105 {
84 assert (hb_blob_get_length ((hb_blob_t *) info) == size && 106 assert (hb_blob_get_length ((hb_blob_t *) info) == size &&
85 hb_blob_get_data ((hb_blob_t *) info, NULL) == data); 107 hb_blob_get_data ((hb_blob_t *) info, NULL) == data);
86 108
87 hb_blob_destroy ((hb_blob_t *) info); 109 hb_blob_destroy ((hb_blob_t *) info);
88 } 110 }
89 111
90 hb_coretext_shaper_face_data_t * 112 static CGFontRef
91 _hb_coretext_shaper_face_data_create (hb_face_t *face) 113 create_cg_font (hb_face_t *face)
92 { 114 {
93 hb_coretext_shaper_face_data_t *data = NULL; 115 CGFontRef cg_font = NULL;
94
95 if (face->destroy == (hb_destroy_func_t) CGFontRelease) 116 if (face->destroy == (hb_destroy_func_t) CGFontRelease)
96 { 117 {
97 data = CGFontRetain ((CGFontRef) face->user_data); 118 cg_font = CGFontRetain ((CGFontRef) face->user_data);
98 } 119 }
99 else 120 else
100 { 121 {
101 hb_blob_t *blob = hb_face_reference_blob (face); 122 hb_blob_t *blob = hb_face_reference_blob (face);
102 unsigned int blob_length; 123 unsigned int blob_length;
103 const char *blob_data = hb_blob_get_data (blob, &blob_length); 124 const char *blob_data = hb_blob_get_data (blob, &blob_length);
104 if (unlikely (!blob_length)) 125 if (unlikely (!blob_length))
105 DEBUG_MSG (CORETEXT, face, "Face has empty blob"); 126 DEBUG_MSG (CORETEXT, face, "Face has empty blob");
106 127
107 CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data); 128 CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data);
108 if (likely (provider)) 129 if (likely (provider))
109 { 130 {
110 data = CGFontCreateWithDataProvider (provider); 131 cg_font = CGFontCreateWithDataProvider (provider);
132 if (unlikely (!cg_font))
133 » DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed") ;
111 CGDataProviderRelease (provider); 134 CGDataProviderRelease (provider);
112 } 135 }
113 } 136 }
137 return cg_font;
138 }
114 139
115 if (unlikely (!data)) { 140 static CTFontRef
116 DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed"); 141 create_ct_font (CGFontRef cg_font, CGFloat font_size)
142 {
143 CTFontRef ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, NULL, NU LL);
144 if (unlikely (!ct_font)) {
145 DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed");
146 return NULL;
147 }
148
149 /* Create font copy with cascade list that has LastResort first; this speeds u p CoreText
150 * font fallback which we don't need anyway. */
151 {
152 CTFontDescriptorRef last_resort_font_desc = get_last_resort_font_desc ();
153 CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0.0, NULL, last_resort_font_desc);
154 CFRelease (last_resort_font_desc);
155 if (new_ct_font)
156 {
157 CFRelease (ct_font);
158 ct_font = new_ct_font;
159 }
160 else
161 DEBUG_MSG (CORETEXT, ct_font, "Font copy with empty cascade list failed");
162 }
163
164 return ct_font;
165 }
166
167 struct hb_coretext_shaper_face_data_t {
168 CGFontRef cg_font;
169 CTFontRef ct_font;
170 };
171
172 hb_coretext_shaper_face_data_t *
173 _hb_coretext_shaper_face_data_create (hb_face_t *face)
174 {
175 hb_coretext_shaper_face_data_t *data = (hb_coretext_shaper_face_data_t *) call oc (1, sizeof (hb_coretext_shaper_face_data_t));
176 if (unlikely (!data))
177 return NULL;
178
179 data->cg_font = create_cg_font (face);
180 if (unlikely (!data->cg_font))
181 {
182 DEBUG_MSG (CORETEXT, face, "CGFont creation failed..");
183 free (data);
184 return NULL;
185 }
186
187 /* We use 36pt size instead of UPEM, because CoreText implements the 'trak' ta ble,
188 * which can make the font too tight at large sizes. 36pt should be a good se mi-neutral
189 * size.
190 *
191 * Since we always create CTFont at a fixed size, our CTFont lives in face_dat a
192 * instead of font_data. Which is good, because when people change scale on
193 * hb_font_t, we won't need to update our CTFont. */
194 data->ct_font = create_ct_font (data->cg_font, 36.);
195 if (unlikely (!data->ct_font))
196 {
197 DEBUG_MSG (CORETEXT, face, "CTFont creation failed.");
198 CFRelease (data->cg_font);
199 free (data);
200 return NULL;
117 } 201 }
118 202
119 return data; 203 return data;
120 } 204 }
121 205
122 void 206 void
123 _hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data) 207 _hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data)
124 { 208 {
125 CFRelease (data); 209 CFRelease (data->ct_font);
210 CFRelease (data->cg_font);
211 free (data);
126 } 212 }
127 213
128 /* 214 /*
129 * Since: 0.9.10 215 * Since: 0.9.10
130 */ 216 */
131 CGFontRef 217 CGFontRef
132 hb_coretext_face_get_cg_font (hb_face_t *face) 218 hb_coretext_face_get_cg_font (hb_face_t *face)
133 { 219 {
134 if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL; 220 if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
135 hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); 221 hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
136 return face_data; 222 return face_data->cg_font;
137 } 223 }
138 224
139 225
140 /* 226 /*
141 * shaper font data 227 * shaper font data
142 */ 228 */
143 229
144 struct hb_coretext_shaper_font_data_t { 230 struct hb_coretext_shaper_font_data_t {};
145 CTFontRef ct_font;
146 CGFloat x_mult, y_mult; /* From CT space to HB space. */
147 };
148 231
149 hb_coretext_shaper_font_data_t * 232 hb_coretext_shaper_font_data_t *
150 _hb_coretext_shaper_font_data_create (hb_font_t *font) 233 _hb_coretext_shaper_font_data_create (hb_font_t *font HB_UNUSED)
151 { 234 {
152 if (unlikely (!hb_coretext_shaper_face_data_ensure (font->face))) return NULL; 235 return (hb_coretext_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
153
154 hb_coretext_shaper_font_data_t *data = (hb_coretext_shaper_font_data_t *) call oc (1, sizeof (hb_coretext_shaper_font_data_t));
155 if (unlikely (!data))
156 return NULL;
157
158 hb_face_t *face = font->face;
159 hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
160
161 /* Choose a CoreText font size and calculate multipliers to convert to HarfBuz z space. */
162 /* TODO: use upem instead of 36? */
163 CGFloat font_size = 36.; /* Default... */
164 /* No idea if the following is even a good idea. */
165 if (font->y_ppem)
166 font_size = font->y_ppem;
167
168 if (font_size < 0)
169 font_size = -font_size;
170 data->x_mult = (CGFloat) font->x_scale / font_size;
171 data->y_mult = (CGFloat) font->y_scale / font_size;
172 data->ct_font = CTFontCreateWithGraphicsFont (face_data, font_size, NULL, NULL );
173 if (unlikely (!data->ct_font)) {
174 DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed");
175 free (data);
176 return NULL;
177 }
178
179 /* Create font copy with cascade list that has LastResort first; this speeds u p CoreText
180 * font fallback which we don't need anyway. */
181 {
182 // TODO Handle allocation failures?
183 CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize(CFST R("LastResort"), 0);
184 CFArrayRef cascade_list = CFArrayCreate (kCFAllocatorDefault,
185 » » » » » (const void **) &last_resort,
186 » » » » » 1,
187 » » » » » &kCFTypeArrayCallBacks);
188 CFRelease (last_resort);
189 CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault,
190 » » » » » » (const void **) &kCTFontCas cadeListAttribute,
191 » » » » » » (const void **) &cascade_li st,
192 » » » » » » 1,
193 » » » » » » &kCFTypeDictionaryKeyCallBa cks,
194 » » » » » » &kCFTypeDictionaryValueCall Backs);
195 CFRelease (cascade_list);
196
197 CTFontDescriptorRef new_font_desc = CTFontDescriptorCreateWithAttributes (at tributes);
198 CFRelease (attributes);
199
200 CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (data->ct_font, 0.0, NULL, new_font_desc);
201 if (new_ct_font)
202 {
203 CFRelease (data->ct_font);
204 data->ct_font = new_ct_font;
205 }
206 else
207 DEBUG_MSG (CORETEXT, font, "Font copy with empty cascade list failed");
208 }
209
210 if (unlikely (!data->ct_font)) {
211 DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed");
212 free (data);
213 return NULL;
214 }
215
216 return data;
217 } 236 }
218 237
219 void 238 void
220 _hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data) 239 _hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data)
221 { 240 {
222 CFRelease (data->ct_font);
223 free (data);
224 } 241 }
225 242
226 243
227 /* 244 /*
228 * shaper shape_plan data 245 * shaper shape_plan data
229 */ 246 */
230 247
231 struct hb_coretext_shaper_shape_plan_data_t {}; 248 struct hb_coretext_shaper_shape_plan_data_t {};
232 249
233 hb_coretext_shaper_shape_plan_data_t * 250 hb_coretext_shaper_shape_plan_data_t *
234 _hb_coretext_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UN USED, 251 _hb_coretext_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UN USED,
235 const hb_feature_t *user_features H B_UNUSED, 252 const hb_feature_t *user_features H B_UNUSED,
236 unsigned int num_user_featur es HB_UNUSED) 253 unsigned int num_user_featur es HB_UNUSED)
237 { 254 {
238 return (hb_coretext_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; 255 return (hb_coretext_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
239 } 256 }
240 257
241 void 258 void
242 _hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_ t *data HB_UNUSED) 259 _hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_ t *data HB_UNUSED)
243 { 260 {
244 } 261 }
245 262
246 CTFontRef 263 CTFontRef
247 hb_coretext_font_get_ct_font (hb_font_t *font) 264 hb_coretext_font_get_ct_font (hb_font_t *font)
248 { 265 {
249 if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return NULL; 266 hb_face_t *face = font->face;
250 hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); 267 if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
251 return font_data->ct_font; 268 hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
269 return face_data->ct_font;
252 } 270 }
253 271
254 272
255 /* 273 /*
256 * shaper 274 * shaper
257 */ 275 */
258 276
259 struct feature_record_t { 277 struct feature_record_t {
260 unsigned int feature; 278 unsigned int feature;
261 unsigned int setting; 279 unsigned int setting;
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 492
475 hb_bool_t 493 hb_bool_t
476 _hb_coretext_shape (hb_shape_plan_t *shape_plan, 494 _hb_coretext_shape (hb_shape_plan_t *shape_plan,
477 hb_font_t *font, 495 hb_font_t *font,
478 hb_buffer_t *buffer, 496 hb_buffer_t *buffer,
479 const hb_feature_t *features, 497 const hb_feature_t *features,
480 unsigned int num_features) 498 unsigned int num_features)
481 { 499 {
482 hb_face_t *face = font->face; 500 hb_face_t *face = font->face;
483 hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); 501 hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
484 hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); 502
503 CGFloat ct_font_size = CTFontGetSize (face_data->ct_font);
504 CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
505 CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size;
485 506
486 /* Attach marks to their bases, to match the 'ot' shaper. 507 /* Attach marks to their bases, to match the 'ot' shaper.
487 * Adapted from hb-ot-shape:hb_form_clusters(). 508 * Adapted from hb-ot-shape:hb_form_clusters().
488 * Note that this only makes us be closer to the 'ot' shaper, 509 * Note that this only makes us be closer to the 'ot' shaper,
489 * but by no means the same. For example, if there's 510 * but by no means the same. For example, if there's
490 * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will 511 * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will
491 * continue pointing to B2 even though B2 was merged into B1's 512 * continue pointing to B2 even though B2 was merged into B1's
492 * cluster... */ 513 * cluster... */
514 if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES)
493 { 515 {
494 hb_unicode_funcs_t *unicode = buffer->unicode; 516 hb_unicode_funcs_t *unicode = buffer->unicode;
495 unsigned int count = buffer->len; 517 unsigned int count = buffer->len;
496 hb_glyph_info_t *info = buffer->info; 518 hb_glyph_info_t *info = buffer->info;
497 for (unsigned int i = 1; i < count; i++) 519 for (unsigned int i = 1; i < count; i++)
498 if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (unicode->general_category (info[i ].codepoint))) 520 if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (unicode->general_category (info[i ].codepoint)))
499 buffer->merge_clusters (i - 1, i + 1); 521 buffer->merge_clusters (i - 1, i + 1);
500 } 522 }
501 523
502 hb_auto_array_t<feature_record_t> feature_records; 524 hb_auto_array_t<feature_record_t> feature_records;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 (const void **) &kCTF ontFeatureSettingsAttribute, 627 (const void **) &kCTF ontFeatureSettingsAttribute,
606 (const void **) &feat ures_array, 628 (const void **) &feat ures_array,
607 1, 629 1,
608 &kCFTypeDictionaryKey CallBacks, 630 &kCFTypeDictionaryKey CallBacks,
609 &kCFTypeDictionaryVal ueCallBacks); 631 &kCFTypeDictionaryVal ueCallBacks);
610 CFRelease (features_array); 632 CFRelease (features_array);
611 633
612 CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes ( attributes); 634 CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes ( attributes);
613 CFRelease (attributes); 635 CFRelease (attributes);
614 636
615 » range->font = CTFontCreateCopyWithAttributes (font_data->ct_font, 0.0, NULL, font_desc); 637 » range->font = CTFontCreateCopyWithAttributes (face_data->ct_font, 0.0, NULL, font_desc);
616 CFRelease (font_desc); 638 CFRelease (font_desc);
617 } 639 }
618 else 640 else
619 { 641 {
620 range->font = NULL; 642 range->font = NULL;
621 } 643 }
622 644
623 range->index_first = last_index; 645 range->index_first = last_index;
624 range->index_last = event->index - 1; 646 range->index_last = event->index - 1;
625 647
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 hb_language_to_strin g (buffer->props.language), 784 hb_language_to_strin g (buffer->props.language),
763 kCFStringEncodingUTF 8, 785 kCFStringEncodingUTF 8,
764 kCFAllocatorNull); 786 kCFAllocatorNull);
765 if (unlikely (!lang)) 787 if (unlikely (!lang))
766 FAIL ("CFStringCreateWithCStringNoCopy failed"); 788 FAIL ("CFStringCreateWithCStringNoCopy failed");
767 CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), 789 CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
768 kCTLanguageAttributeName, lang); 790 kCTLanguageAttributeName, lang);
769 CFRelease (lang); 791 CFRelease (lang);
770 } 792 }
771 CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), 793 CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
772 » » » » kCTFontAttributeName, font_data->ct_font); 794 » » » » kCTFontAttributeName, face_data->ct_font);
773 795
774 if (num_features) 796 if (num_features)
775 { 797 {
776 unsigned int start = 0; 798 unsigned int start = 0;
777 range_record_t *last_range = &range_records[0]; 799 range_record_t *last_range = &range_records[0];
778 for (unsigned int k = 0; k < chars_len; k++) 800 for (unsigned int k = 0; k < chars_len; k++)
779 { 801 {
780 range_record_t *range = last_range; 802 range_record_t *range = last_range;
781 while (log_clusters[k] < range->index_first) 803 while (log_clusters[k] < range->index_first)
782 range--; 804 range--;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance); 877 DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance);
856 878
857 /* CoreText does automatic font fallback (AKA "cascading") for characters 879 /* CoreText does automatic font fallback (AKA "cascading") for characters
858 * not supported by the requested font, and provides no way to turn it off , 880 * not supported by the requested font, and provides no way to turn it off ,
859 * so we must detect if the returned run uses a font other than the reques ted 881 * so we must detect if the returned run uses a font other than the reques ted
860 * one and fill in the buffer with .notdef glyphs instead of random glyph 882 * one and fill in the buffer with .notdef glyphs instead of random glyph
861 * indices from a different font. 883 * indices from a different font.
862 */ 884 */
863 CFDictionaryRef attributes = CTRunGetAttributes (run); 885 CFDictionaryRef attributes = CTRunGetAttributes (run);
864 CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attri butes, kCTFontAttributeName)); 886 CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attri butes, kCTFontAttributeName));
865 if (!CFEqual (run_ct_font, font_data->ct_font)) 887 if (!CFEqual (run_ct_font, face_data->ct_font))
866 { 888 {
867 /* The run doesn't use our main font instance. We have to figure out 889 /* The run doesn't use our main font instance. We have to figure out
868 * whether font fallback happened, or this is just CoreText giving us 890 * whether font fallback happened, or this is just CoreText giving us
869 * another CTFont using the same underlying CGFont. CoreText seems 891 * another CTFont using the same underlying CGFont. CoreText seems
870 * to do that in a variety of situations, one of which being vertical 892 * to do that in a variety of situations, one of which being vertical
871 * text, but also perhaps for caching reasons. 893 * text, but also perhaps for caching reasons.
872 * 894 *
873 * First, see if it uses any of our subfonts created to set font feature s... 895 * First, see if it uses any of our subfonts created to set font feature s...
874 * 896 *
875 * Next, compare the CGFont to the one we used to create our fonts. 897 * Next, compare the CGFont to the one we used to create our fonts.
(...skipping 19 matching lines...) Expand all
895 if (range_records[i].font && CFEqual (run_ct_font, range_records[i].fo nt)) 917 if (range_records[i].font && CFEqual (run_ct_font, range_records[i].fo nt))
896 { 918 {
897 matched = true; 919 matched = true;
898 break; 920 break;
899 } 921 }
900 if (!matched) 922 if (!matched)
901 { 923 {
902 CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0); 924 CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
903 if (run_cg_font) 925 if (run_cg_font)
904 { 926 {
905 » matched = CFEqual (run_cg_font, face_data); 927 » matched = CFEqual (run_cg_font, face_data->cg_font);
906 CFRelease (run_cg_font); 928 CFRelease (run_cg_font);
907 } 929 }
908 } 930 }
909 if (!matched) 931 if (!matched)
910 { 932 {
911 » CFStringRef font_ps_name = CTFontCopyName (font_data->ct_font, kCTFont PostScriptNameKey); 933 » CFStringRef font_ps_name = CTFontCopyName (face_data->ct_font, kCTFont PostScriptNameKey);
912 CFStringRef run_ps_name = CTFontCopyName (run_ct_font, kCTFontPostScri ptNameKey); 934 CFStringRef run_ps_name = CTFontCopyName (run_ct_font, kCTFontPostScri ptNameKey);
913 CFComparisonResult result = CFStringCompare (run_ps_name, font_ps_name , 0); 935 CFComparisonResult result = CFStringCompare (run_ps_name, font_ps_name , 0);
914 CFRelease (run_ps_name); 936 CFRelease (run_ps_name);
915 CFRelease (font_ps_name); 937 CFRelease (font_ps_name);
916 if (result == kCFCompareEqualTo) 938 if (result == kCFCompareEqualTo)
917 matched = true; 939 matched = true;
918 } 940 }
919 if (!matched) 941 if (!matched)
920 { 942 {
921 CFRange range = CTRunGetStringRange (run); 943 CFRange range = CTRunGetStringRange (run);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 * advance (in the advance direction only), and for last glyph we set 1043 * advance (in the advance direction only), and for last glyph we set
1022 * whatever is needed to make the whole run's advance add up. */ 1044 * whatever is needed to make the whole run's advance add up. */
1023 SCRATCH_SAVE(); 1045 SCRATCH_SAVE();
1024 const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : NULL; 1046 const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : NULL;
1025 if (!positions) { 1047 if (!positions) {
1026 ALLOCATE_ARRAY (CGPoint, position_buf, num_glyphs, goto resize_and_ret ry); 1048 ALLOCATE_ARRAY (CGPoint, position_buf, num_glyphs, goto resize_and_ret ry);
1027 CTRunGetPositions (run, range_all, position_buf); 1049 CTRunGetPositions (run, range_all, position_buf);
1028 positions = position_buf; 1050 positions = position_buf;
1029 } 1051 }
1030 hb_glyph_info_t *info = run_info; 1052 hb_glyph_info_t *info = run_info;
1031 CGFloat x_mult = font_data->x_mult, y_mult = font_data->y_mult;
1032 if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) 1053 if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
1033 { 1054 {
1034 hb_position_t x_offset = (positions[0].x - advances_so_far) * x_mult; 1055 hb_position_t x_offset = (positions[0].x - advances_so_far) * x_mult;
1035 for (unsigned int j = 0; j < num_glyphs; j++) 1056 for (unsigned int j = 0; j < num_glyphs; j++)
1036 { 1057 {
1037 double advance; 1058 double advance;
1038 if (likely (j + 1 < num_glyphs)) 1059 if (likely (j + 1 < num_glyphs))
1039 advance = positions[j + 1].x - positions[j].x; 1060 advance = positions[j + 1].x - positions[j].x;
1040 else /* last glyph */ 1061 else /* last glyph */
1041 advance = run_advance - (positions[j].x - positions[0].x); 1062 advance = run_advance - (positions[j].x - positions[0].x);
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1240 1261
1241 hb_bool_t 1262 hb_bool_t
1242 _hb_coretext_aat_shape (hb_shape_plan_t *shape_plan, 1263 _hb_coretext_aat_shape (hb_shape_plan_t *shape_plan,
1243 hb_font_t *font, 1264 hb_font_t *font,
1244 hb_buffer_t *buffer, 1265 hb_buffer_t *buffer,
1245 const hb_feature_t *features, 1266 const hb_feature_t *features,
1246 unsigned int num_features) 1267 unsigned int num_features)
1247 { 1268 {
1248 return _hb_coretext_shape (shape_plan, font, buffer, features, num_features); 1269 return _hb_coretext_shape (shape_plan, font, buffer, features, num_features);
1249 } 1270 }
OLDNEW
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-common.cc ('k') | third_party/harfbuzz-ng/src/hb-directwrite.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698