Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implement font-optical-sizing
https://bugs.webkit.org/show_bug.cgi?id=168895

Reviewed by Dean Jackson.

Source/WebCore:

Upon advice from Microsoft, the only input to optical sizing is just the
font-size computed value. It is implemented by setting the 'opsz' font
variation axis. Because the propery has such a simple grammar, the
implementation is quite straightforward.

Test: fast/text/variations/optical-sizing.html

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::ComputedStyleExtractor::propertyValue):
* css/CSSPrimitiveValueMappings.h:
(WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
(WebCore::CSSPrimitiveValue::operator FontOpticalSizing):
* css/CSSProperties.json:
* css/parser/CSSParserFastPaths.cpp:
(WebCore::CSSParserFastPaths::isValidKeywordPropertyAndValue):
(WebCore::CSSParserFastPaths::isKeywordPropertyID):
* platform/graphics/FontCache.h:
(WebCore::FontDescriptionKey::makeFlagsKey):
* platform/graphics/FontDescription.h:
(WebCore::FontDescription::opticalSizing):
(WebCore::FontDescription::setOpticalSizing):
(WebCore::FontDescription::operator==):
(WebCore::FontCascadeDescription::initialOpticalSizing):
* platform/graphics/cocoa/FontCacheCoreText.cpp:
(WebCore::preparePlatformFont):
(WebCore::fontWithFamily):
(WebCore::FontCache::createFontPlatformData):
(WebCore::FontCache::systemFallbackForCharacters):
* platform/graphics/mac/FontCustomPlatformData.cpp:
(WebCore::FontCustomPlatformData::fontPlatformData):
* platform/text/TextFlags.h:

LayoutTests:

* fast/text/variations/optical-sizing-expected.txt: Added.
* fast/text/variations/optical-sizing.html: Added.

Canonical link: https://commits.webkit.org/186989@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@214364 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
litherum committed Mar 24, 2017
1 parent 639c898 commit b6365ca
Show file tree
Hide file tree
Showing 14 changed files with 242 additions and 60 deletions.
10 changes: 10 additions & 0 deletions LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
2017-03-24 Myles C. Maxfield <mmaxfield@apple.com>

Implement font-optical-sizing
https://bugs.webkit.org/show_bug.cgi?id=168895

Reviewed by Dean Jackson.

* fast/text/variations/optical-sizing-expected.txt: Added.
* fast/text/variations/optical-sizing.html: Added.

2017-03-24 Yoav Weiss <yoav@yoav.ws>

Add a warning for unused link preloads.
Expand Down
23 changes: 23 additions & 0 deletions LayoutTests/fast/text/variations/optical-sizing-expected.txt
@@ -0,0 +1,23 @@
This test makes sure that font-optical-sizing works as expected.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS window.getComputedStyle(document.getElementById('test1')).getPropertyValue('font-optical-sizing') is "auto"
PASS window.getComputedStyle(document.getElementById('test2')).getPropertyValue('font-optical-sizing') is "auto"
PASS window.getComputedStyle(document.getElementById('test3')).getPropertyValue('font-optical-sizing') is "auto"
PASS window.getComputedStyle(document.getElementById('test4')).getPropertyValue('font-optical-sizing') is "none"
PASS window.getComputedStyle(document.getElementById('test5')).getPropertyValue('font-optical-sizing') is "none"
PASS document.getElementById('test1').style.fontOpticalSizing is ""
PASS document.getElementById('test2').style.fontOpticalSizing is "initial"
PASS document.getElementById('test3').style.fontOpticalSizing is "auto"
PASS document.getElementById('test4').style.fontOpticalSizing is "none"
PASS document.getElementById('test5').style.fontOpticalSizing is "inherit"
PASS successfullyParsed is true

TEST COMPLETE
Hello
Hello
Hello
Hello
Hello
31 changes: 31 additions & 0 deletions LayoutTests/fast/text/variations/optical-sizing.html
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<script src="../../../resources/js-test-pre.js"></script>
</head>
<body>
<div id="test1">Hello</div>
<div id="test2" style="font-optical-sizing: initial;">Hello</div>
<div id="test3" style="font-optical-sizing: auto;">Hello</div>
<div id="test4" style="font-optical-sizing: none;">Hello</div>
<div style="font-optical-sizing: none;"><div id="test5" style="font-optical-sizing: inherit;">Hello</div></div>

<script>
description("This test makes sure that font-optical-sizing works as expected.");

shouldBeEqualToString("window.getComputedStyle(document.getElementById('test1')).getPropertyValue('font-optical-sizing')", "auto");
shouldBeEqualToString("window.getComputedStyle(document.getElementById('test2')).getPropertyValue('font-optical-sizing')", "auto");
shouldBeEqualToString("window.getComputedStyle(document.getElementById('test3')).getPropertyValue('font-optical-sizing')", "auto");
shouldBeEqualToString("window.getComputedStyle(document.getElementById('test4')).getPropertyValue('font-optical-sizing')", "none");
shouldBeEqualToString("window.getComputedStyle(document.getElementById('test5')).getPropertyValue('font-optical-sizing')", "none");

shouldBeEqualToString("document.getElementById('test1').style.fontOpticalSizing", "");
shouldBeEqualToString("document.getElementById('test2').style.fontOpticalSizing", "initial");
shouldBeEqualToString("document.getElementById('test3').style.fontOpticalSizing", "auto");
shouldBeEqualToString("document.getElementById('test4').style.fontOpticalSizing", "none");
shouldBeEqualToString("document.getElementById('test5').style.fontOpticalSizing", "inherit");
</script>

<script src="../../../resources/js-test-post.js"></script>
</body>
</html>
39 changes: 39 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,42 @@
2017-03-24 Myles C. Maxfield <mmaxfield@apple.com>

Implement font-optical-sizing
https://bugs.webkit.org/show_bug.cgi?id=168895

Reviewed by Dean Jackson.

Upon advice from Microsoft, the only input to optical sizing is just the
font-size computed value. It is implemented by setting the 'opsz' font
variation axis. Because the propery has such a simple grammar, the
implementation is quite straightforward.

Test: fast/text/variations/optical-sizing.html

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::ComputedStyleExtractor::propertyValue):
* css/CSSPrimitiveValueMappings.h:
(WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
(WebCore::CSSPrimitiveValue::operator FontOpticalSizing):
* css/CSSProperties.json:
* css/parser/CSSParserFastPaths.cpp:
(WebCore::CSSParserFastPaths::isValidKeywordPropertyAndValue):
(WebCore::CSSParserFastPaths::isKeywordPropertyID):
* platform/graphics/FontCache.h:
(WebCore::FontDescriptionKey::makeFlagsKey):
* platform/graphics/FontDescription.h:
(WebCore::FontDescription::opticalSizing):
(WebCore::FontDescription::setOpticalSizing):
(WebCore::FontDescription::operator==):
(WebCore::FontCascadeDescription::initialOpticalSizing):
* platform/graphics/cocoa/FontCacheCoreText.cpp:
(WebCore::preparePlatformFont):
(WebCore::fontWithFamily):
(WebCore::FontCache::createFontPlatformData):
(WebCore::FontCache::systemFallbackForCharacters):
* platform/graphics/mac/FontCustomPlatformData.cpp:
(WebCore::FontCustomPlatformData::fontPlatformData):
* platform/text/TextFlags.h:

2017-03-24 Chris Dumez <cdumez@apple.com>

Unreviewed, rolling out r214329.
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/css/CSSComputedStyleDeclaration.cpp
Expand Up @@ -2949,6 +2949,8 @@ RefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID,
list->append(CSSFontVariationValue::create(feature.tag(), feature.value()));
return WTFMove(list);
}
case CSSPropertyFontOpticalSizing:
return cssValuePool.createValue(style->fontDescription().opticalSizing());
#endif
case CSSPropertyGridAutoFlow: {
auto list = CSSValueList::createSpaceSeparated();
Expand Down
32 changes: 32 additions & 0 deletions Source/WebCore/css/CSSPrimitiveValueMappings.h
Expand Up @@ -5616,4 +5616,36 @@ template<> inline CSSPrimitiveValue::operator FontVariantAlternates() const
return FontVariantAlternates::Normal;
}

