[Cocoa] Make system-ui obey the user-installed-font policy
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 21 Feb 2018 17:34:45 +0000 (17:34 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 21 Feb 2018 17:34:45 +0000 (17:34 +0000)
https://bugs.webkit.org/show_bug.cgi?id=182860
<rdar://problem/36158249>

Reviewed by Antti Koivisto.

Source/WebCore:

We have a completely different codepath for system-ui which makes it follow the system's
font cascade list. This codepath (along with all the other relevant places which create
system fonts) needs to obey the AllowUserInstalledFonts enum. This patch is fairly
mechanical; we simply are hooking up the flag across SystemFontDatabase.

There are a few places which creates system fonts which this patch doesn't touch. This is
not a problem because all the remaining places either:
1) Simply pull out some attributes of the font (name, weight, size, etc.) and then throw
away the font object itself, or
2) Use the font in an environment where script cannot access the characters rendered (such
as DragImages or the fullscreen placeholder view or the inside of the attachment element).

Test: fast/text/user-installed-fonts/system-ui.html

* platform/graphics/cocoa/FontCacheCoreText.cpp:
(WebCore::FontDatabase::collectionForFamily):
(WebCore::FontDatabase::fontForPostScriptName):
(WebCore::fontWithFamily):
(WebCore::installedFontMandatoryAttributes):
(WebCore::createSpecificFontForInstalledFonts):
* platform/graphics/cocoa/FontCacheCoreText.h:
* platform/graphics/cocoa/FontDescriptionCocoa.cpp:
(WebCore::SystemFontDatabase::CoreTextCascadeListParameters::operator== const):
(WebCore::SystemFontDatabase::CoreTextCascadeListParameters::hash const):
(WebCore::SystemFontDatabase::systemFontCascadeList):
(WebCore::SystemFontDatabase::removeCascadeList):
(WebCore::SystemFontDatabase::computeCascadeList):
(WebCore::systemFontParameters):
(WebCore::systemFontCascadeList):
(WebCore::FontCascadeDescription::effectiveFamilyCount const):
(WebCore::FontCascadeDescription::effectiveFamilyAt const):
* platform/graphics/ios/FontCacheIOS.mm:
(WebCore::platformFontWithFamilySpecialCase):
* platform/graphics/mac/FontCacheMac.mm:
(WebCore::platformFontWithFamilySpecialCase):

Tools:

Create a font, FakeHelvetica-ArmenianCharacter.ttf, which supports a particular Armenian
character which isn't isn't supported by any other font on the system.

* WebKitTestRunner/FakeHelvetica-ArmenianCharacter.ttf:
* WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:

LayoutTests:

FakeHelvetica-ArmenianCharacter.ttf is a font which supports a particular Armenian character which
isn't supported by any other font on the system. Installing this font will cause it to be added to
the 'system-ui' font cascade list. When we disable user-installed-fonts, this font should not be
used to render the character.

* fast/text/user-installed-fonts/system-ui-expected-mismatch.html:
* fast/text/user-installed-fonts/system-ui.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@228877 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/text/user-installed-fonts/system-ui-expected-mismatch.html [new file with mode: 0644]
LayoutTests/fast/text/user-installed-fonts/system-ui.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp
Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.h
Source/WebCore/platform/graphics/cocoa/FontDescriptionCocoa.cpp
Source/WebCore/platform/graphics/ios/FontCacheIOS.mm
Source/WebCore/platform/graphics/mac/FontCacheMac.mm
Tools/ChangeLog
Tools/WebKitTestRunner/FakeHelvetica-ArmenianCharacter.ttf [new file with mode: 0644]
Tools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj

index 6a11efb..9ab8ac6 100644 (file)
@@ -1,3 +1,19 @@
+2018-02-21  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [Cocoa] Make system-ui obey the user-installed-font policy
+        https://bugs.webkit.org/show_bug.cgi?id=182860
+        <rdar://problem/36158249>
+
+        Reviewed by Antti Koivisto.
+
+        FakeHelvetica-ArmenianCharacter.ttf is a font which supports a particular Armenian character which
+        isn't supported by any other font on the system. Installing this font will cause it to be added to
+        the 'system-ui' font cascade list. When we disable user-installed-fonts, this font should not be
+        used to render the character.
+
+        * fast/text/user-installed-fonts/system-ui-expected-mismatch.html:
+        * fast/text/user-installed-fonts/system-ui.html:
+
 2018-02-20  Nan Wang  <n_wang@apple.com>
 
         AX: Keyboard focus not following VoiceOver cursor into web content or within web content.
