Open Bug 1212731 Opened 10 years ago Updated 3 years ago

implement font cascading for system fonts under OSX

Categories

(Core :: Graphics: Text, defect, P3)

x86_64
macOS
defect

Tracking

()

REOPENED

People

(Reporter: jtd, Unassigned)

References

Details

(Whiteboard: [gfx-noted])

Attachments

(4 files)

To pick up non-Latin UI fonts under OSX we need to implement support for system font cascade-based fallback. While working on supporting system fonts under OSX 10.11 in bug 1201318, I noticed that we don't really handle system fonts correctly across locales. When the user locale is set to Japanese for example, the system font API's (i.e. [NSFont systemFontOfSize:0.0]) still return a Latin font (e.g. Lucida Grande, Helvetica Neue, San Francisco). This means that UI picks up the default font from pref font lists. This is not really the system defined way of doing this. The OSX way of doing this correctly is to use a system-provided "cascade list", basically an array of font descriptors representing fonts that should be used as fallback for a particular font. For system fonts, this will include hidden system fonts for which there's no other way to look them up. Pseudo code for this: get system font get default cascade for system font (e.g. CTFontCopyDefaultCascadeList(systemFont)) add to a new attributes dictionary, with key kCTFontCascadeListAttribute create a font descriptor, then a new font use CTFontCreateForString(new font, str) to determine the fallback font In terms of the font matching process, normally we choose a font based on: fontlist ==> pref fonts ==> system-wide fallback For this case, we need to use the system font cascade *before* pref fonts: fontlist ==> cascade ==> pref fonts ==> system-wide fallback There's one ripple here and that is that defualt system cascade is hard-coded to prioritize Japanese fonts over Chinese fonts. This is a problem for zh-Hans and zh-Hant locales. There's a private CoreText API for this purpose: // prioritize zh-Hant fonts over ja fonts CFStringRef langs[1] = { CFSTR("zh-Hant") }; langList = CFArrayCreate(kCFAllocatorDefault, (const void **) langs, 1, &kCFTypeArrayCallBacks); CFArrayRef cascade = CTFontCopyDefaultCascadeListForLanguages(systemFont, langList); This is important to pick up .Hiragino Kaku Gothic Interface for Japanese and .Apple SD Gothic NeoI for Korean on OSX 10.11: [.Hiragino Kaku Gothic Interface] .HiraKakuInterface-W0 -0.80 0.00 0.00 80000000 [.Hiragino Kaku Gothic Interface] .HiraKakuInterface-W1 -0.60 0.00 0.00 80000000 [.Hiragino Kaku Gothic Interface] .HiraKakuInterface-W2 -0.40 0.00 0.00 80000000 [.Hiragino Kaku Gothic Interface] .HiraKakuInterface-W3 0.00 0.00 0.00 80000000 [.Hiragino Kaku Gothic Interface] .HiraKakuInterface-W4 0.23 0.00 0.00 80000000 [.Hiragino Kaku Gothic Interface] .HiraKakuInterface-W5 0.30 0.00 0.00 80000002 [.Hiragino Kaku Gothic Interface] .HiraKakuInterface-W6 0.30 0.00 0.00 80000002 [.Hiragino Kaku Gothic Interface] .HiraKakuInterface-W7 0.56 0.00 0.00 80000002 [.Hiragino Kaku Gothic Interface] .HiraKakuInterface-W8 0.62 0.00 0.00 80000002 [.Hiragino Kaku Gothic Interface] .HiraKakuInterface-W9 0.62 0.00 0.00 80000002 [.Apple SD Gothic NeoI] .AppleSDGothicNeoI-Bold 0.00 0.00 0.00 80000000 [.Apple SD Gothic NeoI] .AppleSDGothicNeoI-ExtraBold 0.00 0.00 0.00 80000000 [.Apple SD Gothic NeoI] .AppleSDGothicNeoI-Heavy 0.00 0.00 0.00 80000000 [.Apple SD Gothic NeoI] .AppleSDGothicNeoI-Light 0.00 0.00 0.00 80000000 [.Apple SD Gothic NeoI] .AppleSDGothicNeoI-Medium 0.00 0.00 0.00 80000000 [.Apple SD Gothic NeoI] .AppleSDGothicNeoI-Regular 0.00 0.00 0.00 80000000 [.Apple SD Gothic NeoI] .AppleSDGothicNeoI-SemiBold 0.00 0.00 0.00 80000000 [.Apple SD Gothic NeoI] .AppleSDGothicNeoI-Thin 0.00 0.00 0.00 80000000 [.Apple SD Gothic NeoI] .AppleSDGothicNeoI-UltraLight 0.00 0.00 0.00 80000000
Sample code based on Jiang Jiang's fallback.m and Webkit private CoreText API usage. https://gist.github.com/jjgod/4296416b06b39ef49206
Attachment #8708199 - Flags: review?(m_kato)
Attachment #8708196 - Flags: review?(m_kato) → review+
Attachment #8708199 - Flags: review?(m_kato) → review+
Comment on attachment 8708198 [details] [diff] [review] patch p2 - add system font cascade to fontlist for -apple-system generic Review of attachment 8708198 [details] [diff] [review]: ----------------------------------------------------------------- ::: gfx/thebes/gfxFontEntry.h @@ +796,5 @@ > void SetSkipSpaceFeatureCheck(bool aSkipCheck) { > mSkipDefaultFeatureSpaceCheck = aSkipCheck; > } > > + bool LinkedSystemFamily() { return mLinkedSystemFamily; } bool LinkedSystemFamily() const { ... } ::: gfx/thebes/gfxMacPlatformFontList.h @@ +107,5 @@ > float aDevPixPerCSSPixel); > > + void > + AppendLinkedSystemFamilies(nsIAtom* aLanguage, > + nsTArray<gfxFontFamily*>& aFamilyList) override; virtual void ... ::: gfx/thebes/gfxMacPlatformFontList.mm @@ +804,5 @@ > + CTFontRef systemFont = > + CTFontCreateUIFontForLanguage(kCTFontSystemFontType, 12.0, > + CFSTR("en-US")); > + > + nsAutoCString lang(aLang); Remove "nsAutoCString lang(aLang);" because lang uses one time only. @@ +809,5 @@ > + > + // fetch cascade list > + CFStringRef langStr = > + CFStringCreateWithCString(kCFAllocatorDefault, lang.get(), > + kCFStringEncodingUTF8); Change to CFStringCreateWithCString(kCFAllocatorDefault, PromiseFlatCString(aLang).get(), ...
Attachment #8708198 - Flags: review?(m_kato) → review+
Depends on: 1240407
Depends on: 1244017
Because of the regression in bug 1244017, I backed out the support for the system font cascade. Any re-implementation will need to figure out the details of when and how to apply the system font cascade, as it appears that Safari is not using this in precisely the same way. For example, full-width digits are pulled from Apple Symbols when using the system font cascade fallback order but from Hiragino Kaku Gothic Pro when using our existing fallback. The startup regression can probably be resolved by initializing the system font cascade on a separate thread. This will give slightly different UI rendering for the first few seconds after startup but I doubt this will make much of a difference for CJK locales.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Assignee: jd.bugzilla → nobody
Whiteboard: [gfx-noted]
Target Milestone: mozilla46 → ---
Blocks: 1418724
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: