Skip to content

Commit

Permalink
[CSS] @font-palette-values family-name supports multiple values
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=252569
rdar://105975619

Reviewed by Tim Nguyen.

This patch allows @font-palette-values family-name descriptor to have
a list of family names (per spec).

https://drafts.csswg.org/css-fonts-4/#family-name-syntax

* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/font-palette-36-expected.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/font-palette-36-ref.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/font-palette-36.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/parsing/font-palette-values-invalid-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-fonts/parsing/font-palette-values-valid-expected.txt:
* Source/WebCore/css/CSSFontPaletteValuesRule.cpp:
(WebCore::CSSFontPaletteValuesRule::fontFamily const):
(WebCore::CSSFontPaletteValuesRule::cssText const):
(WebCore::CSSFontPaletteValuesRule::~CSSFontPaletteValuesRule): Deleted.
* Source/WebCore/css/CSSFontSelector.cpp:
(WebCore::CSSFontSelector::addFontPaletteValuesRule):
* Source/WebCore/css/CSSProperties.json:
* Source/WebCore/css/StyleRule.cpp:
(WebCore::StyleRuleFontPaletteValues::create):
(WebCore::StyleRuleFontPaletteValues::StyleRuleFontPaletteValues):
* Source/WebCore/css/StyleRule.h:
* Source/WebCore/css/parser/CSSParserImpl.cpp:
(WebCore::CSSParserImpl::consumeFontFeatureValuesRule):
(WebCore::CSSParserImpl::consumeFontPaletteValuesRule):
* Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::consumeFamilyNameListRaw):
(WebCore::CSSPropertyParserHelpers::consumeFamilyNameList):
* Source/WebCore/css/parser/CSSPropertyParserHelpers.h:

Canonical link: https://commits.webkit.org/267411@main
  • Loading branch information
mdubet committed Aug 29, 2023
1 parent f577450 commit 83db139
Show file tree
Hide file tree
Showing 13 changed files with 136 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
@font-face {
font-family: "COLR-test-font";
src: url("resources/COLR-palettes-test-font.ttf") format("truetype");
}

@font-palette-values --MyPalette {
font-family: "COLR-test-font";
base-palette: 2;
}
</style>
</head>
<body>
<div style="font: 48px 'COLR-test-font'; font-palette: --MyPalette">A</div>
<div style="font: 48px 'COLR-test-font'; font-palette: --MyPalette">A</div>
<div style="font: 48px 'COLR-test-font'; font-palette: --MyPalette">A</div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
@font-face {
font-family: "COLR-test-font";
src: url("resources/COLR-palettes-test-font.ttf") format("truetype");
}

@font-palette-values --MyPalette {
font-family: "COLR-test-font";
base-palette: 2;
}
</style>
</head>
<body>
<div style="font: 48px 'COLR-test-font'; font-palette: --MyPalette">A</div>
<div style="font: 48px 'COLR-test-font'; font-palette: --MyPalette">A</div>
<div style="font: 48px 'COLR-test-font'; font-palette: --MyPalette">A</div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>font-palette multiple family-name and @font-palette-values</title>
<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-palette-prop">
<link rel="help" href="https://drafts.csswg.org/css-fonts-4/#font-palette-values">
<link rel="match" href="font-palette-36-ref.html">
<style>
@font-face {
font-family: "COLR-test-font";
src: url("resources/COLR-palettes-test-font.ttf") format("truetype");
}
@font-face {
font-family: "foo bar";
src: url("resources/COLR-palettes-test-font.ttf") format("truetype");
}
@font-face {
font-family: foo;
src: url("resources/COLR-palettes-test-font.ttf") format("truetype");
}
@font-palette-values --MyPalette {
font-family: "COLR-test-font", "foo bar", foo;
base-palette: light;
}
</style>
</head>
<body>
<div style="font: 48px 'COLR-test-font'; font-palette: --MyPalette;">A</div>
<div style="font: 48px foo; font-palette: --MyPalette;">A</div>
<div style="font: 48px 'foo bar'; font-palette: --MyPalette;">A</div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

PASS CSS Fonts Module Level 4: parsing @font-palette-values
PASS CSS Fonts Module Level 4: parsing @font-palette-values 1
FAIL CSS Fonts Module Level 4: parsing @font-palette-values 1 assert_equals: expected -1 but got 27
PASS CSS Fonts Module Level 4: parsing @font-palette-values 2
PASS CSS Fonts Module Level 4: parsing @font-palette-values 3
PASS CSS Fonts Module Level 4: parsing @font-palette-values 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@ PASS CSS Fonts Module Level 4: parsing @font-palette-values 28
PASS CSS Fonts Module Level 4: parsing @font-palette-values 29
PASS CSS Fonts Module Level 4: parsing @font-palette-values 30
PASS CSS Fonts Module Level 4: parsing @font-palette-values 31
FAIL CSS Fonts Module Level 4: parsing @font-palette-values 32 assert_equals: expected "foo, bar, baz" but got ""
PASS CSS Fonts Module Level 4: parsing @font-palette-values 32