diff --git a/LayoutTests/fast/text/user-installed-fonts/system-ui-expected-mismatch.html b/LayoutTests/fast/text/user-installed-fonts/system-ui-expected-mismatch.html
new file mode 100644 (file)
index 0000000..961c243
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script>
+if (window.testRunner)
+    testRunner.installFakeHelvetica("ArmenianCharacter");
+</script>
+</head>
+<body>
+<div style="font: 48px 'Helvetica2';">&#x58d;</div>
+</html>
diff --git a/LayoutTests/fast/text/user-installed-fonts/system-ui.html b/LayoutTests/fast/text/user-installed-fonts/system-ui.html
new file mode 100644 (file)
index 0000000..cff612e
--- /dev/null
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script>
+if (window.internals)
+    internals.settings.setShouldAllowUserInstalledFonts(false);
+if (window.testRunner)
+    testRunner.installFakeHelvetica("ArmenianCharacter");
+</script>
+</head>
+<body>
+<div style="font: 48px 'system-ui';">&#x58d;</div>
+</html>
index 762b914..40bbf33 100644 (file)
@@ -1,3 +1,47 @@
+2018-02-21  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [Cocoa] Make system-ui obey the user-installed-font policy
+        https://bugs.webkit.org/show_bug.cgi?id=182860
+        <rdar://problem/36158249>
+
+        Reviewed by Antti Koivisto.
+
+        We have a completely different codepath for system-ui which makes it follow the system's
+        font cascade list. This codepath (along with all the other relevant places which create
+        system fonts) needs to obey the AllowUserInstalledFonts enum. This patch is fairly
+        mechanical; we simply are hooking up the flag across SystemFontDatabase.
+
+        There are a few places which creates system fonts which this patch doesn't touch. This is
+        not a problem because all the remaining places either:
+        1) Simply pull out some attributes of the font (name, weight, size, etc.) and then throw
+        away the font object itself, or
+        2) Use the font in an environment where script cannot access the characters rendered (such
+        as DragImages or the fullscreen placeholder view or the inside of the attachment element).
+
+        Test: fast/text/user-installed-fonts/system-ui.html
+
+        * platform/graphics/cocoa/FontCacheCoreText.cpp:
+        (WebCore::FontDatabase::collectionForFamily):
+        (WebCore::FontDatabase::fontForPostScriptName):
+        (WebCore::fontWithFamily):
+        (WebCore::installedFontMandatoryAttributes):
+        (WebCore::createSpecificFontForInstalledFonts):
+        * platform/graphics/cocoa/FontCacheCoreText.h:
+        * platform/graphics/cocoa/FontDescriptionCocoa.cpp:
+        (WebCore::SystemFontDatabase::CoreTextCascadeListParameters::operator== const):
+        (WebCore::SystemFontDatabase::CoreTextCascadeListParameters::hash const):
+        (WebCore::SystemFontDatabase::systemFontCascadeList):
+        (WebCore::SystemFontDatabase::removeCascadeList):
+        (WebCore::SystemFontDatabase::computeCascadeList):
+        (WebCore::systemFontParameters):
+        (WebCore::systemFontCascadeList):
+        (WebCore::FontCascadeDescription::effectiveFamilyCount const):
+        (WebCore::FontCascadeDescription::effectiveFamilyAt const):
+        * platform/graphics/ios/FontCacheIOS.mm:
+        (WebCore::platformFontWithFamilySpecialCase):
+        * platform/graphics/mac/FontCacheMac.mm:
+        (WebCore::platformFontWithFamilySpecialCase):
+
 2018-02-21  Chris Dumez  <cdumez@apple.com>
 
         Unreviewed attempt to fix build after r228867.
index 89227e7..49de822 100644 (file)
@@ -893,7 +893,7 @@ public:
             CFDictionaryAddValue(attributes.get(), kCTFontFamilyNameAttribute, familyNameString.get());
             addAttributesForInstalledFonts(attributes.get(), m_allowUserInstalledFonts);
             auto fontDescriptorToMatch = adoptCF(CTFontDescriptorCreateWithAttributes(attributes.get()));
