128 CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data);
129 if (likely (provider))
130 {
131 cg_font = CGFontCreateWithDataProvider (provider);
132 if (unlikely (!cg_font))
133 DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed");
134 CGDataProviderRelease (provider);
135 }
136 }
137 return cg_font;
138 }
139
140 static CTFontRef
141 create_ct_font (CGFontRef cg_font, CGFloat font_size)
142 {
143 CTFontRef ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, NULL, NULL);
144 if (unlikely (!ct_font)) {
145 DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed");
146 return NULL;
147 }
148 CFURLRef original_url = (CFURLRef)CTFontCopyAttribute(ct_font, kCTFontURLAttribute);
149
150 /* Create font copy with cascade list that has LastResort first; this speeds up CoreText
151 * font fallback which we don't need anyway. */
152 {
153 CTFontDescriptorRef last_resort_font_desc = get_last_resort_font_desc ();
154 CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0.0, NULL, last_resort_font_desc);
155 CFRelease (last_resort_font_desc);
156 if (new_ct_font)
157 {
158 /* The CTFontCreateCopyWithAttributes call fails to stay on the same font
159 * when reconfiguring the cascade list and may switch to a different font
160 * when there are fonts that go by the same name, since the descriptor is
161 * just name and size.
162 *
163 * Avoid reconfiguring the cascade lists if the new font is outside the
164 * system locations that we cannot access from the sandboxed renderer
165 * process in Blink. This can be detected by the new file URL location
166 * that the newly found font points to. */
167 CFURLRef new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute);
255 _hb_coretext_shaper_font_data_create (hb_font_t *font HB_UNUSED)
256 {
257 return (hb_coretext_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
258 }
259
260 void
261 _hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data)
262 {
263 }
264
265
266 /*
267 * shaper shape_plan data
268 */
269
270 struct hb_coretext_shaper_shape_plan_data_t {};
271
272 hb_coretext_shaper_shape_plan_data_t *
273 _hb_coretext_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
274 const hb_feature_t *user_features HB_UNUSED,
275 unsigned int num_user_features HB_UNUSED)
276 {
277 return (hb_coretext_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
278 }
279
280 void
281 _hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_t *data HB_UNUSED)
282 {
283 }
284
285 CTFontRef
286 hb_coretext_font_get_ct_font (hb_font_t *font)
287 {
288 hb_face_t *face = font->face;
289 if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
290 hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
291 return face_data->ct_font;
292 }
293
294
295 /*
700 unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
701 if (unlikely (_consumed > scratch_size)) \
702 { \
703 on_no_room; \
704 assert (0); \
705 } \
706 scratch += _consumed; \
707 scratch_size -= _consumed; \
708 }
709
710 ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, /*nothing*/);
711 unsigned int chars_len = 0;
712 for (unsigned int i = 0; i < buffer->len; i++) {
713 hb_codepoint_t c = buffer->info[i].codepoint;
714 if (likely (c <= 0xFFFFu))
715 pchars[chars_len++] = c;
716 else if (unlikely (c > 0x10FFFFu))
717 pchars[chars_len++] = 0xFFFDu;
718 else {
719 pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10);
720 pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1 << 10) - 1));
721 }
722 }
723
724 ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len, /*nothing*/);
725 chars_len = 0;
726 for (unsigned int i = 0; i < buffer->len; i++)
727 {
728 hb_codepoint_t c = buffer->info[i].codepoint;
729 unsigned int cluster = buffer->info[i].cluster;
730 log_clusters[chars_len++] = cluster;
731 if (hb_in_range (c, 0x10000u, 0x10FFFFu))
732 log_clusters[chars_len++] = cluster; /* Surrogates. */
733 }
734
735 #define FAIL(...) \
736 HB_STMT_START { \
737 DEBUG_MSG (CORETEXT, NULL, __VA_ARGS__); \
738 ret = false; \
739 goto fail; \
740 } HB_STMT_END;
1247 _hb_coretext_aat_shaper_font_data_create (hb_font_t *font)
1248 {
1249 return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL;
1250 }
1251
1252 void
1253 _hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_shaper_font_data_t *data HB_UNUSED)
1254 {
1255 }
1256
1257
1258 /*
1259 * shaper shape_plan data
1260 */
1261
1262 struct hb_coretext_aat_shaper_shape_plan_data_t {};
1263
1264 hb_coretext_aat_shaper_shape_plan_data_t *
1265 _hb_coretext_aat_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
1266 const hb_feature_t *user_features HB_UNUSED,
1267 unsigned int num_user_features HB_UNUSED)
1268 {
1269 return (hb_coretext_aat_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
1270 }
1271
1272 void
1273 _hb_coretext_aat_shaper_shape_plan_data_destroy (hb_coretext_aat_shaper_shape_plan_data_t *data HB_UNUSED)
1274 {
1275 }
1276
1277
1278 /*
1279 * shaper
1280 */
1281
1282 hb_bool_t
1283 _hb_coretext_aat_shape (hb_shape_plan_t *shape_plan,
1284 hb_font_t *font,
1285 hb_buffer_t *buffer,
1286 const hb_feature_t *features,
1287 unsigned int num_features)
|
128 CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data);
129 if (likely (provider))
130 {
131 cg_font = CGFontCreateWithDataProvider (provider);
132 if (unlikely (!cg_font))
133 DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed");
134 CGDataProviderRelease (provider);
135 }
136 }
137 return cg_font;
138 }
139
140 static CTFontRef
141 create_ct_font (CGFontRef cg_font, CGFloat font_size)
142 {
143 CTFontRef ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, NULL, NULL);
144 if (unlikely (!ct_font)) {
145 DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed");
146 return NULL;
147 }
148
149 /* crbug.com/576941 and crbug.com/625902 and the investigation in the latter
150 * bug indicate that the cascade list reconfiguration occasionally causes
151 * crashes in CoreText on OS X 10.9, thus let's skip this step on older
152 * operating system versions. Except for the emoji font, where _not_
153 * reconfiguring the cascade list causes CoreText crashes. For details, see
154 * crbug.com/549610 */
155 // 0x00070000 stands for "kCTVersionNumber10_10", see CoreText.h
156 if (&CTGetCoreTextVersion != NULL && CTGetCoreTextVersion() < 0x00070000) {
157 CFStringRef fontName = CTFontCopyPostScriptName (ct_font);
158 bool isEmojiFont = CFStringCompare (fontName, CFSTR("AppleColorEmoji"), 0) == kCFCompareEqualTo;
159 CFRelease (fontName);
160 if (!isEmojiFont)
161 return ct_font;
162 }
163
164 CFURLRef original_url = (CFURLRef)CTFontCopyAttribute(ct_font, kCTFontURLAttribute);
165
166 /* Create font copy with cascade list that has LastResort first; this speeds up CoreText
167 * font fallback which we don't need anyway. */
168 {
169 CTFontDescriptorRef last_resort_font_desc = get_last_resort_font_desc ();
170 CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0.0, NULL, last_resort_font_desc);
171 CFRelease (last_resort_font_desc);
172 if (new_ct_font)
173 {
174 /* The CTFontCreateCopyWithAttributes call fails to stay on the same font
175 * when reconfiguring the cascade list and may switch to a different font
176 * when there are fonts that go by the same name, since the descriptor is
177 * just name and size.
178 *
179 * Avoid reconfiguring the cascade lists if the new font is outside the
180 * system locations that we cannot access from the sandboxed renderer
181 * process in Blink. This can be detected by the new file URL location
182 * that the newly found font points to. */
183 CFURLRef new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute);
271 _hb_coretext_shaper_font_data_create (hb_font_t *font HB_UNUSED)
272 {
273 return (hb_coretext_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
274 }
275
276 void
277 _hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data)
278 {
279 }
280
281
282 /*
283 * shaper shape_plan data
284 */
285
286 struct hb_coretext_shaper_shape_plan_data_t {};
287
288 hb_coretext_shaper_shape_plan_data_t *
289 _hb_coretext_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
290 const hb_feature_t *user_features HB_UNUSED,
291 unsigned int num_user_features HB_UNUSED,
292 const int *coords HB_UNUSED,
293 unsigned int num_coords HB_UNUSED)
294 {
295 return (hb_coretext_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
296 }
297
298 void
299 _hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_t *data HB_UNUSED)
300 {
301 }
302
303 CTFontRef
304 hb_coretext_font_get_ct_font (hb_font_t *font)
305 {
306 hb_face_t *face = font->face;
307 if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
308 hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
309 return face_data->ct_font;
310 }
311
312
313 /*
718 unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
719 if (unlikely (_consumed > scratch_size)) \
720 { \
721 on_no_room; \
722 assert (0); \
723 } \
724 scratch += _consumed; \
725 scratch_size -= _consumed; \
726 }
727
728 ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, /*nothing*/);
729 unsigned int chars_len = 0;
730 for (unsigned int i = 0; i < buffer->len; i++) {
731 hb_codepoint_t c = buffer->info[i].codepoint;
732 if (likely (c <= 0xFFFFu))
733 pchars[chars_len++] = c;
734 else if (unlikely (c > 0x10FFFFu))
735 pchars[chars_len++] = 0xFFFDu;
736 else {
737 pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10);
738 pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1));
739 }
740 }
741
742 ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len, /*nothing*/);
743 chars_len = 0;
744 for (unsigned int i = 0; i < buffer->len; i++)
745 {
746 hb_codepoint_t c = buffer->info[i].codepoint;
747 unsigned int cluster = buffer->info[i].cluster;
748 log_clusters[chars_len++] = cluster;
749 if (hb_in_range (c, 0x10000u, 0x10FFFFu))
750 log_clusters[chars_len++] = cluster; /* Surrogates. */
751 }
752
753 #define FAIL(...) \
754 HB_STMT_START { \
755 DEBUG_MSG (CORETEXT, NULL, __VA_ARGS__); \
756 ret = false; \
757 goto fail; \
758 } HB_STMT_END;
1265 _hb_coretext_aat_shaper_font_data_create (hb_font_t *font)
1266 {
1267 return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : NULL;
1268 }
1269
1270 void
1271 _hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_shaper_font_data_t *data HB_UNUSED)
1272 {
1273 }
1274
1275
1276 /*
1277 * shaper shape_plan data
1278 */
1279
1280 struct hb_coretext_aat_shaper_shape_plan_data_t {};
1281
1282 hb_coretext_aat_shaper_shape_plan_data_t *
1283 _hb_coretext_aat_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
1284 const hb_feature_t *user_features HB_UNUSED,
1285 unsigned int num_user_features HB_UNUSED,
1286 const int *coords HB_UNUSED,
1287 unsigned int num_coords HB_UNUSED)
1288 {
1289 return (hb_coretext_aat_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
1290 }
1291
1292 void
1293 _hb_coretext_aat_shaper_shape_plan_data_destroy (hb_coretext_aat_shaper_shape_plan_data_t *data HB_UNUSED)
1294 {
1295 }
1296
1297
1298 /*
1299 * shaper
1300 */
1301
1302 hb_bool_t
1303 _hb_coretext_aat_shape (hb_shape_plan_t *shape_plan,
1304 hb_font_t *font,
1305 hb_buffer_t *buffer,
1306 const hb_feature_t *features,
1307 unsigned int num_features)
|