Bug 199769 - Make sure to set kCTFontFallbackOptionAttribute to kCTFontFallbackOptionSystem for system fonts
Summary: Make sure to set kCTFontFallbackOptionAttribute to kCTFontFallbackOptionSyste...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: youenn fablet
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2019-07-12 17:15 PDT by youenn fablet
Modified: 2019-09-17 19:52 PDT (History)
11 users (show)

See Also:


Attachments
Patch (5.29 KB, patch)
2019-07-12 17:18 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
Patch (8.62 KB, patch)
2019-07-12 18:08 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
Patch (8.69 KB, patch)
2019-07-15 11:19 PDT, youenn fablet
commit-queue: commit-queue-
Details | Formatted Diff | Diff
Patch for landing (8.32 KB, patch)
2019-07-15 17:26 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
patch (16.79 KB, patch)
2019-07-15 23:04 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
With tests (28.27 KB, patch)
2019-07-16 09:53 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
With tests (28.29 KB, patch)
2019-07-16 10:54 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
Patch (23.97 KB, patch)
2019-07-16 15:51 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
Patch (24.12 KB, patch)
2019-07-16 16:54 PDT, youenn fablet
no flags Details | Formatted Diff | Diff
Patch (26.06 KB, patch)
2019-07-16 23:44 PDT, youenn fablet
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description youenn fablet 2019-07-12 17:15:21 PDT
This ensures that these system fonts will not resort to user installed fonts in case of a missing character.
Comment 1 youenn fablet 2019-07-12 17:15:40 PDT
<rdar://problem/49390297>
Comment 2 youenn fablet 2019-07-12 17:18:44 PDT
Created attachment 374055 [details]
Patch
Comment 3 youenn fablet 2019-07-12 18:08:54 PDT
Created attachment 374062 [details]
Patch
Comment 4 Alexey Proskuryakov 2019-07-12 18:22:07 PDT
Comment on attachment 374062 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=374062&action=review

> Source/WTF/wtf/Platform.h:1536
> +#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400) || (PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 120000)

No need for iOS version check, we only support building for 12.2 and newer).

I *think* that this check as is disables the feature on watchOS and tvOS, which may or may not be desirable. But let’s be explicit about it if we want this.
Comment 5 Myles C. Maxfield 2019-07-12 22:26:53 PDT
Comment on attachment 374062 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=374062&action=review

> Source/WTF/wtf/Platform.h:1537
> +#define HAVE_DISALLOW_USER_INSTALLED_FONTS 1

“Have disallowed” doesn’t make much sense.
Comment 6 youenn fablet 2019-07-12 22:48:05 PDT
Thanks for the review, I'll update it accordingly.

I tried coming with a test but failed to do it so far, if anybody has an idea, let me know.

It also seems that styles keep a shouldAllowUserInstalledFonts() that is not always in sync with the corresponding setting when changed through internals API.
Comment 7 youenn fablet 2019-07-15 09:28:43 PDT
(In reply to Alexey Proskuryakov from comment #4)
> Comment on attachment 374062 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=374062&action=review
> 
> > Source/WTF/wtf/Platform.h:1536
> > +#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400) || (PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 120000)
> 
> No need for iOS version check, we only support building for 12.2 and newer).

OK

> I *think* that this check as is disables the feature on watchOS and tvOS,
> which may or may not be desirable. But let’s be explicit about it if we want
> this.

I think it is fine as is.

> > Source/WTF/wtf/Platform.h:1537
> > +#define HAVE_DISALLOW_USER_INSTALLED_FONTS 1
> 
> “Have disallowed” doesn’t make much sense.

Will change to HAVE(CAN_DISALLOW_USER_INSTALLED_FONTS)
Comment 8 youenn fablet 2019-07-15 11:19:06 PDT
Created attachment 374125 [details]
Patch
Comment 9 WebKit Commit Bot 2019-07-15 17:18:03 PDT
Comment on attachment 374125 [details]
Patch

Rejecting attachment 374125 [details] from commit-queue.

Failed to run "['/Volumes/Data/EWS/WebKit/Tools/Scripts/webkit-patch', '--status-host=webkit-queues.webkit.org', '--bot-id=webkit-cq-03', 'validate-changelog', '--check-oops', '--non-interactive', 374125, '--port=mac']" exit_code: 1 cwd: /Volumes/Data/EWS/WebKit

ChangeLog entry in Source/WTF/ChangeLog contains OOPS!.

Full output: https://webkit-queues.webkit.org/results/12746368
Comment 10 youenn fablet 2019-07-15 17:26:25 PDT
Created attachment 374169 [details]
Patch for landing
Comment 11 youenn fablet 2019-07-15 23:04:56 PDT
Created attachment 374195 [details]
patch
Comment 12 youenn fablet 2019-07-16 09:53:36 PDT
Created attachment 374213 [details]
With tests
Comment 13 youenn fablet 2019-07-16 10:54:11 PDT
Created attachment 374218 [details]
With tests
Comment 14 Myles C. Maxfield 2019-07-16 11:51:22 PDT
Comment on attachment 374218 [details]
With tests