-            RetainPtr<CFSetRef> mandatoryAttributes = installedFontMandatoryAttributes(m_allowUserInstalledFonts);
+            auto mandatoryAttributes = installedFontMandatoryAttributes(m_allowUserInstalledFonts);
             if (auto matches = adoptCF(CTFontDescriptorCreateMatchingFontDescriptors(fontDescriptorToMatch.get(), mandatoryAttributes.get()))) {
                 auto count = CFArrayGetCount(matches.get());
                 Vector<InstalledFont> result;
@@ -923,7 +923,7 @@ public:
             CFDictionaryAddValue(attributes.get(), nameAttribute, postScriptNameString.get());
             addAttributesForInstalledFonts(attributes.get(), m_allowUserInstalledFonts);
             auto fontDescriptorToMatch = adoptCF(CTFontDescriptorCreateWithAttributes(attributes.get()));
-            RetainPtr<CFSetRef> mandatoryAttributes = installedFontMandatoryAttributes(m_allowUserInstalledFonts);
+            auto mandatoryAttributes = installedFontMandatoryAttributes(m_allowUserInstalledFonts);
             auto match = adoptCF(CTFontDescriptorCreateMatchingFontDescriptor(fontDescriptorToMatch.get(), mandatoryAttributes.get()));
             return InstalledFont(match.get());
         }).iterator->value;
@@ -1201,7 +1201,7 @@ static RetainPtr<CTFontRef> fontWithFamily(const AtomicString& family, const Fon
 
     const auto& request = fontDescription.fontSelectionRequest();
     FontLookup fontLookup;
-    fontLookup.result = platformFontWithFamilySpecialCase(family, request, size);
+    fontLookup.result = platformFontWithFamilySpecialCase(family, request, size, fontDescription.shouldAllowUserInstalledFonts());
     if (!fontLookup.result)
         fontLookup = platformFontLookupWithFamily(family, request, size, fontDescription.shouldAllowUserInstalledFonts());
     return preparePlatformFont(fontLookup.result.get(), fontDescription, fontFaceFeatures, fontFaceVariantSettings, fontFaceCapabilities, size, !fontLookup.createdFromPostScriptName);
@@ -1428,6 +1428,28 @@ void addAttributesForInstalledFonts(CFMutableDictionaryRef attributes, AllowUser
 #endif
 }
 
+RetainPtr<CTFontRef> createFontForInstalledFonts(CTFontDescriptorRef fontDescriptor, CGFloat size, AllowUserInstalledFonts allowUserInstalledFonts)
+{
+    auto attributes = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+    addAttributesForInstalledFonts(attributes.get(), allowUserInstalledFonts);
+    if (CFDictionaryGetCount(attributes.get())) {
+        auto resultFontDescriptor = adoptCF(CTFontDescriptorCreateCopyWithAttributes(fontDescriptor, attributes.get()));
+        return adoptCF(CTFontCreateWithFontDescriptor(resultFontDescriptor.get(), size, nullptr));
+    }
+    return adoptCF(CTFontCreateWithFontDescriptor(fontDescriptor, size, nullptr));
+}
+
+RetainPtr<CTFontRef> createFontForInstalledFonts(CTFontRef font, AllowUserInstalledFonts allowUserInstalledFonts)
+{
+    auto attributes = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+    addAttributesForInstalledFonts(attributes.get(), allowUserInstalledFonts);
+    if (CFDictionaryGetCount(attributes.get())) {
+        auto modification = adoptCF(CTFontDescriptorCreateWithAttributes(attributes.get()));
+        return adoptCF(CTFontCreateCopyWithAttributes(font, CTFontGetSize(font), nullptr, modification.get()));
+    }
+    return font;
+}
+
 void addAttributesForWebFonts(CFMutableDictionaryRef attributes, AllowUserInstalledFonts allowUserInstalledFonts)
 {
 #if CAN_DISALLOW_USER_INSTALLED_FONTS
@@ -1451,8 +1473,8 @@ RetainPtr<CFSetRef> installedFontMandatoryAttributes(AllowUserInstalledFonts all
     }
 #else
     UNUSED_PARAM(allowUserInstalledFonts);
-#endif
     return nullptr;
+#endif
 }
 
 Ref<Font> FontCache::lastResortFallbackFont(const FontDescription& fontDescription)
index 2b4b241..5cf6cd2 100644 (file)
@@ -52,11 +52,13 @@ struct SynthesisPair {
 
 RetainPtr<CTFontRef> preparePlatformFont(CTFontRef, const FontDescription&, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, FontSelectionSpecifiedCapabilities fontFaceCapabilities, float size, bool applyWeightWidthSlopeVariations = true);
 SynthesisPair computeNecessarySynthesis(CTFontRef, const FontDescription&, bool isPlatformFont = false);
-RetainPtr<CTFontRef> platformFontWithFamilySpecialCase(const AtomicString& family, FontSelectionRequest, float size);
+RetainPtr<CTFontRef> platformFontWithFamilySpecialCase(const AtomicString& family, FontSelectionRequest, float size, AllowUserInstalledFonts);
 RetainPtr<CTFontRef> platformFontWithFamily(const AtomicString& family, FontSelectionRequest, TextRenderingMode, float size);
 bool requiresCustomFallbackFont(UChar32 character);
 FontSelectionCapabilities capabilitiesForFontDescriptor(CTFontDescriptorRef);
 void addAttributesForInstalledFonts(CFMutableDictionaryRef attributes, AllowUserInstalledFonts);
+RetainPtr<CTFontRef> createFontForInstalledFonts(CTFontDescriptorRef, CGFloat size, AllowUserInstalledFonts);
+RetainPtr<CTFontRef> createFontForInstalledFonts(CTFontRef, AllowUserInstalledFonts);
 void addAttributesForWebFonts(CFMutableDictionaryRef attributes, AllowUserInstalledFonts);
 RetainPtr<CFSetRef> installedFontMandatoryAttributes(AllowUserInstalledFonts);
 
index 05479eb..42afa48 100644 (file)
@@ -65,6 +65,7 @@ public:
                 && locale == other.locale
                 && weight == other.weight
                 && size == other.size
+                && allowUserInstalledFonts == other.allowUserInstalledFonts
                 && italic == other.italic;
         }
 
@@ -76,6 +77,7 @@ public:
             hasher.add(locale.isNull() ? 0 : locale.existingHash());
             hasher.add(weight);
             hasher.add(size);
+            hasher.add(static_cast<unsigned>(allowUserInstalledFonts));
             hasher.add(italic);
             return hasher.hash();
         }
