[coretext] Compare CGFont and PS name, if CTFont didn't match
See comments. Fixes vertical text. CoreText backend is in very good shape now! Also see:5a0eed3b50
25f4fb9b56
Fixes http://github.com/behdad/harfbuzz/pull/36
This commit is contained in:
parent
5a0eed3b50
commit
fd0001d7db
|
@ -760,7 +760,7 @@ retry:
|
||||||
|
|
||||||
/* CoreText does automatic font fallback (AKA "cascading") for characters
|
/* CoreText does automatic font fallback (AKA "cascading") for characters
|
||||||
* not supported by the requested font, and provides no way to turn it off,
|
* 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
|
* so we must 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
|
* one and fill in the buffer with .notdef glyphs instead of random glyph
|
||||||
* indices from a different font.
|
* indices from a different font.
|
||||||
*/
|
*/
|
||||||
|
@ -768,11 +768,34 @@ retry:
|
||||||
CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
|
CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
|
||||||
if (!CFEqual (run_ct_font, font_data->ct_font))
|
if (!CFEqual (run_ct_font, font_data->ct_font))
|
||||||
{
|
{
|
||||||
/* The run doesn't use our main font. See if it uses any of our subfonts
|
/* The run doesn't use our main font instance. We have to figure out
|
||||||
* created to set font features... Only if the font didn't match any of
|
* whether font fallback happened, or this is just CoreText giving us
|
||||||
* those, consider reject the font. What we really want is to check the
|
* another CTFont using the same underlying CGFont. CoreText seems
|
||||||
* underlying CGFont, but apparently there's no safe way to do that.
|
* to do that in a variety of situations, one of which being vertical
|
||||||
* See: http://github.com/behdad/harfbuzz/pull/36 */
|
* text, but also perhaps for caching reasons.
|
||||||
|
*
|
||||||
|
* First, see if it uses any of our subfonts created to set font features...
|
||||||
|
*
|
||||||
|
* Next, compare the CGFont to the one we used to create our fonts.
|
||||||
|
* Even this doesn't work all the time.
|
||||||
|
*
|
||||||
|
* Finally, we compare PS names, which I don't think are unique...
|
||||||
|
*
|
||||||
|
* Looks like if we really want to be sure here we have to modify the
|
||||||
|
* font to change the name table, similar to what we do in the uniscribe
|
||||||
|
* backend.
|
||||||
|
*
|
||||||
|
* However, even that wouldn't work if we were passed in the CGFont to
|
||||||
|
* begin with.
|
||||||
|
*
|
||||||
|
* Webkit uses a slightly different approach: it installs LastResort
|
||||||
|
* as fallback chain, and then checks PS name of used font against
|
||||||
|
* LastResort. That one is safe for any font except for LastResort,
|
||||||
|
* as opposed to ours, which can fail if we are using any uninstalled
|
||||||
|
* font that has the same name as an installed font.
|
||||||
|
*
|
||||||
|
* See: http://github.com/behdad/harfbuzz/pull/36
|
||||||
|
*/
|
||||||
bool matched = false;
|
bool matched = false;
|
||||||
for (unsigned int i = 0; i < range_records.len; i++)
|
for (unsigned int i = 0; i < range_records.len; i++)
|
||||||
if (range_records[i].font && CFEqual (run_ct_font, range_records[i].font))
|
if (range_records[i].font && CFEqual (run_ct_font, range_records[i].font))
|
||||||
|
@ -781,6 +804,25 @@ retry:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!matched)
|
if (!matched)
|
||||||
|
{
|
||||||
|
CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
|
||||||
|
if (run_cg_font)
|
||||||
|
{
|
||||||
|
matched = CFEqual (run_cg_font, face_data);
|
||||||
|
CFRelease (run_cg_font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!matched)
|
||||||
|
{
|
||||||
|
CFStringRef font_ps_name = CTFontCopyName (font_data->ct_font, kCTFontPostScriptNameKey);
|
||||||
|
CFStringRef run_ps_name = CTFontCopyName (run_ct_font, kCTFontPostScriptNameKey);
|
||||||
|
CFComparisonResult result = CFStringCompare (run_ps_name, font_ps_name, 0);
|
||||||
|
CFRelease (run_ps_name);
|
||||||
|
CFRelease (font_ps_name);
|
||||||
|
if (result == kCFCompareEqualTo)
|
||||||
|
matched = true;
|
||||||
|
}
|
||||||
|
if (!matched)
|
||||||
{
|
{
|
||||||
CFRange range = CTRunGetStringRange (run);
|
CFRange range = CTRunGetStringRange (run);
|
||||||
DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld",
|
DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld",
|
||||||
|
|
Loading…
Reference in New Issue