View in context: https://bugs.webkit.org/attachment.cgi?id=374218&action=review

> Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp:842
> +#if !HAVE(CAN_DISALLOW_USER_INSTALLED_FONTS)

Nit: How about HAVE(DISALLOWABLE_USER_INSTALLED_FONTS)

> Tools/WebKitTestRunner/TestController.cpp:1399
> +        else if (key == "allowUserInstalledFonts")

I'm amazed this didn't exist already.
Comment 15 Myles C. Maxfield 2019-07-16 11:54:35 PDT
Comment on attachment 374218 [details]
With tests

View in context: https://bugs.webkit.org/attachment.cgi?id=374218&action=review

> Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp:573
> +        return createFontForInstalledFonts(originalFont, fontDescription.shouldAllowUserInstalledFonts());

This should have already been called before this function. Why not put this call at the end of lookupFallbackFont()? It would be more performant there.
Comment 16 Myles C. Maxfield 2019-07-16 11:58:39 PDT
Comment on attachment 374218 [details]
With tests

View in context: https://bugs.webkit.org/attachment.cgi?id=374218&action=review

> Tools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:99
> +		41D5B62622DD9D36000F4C4A /* FakeHelvetica-SingleExtendedCharacter.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 41D5B62522DD9D36000F4C4A /* FakeHelvetica-SingleExtendedCharacter.ttf */; };

Woah, how did you build this font?
Comment 17 youenn fablet 2019-07-16 13:18:46 PDT
(In reply to Myles C. Maxfield from comment #15)
> Comment on attachment 374218 [details]
> With tests
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=374218&action=review
> 
> > Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp:573
> > +        return createFontForInstalledFonts(originalFont, fontDescription.shouldAllowUserInstalledFonts());
> 
> This should have already been called before this function. Why not put this
> call at the end of lookupFallbackFont()? It would be more performant there.

That is the first thing I did to verify this was the issue.

I moved this wrapping so that this was making sure preparePlatformFont would always return a 'safe' font.
For instance, there is no guarantee to have the same fontDescription.shouldAllowUserInstalledFonts value.
I guess we could beef-up the optimisation if-check to validate this, or use an ASSERT.

Is it perf sensitive?

> View in context:
> https://bugs.webkit.org/attachment.cgi?id=374218&action=review
> 
> > Tools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:99
> > +		41D5B62622DD9D36000F4C4A /* FakeHelvetica-SingleExtendedCharacter.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 41D5B62522DD9D36000F4C4A /* FakeHelvetica-SingleExtendedCharacter.ttf */; };
> 
> Woah, how did you build this font?

