[coretext] Avoid font fallback with CoreText shaper
CoreText does automatic font fallback (AKA "cascading") for characters not supported by the requested font, and provides no way to turn it off, so detect if the returned run uses a font other than the requested one and fill in the buffer with .notdef glyphs instead of random indices glyph from a different font.
This commit is contained in:
parent
63bae73aef
commit
c8213c6198
|
@ -651,6 +651,41 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
|
|||
for (unsigned int i = 0; i < num_runs; i++) {
|
||||
CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex (glyph_runs, i);
|
||||
|
||||
/* CoreText does automatic font fallback (AKA "cascading") for characters
|
||||
* not supported by the requested font, and provides no way to turn it off,
|
||||
* so we detect if the returned run uses a font other than the requested
|
||||
* one and fill in the buffer with .notdef glyphs instead of random glyph
|
||||
* indices from a different font.
|
||||
*/
|
||||
CFRange range = CTRunGetStringRange (run);
|
||||
CFDictionaryRef attributes = CTRunGetAttributes (run);
|
||||
CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
|
||||
CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
|
||||
CGFontRef cg_font = CTFontCopyGraphicsFont (font_data->ct_font, 0);
|
||||
if (!CFEqual (run_cg_font, cg_font)) {
|
||||
CFRelease (run_cg_font);
|
||||
CFRelease (cg_font);
|
||||
for (CFIndex j = 0; j < range.length; j++) {
|
||||
CGGlyph notdef = 0;
|
||||
double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFontHorizontalOrientation, ¬def, NULL, 1);
|
||||
|
||||
hb_glyph_info_t *info = &buffer->info[buffer->len];
|
||||
|
||||
info->codepoint = notdef;
|
||||
info->cluster = range.location + j;
|
||||
|
||||
info->mask = advance;
|
||||
info->var1.u32 = 0;
|
||||
info->var2.u32 = 0;
|
||||
|
||||
buffer->len++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
CFRelease (run_cg_font);
|
||||
CFRelease (cg_font);
|
||||
|
||||
unsigned int num_glyphs = CTRunGetGlyphCount (run);
|
||||
if (num_glyphs == 0)
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue