Changeset 269957 in webkit


Ignore:
Timestamp:
Nov 18, 2020 8:03:50 AM (3 years ago)
Author:
Chris Lord
Message:

Make CSS font shorthands parsable within a worker (i.e. without CSSValuePool)
https://bugs.webkit.org/show_bug.cgi?id=202794

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

  • web-platform-tests/html/canvas/element/text-styles/2d.text.font.parse.invalid-expected.txt:

Source/WebCore:

Add functions to make it possible to parse CSS font shorthand
properties without using CSS values, so it can be done safely off of
the main thread. To support and test this, also add functions to make
it possible to resolve those properties into a style without
StyleBuilder and use that within CanvasRenderingContext2D.

No new tests, covered by existing tests.

  • Sources.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • css/parser/CSSParser.cpp:

(WebCore::CSSParser::parseFontWorkerSafe):

  • css/parser/CSSParser.h:
  • css/parser/CSSPropertyParser.cpp:

(WebCore::consumeFontWeight):
(WebCore::consumeFontStretchKeywordValue):
(WebCore::consumeFontStyle):
(WebCore::consumeFamilyName):

  • css/parser/CSSPropertyParser.h:
  • css/parser/CSSPropertyParserHelpers.cpp:

(WebCore::CSSPropertyParserHelpers::CalcParser::consumePercentRaw):
(WebCore::CSSPropertyParserHelpers::CalcParser::consumeAngleRaw):
(WebCore::CSSPropertyParserHelpers::CalcParser::consumeLengthRaw):
(WebCore::CSSPropertyParserHelpers::CalcParser::consumeLengthOrPercentRaw):
(WebCore::CSSPropertyParserHelpers::consumeNumberRaw):
(WebCore::CSSPropertyParserHelpers::consumeNumber):
(WebCore::CSSPropertyParserHelpers::consumeFontWeightNumberRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontWeightNumber):
(WebCore::CSSPropertyParserHelpers::consumeLengthRaw):
(WebCore::CSSPropertyParserHelpers::consumeLength):
(WebCore::CSSPropertyParserHelpers::consumePercent):
(WebCore::CSSPropertyParserHelpers::consumeLengthOrPercentRaw):
(WebCore::CSSPropertyParserHelpers::consumeLengthOrPercent):
(WebCore::CSSPropertyParserHelpers::consumeAngleRaw):
(WebCore::CSSPropertyParserHelpers::consumeIdentRaw):
(WebCore::CSSPropertyParserHelpers::consumeIdent):
(WebCore::CSSPropertyParserHelpers::consumeIdentRangeRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontVariantCSS21Raw):
(WebCore::CSSPropertyParserHelpers::consumeFontWeightKeywordValueRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontWeightRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontStretchKeywordValueRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontStyleKeywordValueRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontStyleRaw):
(WebCore::CSSPropertyParserHelpers::concatenateFamilyName):
(WebCore::CSSPropertyParserHelpers::consumeFamilyNameRaw):
(WebCore::CSSPropertyParserHelpers::consumeGenericFamilyRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontFamilyRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontSizeRaw):
(WebCore::CSSPropertyParserHelpers::consumeLineHeightRaw):
(WebCore::CSSPropertyParserHelpers::consumeFontWorkerSafe):
(WebCore::CSSPropertyParserHelpers::genericFontFamilyFromValueID):

  • css/parser/CSSPropertyParserHelpers.h:

(WebCore::CSSPropertyParserHelpers::consumeIdentRaw):

  • html/canvas/CanvasRenderingContext2D.cpp:

(WebCore::CanvasRenderingContext2D::setFont):

  • style/StyleBuilderCustom.h:

(WebCore::Style::BuilderCustom::applyValueFontFamily):

  • style/StyleResolveForFontRaw.cpp: Added.

(WebCore::Style::resolveForFontRaw):

  • style/StyleResolveForFontRaw.h: Added.
