Modified: trunk/Source/WebCore/ChangeLog (210882 => 210883)
--- trunk/Source/WebCore/ChangeLog 2017-01-18 21:35:30 UTC (rev 210882)
+++ trunk/Source/WebCore/ChangeLog 2017-01-18 21:40:26 UTC (rev 210883)
@@ -1,5 +1,26 @@
2017-01-18 Myles C. Maxfield <mmaxfi...@apple.com>
+ [Cocoa] Variation fonts without variations specified are not rendered as if the default variations were specified
+ https://bugs.webkit.org/show_bug.cgi?id=166672
+ <rdar://problem/29779119>
+ <rdar://problem/29848883>
+
+ Reviewed by Simon Fraser.
+
+ CoreText has a bug (<rdar://problem/29859207>) where variation fonts without
+ a specified variation value are rendered as if the minimum value is specified,
+ rather than the default value. The solution is to apply default values where
+ they are omitted.
+
+ Test: fast/text/variations/advances.html
+
+ * platform/graphics/cocoa/FontCacheCoreText.cpp:
+ (WebCore::defaultVariationValues):
+ (WebCore::fontIsSystemFont):
+ (WebCore::preparePlatformFont):
+
+2017-01-18 Myles C. Maxfield <mmaxfi...@apple.com>
+
background-repeat-x doesn't work
https://bugs.webkit.org/show_bug.cgi?id=166997
Modified: trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp (210882 => 210883)
--- trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp 2017-01-18 21:35:30 UTC (rev 210882)
+++ trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp 2017-01-18 21:40:26 UTC (rev 210883)
@@ -396,7 +396,7 @@
CFNumberGetValue(maximumValue, kCFNumberFloatType, &rawMaximumValue);
// FIXME: Remove when <rdar://problem/28893836> is fixed
-#define WORKAROUND_CORETEXT_VARIATIONS_EXTENTS_BUG (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < 110000)
+#define WORKAROUND_CORETEXT_VARIATIONS_EXTENTS_BUG ((PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < 110000))
#if WORKAROUND_CORETEXT_VARIATIONS_EXTENTS_BUG
float epsilon = 0.001;
rawMinimumValue += epsilon;
@@ -419,9 +419,30 @@
}
#endif
+#define WORKAROUND_CORETEXT_VARIATIONS_UNSPECIFIED_VALUE_BUG ((PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < 110000))
+#if ENABLE(VARIATION_FONTS) && WORKAROUND_CORETEXT_VARIATIONS_UNSPECIFIED_VALUE_BUG
+static inline bool fontIsSystemFont(CTFontRef font)
+{
+ if (CTFontDescriptorIsSystemUIFont(adoptCF(CTFontCopyFontDescriptor(font)).get()))
+ return true;
+ auto name = adoptCF(CTFontCopyPostScriptName(font));
+ return CFStringGetLength(name.get()) > 0 && CFStringGetCharacterAtIndex(name.get(), 0) == '.';
+}
+#endif
+
RetainPtr<CTFontRef> preparePlatformFont(CTFontRef originalFont, TextRenderingMode textRenderingMode, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, const FontFeatureSettings& features, const FontVariantSettings& variantSettings, const FontVariationSettings& variations)
{
- if (!originalFont || (!features.size() && variations.isEmpty() && (textRenderingMode == AutoTextRendering) && variantSettings.isAllNormal()
+ bool alwaysAddVariations = false;
+
+ // FIXME: Remove when <rdar://problem/29859207> is fixed
+#if ENABLE(VARIATION_FONTS)
+ auto defaultValues = defaultVariationValues(originalFont);
+#if WORKAROUND_CORETEXT_VARIATIONS_UNSPECIFIED_VALUE_BUG
+ alwaysAddVariations = !defaultValues.isEmpty();
+#endif
+#endif
+
+ if (!originalFont || (!features.size() && (!alwaysAddVariations && variations.isEmpty()) && (textRenderingMode == AutoTextRendering) && variantSettings.isAllNormal()
&& (!fontFaceFeatures || !fontFaceFeatures->size()) && (!fontFaceVariantSettings || fontFaceVariantSettings->isAllNormal())))
return originalFont;
@@ -458,27 +479,42 @@
featuresToBeApplied.set(newFeature.tag(), newFeature.value());
#if ENABLE(VARIATION_FONTS)
- auto defaultValues = defaultVariationValues(originalFont);
-
VariationsMap variationsToBeApplied;
- for (auto& newVariation : variations) {
- auto iterator = defaultValues.find(newVariation.tag());
- if (iterator != defaultValues.end()) {
- float valueToApply = std::max(std::min(newVariation.value(), iterator->value.maximumValue), iterator->value.minimumValue);
- // FIXME: Remove when <rdar://problem/28707822> is fixed
-#define WORKAROUND_CORETEXT_VARIATIONS_DEFAULT_VALUE_BUG (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < 110000)
+ auto applyVariationValue = [&](const FontTag& tag, float value, bool isDefaultValue) {
+ // FIXME: Remove when <rdar://problem/28707822> is fixed
+#define WORKAROUND_CORETEXT_VARIATIONS_DEFAULT_VALUE_BUG ((PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < 110000))
#if WORKAROUND_CORETEXT_VARIATIONS_DEFAULT_VALUE_BUG
- if (valueToApply == iterator->value.defaultValue)
- valueToApply += 0.0001;
+ if (isDefaultValue)
+ value += 0.0001;
+#else
+ UNUSED_PARAM(isDefaultValue);
#endif
#undef WORKAROUND_CORETEXT_VARIATIONS_DEFAULT_VALUE_BUG
+ variationsToBeApplied.set(tag, value);
+ };
- variationsToBeApplied.set(newVariation.tag(), valueToApply);
+ for (auto& newVariation : variations) {
+ auto iterator = defaultValues.find(newVariation.tag());
+ if (iterator == defaultValues.end())
+ continue;
+ float valueToApply = clampTo(newVariation.value(), iterator->value.minimumValue, iterator->value.maximumValue);
+ bool isDefaultValue = valueToApply == iterator->value.defaultValue;
+ applyVariationValue(newVariation.tag(), valueToApply, isDefaultValue);
+ }
+
+#if WORKAROUND_CORETEXT_VARIATIONS_UNSPECIFIED_VALUE_BUG
+ if (!fontIsSystemFont(originalFont)) {
+ for (auto& defaultValue : defaultValues) {
+ if (!variationsToBeApplied.contains(defaultValue.key))
+ applyVariationValue(defaultValue.key, defaultValue.value.defaultValue, true);
}
}
#endif
+#undef WORKAROUND_CORETEXT_VARIATIONS_UNSPECIFIED_VALUE_BUG
+#endif // ENABLE(VARIATION_FONTS)
+
auto attributes = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
if (!featuresToBeApplied.isEmpty()) {
auto featureArray = adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, features.size(), &kCFTypeArrayCallBacks));