@@ -96,6 +98,7 @@ public:
         AtomicString locale;
         CGFloat weight { 0 };
         float size { 0 };
+        AllowUserInstalledFonts allowUserInstalledFonts { AllowUserInstalledFonts::No };
         bool italic { false };
     };
 
@@ -116,8 +119,8 @@ public:
             if (clientUse == ClientUse::ForSystemUI) {
                 systemFont = adoptCF(CTFontCreateUIFontForLanguage(kCTFontUIFontSystem, parameters.size, localeString.get()));
                 ASSERT(systemFont);
-                // FIXME: Use applyWeightAndItalics() in both cases once <rdar://problem/33046041> is fixed.
-                systemFont = applyWeightAndItalics(systemFont.get(), parameters.weight, parameters.italic, parameters.size);
+                // FIXME: Use applyWeightItalicsAndFallbackBehavior() in both cases once <rdar://problem/33046041> is fixed.
+                systemFont = applyWeightItalicsAndFallbackBehavior(systemFont.get(), parameters.weight, parameters.italic, parameters.size, parameters.allowUserInstalledFonts);
             } else {
 #if PLATFORM(IOS)
                 ASSERT(clientUse == ClientUse::ForTextStyle);
@@ -125,7 +128,7 @@ public:
                 CTFontSymbolicTraits traits = (parameters.weight >= kCTFontWeightSemibold ? kCTFontTraitBold : 0) | (parameters.italic ? kCTFontTraitItalic : 0);
                 if (traits)
                     fontDescriptor = adoptCF(CTFontDescriptorCreateCopyWithSymbolicTraits(fontDescriptor.get(), traits, traits));
-                systemFont = adoptCF(CTFontCreateWithFontDescriptor(fontDescriptor.get(), parameters.size, nullptr));
+                systemFont = createFontForInstalledFonts(fontDescriptor.get(), parameters.size, parameters.allowUserInstalledFonts);
 #else
                 ASSERT_NOT_REACHED();
 #endif
@@ -147,7 +150,7 @@ private:
     {
     }
 
-    static RetainPtr<CTFontRef> applyWeightAndItalics(CTFontRef font, CGFloat weight, bool italic, float size)
+    static RetainPtr<CTFontRef> applyWeightItalicsAndFallbackBehavior(CTFontRef font, CGFloat weight, bool italic, float size, AllowUserInstalledFonts allowUserInstalledFonts)
     {
         auto weightNumber = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &weight));
         const float systemFontItalicSlope = 0.07;