I used FontForge, my first and probably last work on editing fonts.
Comment 18 youenn fablet 2019-07-16 13:28:12 PDT
(In reply to Myles C. Maxfield from comment #14)
> Comment on attachment 374218 [details]
> With tests
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=374218&action=review
> 
> > Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp:842
> > +#if !HAVE(CAN_DISALLOW_USER_INSTALLED_FONTS)
> 
> Nit: How about HAVE(DISALLOWABLE_USER_INSTALLED_FONTS)

OK

> > Tools/WebKitTestRunner/TestController.cpp:1399
> > +        else if (key == "allowUserInstalledFonts")
> 
> I'm amazed this didn't exist already.

I think we should probably modify all existing tests to use this one and not the internals settings one.
Comment 19 youenn fablet 2019-07-16 13:35:03 PDT
(In reply to youenn fablet from comment #17)
> (In reply to Myles C. Maxfield from comment #15)
> > Comment on attachment 374218 [details]
> > With tests
> > 
> > View in context:
> > https://bugs.webkit.org/attachment.cgi?id=374218&action=review
> > 
> > > Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp:573
> > > +        return createFontForInstalledFonts(originalFont, fontDescription.shouldAllowUserInstalledFonts());
> > 
> > This should have already been called before this function. Why not put this
> > call at the end of lookupFallbackFont()? It would be more performant there.
> 
> That is the first thing I did to verify this was the issue.
> 
> I moved this wrapping so that this was making sure preparePlatformFont would
> always return a 'safe' font.
> For instance, there is no guarantee to have the same
> fontDescription.shouldAllowUserInstalledFonts value.
> I guess we could beef-up the optimisation if-check to validate this, or use
> an ASSERT.
> 
> Is it perf sensitive?

Or maybe optimize createFontForInstalledFonts in case font already has the right attribute.
Comment 20 Myles C. Maxfield 2019-07-16 13:36:04 PDT
Comment on attachment 374218 [details]
With tests

View in context: https://bugs.webkit.org/attachment.cgi?id=374218&action=review

>>> Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp:573
>>> +        return createFontForInstalledFonts(originalFont, fontDescription.shouldAllowUserInstalledFonts());
>> 
>> This should have already been called before this function. Why not put this call at the end of lookupFallbackFont()? It would be more performant there.
> 
> That is the first thing I did to verify this was the issue.
> 
> I moved this wrapping so that this was making sure preparePlatformFont would always return a 'safe' font.
> For instance, there is no guarantee to have the same fontDescription.shouldAllowUserInstalledFonts value.
> I guess we could beef-up the optimisation if-check to validate this, or use an ASSERT.
> 
> Is it perf sensitive?

Creating fonts affects PLT and is perf sensitive.

I like the ASSERT() idea. Can we put the createFontForInstalledFonts() call in lookupFallbackFont() and add an ASSERT() in preparePlatformFont()?

>>> Tools/WebKitTestRunner/TestController.cpp:1399
>>> +        else if (key == "allowUserInstalledFonts")
>> 
>> I'm amazed this didn't exist already.
> 
> I think we should probably modify all existing tests to use this one and not the internals settings one.

Is there an internals settings one? There's an internals function to install some fonts, but none that I can see to disable user-installed fonts.

In general, I believe internals is preferable to the <!-- webkit-test-runner [ allowUserInstalledFonts=false ] --> thing. If we can migrate to that, we should. (Also, moving to internals should require 0 lines of code since all Settings are already exposed to internals already. You should already just be able to say

if (window.internals)
    window.internals.settings.setShouldAllowUserInstalledFonts(false);

And it should just work on ToT.
Comment 21 youenn fablet 2019-07-16 13:41:21 PDT
> In general, I believe internals is preferable to the <!-- webkit-test-runner
> [ allowUserInstalledFonts=false ] --> thing. If we can migrate to that, we
> should. (Also, moving to internals should require 0 lines of code since all
> Settings are already exposed to internals already. You should already just
> be able to say
> 
> if (window.internals)
>     window.internals.settings.setShouldAllowUserInstalledFonts(false);
> 
> And it should just work on ToT.

internals.settings.setShouldAllowUserInstalledFonts is affecting the setting and will adjust the setting in some of the places it is stored but not all.
Some rendering code is sticking with the old initial value for instance.
Hence why I went with the webkit-test-runner option.
Comment 22 Myles C. Maxfield 2019-07-16 13:47:47 PDT
(In reply to youenn fablet from comment #21)
> > In general, I believe internals is preferable to the <!-- webkit-test-runner
> > [ allowUserInstalledFonts=false ] --> thing. If we can migrate to that, we
> > should. (Also, moving to internals should require 0 lines of code since all
> > Settings are already exposed to internals already. You should already just
> > be able to say
> > 
> > if (window.internals)
> >     window.internals.settings.setShouldAllowUserInstalledFonts(false);
> > 
> > And it should just work on ToT.
> 
> internals.settings.setShouldAllowUserInstalledFonts is affecting the setting
> and will adjust the setting in some of the places it is stored but not all.
> Some rendering code is sticking with the old initial value for instance.
> Hence why I went with the webkit-test-runner option.

I'm surprised at the idea that, because something is buggy, we should build a new way of doing the same thing, rather than just fixing the bug(s). Especially because the replacement method is less preferable than the original method.
Comment 23 youenn fablet 2019-07-16 15:51:10 PDT
Created attachment 374252 [details]
Patch
Comment 24 youenn fablet 2019-07-16 16:54:50 PDT
Created attachment 374263 [details]
Patch
Comment 25 youenn fablet 2019-07-16 23:44:17 PDT
Created attachment 374281 [details]
Patch
Comment 26 youenn fablet 2019-07-16 23:45:44 PDT
(In reply to youenn fablet from comment #25)
> Created attachment 374281 [details]
> Patch

Made sure that the cached font descriptors in FontDatabase have exactly the right fallback option.
Comment 27 Myles C. Maxfield 2019-07-17 18:57:56 PDT
Comment on attachment 374281 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=374281&action=review

> Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp:572
> +        return createFontForInstalledFonts(originalFont, fontDescription.shouldAllowUserInstalledFonts());

I thought we needed to guard this; only call it when it's actually necessary.

> Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp:882
> +            addAttributesForInstalledFonts(attributes.get(), allowUserInstalledFonts);

I don't think this is actually necessary. You're already calling this in preparePlatformFont().
Comment 28 youenn fablet 2019-07-17 19:50:06 PDT
Comment on attachment 374281 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=374281&action=review

>> Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp:572
>> +        return createFontForInstalledFonts(originalFont, fontDescription.shouldAllowUserInstalledFonts());
> 
> I thought we needed to guard this; only call it when it's actually necessary.

createFontForInstalledFonts is a no-op if the fallback attribute is matching the policy.

>> Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp:882
>> +            addAttributesForInstalledFonts(attributes.get(), allowUserInstalledFonts);
> 
> I don't think this is actually necessary. You're already calling this in preparePlatformFont().

It does help as preparePlatformFont will in most cases become a no-op, especially since we are caching these descriptors, this ensure we do not change the attribute again and again in preparePlatformFont
Comment 29 WebKit Commit Bot 2019-07-18 11:34:35 PDT
Comment on attachment 374281 [details]
Patch

Clearing flags on attachment: 374281

Committed r247566: <https://trac.webkit.org/changeset/247566>
Comment 30 WebKit Commit Bot 2019-07-18 11:34:37 PDT
All reviewed patches have been landed.  Closing bug.