Location:
trunk
Files:
2 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r269950 r269957  
     12020-11-18  Chris Lord  <clord@igalia.com>
     2
     3        Make CSS font shorthands parsable within a worker (i.e. without CSSValuePool)
     4        https://bugs.webkit.org/show_bug.cgi?id=202794
     5
     6        Reviewed by Darin Adler.
     7
     8        * web-platform-tests/html/canvas/element/text-styles/2d.text.font.parse.invalid-expected.txt:
     9
    1102020-11-18  Commit Queue  <commit-queue@webkit.org>
    211
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/canvas/element/text-styles/2d.text.font.parse.invalid-expected.txt

    r269598 r269957  
    22Actual output:
    33
    4 FAIL Canvas test: 2d.text.font.parse.invalid assert_equals: ctx.font === '20px serif' (got 13px sans-serif[string], expected 20px serif[string]) expected "20px serif" but got "13px sans-serif"
     4PASS Canvas test: 2d.text.font.parse.invalid
    55
  • trunk/Source/WebCore/ChangeLog

    r269955 r269957  
     12020-11-18  Chris Lord  <clord@igalia.com>
     2
     3        Make CSS font shorthands parsable within a worker (i.e. without CSSValuePool)
     4        https://bugs.webkit.org/show_bug.cgi?id=202794
     5
     6        Reviewed by Darin Adler.
     7
     8        Add functions to make it possible to parse CSS font shorthand
     9        properties without using CSS values, so it can be done safely off of
     10        the main thread. To support and test this, also add functions to make
     11        it possible to resolve those properties into a style without
     12        StyleBuilder and use that within CanvasRenderingContext2D.
     13
     14        No new tests, covered by existing tests.
     15
     16        * Sources.txt:
     17        * WebCore.xcodeproj/project.pbxproj:
     18        * css/parser/CSSParser.cpp:
     19        (WebCore::CSSParser::parseFontWorkerSafe):
     20        * css/parser/CSSParser.h:
     21        * css/parser/CSSPropertyParser.cpp:
     22        (WebCore::consumeFontWeight):
     23        (WebCore::consumeFontStretchKeywordValue):
     24        (WebCore::consumeFontStyle):
     25        (WebCore::consumeFamilyName):
     26        * css/parser/CSSPropertyParser.h:
     27        * css/parser/CSSPropertyParserHelpers.cpp:
     28        (WebCore::CSSPropertyParserHelpers::CalcParser::consumePercentRaw):
     29        (WebCore::CSSPropertyParserHelpers::CalcParser::consumeAngleRaw):
     30        (WebCore::CSSPropertyParserHelpers::CalcParser::consumeLengthRaw):
     31        (WebCore::CSSPropertyParserHelpers::CalcParser::consumeLengthOrPercentRaw):
     32        (WebCore::CSSPropertyParserHelpers::consumeNumberRaw):
     33        (WebCore::CSSPropertyParserHelpers::consumeNumber):
     34        (WebCore::CSSPropertyParserHelpers::consumeFontWeightNumberRaw):
     35        (WebCore::CSSPropertyParserHelpers::consumeFontWeightNumber):
     36        (WebCore::CSSPropertyParserHelpers::consumeLengthRaw):
     37        (WebCore::CSSPropertyParserHelpers::consumeLength):
     38        (WebCore::CSSPropertyParserHelpers::consumePercent):
     39        (WebCore::CSSPropertyParserHelpers::consumeLengthOrPercentRaw):
     40        (WebCore::CSSPropertyParserHelpers::consumeLengthOrPercent):
     41        (WebCore::CSSPropertyParserHelpers::consumeAngleRaw):
     42        (WebCore::CSSPropertyParserHelpers::consumeIdentRaw):
     43        (WebCore::CSSPropertyParserHelpers::consumeIdent):
     44        (WebCore::CSSPropertyParserHelpers::consumeIdentRangeRaw):
     45        (WebCore::CSSPropertyParserHelpers::consumeFontVariantCSS21Raw):
     46        (WebCore::CSSPropertyParserHelpers::consumeFontWeightKeywordValueRaw):
     47        (WebCore::CSSPropertyParserHelpers::consumeFontWeightRaw):
     48        (WebCore::CSSPropertyParserHelpers::consumeFontStretchKeywordValueRaw):
     49        (WebCore::CSSPropertyParserHelpers::consumeFontStyleKeywordValueRaw):
     50        (WebCore::CSSPropertyParserHelpers::consumeFontStyleRaw):
     51        (WebCore::CSSPropertyParserHelpers::concatenateFamilyName):
     52        (WebCore::CSSPropertyParserHelpers::consumeFamilyNameRaw):
     53        (WebCore::CSSPropertyParserHelpers::consumeGenericFamilyRaw):
     54        (WebCore::CSSPropertyParserHelpers::consumeFontFamilyRaw):
     55        (WebCore::CSSPropertyParserHelpers::consumeFontSizeRaw):
     56        (WebCore::CSSPropertyParserHelpers::consumeLineHeightRaw):
     57        (WebCore::CSSPropertyParserHelpers::consumeFontWorkerSafe):
     58        (WebCore::CSSPropertyParserHelpers::genericFontFamilyFromValueID):
     59        * css/parser/CSSPropertyParserHelpers.h:
     60        (WebCore::CSSPropertyParserHelpers::consumeIdentRaw):
     61        * html/canvas/CanvasRenderingContext2D.cpp:
     62        (WebCore::CanvasRenderingContext2D::setFont):
     63        * style/StyleBuilderCustom.h:
     64        (WebCore::Style::BuilderCustom::applyValueFontFamily):
     65        * style/StyleResolveForFontRaw.cpp: Added.
     66        (WebCore::Style::resolveForFontRaw):
     67        * style/StyleResolveForFontRaw.h: Added.
     68
    1692020-11-18  Michael Catanzaro  <mcatanzaro@gnome.org>
    270
  • trunk/Source/WebCore/Sources.txt

    r269880 r269957  
    24282428style/StyleRelations.cpp
    24292429style/StyleResolveForDocument.cpp
     2430style/StyleResolveForFontRaw.cpp
    24302431style/StyleResolver.cpp
    24312432style/StyleScope.cpp
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r269953 r269957  
    51375137                E4D33F46252C50FC00837D05 /* LayoutIntegrationLineIteratorModernPath.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D33F45252C50FB00837D05 /* LayoutIntegrationLineIteratorModernPath.h */; };
    51385138                E4D58EB517B4DBDC00CBDCA8 /* StyleResolveForDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EB317B4DBDC00CBDCA8 /* StyleResolveForDocument.h */; };
     5139                E4D68EB517B4DBDC00CBDCA8 /* StyleResolveForFontRaw.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D68EB317B4DBDC00CBDCA8 /* StyleResolveForFontRaw.h */; };
    51395140                E4D58EB917B4ED8900CBDCA8 /* StyleFontSizeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EB717B4ED8900CBDCA8 /* StyleFontSizeFunctions.h */; };
    51405141                E4D58EBB17B8F12800CBDCA8 /* ElementTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EBA17B8F12800CBDCA8 /* ElementTraversal.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    1628716288                E4D58EB217B4DBDC00CBDCA8 /* StyleResolveForDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleResolveForDocument.cpp; sourceTree = "<group>"; };
    1628816289                E4D58EB317B4DBDC00CBDCA8 /* StyleResolveForDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleResolveForDocument.h; sourceTree = "<group>"; };
     16290                E4D68EB217B4DBDC00CBDCA8 /* StyleResolveForFontRaw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleResolveForFontRaw.cpp; sourceTree = "<group>"; };
     16291                E4D68EB317B4DBDC00CBDCA8 /* StyleResolveForFontRaw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleResolveForFontRaw.h; sourceTree = "<group>"; };
    1628916292                E4D58EB617B4ED8900CBDCA8 /* StyleFontSizeFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleFontSizeFunctions.cpp; sourceTree = "<group>"; };
    1629016293                E4D58EB717B4ED8900CBDCA8 /* StyleFontSizeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleFontSizeFunctions.h; sourceTree = "<group>"; };
     
    2886828871                                E4D58EB217B4DBDC00CBDCA8 /* StyleResolveForDocument.cpp */,
    2886928872                                E4D58EB317B4DBDC00CBDCA8 /* StyleResolveForDocument.h */,
     28873                                E4D68EB217B4DBDC00CBDCA8 /* StyleResolveForFontRaw.cpp */,
     28874                                E4D68EB317B4DBDC00CBDCA8 /* StyleResolveForFontRaw.h */,
    2887028875                                E139866115478474001E3F65 /* StyleResolver.cpp */,
    2887128876                                E139866215478474001E3F65 /* StyleResolver.h */,
     
    3451934524                                E461802D1C8DD2900026C02C /* StyleRelations.h in Headers */,
    3452034525                                E4D58EB517B4DBDC00CBDCA8 /* StyleResolveForDocument.h in Headers */,
     34526                                E4D68EB517B4DBDC00CBDCA8 /* StyleResolveForFontRaw.h in Headers */,
    3452134527                                E139866415478474001E3F65 /* StyleResolver.h in Headers */,
    3452234528                                E4BBED4D14FCDBA1003F0B98 /* StyleRule.h in Headers */,
  • trunk/Source/WebCore/css/parser/CSSParser.cpp

    r268741 r269957  
    139139}
    140140
     141Optional<CSSPropertyParserHelpers::FontRaw> CSSParser::parseFontWorkerSafe(const String& string, CSSParserMode cssParserMode)
     142{
     143    CSSTokenizer tokenizer(string);
     144    CSSParserTokenRange range(tokenizer.tokenRange());
     145    range.consumeWhitespace();
     146
     147    return CSSPropertyParserHelpers::consumeFontWorkerSafe(range, cssParserMode);
     148}
     149
    141150RefPtr<CSSValue> CSSParser::parseSingleValue(CSSPropertyID propertyID, const String& string, const CSSParserContext& context)
    142151{
  • trunk/Source/WebCore/css/parser/CSSParser.h

    r268741 r269957  
    4444class RenderStyle;
    4545template<typename> struct SRGBA;
     46
     47namespace CSSPropertyParserHelpers {
     48struct FontRaw;
     49}
    4650
    4751namespace Style {
     
    9397    static Optional<SRGBA<uint8_t>> parseHexColor(StringView);
    9498
     99    static Optional<CSSPropertyParserHelpers::FontRaw> parseFontWorkerSafe(const String&, CSSParserMode = HTMLStandardMode);
     100
    95101private:
    96102    ParseResult parseValue(MutableStyleProperties&, CSSPropertyID, const String&, bool important);
  • trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp

    r269820 r269957  
    5555#include "CSSPendingSubstitutionValue.h"
    5656#include "CSSPrimitiveValueMappings.h"
    57 #include "CSSPropertyParserHelpers.h"
    5857#include "CSSReflectValue.h"
    5958#include "CSSShadowValue.h"
     
    865864}
    866865
    867 static RefPtr<CSSPrimitiveValue> consumeFontWeightKeywordValue(CSSParserTokenRange& range)
    868 {
    869     return consumeIdent<CSSValueNormal, CSSValueBold, CSSValueBolder, CSSValueLighter>(range);
    870 }
    871 
    872866static RefPtr<CSSPrimitiveValue> consumeFontWeight(CSSParserTokenRange& range)
    873867{
    874     if (auto result = consumeFontWeightKeywordValue(range))
    875         return result;
    876     return consumeFontWeightNumber(range);
     868    if (auto result = consumeFontWeightRaw(range)) {
     869        return switchOn(*result, [] (CSSValueID valueID) {
     870            return CSSValuePool::singleton().createIdentifierValue(valueID);
     871        }, [] (double weightNumber) {
     872            return CSSValuePool::singleton().createValue(weightNumber, CSSUnitType::CSS_NUMBER);
     873        });
     874    }
     875    return nullptr;
    877876}
    878877
     
    911910static RefPtr<CSSPrimitiveValue> consumeFontStretchKeywordValue(CSSParserTokenRange& range)
    912911{
    913     return consumeIdent<CSSValueUltraCondensed, CSSValueExtraCondensed, CSSValueCondensed, CSSValueSemiCondensed, CSSValueNormal, CSSValueSemiExpanded, CSSValueExpanded, CSSValueExtraExpanded, CSSValueUltraExpanded>(range);
     912    if (auto valueID = consumeFontStretchKeywordValueRaw(range))
     913        return CSSValuePool::singleton().createIdentifierValue(*valueID);
     914    return nullptr;
    914915}
    915916
     
    966967static RefPtr<CSSFontStyleValue> consumeFontStyle(CSSParserTokenRange& range, CSSParserMode cssParserMode)
    967968{
    968     auto result = consumeFontStyleKeywordValue(range);
    969     if (!result)
    970         return nullptr;
    971 
    972     auto valueID = result->valueID();
    973     if (valueID == CSSValueNormal || valueID == CSSValueItalic)
    974         return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(valueID));
    975     ASSERT(result->valueID() == CSSValueOblique);
     969    if (auto result = consumeFontStyleRaw(range, cssParserMode)) {
    976970#if ENABLE(VARIATION_FONTS)
    977     if (!range.atEnd()) {
    978         if (auto angle = consumeAngle(range, cssParserMode)) {
    979             if (fontStyleIsWithinRange(angle->value<float>(CSSUnitType::CSS_DEG)))
    980                 return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(CSSValueOblique), WTFMove(angle));
    981             return nullptr;
    982         }
    983     }
    984 #else
    985     UNUSED_PARAM(cssParserMode);
     971        if (result->style == CSSValueOblique && result->angle) {
     972            return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(CSSValueOblique),
     973                CSSValuePool::singleton().createValue(result->angle->value, result->angle->type));
     974        }
    986975#endif
    987     return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(CSSValueOblique));
     976        return CSSFontStyleValue::create(CSSValuePool::singleton().createIdentifierValue(result->style));
     977    }
     978    return nullptr;
    988979}
    989980
     
    10191010#endif
    10201011
    1021 static String concatenateFamilyName(CSSParserTokenRange& range)
    1022 {
    1023     StringBuilder builder;
    1024     bool addedSpace = false;
    1025     const CSSParserToken& firstToken = range.peek();
    1026     while (range.peek().type() == IdentToken) {
    1027         if (!builder.isEmpty()) {
    1028             builder.append(' ');
    1029             addedSpace = true;
    1030         }
    1031         builder.append(range.consumeIncludingWhitespace().value());
    1032     }
    1033     if (!addedSpace && isCSSWideKeyword(firstToken.id()))
    1034         return String();
    1035     return builder.toString();
    1036 }
    1037 
    10381012static RefPtr<CSSValue> consumeFamilyName(CSSParserTokenRange& range)
    10391013{
    1040     if (range.peek().type() == StringToken)
    1041         return CSSValuePool::singleton().createFontFamilyValue(range.consumeIncludingWhitespace().value().toString());
    1042     if (range.peek().type() != IdentToken)
    1043         return nullptr;
    1044     String familyName = concatenateFamilyName(range);
     1014    auto familyName = consumeFamilyNameRaw(range);
    10451015    if (familyName.isNull())
    10461016        return nullptr;
  • trunk/Source/WebCore/css/parser/CSSPropertyParser.h

    r254373 r269957  
    2424
    2525#include "CSSParserTokenRange.h"
     26#include "CSSPropertyParserHelpers.h"
    2627#include "StyleRule.h"
    2728#include <wtf/text/StringView.h>
  • trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp

    r269354 r269957  
    131131    Optional<double> consumePercentRaw()
    132132    {
    133         if (!m_calcValue || m_calcValue->category() != CalculationCategory::Percent)
     133        if (!m_calcValue)
     134            return WTF::nullopt;
     135        auto category = m_calcValue->category();
     136        if (category != CalculationCategory::Percent)
    134137            return WTF::nullopt;
    135138        m_sourceRange = m_range;
     
    137140    }
    138141
    139     Optional<Angle> consumeAngleRaw()
     142    Optional<AngleRaw> consumeAngleRaw()
    140143    {
    141144        if (!m_calcValue || m_calcValue->category() != CalculationCategory::Angle)
     
    145148    }
    146149
     150    Optional<LengthRaw> consumeLengthRaw()
     151    {
     152        if (!m_calcValue || m_calcValue->category() != CalculationCategory::Length)
     153            return WTF::nullopt;
     154        m_sourceRange = m_range;
     155        return { { m_calcValue->primitiveType(), m_calcValue->doubleValue() } };
     156    }
     157
     158    Optional<LengthOrPercentRaw> consumeLengthOrPercentRaw()
     159    {
     160        if (!m_calcValue)
     161            return WTF::nullopt;
     162
     163        switch (m_calcValue->category()) {
     164        case CalculationCategory::Length:
     165            m_sourceRange = m_range;
     166            return { LengthRaw({ m_calcValue->primitiveType(), m_calcValue->doubleValue() }) };
     167        case CalculationCategory::Percent:
     168        case CalculationCategory::PercentLength:
     169        case CalculationCategory::PercentNumber:
     170            m_sourceRange = m_range;
     171            return { { m_calcValue->doubleValue() } };
     172        default:
     173            return WTF::nullopt;
     174        }
     175    }
     176
    147177private:
    148178    CSSParserTokenRange& m_sourceRange;
     
    178208}
    179209
    180 bool consumeNumberRaw(CSSParserTokenRange& range, double& result)
    181 {
    182     const CSSParserToken& token = range.peek();
    183     if (token.type() == NumberToken) {
    184         result = range.consumeIncludingWhitespace().numericValue();
    185         return true;
    186     }
    187 
    188     if (token.type() != FunctionToken)
    189         return false;
    190 
    191     CalcParser calcParser(range, CalculationCategory::Number, ValueRangeAll);
    192     return calcParser.consumeNumberRaw(result);
    193 }
    194 
    195 // FIXME: Work out if this can just call consumeNumberRaw
    196 RefPtr<CSSPrimitiveValue> consumeNumber(CSSParserTokenRange& range, ValueRange valueRange)
     210bool consumeNumberRaw(CSSParserTokenRange& range, double& result, ValueRange valueRange)
    197211{
    198212    const CSSParserToken& token = range.peek();
    199213    if (token.type() == NumberToken) {
    200214        if (valueRange == ValueRangeNonNegative && token.numericValue() < 0)
    201             return nullptr;
    202         return CSSValuePool::singleton().createValue(range.consumeIncludingWhitespace().numericValue(), token.unitType());
     215            return false;
     216        result = range.consumeIncludingWhitespace().numericValue();
     217        return true;
    203218    }
    204219
    205220    if (token.type() != FunctionToken)
    206         return nullptr;
     221        return false;
    207222
    208223    CalcParser calcParser(range, CalculationCategory::Number, valueRange);
    209     if (const CSSCalcValue* calcValue = calcParser.value()) {
    210         if (calcValue->category() != CalculationCategory::Number)
    211             return nullptr;
    212         return calcParser.consumeValue();
    213     }
     224    return calcParser.consumeNumberRaw(result);
     225}
     226
     227// FIXME: Work out if this can just call consumeNumberRaw
     228RefPtr<CSSPrimitiveValue> consumeNumber(CSSParserTokenRange& range, ValueRange valueRange)
     229{
     230    const CSSParserToken& token = range.peek();
     231    if (token.type() == FunctionToken) {
     232        CalcParser calcParser(range, CalculationCategory::Number, valueRange);
     233        if (const auto* calcValue = calcParser.value()) {
     234            if (calcValue->category() == CalculationCategory::Number)
     235                return calcParser.consumeValue();
     236        }
     237        return nullptr;
     238    }
     239
     240    double number;
     241    if (consumeNumberRaw(range, number, valueRange))
     242        return CSSValuePool::singleton().createValue(number, token.unitType());
    214243
    215244    return nullptr;
     
    223252#endif
    224253
    225 RefPtr<CSSPrimitiveValue> consumeFontWeightNumber(CSSParserTokenRange& range)
     254Optional<double> consumeFontWeightNumberRaw(CSSParserTokenRange& range)
    226255{
    227256    // Values less than or equal to 0 or greater than or equal to 1000 are parse errors.
     
    231260        && token.numericValueType() == IntegerValueType && divisibleBy100(token.numericValue())
    232261#endif
    233     )
    234         return consumeNumber(range, ValueRangeAll);
     262    ) {
     263        double result;
     264        if (consumeNumberRaw(range, result))
     265            return result;
     266        return WTF::nullopt;
     267    }
    235268
    236269    if (token.type() != FunctionToken)
    237         return nullptr;
     270        return WTF::nullopt;
    238271
    239272    // "[For calc()], the used value resulting from an expression must be clamped to the range allowed in the target context."
     
    246279    ) {
    247280        result = std::min(std::max(result, std::nextafter(0., 1.)), std::nextafter(1000., 0.));
    248         return CSSValuePool::singleton().createValue(result, CSSUnitType::CSS_NUMBER);
    249     }
    250 
     281        return result;
     282    }
     283
     284    return WTF::nullopt;
     285}
     286
     287RefPtr<CSSPrimitiveValue> consumeFontWeightNumber(CSSParserTokenRange& range)
     288{
     289    if (auto result = consumeFontWeightNumberRaw(range))
     290        return CSSValuePool::singleton().createValue(*result, CSSUnitType::CSS_NUMBER);
    251291    return nullptr;
    252292}
     
    260300}
    261301
    262 RefPtr<CSSPrimitiveValue> consumeLength(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
     302Optional<LengthRaw> consumeLengthRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
    263303{
    264304    const CSSParserToken& token = range.peek();
     
    267307        case CSSUnitType::CSS_QUIRKY_EMS:
    268308            if (cssParserMode != UASheetMode)
    269                 return nullptr;
     309                return WTF::nullopt;
    270310            FALLTHROUGH;
    271311        case CSSUnitType::CSS_EMS:
     
    288328            break;
    289329        default:
    290             return nullptr;
     330            return WTF::nullopt;
    291331        }
    292332        if ((valueRange == ValueRangeNonNegative && token.numericValue() < 0) || std::isinf(token.numericValue()))
    293             return nullptr;
    294         return CSSValuePool::singleton().createValue(range.consumeIncludingWhitespace().numericValue(), token.unitType());
     333            return WTF::nullopt;
     334        return { { token.unitType(), range.consumeIncludingWhitespace().numericValue() } };
    295335    }
    296336    if (token.type() == NumberToken) {
    297337        if (!shouldAcceptUnitlessValue(token.numericValue(), cssParserMode, unitless)
    298338            || (valueRange == ValueRangeNonNegative && token.numericValue() < 0))
    299             return nullptr;
     339            return WTF::nullopt;
    300340        if (std::isinf(token.numericValue()))
    301             return nullptr;
    302         CSSUnitType unitType = CSSUnitType::CSS_PX;
    303         return CSSValuePool::singleton().createValue(range.consumeIncludingWhitespace().numericValue(), unitType);
     341            return WTF::nullopt;
     342        return { { CSSUnitType::CSS_PX, range.consumeIncludingWhitespace().numericValue() } };
    304343    }
    305344
    306345    if (token.type() != FunctionToken)
    307         return nullptr;
     346        return WTF::nullopt;
    308347
    309348    CalcParser calcParser(range, CalculationCategory::Length, valueRange);
    310     if (calcParser.value() && calcParser.value()->category() == CalculationCategory::Length)
    311         return calcParser.consumeValue();
     349    return calcParser.consumeLengthRaw();
     350}
     351
     352RefPtr<CSSPrimitiveValue> consumeLength(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
     353{
     354    const CSSParserToken& token = range.peek();
     355    if (token.type() == FunctionToken) {
     356        CalcParser calcParser(range, CalculationCategory::Length, valueRange);
     357        if (calcParser.value() && calcParser.value()->category() == CalculationCategory::Length)
     358            return calcParser.consumeValue();
     359    }
     360
     361    if (auto result = consumeLengthRaw(range, cssParserMode, valueRange, unitless))
     362        return CSSValuePool::singleton().createValue(result->value, result->type);
    312363
    313364    return nullptr;
     
    334385    const CSSParserToken& token = range.peek();
    335386    if (token.type() == FunctionToken) {
    336         CalcParser calcParser(range, CalculationCategory::Angle, valueRange);
     387        CalcParser calcParser(range, CalculationCategory::Percent, valueRange);
    337388        if (const CSSCalcValue* calculation = calcParser.value()) {
    338389            if (calculation->category() == CalculationCategory::Percent)
     
    362413}
    363414
    364 RefPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
     415Optional<LengthOrPercentRaw> consumeLengthOrPercentRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
    365416{
    366417    const CSSParserToken& token = range.peek();
    367     if (token.type() == DimensionToken || token.type() == NumberToken)
    368         return consumeLength(range, cssParserMode, valueRange, unitless);
    369     if (token.type() == PercentageToken)
    370         return consumePercent(range, valueRange);
     418    if (token.type() == DimensionToken || token.type() == NumberToken) {
     419        if (auto result = consumeLengthRaw(range, cssParserMode, valueRange, unitless))
     420            return { *result };
     421        return WTF::nullopt;
     422    }
     423    if (token.type() == PercentageToken) {
     424        if (auto result = consumePercentRaw(range, valueRange))
     425            return { *result };
     426        return WTF::nullopt;
     427    }
    371428
    372429    if (token.type() != FunctionToken)
    373         return nullptr;
     430        return WTF::nullopt;
    374431
    375432    CalcParser calcParser(range, CalculationCategory::Length, valueRange);
    376433    if (const CSSCalcValue* calculation = calcParser.value()) {
    377434        if (canConsumeCalcValue(calculation->category(), cssParserMode))
    378             return calcParser.consumeValue();
     435            return calcParser.consumeLengthOrPercentRaw();
     436    }
     437    return WTF::nullopt;
     438}
     439
     440RefPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
     441{
     442    const CSSParserToken& token = range.peek();
     443    if (token.type() == FunctionToken) {
     444        CalcParser calcParser(range, CalculationCategory::Length, valueRange);
     445        if (const CSSCalcValue* calculation = calcParser.value()) {
     446            if (canConsumeCalcValue(calculation->category(), cssParserMode))
     447                return calcParser.consumeValue();
     448        }
     449        return nullptr;
     450    }
     451
     452    if (auto result = consumeLengthOrPercentRaw(range, cssParserMode, valueRange, unitless)) {
     453        return switchOn(*result, [] (LengthRaw length) {
     454            return CSSValuePool::singleton().createValue(length.value, length.type);
     455        }, [] (double percentage) {
     456            return CSSValuePool::singleton().createValue(percentage, CSSUnitType::CSS_PERCENTAGE);
     457        });
    379458    }
    380459    return nullptr;
    381460}
    382461
    383 Optional<Angle> consumeAngleRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless)
     462Optional<AngleRaw> consumeAngleRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless)
    384463{
    385464    const CSSParserToken& token = range.peek();
     
    503582}
    504583
     584Optional<CSSValueID> consumeIdentRaw(CSSParserTokenRange& range)
     585{
     586    if (range.peek().type() != IdentToken)
     587        return WTF::nullopt;
     588    return range.consumeIncludingWhitespace().id();
     589}
     590
    505591RefPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange& range)
    506592{
    507     if (range.peek().type() != IdentToken)
    508         return nullptr;
    509     return CSSValuePool::singleton().createIdentifierValue(range.consumeIncludingWhitespace().id());
     593    if (auto result = consumeIdentRaw(range))
     594        return CSSValuePool::singleton().createIdentifierValue(*result);
     595    return nullptr;
     596}
     597
     598Optional<CSSValueID> consumeIdentRangeRaw(CSSParserTokenRange& range, CSSValueID lower, CSSValueID upper)
     599{
     600    if (range.peek().id() < lower || range.peek().id() > upper)
     601        return WTF::nullopt;
     602    return consumeIdentRaw(range);
    510603}
    511604
     
    18191912}
    18201913
     1914Optional<CSSValueID> consumeFontVariantCSS21Raw(CSSParserTokenRange& range)
     1915{
     1916    return consumeIdentRaw<CSSValueNormal, CSSValueSmallCaps>(range);
     1917}
     1918
     1919Optional<CSSValueID> consumeFontWeightKeywordValueRaw(CSSParserTokenRange& range)
     1920{
     1921    return consumeIdentRaw<CSSValueNormal, CSSValueBold, CSSValueBolder, CSSValueLighter>(range);
     1922}
     1923
     1924Optional<FontWeightRaw> consumeFontWeightRaw(CSSParserTokenRange& range)
     1925{
     1926    if (auto result = consumeFontWeightKeywordValueRaw(range))
     1927        return { *result };
     1928    if (auto result = consumeFontWeightNumberRaw(range))
     1929        return { *result };
     1930    return WTF::nullopt;
     1931}
     1932
     1933Optional<CSSValueID> consumeFontStretchKeywordValueRaw(CSSParserTokenRange& range)
     1934{
     1935    return consumeIdentRaw<CSSValueUltraCondensed, CSSValueExtraCondensed, CSSValueCondensed, CSSValueSemiCondensed, CSSValueNormal, CSSValueSemiExpanded, CSSValueExpanded, CSSValueExtraExpanded, CSSValueUltraExpanded>(range);
     1936}
     1937
     1938Optional<CSSValueID> consumeFontStyleKeywordValueRaw(CSSParserTokenRange& range)
     1939{
     1940    return consumeIdentRaw<CSSValueNormal, CSSValueItalic, CSSValueOblique>(range);
     1941}
     1942
     1943Optional<FontStyleRaw> consumeFontStyleRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode)
     1944{
     1945    auto result = consumeFontStyleKeywordValueRaw(range);
     1946    if (!result)
     1947        return WTF::nullopt;
     1948
     1949    auto ident = *result;
     1950    if (ident == CSSValueNormal || ident == CSSValueItalic)
     1951        return { { ident, WTF::nullopt } };
     1952    ASSERT(ident == CSSValueOblique);
     1953#if ENABLE(VARIATION_FONTS)
     1954    if (!range.atEnd()) {
     1955        if (auto angle = consumeAngleRaw(range, cssParserMode)) {
     1956            auto angleInDegrees = CSSPrimitiveValue::computeDegrees(angle->type, angle->value);
     1957            if (fontStyleIsWithinRange(angleInDegrees))
     1958                return { { CSSValueOblique, WTFMove(angle) } };
     1959            return WTF::nullopt;
     1960        }
     1961    }
     1962#else
     1963    UNUSED_PARAM(cssParserMode);
     1964#endif
     1965    return { { CSSValueOblique, WTF::nullopt } };
     1966}
     1967
     1968String concatenateFamilyName(CSSParserTokenRange& range)
     1969{
     1970    StringBuilder builder;
     1971    bool addedSpace = false;
     1972    const CSSParserToken& firstToken = range.peek();
     1973    while (range.peek().type() == IdentToken) {
     1974        if (!builder.isEmpty()) {
     1975            builder.append(' ');
     1976            addedSpace = true;
     1977        }
     1978        builder.append(range.consumeIncludingWhitespace().value());
     1979    }
     1980    if (!addedSpace && isCSSWideKeyword(firstToken.id()))
     1981        return String();
     1982    return builder.toString();
     1983}
     1984
     1985String consumeFamilyNameRaw(CSSParserTokenRange& range)
     1986{
     1987    if (range.peek().type() == StringToken)
     1988        return range.consumeIncludingWhitespace().value().toString();
     1989    if (range.peek().type() != IdentToken)
     1990        return String();
     1991    return concatenateFamilyName(range);
     1992}
     1993
     1994Optional<CSSValueID> consumeGenericFamilyRaw(CSSParserTokenRange& range)
     1995{
     1996    return consumeIdentRangeRaw(range, CSSValueSerif, CSSValueWebkitBody);
     1997}
     1998
     1999Optional<WTF::Vector<FontFamilyRaw>> consumeFontFamilyRaw(CSSParserTokenRange& range)
     2000{
     2001    WTF::Vector<FontFamilyRaw> list;
     2002    do {
     2003        if (auto ident = consumeGenericFamilyRaw(range))
     2004            list.append({ *ident });
     2005        else {
     2006            auto familyName = consumeFamilyNameRaw(range);
     2007            if (familyName.isNull())
     2008                return WTF::nullopt;
     2009            list.append({ familyName });
     2010        }
     2011    } while (consumeCommaIncludingWhitespace(range));
     2012    return list;
     2013}
     2014
     2015Optional<FontSizeRaw> consumeFontSizeRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless)
     2016{
     2017    if (range.peek().id() >= CSSValueXxSmall && range.peek().id() <= CSSValueLarger) {
     2018        if (auto ident = consumeIdentRaw(range))
     2019            return { *ident };
     2020        return WTF::nullopt;
     2021    }
     2022
     2023    if (auto result = consumeLengthOrPercentRaw(range, cssParserMode, ValueRangeNonNegative, unitless))
     2024        return { *result };
     2025
     2026    return WTF::nullopt;
     2027}
     2028
     2029Optional<LineHeightRaw> consumeLineHeightRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode)
     2030{
     2031    if (range.peek().id() == CSSValueNormal) {
     2032        if (auto ident = consumeIdentRaw(range))
     2033            return { *ident };
     2034        return WTF::nullopt;
     2035    }
     2036
     2037    double number;
     2038    if (consumeNumberRaw(range, number, ValueRangeNonNegative))
     2039        return { number };
     2040
     2041    if (auto lengthOrPercent = consumeLengthOrPercentRaw(range, cssParserMode, ValueRangeNonNegative))
     2042        return { *lengthOrPercent };
     2043
     2044    return WTF::nullopt;
     2045}
     2046
     2047Optional<FontRaw> consumeFontWorkerSafe(CSSParserTokenRange& range, CSSParserMode cssParserMode)
     2048{
     2049    // Let's check if there is an inherit or initial somewhere in the shorthand.
     2050    CSSParserTokenRange rangeCopy = range;
     2051    while (!rangeCopy.atEnd()) {
     2052        CSSValueID id = rangeCopy.consumeIncludingWhitespace().id();
     2053        if (id == CSSValueInherit || id == CSSValueInitial)
     2054            return WTF::nullopt;
     2055    }
     2056
     2057    FontRaw result;
     2058
     2059    while (!range.atEnd()) {
     2060        CSSValueID id = range.peek().id();
     2061        if (!result.style) {
     2062            if ((result.style = consumeFontStyleRaw(range, cssParserMode)))
     2063                continue;
     2064        }
     2065        if (!result.variantCaps && (id == CSSValueNormal || id == CSSValueSmallCaps)) {
     2066            // Font variant in the shorthand is particular, it only accepts normal or small-caps.
     2067            // See https://drafts.csswg.org/css-fonts/#propdef-font
     2068            if ((result.variantCaps = consumeFontVariantCSS21Raw(range)))
     2069                continue;
     2070        }
     2071        if (!result.weight) {
     2072            if ((result.weight = consumeFontWeightRaw(range)))
     2073                continue;
     2074        }
     2075        if (!result.stretch) {
     2076            if ((result.stretch = consumeFontStretchKeywordValueRaw(range)))
     2077                continue;
     2078        }
     2079        break;
     2080    }
     2081
     2082    if (range.atEnd())
     2083        return WTF::nullopt;
     2084
     2085    // Now a font size _must_ come.
     2086    if (auto size = consumeFontSizeRaw(range, cssParserMode))
     2087        result.size = *size;
     2088    else
     2089        return WTF::nullopt;
     2090
     2091    if (range.atEnd())
     2092        return WTF::nullopt;
     2093
     2094    if (consumeSlashIncludingWhitespace(range)) {
     2095        if (!(result.lineHeight = consumeLineHeightRaw(range, cssParserMode)))
     2096            return WTF::nullopt;
     2097    }
     2098
     2099    // Font family must come now.
     2100    if (auto family = consumeFontFamilyRaw(range))
     2101        result.family = *family;
     2102    else
     2103        return WTF::nullopt;
     2104
     2105    if (!range.atEnd())
     2106        return WTF::nullopt;
     2107
     2108    return result;
     2109}
     2110
     2111const AtomString& genericFontFamilyFromValueID(CSSValueID ident)
     2112{
     2113    switch (ident) {
     2114    case CSSValueSerif:
     2115        return serifFamily.get();
     2116    case CSSValueSansSerif:
     2117        return sansSerifFamily.get();
     2118    case CSSValueCursive:
     2119        return cursiveFamily.get();
     2120    case CSSValueFantasy:
     2121        return fantasyFamily.get();
     2122    case CSSValueMonospace:
     2123        return monospaceFamily.get();
     2124    case CSSValueWebkitPictograph:
     2125        return pictographFamily.get();
     2126    case CSSValueSystemUi:
     2127        return systemUiFamily.get();
     2128    default:
     2129        return emptyAtom();
     2130    }
     2131}
     2132
    18212133} // namespace CSSPropertyParserHelpers
    18222134
  • trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h

    r267154 r269957  
    3838#include "Length.h" // For ValueRange
    3939#include <wtf/OptionSet.h>
     40#include <wtf/Variant.h>
     41#include <wtf/Vector.h>
    4042
    4143namespace WebCore {
     
    5658enum class AllowXResolutionUnit { Allow, Forbid };
    5759
    58 struct Angle {
     60struct AngleRaw {
    5961    CSSUnitType type;
    6062    double value;
    6163};
    6264
     65struct LengthRaw {
     66    CSSUnitType type;
     67    double value;
     68};
     69
     70using LengthOrPercentRaw = WTF::Variant<LengthRaw, double>;
     71
    6372RefPtr<CSSPrimitiveValue> consumeInteger(CSSParserTokenRange&, double minimumValue = -std::numeric_limits<double>::max());
    6473RefPtr<CSSPrimitiveValue> consumePositiveInteger(CSSParserTokenRange&);
    65 bool consumeNumberRaw(CSSParserTokenRange&, double& result);
     74bool consumeNumberRaw(CSSParserTokenRange&, double& result, ValueRange = ValueRangeAll);
    6675RefPtr<CSSPrimitiveValue> consumeNumber(CSSParserTokenRange&, ValueRange);
     76Optional<double> consumeFontWeightNumberRaw(CSSParserTokenRange&);
    6777RefPtr<CSSPrimitiveValue> consumeFontWeightNumber(CSSParserTokenRange&);
     78Optional<LengthRaw> consumeLengthRaw(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
    6879RefPtr<CSSPrimitiveValue> consumeLength(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
    6980Optional<double> consumePercentRaw(CSSParserTokenRange&, ValueRange = ValueRangeAll);
    7081RefPtr<CSSPrimitiveValue> consumePercent(CSSParserTokenRange&, ValueRange);
     82Optional<LengthOrPercentRaw> consumeLengthOrPercentRaw(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
    7183RefPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
    72 Optional<Angle> consumeAngleRaw(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk);
     84Optional<AngleRaw> consumeAngleRaw(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk = UnitlessQuirk::Forbid);
    7385RefPtr<CSSPrimitiveValue> consumeAngle(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk = UnitlessQuirk::Forbid);
    7486RefPtr<CSSPrimitiveValue> consumeTime(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
    7587RefPtr<CSSPrimitiveValue> consumeResolution(CSSParserTokenRange&, AllowXResolutionUnit = AllowXResolutionUnit::Forbid);
    7688
     89Optional<CSSValueID> consumeIdentRaw(CSSParserTokenRange&);
    7790RefPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange&);
     91Optional<CSSValueID> consumeIdentRangeRaw(CSSParserTokenRange&, CSSValueID lower, CSSValueID upper);
    7892RefPtr<CSSPrimitiveValue> consumeIdentRange(CSSParserTokenRange&, CSSValueID lower, CSSValueID upper);
    7993template<CSSValueID, CSSValueID...> inline bool identMatches(CSSValueID id);
     94template<CSSValueID... allowedIdents> Optional<CSSValueID> consumeIdentRaw(CSSParserTokenRange&);
    8095template<CSSValueID... allowedIdents> RefPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange&);
    8196
     
    116131RefPtr<CSSShadowValue> consumeSingleShadow(CSSParserTokenRange&, CSSParserMode, bool allowInset, bool allowSpread);
    117132
     133struct FontStyleRaw {
     134    CSSValueID style;
     135    Optional<AngleRaw> angle;
     136};
     137using FontWeightRaw = WTF::Variant<CSSValueID, double>;
     138using FontSizeRaw = WTF::Variant<CSSValueID, CSSPropertyParserHelpers::LengthOrPercentRaw>;
     139using LineHeightRaw = WTF::Variant<CSSValueID, double, CSSPropertyParserHelpers::LengthOrPercentRaw>;
     140using FontFamilyRaw = WTF::Variant<CSSValueID, String>;
     141
     142struct FontRaw {
     143    Optional<FontStyleRaw> style;
     144    Optional<CSSValueID> variantCaps;
     145    Optional<FontWeightRaw> weight;
     146    Optional<CSSValueID> stretch;
     147    FontSizeRaw size;
     148    Optional<LineHeightRaw> lineHeight;
     149    WTF::Vector<FontFamilyRaw> family;
     150};
     151
     152Optional<CSSValueID> consumeFontVariantCSS21Raw(CSSParserTokenRange&);
     153Optional<CSSValueID> consumeFontWeightKeywordValueRaw(CSSParserTokenRange&);
     154Optional<FontWeightRaw> consumeFontWeightRaw(CSSParserTokenRange&);
     155Optional<CSSValueID> consumeFontStretchKeywordValueRaw(CSSParserTokenRange&);
     156Optional<CSSValueID> consumeFontStyleKeywordValueRaw(CSSParserTokenRange&);
     157Optional<FontStyleRaw> consumeFontStyleRaw(CSSParserTokenRange&, CSSParserMode);
     158String concatenateFamilyName(CSSParserTokenRange&);
     159String consumeFamilyNameRaw(CSSParserTokenRange&);
     160Optional<CSSValueID> consumeGenericFamilyRaw(CSSParserTokenRange&);
     161Optional<WTF::Vector<FontFamilyRaw>> consumeFontFamilyRaw(CSSParserTokenRange&);
     162Optional<FontSizeRaw> consumeFontSizeRaw(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk = UnitlessQuirk::Forbid);
     163Optional<LineHeightRaw> consumeLineHeightRaw(CSSParserTokenRange&, CSSParserMode);
     164Optional<FontRaw> consumeFontWorkerSafe(CSSParserTokenRange&, CSSParserMode);
     165const AtomString& genericFontFamilyFromValueID(CSSValueID);
     166
    118167// Template implementations are at the bottom of the file for readability.
    119168
     
    122171{
    123172    return id == head || identMatches<tail...>(id);
     173}
     174
     175template<CSSValueID... names> Optional<CSSValueID> consumeIdentRaw(CSSParserTokenRange& range)
     176{
     177    if (range.peek().type() != IdentToken || !identMatches<names...>(range.peek().id()))
     178        return WTF::nullopt;
     179    return range.consumeIncludingWhitespace().id();
    124180}
    125181
  • trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp

    r267742 r269957  
    3737#include "CSSParser.h"
    3838#include "CSSPropertyNames.h"
     39#include "CSSPropertyParserHelpers.h"
    3940#include "Gradient.h"
    4041#include "ImageBuffer.h"
    4142#include "ImageData.h"
    4243#include "InspectorInstrumentation.h"
     44#include "NodeRenderStyle.h"
    4345#include "Path2D.h"
    4446#include "RenderTheme.h"
    4547#include "ResourceLoadObserver.h"
    4648#include "RuntimeEnabledFeatures.h"
     49#include "Settings.h"
    4750#include "StyleBuilder.h"
     51#include "StyleFontSizeFunctions.h"
    4852#include "StyleProperties.h"
     53#include "StyleResolveForFontRaw.h"
    4954#include "TextMetrics.h"
    5055#include "TextRun.h"
     
    135140        return;
    136141
    137     auto parsedStyle = MutableStyleProperties::create();
    138     CSSParser::parseValue(parsedStyle, CSSPropertyFont, newFont, true, strictToCSSParserMode(!m_usesCSSCompatibilityParseMode));
    139     if (parsedStyle->isEmpty())
    140         return;
    141 
    142     String fontValue = parsedStyle->getPropertyValue(CSSPropertyFont);
    143 
    144142    // According to http://lists.w3.org/Archives/Public/public-html/2009Jul/0947.html,
    145     // the "inherit" and "initial" values must be ignored.
    146     if (fontValue == "inherit" || fontValue == "initial")
     143    // the "inherit" and "initial" values must be ignored. parseFontWorkerSafe() ignores these.
     144    auto fontRaw = CSSParser::parseFontWorkerSafe(newFont, strictToCSSParserMode(!m_usesCSSCompatibilityParseMode));
     145    if (!fontRaw)
    147146        return;
    148147
     
    154153    // Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work
    155154    // relative to the canvas.
    156     auto newStyle = RenderStyle::createPtr();
    157 
    158155    Document& document = canvas().document();
    159156    document.updateStyleIfNeeded();
    160157
     158    FontCascadeDescription fontDescription;
    161159    if (auto* computedStyle = canvas().computedStyle())
    162         newStyle->setFontDescription(FontCascadeDescription { computedStyle->fontDescription() });
     160        fontDescription = FontCascadeDescription { computedStyle->fontDescription() };
    163161    else {
    164         FontCascadeDescription defaultFontDescription;
    165         defaultFontDescription.setOneFamily(DefaultFontFamily);
    166         defaultFontDescription.setSpecifiedSize(DefaultFontSize);
    167         defaultFontDescription.setComputedSize(DefaultFontSize);
    168 
    169         newStyle->setFontDescription(WTFMove(defaultFontDescription));
    170     }
    171 
    172     newStyle->fontCascade().update(&document.fontSelector());
    173 
    174     // Now map the font property longhands into the style.
    175 
    176     Style::MatchResult matchResult;
    177     auto parentStyle = RenderStyle::clone(*newStyle);
    178     Style::Builder styleBuilder(*newStyle, { document, parentStyle }, matchResult, { });
    179 
    180     styleBuilder.applyPropertyValue(CSSPropertyFontFamily, parsedStyle->getPropertyCSSValue(CSSPropertyFontFamily).get());
    181     styleBuilder.applyPropertyValue(CSSPropertyFontStyle, parsedStyle->getPropertyCSSValue(CSSPropertyFontStyle).get());
    182     styleBuilder.applyPropertyValue(CSSPropertyFontVariantCaps, parsedStyle->getPropertyCSSValue(CSSPropertyFontVariantCaps).get());
    183     styleBuilder.applyPropertyValue(CSSPropertyFontWeight, parsedStyle->getPropertyCSSValue(CSSPropertyFontWeight).get());
    184     styleBuilder.applyPropertyValue(CSSPropertyFontSize, parsedStyle->getPropertyCSSValue(CSSPropertyFontSize).get());
    185     styleBuilder.applyPropertyValue(CSSPropertyLineHeight, parsedStyle->getPropertyCSSValue(CSSPropertyLineHeight).get());
    186 
    187     modifiableState().font.initialize(document.fontSelector(), *newStyle);
     162        fontDescription.setOneFamily(DefaultFontFamily);
     163        fontDescription.setSpecifiedSize(DefaultFontSize);
     164        fontDescription.setComputedSize(DefaultFontSize);
     165    }
     166
     167    if (auto fontStyle = Style::resolveForFontRaw(*fontRaw, WTFMove(fontDescription), document))
     168        modifiableState().font.initialize(document.fontSelector(), *fontStyle);
    188169}
    189170
  • trunk/Source/WebCore/style/StyleBuilderCustom.h

    r269820 r269957  
    3232#include "CSSGradientValue.h"
    3333#include "CSSGridTemplateAreasValue.h"
     34#include "CSSPropertyParserHelpers.h"
    3435#include "CSSRegisteredCustomProperty.h"
    3536#include "CSSShadowValue.h"
     
    10131014            isGenericFamily = fontFamily.fromSystemFontID;
    10141015        } else {
    1015             switch (contentValue.valueID()) {
    1016             case CSSValueWebkitBody:
     1016            if (contentValue.valueID() == CSSValueWebkitBody)
    10171017                family = builderState.document().settings().standardFontFamily();
    1018                 break;
    1019             case CSSValueSerif:
    1020                 family = serifFamily;
     1018            else {
    10211019                isGenericFamily = true;
    1022                 break;
    1023             case CSSValueSansSerif:
    1024                 family = sansSerifFamily;
    1025                 isGenericFamily = true;
    1026                 break;
    1027             case CSSValueCursive:
    1028                 family = cursiveFamily;
    1029                 isGenericFamily = true;
    1030                 break;
    1031             case CSSValueFantasy:
    1032                 family = fantasyFamily;
    1033                 isGenericFamily = true;
    1034                 break;
    1035             case CSSValueMonospace:
    1036                 family = monospaceFamily;
    1037                 isGenericFamily = true;
    1038                 break;
    1039             case CSSValueWebkitPictograph:
    1040                 family = pictographFamily;
    1041                 isGenericFamily = true;
    1042                 break;
    1043             case CSSValueSystemUi:
    1044                 family = systemUiFamily;
    1045                 isGenericFamily = true;
    1046                 break;
    1047             default:
    1048                 break;
     1020                family = CSSPropertyParserHelpers::genericFontFamilyFromValueID(contentValue.valueID());
    10491021            }
    10501022        }
Note: See TracChangeset for help on using the changeset viewer.