template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontOpticalSizing sizing)
: CSSValue(PrimitiveClass)
{
m_primitiveUnitType = CSS_VALUE_ID;
switch (sizing) {
case FontOpticalSizing::Enabled:
m_value.valueID = CSSValueAuto;
break;
case FontOpticalSizing::Disabled:
m_value.valueID = CSSValueNone;
break;
default:
ASSERT_NOT_REACHED();
break;
}
}

template<> inline CSSPrimitiveValue::operator FontOpticalSizing() const
{
ASSERT(isValueID());
switch (m_value.valueID) {
case CSSValueAuto:
return FontOpticalSizing::Enabled;
case CSSValueNone:
return FontOpticalSizing::Disabled;
default:
break;
}
ASSERT_NOT_REACHED();
return FontOpticalSizing::Enabled;
}

}
111 changes: 64 additions & 47 deletions Source/WebCore/css/CSSProperties.json
Expand Up @@ -520,6 +520,70 @@
"url": "https://drafts.csswg.org/css-fonts-3/#font-variant-east-asian-prop"
}
},
"font-synthesis": {
"inherited": true,
"codegen-properties": {
"converter": "FontSynthesis",
"font-property": true,
"high-priority": true
},
"specification": {
"category": "css-fonts",
"url": "https://drafts.csswg.org/css-fonts-3/#font-synthesis-prop"
}
},
"font-optical-sizing": {
"inherited": true,
"values": [
"auto",
"none"
],
"codegen-properties": {
"name-for-methods": "OpticalSizing",
"font-property": true,
"high-priority": true,
"enable-if": "ENABLE_VARIATION_FONTS"
},
"specification": {
"category": "css-fonts",
"url": "https://drafts.csswg.org/css-fonts-4/#optical-sizing-control-the-font-optical-sizing-property"
}
},
"font": {
"inherited": true,
"codegen-properties": {
"longhands": [
"font-family",
"font-size",
"font-style",
"font-variant-caps",
"font-weight",
"font-stretch",
"line-height"
]
},
"specification": {
"category": "css-fonts",
"url": "https://www.w3.org/TR/css-fonts-3/#font-prop"
}
},
"font-variant": {
"inherited": true,
"codegen-properties": {
"longhands": [
"font-variant-ligatures",
"font-variant-position",
"font-variant-caps",
"font-variant-numeric",
"font-variant-alternates",
"font-variant-east-asian"
]
},
"specification": {
"category": "css-fonts",
"url": "https://www.w3.org/TR/css-fonts-3/#propdef-font-variant"
}
},
"-webkit-locale": {
"inherited": true,
"codegen-properties": {
Expand Down Expand Up @@ -655,18 +719,6 @@
"url": "https://msdn.microsoft.com/en-us/library/ms531189(v=vs.85).aspx"
}
},
"font-synthesis": {
"inherited": true,
"codegen-properties": {
"converter": "FontSynthesis",
"font-property": true,
"high-priority": true
},
"specification": {
"category": "css-fonts",
"url": "https://drafts.csswg.org/css-fonts-3/#font-synthesis-prop"
}
},
"-webkit-ruby-position": {
"inherited": true,
"values": [
Expand Down Expand Up @@ -2017,41 +2069,6 @@
"url": "https://www.w3.org/TR/SVG/filters.html#FloodOpacityProperty"
}
},
"font": {
"inherited": true,
"codegen-properties": {
"longhands": [
"font-family",
"font-size",
"font-style",
"font-variant-caps",
"font-weight",
"font-stretch",
"line-height"
]
},
"specification": {
"category": "css-fonts",
"url": "https://www.w3.org/TR/css-fonts-3/#font-prop"
}
},
"font-variant": {
"inherited": true,
"codegen-properties": {
"longhands": [
"font-variant-ligatures",
"font-variant-position",
"font-variant-caps",
"font-variant-numeric",
"font-variant-alternates",
"font-variant-east-asian"
]
},
"specification": {
"category": "css-fonts",
"url": "https://www.w3.org/TR/css-fonts-3/#propdef-font-variant"
}
},
"glyph-orientation-horizontal": {
"inherited": true,
"codegen-properties": {
Expand Down
7 changes: 7 additions & 0 deletions Source/WebCore/css/parser/CSSParserFastPaths.cpp
Expand Up @@ -799,6 +799,10 @@ bool CSSParserFastPaths::isValidKeywordPropertyAndValue(CSSPropertyID propertyId
#if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
case CSSPropertyWebkitOverflowScrolling:
return valueID == CSSValueAuto || valueID == CSSValueTouch;
#endif
#if ENABLE(VARIATION_FONTS)
case CSSPropertyFontOpticalSizing:
return valueID == CSSValueAuto || valueID == CSSValueNone;
#endif
default:
ASSERT_NOT_REACHED();
Expand Down Expand Up @@ -961,6 +965,9 @@ bool CSSParserFastPaths::isKeywordPropertyID(CSSPropertyID propertyId)
#if ENABLE(APPLE_PAY)
case CSSPropertyApplePayButtonStyle:
case CSSPropertyApplePayButtonType:
#endif
#if ENABLE(VARIATION_FONTS)
case CSSPropertyFontOpticalSizing:
#endif
return true;
case CSSPropertyJustifyContent:
Expand Down
5 changes: 3 additions & 2 deletions Source/WebCore/platform/graphics/FontCache.h
Expand Up @@ -122,7 +122,8 @@ struct FontDescriptionKey {
static std::array<unsigned, 2> makeFlagsKey(const FontDescription& description)
{
static_assert(USCRIPT_CODE_LIMIT < 0x1000, "Script code must fit in an unsigned along with the other flags");
unsigned first = static_cast<unsigned>(description.script()) << 11
unsigned first = static_cast<unsigned>(description.script()) << 12
| static_cast<unsigned>(description.opticalSizing()) << 11
| static_cast<unsigned>(description.textRenderingMode()) << 9
| static_cast<unsigned>(description.fontSynthesis()) << 6
| static_cast<unsigned>(description.widthVariant()) << 4
Expand Down Expand Up @@ -275,7 +276,7 @@ struct SynthesisPair {
bool needsSyntheticOblique;
};

RetainPtr<CTFontRef> preparePlatformFont(CTFontRef, TextRenderingMode, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, const FontFeatureSettings& features, const FontVariantSettings&, FontSelectionRequest, const FontVariationSettings&);
RetainPtr<CTFontRef> preparePlatformFont(CTFontRef, TextRenderingMode, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, const FontFeatureSettings& features, const FontVariantSettings&, FontSelectionRequest, const FontVariationSettings&, FontOpticalSizing, float size);
SynthesisPair computeNecessarySynthesis(CTFontRef, const FontDescription&, bool isPlatformFont = false);
RetainPtr<CTFontRef> platformFontWithFamilySpecialCase(const AtomicString& family, FontSelectionRequest, float size);
RetainPtr<CTFontRef> platformFontWithFamily(const AtomicString& family, FontSelectionRequest, TextRenderingMode, float size);
Expand Down
7 changes: 6 additions & 1 deletion Source/WebCore/platform/graphics/FontDescription.h
Expand Up @@ -95,6 +95,7 @@ class FontDescription {
variantEastAsianWidth(),
variantEastAsianRuby() };
}
FontOpticalSizing opticalSizing() const { return static_cast<FontOpticalSizing>(m_opticalSizing); }

void setComputedSize(float s) { m_computedSize = clampToFloat(s); }
void setItalic(FontSelectionValue italic) { m_fontSelectionRequest.slope = italic; }
Expand Down Expand Up @@ -127,6 +128,7 @@ class FontDescription {
void setVariantEastAsianVariant(FontVariantEastAsianVariant variant) { m_variantEastAsianVariant = static_cast<unsigned>(variant); }
void setVariantEastAsianWidth(FontVariantEastAsianWidth variant) { m_variantEastAsianWidth = static_cast<unsigned>(variant); }
void setVariantEastAsianRuby(FontVariantEastAsianRuby variant) { m_variantEastAsianRuby = static_cast<unsigned>(variant); }
void setOpticalSizing(FontOpticalSizing sizing) { m_opticalSizing = static_cast<unsigned>(sizing); }

private:
// FIXME: Investigate moving these into their own object on the heap (to save memory).
Expand Down Expand Up @@ -158,6 +160,7 @@ class FontDescription {
unsigned m_variantEastAsianVariant : 3; // FontVariantEastAsianVariant
unsigned m_variantEastAsianWidth : 2; // FontVariantEastAsianWidth
unsigned m_variantEastAsianRuby : 1; // FontVariantEastAsianRuby
unsigned m_opticalSizing : 1; // FontOpticalSizing
};

inline bool FontDescription::operator==(const FontDescription& other) const
Expand Down Expand Up @@ -189,7 +192,8 @@ inline bool FontDescription::operator==(const FontDescription& other) const
&& m_variantAlternates == other.m_variantAlternates
&& m_variantEastAsianVariant == other.m_variantEastAsianVariant
&& m_variantEastAsianWidth == other.m_variantEastAsianWidth
&& m_variantEastAsianRuby == other.m_variantEastAsianRuby;
&& m_variantEastAsianRuby == other.m_variantEastAsianRuby
&& m_opticalSizing == other.m_opticalSizing;
}

// FIXME: Move to a file of its own.
Expand Down Expand Up @@ -271,6 +275,7 @@ class FontCascadeDescription : public FontDescription {
static FontVariantPosition initialVariantPosition() { return FontVariantPosition::Normal; }
static FontVariantCaps initialVariantCaps() { return FontVariantCaps::Normal; }
static FontVariantAlternates initialVariantAlternates() { return FontVariantAlternates::Normal; }
static FontOpticalSizing initialOpticalSizing() { return FontOpticalSizing::Enabled; }
static const AtomicString& initialLocale() { return nullAtom; }

private:
Expand Down

0 comments on commit b6365ca

Please sign in to comment.