Bug 215691 - [Cocoa] Disable fallback by using kCTFontFallbackOptionNone instead of kCTFontCascadeListAttribute and LastResort
Summary: [Cocoa] Disable fallback by using kCTFontFallbackOptionNone instead of kCTFon...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Myles C. Maxfield
URL:
Keywords: InRadar
Depends on: 225567
Blocks:
  Show dependency treegraph
 
Reported: 2020-08-19 23:32 PDT by Myles C. Maxfield
Modified: 2021-07-22 11:03 PDT (History)
1 user (show)

See Also:


Attachments
Patch (4.32 KB, patch)
2020-08-19 23:33 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Myles C. Maxfield 2020-08-19 23:32:48 PDT
[Cocoa] Disable fallback by using kCTFontFallbackOptionNone instead of kCTFontCascadeListAttribute and LastResort
Comment 1 Myles C. Maxfield 2020-08-19 23:33:58 PDT
Created attachment 406920 [details]
Patch
Comment 2 Myles C. Maxfield 2020-08-19 23:34:24 PDT
<rdar://problem/52386488>
Comment 3 Myles C. Maxfield 2020-09-07 14:10:16 PDT
I see what's happening.

Previously, something really bad was happening. In the complex text codepath, we try to only ever create CTRuns with characters that we know will never trigger font fallback, and if we mess it up somehow, we inject LastResort into the cascade list just after the font we expect to be used. Then, we just assume that we are successful, and ignore the font that Core Text actually used for the CTRuns, and just clobber the used font with out own font we assume Core Text will use. This means that, if we get it wrong, we can use Last Resort's glyph IDs with the wrong font. This is super bad.

Indeed, it looks like we "mess it up" any time small-caps is triggered with a font that supports the lowercase characters but doesn't support the uppercase characters.

(Aside: there is no guarantee that we won't mess it up; in fact, our cluster segmentation code is significantly different than the one used in Core Text, so 'messing it up' is probably more common than we'd like. The more robust solution to this is to consider the font that Core Text *actually* used for the run, rather than pretending we know what it will do.)

This patch disables font fallback entirely in Core Text, which means that instead of returning runs using Last Resort, it will instead return .notdef glyph IDs in the primary font. These end up getting rendered visibly as the tofu. So this is kind of a progression, in that before we would get random characters rendered (which is what happens when you render glyph IDs from one font using another font), but now we get .notdef rendered instead.

I think I'll open a new bug for fixing the problem that this bug uncovered, and block this one on that one.
Comment 4 Myles C. Maxfield 2020-09-07 14:46:38 PDT
I think we should do 4 things:

1. Make WebKit properly do font fallback when small-caps is specified, thereby fixing this test
2. Make WebKit's cluster segmentation match Core Texts, to decrease the probability we will "mess it up" like above
3. Consider the font that Core Text actually uses to render its CTRuns (this will involve somehow mapping CTFonts to WebCore::Font objects, which might be impossible???)
4. Switching to kCTFontFallbackOptionNone like this patch does