16 changes: 9 additions & 7 deletions Source/WebCore/css/CSSFontPaletteValuesRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "StyleProperties.h"
#include "StyleRule.h"
#include <wtf/text/StringBuilder.h>
#include <wtf/text/WTFString.h>

namespace WebCore {

Expand All @@ -42,9 +43,7 @@ CSSFontPaletteValuesRule::CSSFontPaletteValuesRule(StyleRuleFontPaletteValues& f
{
}

CSSFontPaletteValuesRule::~CSSFontPaletteValuesRule()
{
}
CSSFontPaletteValuesRule::~CSSFontPaletteValuesRule() = default;

String CSSFontPaletteValuesRule::name() const
{
Expand All @@ -53,7 +52,10 @@ String CSSFontPaletteValuesRule::name() const

String CSSFontPaletteValuesRule::fontFamily() const
{
return m_fontPaletteValuesRule->fontFamily();
auto serialize = [] (auto& family) {
return serializeFontFamily(family.string());
};
return makeStringByJoining(m_fontPaletteValuesRule->fontFamilies().map(serialize).span(), ", "_s);
}

String CSSFontPaletteValuesRule::basePalette() const
Expand Down Expand Up @@ -87,9 +89,9 @@ String CSSFontPaletteValuesRule::overrideColors() const
String CSSFontPaletteValuesRule::cssText() const
{
StringBuilder builder;
builder.append("@font-palette-values ", m_fontPaletteValuesRule->name(), " { ");
if (!m_fontPaletteValuesRule->fontFamily().isNull())
builder.append("font-family: ", m_fontPaletteValuesRule->fontFamily(), "; ");
builder.append("@font-palette-values ", name(), " { ");
if (!m_fontPaletteValuesRule->fontFamilies().isEmpty())
builder.append("font-family: ", fontFamily(), "; ");

if (m_fontPaletteValuesRule->basePalette()) {
switch (m_fontPaletteValuesRule->basePalette()->type) {
Expand Down
7 changes: 4 additions & 3 deletions Source/WebCore/css/CSSFontSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,12 @@ void CSSFontSelector::addFontPaletteValuesRule(const StyleRuleFontPaletteValues&
auto& name = fontPaletteValuesRule.name();
ASSERT(!name.isNull());

auto& fontFamily = fontPaletteValuesRule.fontFamily();
if (fontFamily.isNull())
auto& fontFamilies = fontPaletteValuesRule.fontFamilies();
if (fontFamilies.isEmpty())
return;

m_paletteMap.set(std::make_pair(fontFamily, name), fontPaletteValuesRule.fontPaletteValues());
for (auto& fontFamily : fontFamilies)
m_paletteMap.set(std::make_pair(fontFamily, name), fontPaletteValuesRule.fontPaletteValues());

++m_version;
}
Expand Down
6 changes: 3 additions & 3 deletions Source/WebCore/css/CSSProperties.json
Original file line number Diff line number Diff line change
Expand Up @@ -9686,13 +9686,13 @@
"@font-palette-values": {
"font-family": {
"codegen-properties": {
"parser-function": "consumeFamilyName",
"parser-grammar-unused": "<family-name>",
"parser-function": "consumeFamilyNameList",
"parser-grammar-unused": "<family-name>#",
"parser-grammar-unused-reason": "Needs support for special 'family-name' processing."
},
"specification": {
"category": "css-fonts-4",
"url": "https://www.w3.org/TR/css-fonts-4/#font-family-2-desc"
"url": "https://drafts.csswg.org/css-fonts-4/#font-family-2-desc"
}
},
"base-palette": {
Expand Down
8 changes: 4 additions & 4 deletions Source/WebCore/css/StyleRule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,15 +411,15 @@ Ref<StyleRuleFontFeatureValues> StyleRuleFontFeatureValues::create(const Vector<
return adoptRef(*new StyleRuleFontFeatureValues(fontFamilies, WTFMove(values)));
}

Ref<StyleRuleFontPaletteValues> StyleRuleFontPaletteValues::create(const AtomString& name, const AtomString& fontFamily, std::optional<FontPaletteIndex> basePalette, Vector<FontPaletteValues::OverriddenColor>&& overrideColors)
Ref<StyleRuleFontPaletteValues> StyleRuleFontPaletteValues::create(const AtomString& name, Vector<AtomString>&& fontFamilies, std::optional<FontPaletteIndex> basePalette, Vector<FontPaletteValues::OverriddenColor>&& overrideColors)
{
return adoptRef(*new StyleRuleFontPaletteValues(name, fontFamily, basePalette, WTFMove(overrideColors)));
return adoptRef(*new StyleRuleFontPaletteValues(name, WTFMove(fontFamilies), basePalette, WTFMove(overrideColors)));
}

StyleRuleFontPaletteValues::StyleRuleFontPaletteValues(const AtomString& name, const AtomString& fontFamily, std::optional<FontPaletteIndex> basePalette, Vector<FontPaletteValues::OverriddenColor>&& overrideColors)
StyleRuleFontPaletteValues::StyleRuleFontPaletteValues(const AtomString& name, Vector<AtomString>&& fontFamilies, std::optional<FontPaletteIndex> basePalette, Vector<FontPaletteValues::OverriddenColor>&& overrideColors)
: StyleRuleBase(StyleRuleType::FontPaletteValues)
, m_name(name)
, m_fontFamily(fontFamily)
, m_fontFamilies(WTFMove(fontFamilies))
, m_fontPaletteValues(basePalette, WTFMove(overrideColors))
{
}
Expand Down
8 changes: 4 additions & 4 deletions Source/WebCore/css/StyleRule.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,22 +196,22 @@ class StyleRuleFontFace final : public StyleRuleBase {

class StyleRuleFontPaletteValues final : public StyleRuleBase {
public:
static Ref<StyleRuleFontPaletteValues> create(const AtomString& name, const AtomString& fontFamily, std::optional<FontPaletteIndex> basePalette, Vector<FontPaletteValues::OverriddenColor>&&);
static Ref<StyleRuleFontPaletteValues> create(const AtomString& name, Vector<AtomString>&& fontFamilies, std::optional<FontPaletteIndex> basePalette, Vector<FontPaletteValues::OverriddenColor>&&);

const AtomString& name() const { return m_name; }
const AtomString& fontFamily() const { return m_fontFamily; }
const Vector<AtomString>& fontFamilies() const { return m_fontFamilies; }
const FontPaletteValues& fontPaletteValues() const { return m_fontPaletteValues; }
std::optional<FontPaletteIndex> basePalette() const { return m_fontPaletteValues.basePalette(); }
const Vector<FontPaletteValues::OverriddenColor>& overrideColors() const { return m_fontPaletteValues.overrideColors(); }

Ref<StyleRuleFontPaletteValues> copy() const { return adoptRef(*new StyleRuleFontPaletteValues(*this)); }

private:
StyleRuleFontPaletteValues(const AtomString& name, const AtomString& fontFamily, std::optional<FontPaletteIndex> basePalette, Vector<FontPaletteValues::OverriddenColor>&& overrideColors);
StyleRuleFontPaletteValues(const AtomString& name, Vector<AtomString>&& fontFamilies, std::optional<FontPaletteIndex> basePalette, Vector<FontPaletteValues::OverriddenColor>&& overrideColors);
StyleRuleFontPaletteValues(const StyleRuleFontPaletteValues&) = default;

AtomString m_name;
AtomString m_fontFamily;
Vector<AtomString> m_fontFamilies;
FontPaletteValues m_fontPaletteValues;
};

Expand Down
29 changes: 22 additions & 7 deletions Source/WebCore/css/parser/CSSParserImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@
#include "StyleRule.h"
#include "StyleRuleImport.h"
#include "StyleSheetContents.h"
#include "css/CSSValueList.h"
#include <bitset>
#include <memory>
#include <optional>

namespace WebCore {

Expand Down Expand Up @@ -762,7 +764,7 @@ RefPtr<StyleRuleFontFeatureValues> CSSParserImpl::consumeFontFeatureValuesRule(C
// @font-feature-values <family-name># { <declaration-list> }

auto originalPrelude = prelude;
auto fontFamilies = CSSPropertyParserHelpers::consumeFamilyNameList(prelude);
auto fontFamilies = CSSPropertyParserHelpers::consumeFamilyNameListRaw(prelude);
if (fontFamilies.isEmpty() || !prelude.atEnd())
return nullptr;

Expand Down Expand Up @@ -811,14 +813,27 @@ RefPtr<StyleRuleFontPaletteValues> CSSParserImpl::consumeFontPaletteValuesRule(C
auto declarations = consumeDeclarationListInNewNestingContext(block, StyleRuleType::FontPaletteValues);
auto properties = createStyleProperties(declarations, m_context.mode);

auto fontFamily = [&] () -> AtomString {
auto fontFamilies = [&] {
Vector<AtomString> fontFamilies;
auto append = [&] (auto& value) {
if (value.isFontFamily())
fontFamilies.append(AtomString { value.stringValue() });
};
auto cssFontFamily = properties->getPropertyCSSValue(CSSPropertyFontFamily);
if (!cssFontFamily)
return { };
return fontFamilies;
auto cssPrimitiveFontFamilies = dynamicDowncast<CSSValueList>(*cssFontFamily);
if (cssPrimitiveFontFamilies) {
for (auto& item : *cssPrimitiveFontFamilies)
append(downcast<CSSPrimitiveValue>(item));
return fontFamilies;
}

auto cssPrimitiveFontFamily = dynamicDowncast<CSSPrimitiveValue>(*cssFontFamily);
if (!cssPrimitiveFontFamily || !cssPrimitiveFontFamily->isFontFamily())
return { };
return AtomString { cssPrimitiveFontFamily->stringValue() };
if (!cssPrimitiveFontFamily)
return fontFamilies;
append(*cssPrimitiveFontFamily);
return fontFamilies;
}();

std::optional<FontPaletteIndex> basePalette;
Expand All @@ -845,7 +860,7 @@ RefPtr<StyleRuleFontPaletteValues> CSSParserImpl::consumeFontPaletteValuesRule(C
}
}

return StyleRuleFontPaletteValues::create(AtomString { name->stringValue() }, fontFamily, WTFMove(basePalette), WTFMove(overrideColors));
return StyleRuleFontPaletteValues::create(AtomString { name->stringValue() }, WTFMove(fontFamilies), WTFMove(basePalette), WTFMove(overrideColors));
}

RefPtr<StyleRuleKeyframes> CSSParserImpl::consumeKeyframesRule(CSSParserTokenRange prelude, CSSParserTokenRange block)
Expand Down
10 changes: 9 additions & 1 deletion Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
#include "CSSTimingFunctionValue.h"
#include "CSSTransformListValue.h"
#include "CSSUnresolvedColor.h"
#include "CSSValueKeywords.h"
#include "CSSValuePair.h"
#include "CSSValuePool.h"
#include "CSSVariableData.h"
Expand Down Expand Up @@ -4884,7 +4885,7 @@ AtomString consumeFamilyNameRaw(CSSParserTokenRange& range)
return concatenateFamilyName(range);
}

Vector<AtomString> consumeFamilyNameList(CSSParserTokenRange& range)
Vector<AtomString> consumeFamilyNameListRaw(CSSParserTokenRange& range)
{
Vector<AtomString> result;
do {
Expand Down Expand Up @@ -5518,6 +5519,13 @@ RefPtr<CSSValue> consumeFamilyName(CSSParserTokenRange& range)
return CSSValuePool::singleton().createFontFamilyValue(familyName);
}

RefPtr<CSSValue> consumeFamilyNameList(CSSParserTokenRange& range)
{
return consumeCommaSeparatedListWithoutSingleValueOptimization(range, [] (auto& range) {
return consumeFamilyName(range);
});
}

static RefPtr<CSSValue> consumeGenericFamily(CSSParserTokenRange& range)
{
return consumeIdentRange(range, CSSValueSerif, CSSValueWebkitBody);
Expand Down
3 changes: 2 additions & 1 deletion Source/WebCore/css/parser/CSSPropertyParserHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ std::optional<CSSValueID> consumeFontStretchKeywordValueRaw(CSSParserTokenRange&
AtomString concatenateFamilyName(CSSParserTokenRange&);
AtomString consumeFamilyNameRaw(CSSParserTokenRange&);
// https://drafts.csswg.org/css-fonts-4/#family-name-value
Vector<AtomString> consumeFamilyNameList(CSSParserTokenRange&);
Vector<AtomString> consumeFamilyNameListRaw(CSSParserTokenRange&);
RefPtr<CSSValue> consumeFamilyNameList(CSSParserTokenRange&);
std::optional<FontRaw> consumeFontRaw(CSSParserTokenRange&, CSSParserMode);
const AtomString& genericFontFamily(CSSValueID);
WebKitFontFamilyNames::FamilyNamesIndex genericFontFamilyIndex(CSSValueID);
Expand Down

0 comments on commit 83db139

Please sign in to comment.