@@ -156,9 +159,9 @@ private:
         CFTypeRef traitsKeys[] = { kCTFontWeightTrait, kCTFontSlantTrait, kCTFontUIFontDesignTrait };
         CFTypeRef traitsValues[] = { weightNumber.get(), italicsNumber.get(), kCFBooleanTrue };
         auto traitsDictionary = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, traitsKeys, traitsValues, WTF_ARRAY_LENGTH(traitsKeys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-        CFTypeRef modificationKeys[] = { kCTFontTraitsAttribute };
-        CFTypeRef modificationValues[] = { traitsDictionary.get() };
-        auto attributes = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, modificationKeys, modificationValues, WTF_ARRAY_LENGTH(modificationKeys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+        auto attributes = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+        CFDictionaryAddValue(attributes.get(), kCTFontTraitsAttribute, traitsDictionary.get());
+        addAttributesForInstalledFonts(attributes.get(), allowUserInstalledFonts);
         auto modification = adoptCF(CTFontDescriptorCreateWithAttributes(attributes.get()));
         return adoptCF(CTFontCreateCopyWithAttributes(font, size, nullptr, modification.get()));
     }
@@ -241,7 +244,7 @@ static inline bool isUIFontTextStyle(const AtomicString& string)
 }
 #endif
 
-static inline SystemFontDatabase::CoreTextCascadeListParameters systemFontParameters(const FontCascadeDescription& description, const AtomicString& familyName, SystemFontDatabase::ClientUse clientUse)
+static inline SystemFontDatabase::CoreTextCascadeListParameters systemFontParameters(const FontCascadeDescription& description, const AtomicString& familyName, SystemFontDatabase::ClientUse clientUse, AllowUserInstalledFonts allowUserInstalledFonts)
 {
     SystemFontDatabase::CoreTextCascadeListParameters result;
     result.locale = description.locale();
@@ -279,6 +282,8 @@ static inline SystemFontDatabase::CoreTextCascadeListParameters systemFontParame
         result.fontName = familyName;
     }
 
+    result.allowUserInstalledFonts = allowUserInstalledFonts;
+
     return result;
 }
 
@@ -287,9 +292,9 @@ void FontDescription::invalidateCaches()
     SystemFontDatabase::singleton().clear();
 }
 
-static inline Vector<RetainPtr<CTFontDescriptorRef>> systemFontCascadeList(const FontCascadeDescription& description, const AtomicString& cssFamily, SystemFontDatabase::ClientUse clientUse)
+static inline Vector<RetainPtr<CTFontDescriptorRef>> systemFontCascadeList(const FontCascadeDescription& description, const AtomicString& cssFamily, SystemFontDatabase::ClientUse clientUse, AllowUserInstalledFonts allowUserInstalledFonts)
 {
-    return SystemFontDatabase::singleton().systemFontCascadeList(systemFontParameters(description, cssFamily, clientUse), clientUse);
+    return SystemFontDatabase::singleton().systemFontCascadeList(systemFontParameters(description, cssFamily, clientUse, allowUserInstalledFonts), clientUse);
 }
 
 unsigned FontCascadeDescription::effectiveFamilyCount() const
@@ -299,10 +304,10 @@ unsigned FontCascadeDescription::effectiveFamilyCount() const
     for (unsigned i = 0; i < familyCount(); ++i) {
         const auto& cssFamily = familyAt(i);
         if (isSystemFontString(cssFamily))
-            result += systemFontCascadeList(*this, cssFamily, SystemFontDatabase::ClientUse::ForSystemUI).size();
+            result += systemFontCascadeList(*this, cssFamily, SystemFontDatabase::ClientUse::ForSystemUI, shouldAllowUserInstalledFonts()).size();
 #if PLATFORM(IOS)
         else if (isUIFontTextStyle(cssFamily))
-            result += systemFontCascadeList(*this, cssFamily, SystemFontDatabase::ClientUse::ForTextStyle).size();
+            result += systemFontCascadeList(*this, cssFamily, SystemFontDatabase::ClientUse::ForTextStyle, shouldAllowUserInstalledFonts()).size();
 #endif
         else
             ++result;
@@ -322,14 +327,14 @@ FontFamilySpecification FontCascadeDescription::effectiveFamilyAt(unsigned index
     for (unsigned i = 0; i < familyCount(); ++i) {
         const auto& cssFamily = familyAt(i);
         if (isSystemFontString(cssFamily)) {
-            auto cascadeList = systemFontCascadeList(*this, cssFamily, SystemFontDatabase::ClientUse::ForSystemUI);
+            auto cascadeList = systemFontCascadeList(*this, cssFamily, SystemFontDatabase::ClientUse::ForSystemUI, shouldAllowUserInstalledFonts());
             if (index < cascadeList.size())
                 return FontFamilySpecification(cascadeList[index].get());
             index -= cascadeList.size();
         }
 #if PLATFORM(IOS)
         else if (isUIFontTextStyle(cssFamily)) {
-            auto cascadeList = systemFontCascadeList(*this, cssFamily, SystemFontDatabase::ClientUse::ForTextStyle);
+            auto cascadeList = systemFontCascadeList(*this, cssFamily, SystemFontDatabase::ClientUse::ForTextStyle, shouldAllowUserInstalledFonts());
             if (index < cascadeList.size())
                 return FontFamilySpecification(cascadeList[index].get());
             index -= cascadeList.size();
index a069f40..deeb97a 100644 (file)
@@ -132,7 +132,7 @@ static RetainPtr<CTFontDescriptorRef> systemFontDescriptor(FontSelectionValue we
     return adoptCF(CTFontDescriptorCreateCopyWithAttributes(fontDescriptor.get(), static_cast<CFDictionaryRef>(attributes.get())));
 }
 
-RetainPtr<CTFontRef> platformFontWithFamilySpecialCase(const AtomicString& family, FontSelectionRequest request, float size)
+RetainPtr<CTFontRef> platformFontWithFamilySpecialCase(const AtomicString& family, FontSelectionRequest request, float size, AllowUserInstalledFonts allowUserInstalledFonts)
 {
     // FIXME: See comment in FontCascadeDescription::effectiveFamilyAt() in FontDescriptionCocoa.cpp
     if (family.startsWith("UICTFontTextStyle")) {
@@ -141,18 +141,18 @@ RetainPtr<CTFontRef> platformFontWithFamilySpecialCase(const AtomicString& famil
         RetainPtr<CTFontDescriptorRef> fontDescriptor = adoptCF(CTFontDescriptorCreateWithTextStyle(familyNameStr.get(), RenderThemeIOS::contentSizeCategory(), nullptr));
         if (traits)
             fontDescriptor = adoptCF(CTFontDescriptorCreateCopyWithSymbolicTraits(fontDescriptor.get(), traits, traits));
-
-        return adoptCF(CTFontCreateWithFontDescriptor(fontDescriptor.get(), size, nullptr));
+        return createFontForInstalledFonts(fontDescriptor.get(), size, allowUserInstalledFonts);
     }
 
     if (equalLettersIgnoringASCIICase(family, "-webkit-system-font") || equalLettersIgnoringASCIICase(family, "-apple-system") || equalLettersIgnoringASCIICase(family, "-apple-system-font") || equalLettersIgnoringASCIICase(family, "system-ui")) {
-        return adoptCF(CTFontCreateWithFontDescriptor(systemFontDescriptor(request.weight, isFontWeightBold(request.weight), isItalic(request.slope), size).get(), size, nullptr));
+        auto fontDescriptor = systemFontDescriptor(request.weight, isFontWeightBold(request.weight), isItalic(request.slope), size);
+        return createFontForInstalledFonts(fontDescriptor.get(), size, allowUserInstalledFonts);
     }
 
     if (equalLettersIgnoringASCIICase(family, "-apple-system-monospaced-numbers")) {
         RetainPtr<CTFontDescriptorRef> systemFontDescriptor = adoptCF(CTFontDescriptorCreateForUIType(kCTFontUIFontSystem, size, nullptr));
         RetainPtr<CTFontDescriptorRef> monospaceFontDescriptor = adoptCF(CTFontDescriptorCreateCopyWithFeature(systemFontDescriptor.get(), (CFNumberRef)@(kNumberSpacingType), (CFNumberRef)@(kMonospacedNumbersSelector)));
-        return adoptCF(CTFontCreateWithFontDescriptor(monospaceFontDescriptor.get(), size, nullptr));
+        return createFontForInstalledFonts(monospaceFontDescriptor.get(), size, allowUserInstalledFonts);
     }
 
     if (equalLettersIgnoringASCIICase(family, "lastresort")) {
index 230a973..211d899 100644 (file)
@@ -73,7 +73,7 @@ static CGFloat toNSFontWeight(FontSelectionValue fontWeight)
     return NSFontWeightBlack;
 }
 
-RetainPtr<CTFontRef> platformFontWithFamilySpecialCase(const AtomicString& family, FontSelectionRequest request, float size)
+RetainPtr<CTFontRef> platformFontWithFamilySpecialCase(const AtomicString& family, FontSelectionRequest request, float size, AllowUserInstalledFonts allowUserInstalledFonts)
 {
     // FIXME: See comment in FontCascadeDescription::effectiveFamilyAt() in FontDescriptionCocoa.cpp
     if (equalLettersIgnoringASCIICase(family, "-webkit-system-font") || equalLettersIgnoringASCIICase(family, "-apple-system") || equalLettersIgnoringASCIICase(family, "-apple-system-font") || equalLettersIgnoringASCIICase(family, "system-ui")) {
@@ -85,7 +85,7 @@ RetainPtr<CTFontRef> platformFontWithFamilySpecialCase(const AtomicString& famil
             if (auto italicizedFont = adoptCF(CTFontCreateCopyWithSymbolicTraits(result.get(), size, nullptr, desiredTraits, desiredTraits)))
                 result = italicizedFont;
         }
-        return result;
+        return createFontForInstalledFonts(result.get(), allowUserInstalledFonts);
     }
 
     if (equalLettersIgnoringASCIICase(family, "-apple-system-monospaced-numbers")) {
@@ -98,19 +98,23 @@ RetainPtr<CTFontRef> platformFontWithFamilySpecialCase(const AtomicString& famil
         RetainPtr<CFDictionaryRef> featureIdentifier = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, featureKeys, featureValues, WTF_ARRAY_LENGTH(featureKeys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
         CFTypeRef featureIdentifiers[] = { featureIdentifier.get() };
         RetainPtr<CFArrayRef> featureArray = adoptCF(CFArrayCreate(kCFAllocatorDefault, featureIdentifiers, 1, &kCFTypeArrayCallBacks));
-        CFTypeRef attributesKeys[] = { kCTFontFeatureSettingsAttribute };
-        CFTypeRef attributesValues[] = { featureArray.get() };
-        RetainPtr<CFDictionaryRef> attributes = adoptCF(CFDictionaryCreate(kCFAllocatorDefault, attributesKeys, attributesValues, WTF_ARRAY_LENGTH(attributesKeys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-
+        auto attributes = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+        CFDictionaryAddValue(attributes.get(), kCTFontFeatureSettingsAttribute, featureArray.get());
+        addAttributesForInstalledFonts(attributes.get(), allowUserInstalledFonts);
         RetainPtr<CTFontRef> result = toCTFont([NSFont systemFontOfSize:size]);
-        return adoptCF(CTFontCreateCopyWithAttributes(result.get(), size, nullptr, adoptCF(CTFontDescriptorCreateWithAttributes(attributes.get())).get()));
+        auto modification = adoptCF(CTFontDescriptorCreateWithAttributes(attributes.get()));
+        return adoptCF(CTFontCreateCopyWithAttributes(result.get(), size, nullptr, modification.get()));
     }
 
-    if (equalLettersIgnoringASCIICase(family, "-apple-menu"))
-        return toCTFont([NSFont menuFontOfSize:size]);
+    if (equalLettersIgnoringASCIICase(family, "-apple-menu")) {
+        RetainPtr<CTFontRef> result = toCTFont([NSFont menuFontOfSize:size]);
+        return createFontForInstalledFonts(result.get(), allowUserInstalledFonts);
+    }
 
-    if (equalLettersIgnoringASCIICase(family, "-apple-status-bar"))
-        return toCTFont([NSFont labelFontOfSize:size]);
+    if (equalLettersIgnoringASCIICase(family, "-apple-status-bar")) {
+        RetainPtr<CTFontRef> result = toCTFont([NSFont labelFontOfSize:size]);
+        return createFontForInstalledFonts(result.get(), allowUserInstalledFonts);
+    }
 
     if (equalLettersIgnoringASCIICase(family, "lastresort")) {
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300
index cfadfcf..89a7880 100644 (file)
@@ -1,3 +1,17 @@
+2018-02-21  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [Cocoa] Make system-ui obey the user-installed-font policy
+        https://bugs.webkit.org/show_bug.cgi?id=182860
+        <rdar://problem/36158249>
+
+        Reviewed by Antti Koivisto.
+
+        Create a font, FakeHelvetica-ArmenianCharacter.ttf, which supports a particular Armenian
+        character which isn't isn't supported by any other font on the system.
+
+        * WebKitTestRunner/FakeHelvetica-ArmenianCharacter.ttf:
+        * WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:
+
 2018-02-20  Timothy Horton  <timothy_horton@apple.com>
 
         Try to fix the 32-bit build after r228857
diff --git a/Tools/WebKitTestRunner/FakeHelvetica-ArmenianCharacter.ttf b/Tools/WebKitTestRunner/FakeHelvetica-ArmenianCharacter.ttf
new file mode 100644 (file)
index 0000000..10984f3
Binary files /dev/null and b/Tools/WebKitTestRunner/FakeHelvetica-ArmenianCharacter.ttf differ
index fc6f84e..e176b0d 100644 (file)
@@ -54,6 +54,7 @@
                1CBA02971FD87DEE00179C7D /* FakeHelvetica-Helvetica2-400.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 1CBA02921FD86EA100179C7D /* FakeHelvetica-Helvetica2-400.ttf */; };
                1CBA02981FD87DF000179C7D /* FakeHelvetica-Helvetica-500.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 1CBA02931FD86EA100179C7D /* FakeHelvetica-Helvetica-500.ttf */; };
                1CBA02991FD87DF300179C7D /* FakeHelvetica-Helvetica-400.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 1CBA02941FD86EA100179C7D /* FakeHelvetica-Helvetica-400.ttf */; };
+               1CEA84DD203782ED00440D08 /* FakeHelvetica-ArmenianCharacter.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 1CEA84DC203782ED00440D08 /* FakeHelvetica-ArmenianCharacter.ttf */; };
                29210EAE144CACB700835BB5 /* AccessibilityUIElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29210EA9144CACB200835BB5 /* AccessibilityUIElement.cpp */; };
                29210EB0144CACBD00835BB5 /* AccessibilityController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29210EA2144CAAA500835BB5 /* AccessibilityController.cpp */; };
                29210EB4144CACD500835BB5 /* AccessibilityTextMarker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 29210EB1144CACD400835BB5 /* AccessibilityTextMarker.cpp */; };
                1CBA02931FD86EA100179C7D /* FakeHelvetica-Helvetica-500.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "FakeHelvetica-Helvetica-500.ttf"; path = "fonts/FakeHelvetica-Helvetica-500.ttf"; sourceTree = "<group>"; };
                1CBA02941FD86EA100179C7D /* FakeHelvetica-Helvetica-400.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "FakeHelvetica-Helvetica-400.ttf"; path = "fonts/FakeHelvetica-Helvetica-400.ttf"; sourceTree = "<group>"; };
                1CBA02951FD86EA100179C7D /* FakeHelvetica-Helvetica2-500.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "FakeHelvetica-Helvetica2-500.ttf"; path = "fonts/FakeHelvetica-Helvetica2-500.ttf"; sourceTree = "<group>"; };
+               1CEA84DC203782ED00440D08 /* FakeHelvetica-ArmenianCharacter.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "FakeHelvetica-ArmenianCharacter.ttf"; sourceTree = "<group>"; };
                26D758E5160BECDC00268472 /* GeolocationProviderMock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GeolocationProviderMock.cpp; sourceTree = "<group>"; };
                26D758E6160BECDD00268472 /* GeolocationProviderMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeolocationProviderMock.h; sourceTree = "<group>"; };
                29210EA2144CAAA500835BB5 /* AccessibilityController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityController.cpp; sourceTree = "<group>"; };
                        isa = PBXGroup;
                        children = (
                                6510A77711EC643800410867 /* AHEM____.TTF */,
+                               1CEA84DC203782ED00440D08 /* FakeHelvetica-ArmenianCharacter.ttf */,
                                1CBA02941FD86EA100179C7D /* FakeHelvetica-Helvetica-400.ttf */,
                                1CBA02931FD86EA100179C7D /* FakeHelvetica-Helvetica-500.ttf */,
                                1CBA02921FD86EA100179C7D /* FakeHelvetica-Helvetica2-400.ttf */,
                        buildActionMask = 2147483647;
                        files = (
                                6510A78211EC643800410867 /* AHEM____.TTF in Resources */,
+                               1CEA84DD203782ED00440D08 /* FakeHelvetica-ArmenianCharacter.ttf in Resources */,
                                1CBA02991FD87DF300179C7D /* FakeHelvetica-Helvetica-400.ttf in Resources */,
                                1CBA02981FD87DF000179C7D /* FakeHelvetica-Helvetica-500.ttf in Resources */,
                                1CBA02971FD87DEE00179C7D /* FakeHelvetica-Helvetica2-400.ttf in Resources */,