Changeset 272870 in webkit


Ignore:
Timestamp:
Feb 15, 2021 11:24:12 AM (3 years ago)
Author:
weinig@apple.com
Message:

Prepare for adding relative color support
https://bugs.webkit.org/show_bug.cgi?id=221881

Reviewed by Darin Adler.

Source/WebCore:

In preparation for adding experimental relative color support a little cleanup
is in order. This change:

  • Threads a CSSParserContext through the color parsing functions. This will be needed to check if the feature is enabled or not.
  • Does a small cleanup of CSSParserContext, sorting features and using the initialization list in the constructor.
  • Refactors some of the color parsing helpers to extract more helpers. These clarify the code better and will be shared by the relative parsers.
  • Move normalization of components to after parsing to avoid unnecessary work in the case of failure and separate the phases a bit more.
  • Removes some unnecessary ValueRangeAll parameters that were already the default.
  • Switch HSLA and HWBA to stop storing their components in a 0-1 normalization and instead use values that match the input, 0-360 for hue, and 0-100 for the the remaining two components. This seems more natural, and will simplify future color function work that expects the values in this form.
  • css/parser/CSSParser.cpp:

(WebCore::CSSParser::parseColorWorkerSafe):

  • css/parser/CSSParserContext.cpp:

(WebCore::shouldEnableLegacyOverflowScrollingTouch):
(WebCore::CSSParserContext::CSSParserContext):
(WebCore::operator==):

  • css/parser/CSSParserContext.h:

(WebCore::CSSParserContextHash::hash):

  • css/parser/CSSPropertyParser.cpp:

(WebCore::consumeShadow):
(WebCore::consumeCaretColor):
(WebCore::consumeOutlineColor):
(WebCore::consumePaintStroke):
(WebCore::consumeBackgroundComponent):
(WebCore::CSSPropertyParser::parseSingleValue):
(WebCore::CSSPropertyParser::consumeBorder):

  • css/parser/CSSPropertyParserHelpers.cpp:

(WebCore::CSSPropertyParserHelpers::consumeOptionalAlpha):
(WebCore::CSSPropertyParserHelpers::consumeHue):
(WebCore::CSSPropertyParserHelpers::normalizeHue):
(WebCore::CSSPropertyParserHelpers::clampRGBComponent):
(WebCore::CSSPropertyParserHelpers::parseRGBParameters):
(WebCore::CSSPropertyParserHelpers::parseHSLParameters):
(WebCore::CSSPropertyParserHelpers::normalizeWhitenessBlackness):
(WebCore::CSSPropertyParserHelpers::parseHWBParameters):
(WebCore::CSSPropertyParserHelpers::parseLabParameters):
(WebCore::CSSPropertyParserHelpers::parseLCHParameters):
(WebCore::CSSPropertyParserHelpers::parseColorFunctionForRGBTypes):
(WebCore::CSSPropertyParserHelpers::parseColorFunctionForLabParameters):
(WebCore::CSSPropertyParserHelpers::parseColorFunctionForXYZParameters):
(WebCore::CSSPropertyParserHelpers::parseColorFunction):
(WebCore::CSSPropertyParserHelpers::consumeColorWorkerSafe):
(WebCore::CSSPropertyParserHelpers::consumeColor):
(WebCore::CSSPropertyParserHelpers::consumeDeprecatedGradientStopColor):
(WebCore::CSSPropertyParserHelpers::consumeDeprecatedGradientColorStop):
(WebCore::CSSPropertyParserHelpers::consumeDeprecatedGradient):
(WebCore::CSSPropertyParserHelpers::consumeGradientColorStops):
(WebCore::CSSPropertyParserHelpers::consumeDeprecatedRadialGradient):
(WebCore::CSSPropertyParserHelpers::consumeRadialGradient):
(WebCore::CSSPropertyParserHelpers::consumeLinearGradient):
(WebCore::CSSPropertyParserHelpers::consumeConicGradient):
(WebCore::CSSPropertyParserHelpers::consumeImageOrNone):
(WebCore::CSSPropertyParserHelpers::consumeCrossFade):
(WebCore::CSSPropertyParserHelpers::consumeGeneratedImage):
(WebCore::CSSPropertyParserHelpers::consumeFilterFunction):
(WebCore::CSSPropertyParserHelpers::consumeSingleShadow):
(WebCore::CSSPropertyParserHelpers::consumeImage):
(WebCore::CSSPropertyParserHelpers::parseOptionalAlpha): Deleted.

  • css/parser/CSSPropertyParserHelpers.h:

(WebCore::CSSPropertyParserHelpers::consumeImage):

  • editing/cocoa/DataDetection.mm:

(WebCore::DataDetection::detectContentInRange):

  • platform/graphics/ColorConversion.cpp:

(WebCore::calculateHSLHue):
(WebCore::SRGBA<float>>::convert):
(WebCore::HSLA<float>>::convert):
(WebCore::HWBA<float>>::convert):

  • platform/graphics/ColorModels.h:
  • rendering/RenderTheme.cpp:

(WebCore::RenderTheme::datePlaceholderTextColor const):

Tools:

  • TestWebKitAPI/Tests/WebCore/ColorTests.cpp:

Update HSLA tests to account for HSLA now using 0-360, 0-100, 0-100 bounds rather than 0-1, 0-1, 0-1.

Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r272866 r272870  
     12021-02-15  Sam Weinig  <weinig@apple.com>
     2
     3        Prepare for adding relative color support
     4        https://bugs.webkit.org/show_bug.cgi?id=221881
     5
     6        Reviewed by Darin Adler.
     7
     8        In preparation for adding experimental relative color support a little cleanup
     9        is in order. This change:
     10       
     11        - Threads a CSSParserContext through the color parsing functions. This will be
     12          needed to check if the feature is enabled or not.
     13        - Does a small cleanup of CSSParserContext, sorting features and using the initialization
     14          list in the constructor.
     15        - Refactors some of the color parsing helpers to extract more helpers. These clarify
     16          the code better and will be shared by the relative parsers.
     17        - Move normalization of components to after parsing to avoid unnecessary work
     18          in the case of failure and separate the phases a bit more.
     19        - Removes some unnecessary ValueRangeAll parameters that were already the default.
     20        - Switch HSLA and HWBA to stop storing their components in a 0-1 normalization
     21          and instead use values that match the input, 0-360 for hue, and 0-100 for the
     22          the remaining two components. This seems more natural, and will simplify
     23          future color function work that expects the values in this form.
     24
     25        * css/parser/CSSParser.cpp:
     26        (WebCore::CSSParser::parseColorWorkerSafe):
     27        * css/parser/CSSParserContext.cpp:
     28        (WebCore::shouldEnableLegacyOverflowScrollingTouch):
     29        (WebCore::CSSParserContext::CSSParserContext):
     30        (WebCore::operator==):
     31        * css/parser/CSSParserContext.h:
     32        (WebCore::CSSParserContextHash::hash):
     33        * css/parser/CSSPropertyParser.cpp:
     34        (WebCore::consumeShadow):
     35        (WebCore::consumeCaretColor):
     36        (WebCore::consumeOutlineColor):
     37        (WebCore::consumePaintStroke):
     38        (WebCore::consumeBackgroundComponent):
     39        (WebCore::CSSPropertyParser::parseSingleValue):
     40        (WebCore::CSSPropertyParser::consumeBorder):
     41        * css/parser/CSSPropertyParserHelpers.cpp:
     42        (WebCore::CSSPropertyParserHelpers::consumeOptionalAlpha):
     43        (WebCore::CSSPropertyParserHelpers::consumeHue):
     44        (WebCore::CSSPropertyParserHelpers::normalizeHue):
     45        (WebCore::CSSPropertyParserHelpers::clampRGBComponent):
     46        (WebCore::CSSPropertyParserHelpers::parseRGBParameters):
     47        (WebCore::CSSPropertyParserHelpers::parseHSLParameters):
     48        (WebCore::CSSPropertyParserHelpers::normalizeWhitenessBlackness):
     49        (WebCore::CSSPropertyParserHelpers::parseHWBParameters):
     50        (WebCore::CSSPropertyParserHelpers::parseLabParameters):
     51        (WebCore::CSSPropertyParserHelpers::parseLCHParameters):
     52        (WebCore::CSSPropertyParserHelpers::parseColorFunctionForRGBTypes):
     53        (WebCore::CSSPropertyParserHelpers::parseColorFunctionForLabParameters):
     54        (WebCore::CSSPropertyParserHelpers::parseColorFunctionForXYZParameters):
     55        (WebCore::CSSPropertyParserHelpers::parseColorFunction):
     56        (WebCore::CSSPropertyParserHelpers::consumeColorWorkerSafe):
     57        (WebCore::CSSPropertyParserHelpers::consumeColor):
     58        (WebCore::CSSPropertyParserHelpers::consumeDeprecatedGradientStopColor):
     59        (WebCore::CSSPropertyParserHelpers::consumeDeprecatedGradientColorStop):
     60        (WebCore::CSSPropertyParserHelpers::consumeDeprecatedGradient):
     61        (WebCore::CSSPropertyParserHelpers::consumeGradientColorStops):
     62        (WebCore::CSSPropertyParserHelpers::consumeDeprecatedRadialGradient):
     63        (WebCore::CSSPropertyParserHelpers::consumeRadialGradient):
     64        (WebCore::CSSPropertyParserHelpers::consumeLinearGradient):
     65        (WebCore::CSSPropertyParserHelpers::consumeConicGradient):
     66        (WebCore::CSSPropertyParserHelpers::consumeImageOrNone):
     67        (WebCore::CSSPropertyParserHelpers::consumeCrossFade):
     68        (WebCore::CSSPropertyParserHelpers::consumeGeneratedImage):
     69        (WebCore::CSSPropertyParserHelpers::consumeFilterFunction):
     70        (WebCore::CSSPropertyParserHelpers::consumeSingleShadow):
     71        (WebCore::CSSPropertyParserHelpers::consumeImage):
     72        (WebCore::CSSPropertyParserHelpers::parseOptionalAlpha): Deleted.
     73        * css/parser/CSSPropertyParserHelpers.h:
     74        (WebCore::CSSPropertyParserHelpers::consumeImage):
     75        * editing/cocoa/DataDetection.mm:
     76        (WebCore::DataDetection::detectContentInRange):
     77        * platform/graphics/ColorConversion.cpp:
     78        (WebCore::calculateHSLHue):
     79        (WebCore::SRGBA<float>>::convert):
     80        (WebCore::HSLA<float>>::convert):
     81        (WebCore::HWBA<float>>::convert):
     82        * platform/graphics/ColorModels.h:
     83        * rendering/RenderTheme.cpp:
     84        (WebCore::RenderTheme::datePlaceholderTextColor const):
     85
    1862021-02-15  Antoine Quint  <graouts@webkit.org>
    287
  • trunk/Source/WebCore/css/parser/CSSParser.cpp

    r269957 r272870  
    118118    range.consumeWhitespace();
    119119
    120     return CSSPropertyParserHelpers::consumeColorWorkerSafe(range, HTMLStandardMode);
     120    return CSSPropertyParserHelpers::consumeColorWorkerSafe(range, strictCSSParserContext());
    121121}
    122122
  • trunk/Source/WebCore/css/parser/CSSParserContext.cpp

    r270613 r272870  
    11/*
    2  * Copyright (C) 2018-2020 Apple Inc. All rights reserved.
     2 * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4848}
    4949
    50 CSSParserContext::CSSParserContext(const Document& document, const URL& sheetBaseURL, const String& charset)
    51     : baseURL(sheetBaseURL.isNull() ? document.baseURL() : sheetBaseURL)
    52     , charset(charset)
    53     , mode(document.inQuirksMode() ? HTMLQuirksMode : HTMLStandardMode)
    54     , isHTMLDocument(document.isHTMLDocument())
    55     , hasDocumentSecurityOrigin(sheetBaseURL.isNull() || document.securityOrigin().canRequest(baseURL))
     50#if ENABLE(OVERFLOW_SCROLLING_TOUCH)
     51static bool shouldEnableLegacyOverflowScrollingTouch(const Document& document)
    5652{
    57     enforcesCSSMIMETypeInNoQuirksMode = document.settings().enforceCSSMIMETypeInNoQuirksMode();
    58     useLegacyBackgroundSizeShorthandBehavior = document.settings().useLegacyBackgroundSizeShorthandBehavior();
    59 #if ENABLE(TEXT_AUTOSIZING)
    60     textAutosizingEnabled = document.settings().textAutosizingEnabled();
    61 #endif
    62 #if ENABLE(OVERFLOW_SCROLLING_TOUCH)
    63     legacyOverflowScrollingTouchEnabled = document.settings().legacyOverflowScrollingTouchEnabled();
    6453    // The legacy -webkit-overflow-scrolling: touch behavior may have been disabled through the website policy,
    6554    // in that case we want to disable the legacy behavior regardless of what the setting says.
    6655    if (auto* loader = document.loader()) {
    6756        if (loader->legacyOverflowScrollingTouchPolicy() == LegacyOverflowScrollingTouchPolicy::Disable)
    68             legacyOverflowScrollingTouchEnabled = false;
     57            return false;
    6958    }
     59    return document.settings().legacyOverflowScrollingTouchEnabled();
     60}
    7061#endif
    71     springTimingFunctionEnabled = document.settings().springTimingFunctionEnabled();
    72     constantPropertiesEnabled = document.settings().constantPropertiesEnabled();
    73     colorFilterEnabled = document.settings().colorFilterEnabled();
     62
     63CSSParserContext::CSSParserContext(const Document& document, const URL& sheetBaseURL, const String& charset)
     64    : baseURL { sheetBaseURL.isNull() ? document.baseURL() : sheetBaseURL }
     65    , charset { charset }
     66    , mode { document.inQuirksMode() ? HTMLQuirksMode : HTMLStandardMode }
     67    , isHTMLDocument { document.isHTMLDocument() }
     68    , hasDocumentSecurityOrigin { sheetBaseURL.isNull() || document.securityOrigin().canRequest(baseURL) }
     69    , useSystemAppearance { document.page() ? document.page()->useSystemAppearance() : false }
     70    , aspectRatioEnabled { document.settings().aspectRatioEnabled() }
     71    , colorFilterEnabled { document.settings().colorFilterEnabled() }
     72    , constantPropertiesEnabled { document.settings().constantPropertiesEnabled() }
     73    , deferredCSSParserEnabled { document.settings().deferredCSSParserEnabled() }
     74    , enforcesCSSMIMETypeInNoQuirksMode { document.settings().enforceCSSMIMETypeInNoQuirksMode() }
     75    , individualTransformPropertiesEnabled { document.settings().cssIndividualTransformPropertiesEnabled() }
     76#if ENABLE(OVERFLOW_SCROLLING_TOUCH)
     77    , legacyOverflowScrollingTouchEnabled { shouldEnableLegacyOverflowScrollingTouch(document) }
     78#endif
     79    , overscrollBehaviorEnabled { document.settings().overscrollBehaviorEnabled() }
     80    , scrollBehaviorEnabled { document.settings().CSSOMViewSmoothScrollingEnabled() }
     81    , springTimingFunctionEnabled { document.settings().springTimingFunctionEnabled() }
     82#if ENABLE(TEXT_AUTOSIZING)
     83    , textAutosizingEnabled { document.settings().textAutosizingEnabled() }
     84#endif
     85    , useLegacyBackgroundSizeShorthandBehavior { document.settings().useLegacyBackgroundSizeShorthandBehavior() }
    7486#if ENABLE(ATTACHMENT_ELEMENT)
    75     attachmentEnabled = RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled();
     87    , attachmentEnabled { RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled() }
    7688#endif
    77     deferredCSSParserEnabled = document.settings().deferredCSSParserEnabled();
    78     scrollBehaviorEnabled = document.settings().CSSOMViewSmoothScrollingEnabled();
    79     overscrollBehaviorEnabled = document.settings().overscrollBehaviorEnabled();
    80     useSystemAppearance = document.page() ? document.page()->useSystemAppearance() : false;
    81     individualTransformPropertiesEnabled = document.settings().cssIndividualTransformPropertiesEnabled();
    82     aspectRatioEnabled = document.settings().aspectRatioEnabled();
     89{
    8390}
    8491
     
    8895        && a.charset == b.charset
    8996        && a.mode == b.mode
     97        && a.enclosingRuleType == b.enclosingRuleType
    9098        && a.isHTMLDocument == b.isHTMLDocument
     99        && a.hasDocumentSecurityOrigin == b.hasDocumentSecurityOrigin
     100        && a.isContentOpaque == b.isContentOpaque
     101        && a.useSystemAppearance == b.useSystemAppearance
     102        && a.aspectRatioEnabled == b.aspectRatioEnabled
     103        && a.colorFilterEnabled == b.colorFilterEnabled
     104        && a.constantPropertiesEnabled == b.constantPropertiesEnabled
     105        && a.deferredCSSParserEnabled == b.deferredCSSParserEnabled
     106        && a.enforcesCSSMIMETypeInNoQuirksMode == b.enforcesCSSMIMETypeInNoQuirksMode
     107        && a.individualTransformPropertiesEnabled == b.individualTransformPropertiesEnabled
     108#if ENABLE(OVERFLOW_SCROLLING_TOUCH)
     109        && a.legacyOverflowScrollingTouchEnabled == b.legacyOverflowScrollingTouchEnabled
     110#endif
     111        && a.overscrollBehaviorEnabled == b.overscrollBehaviorEnabled
     112        && a.scrollBehaviorEnabled == b.scrollBehaviorEnabled
     113        && a.springTimingFunctionEnabled == b.springTimingFunctionEnabled
    91114#if ENABLE(TEXT_AUTOSIZING)
    92115        && a.textAutosizingEnabled == b.textAutosizingEnabled
    93116#endif
    94 #if ENABLE(OVERFLOW_SCROLLING_TOUCH)
    95         && a.legacyOverflowScrollingTouchEnabled == b.legacyOverflowScrollingTouchEnabled
    96 #endif
    97         && a.enforcesCSSMIMETypeInNoQuirksMode == b.enforcesCSSMIMETypeInNoQuirksMode
    98117        && a.useLegacyBackgroundSizeShorthandBehavior == b.useLegacyBackgroundSizeShorthandBehavior
    99         && a.springTimingFunctionEnabled == b.springTimingFunctionEnabled
    100         && a.constantPropertiesEnabled == b.constantPropertiesEnabled
    101         && a.colorFilterEnabled == b.colorFilterEnabled
    102118#if ENABLE(ATTACHMENT_ELEMENT)
    103119        && a.attachmentEnabled == b.attachmentEnabled
    104120#endif
    105         && a.deferredCSSParserEnabled == b.deferredCSSParserEnabled
    106         && a.scrollBehaviorEnabled == b.scrollBehaviorEnabled
    107         && a.individualTransformPropertiesEnabled == b.individualTransformPropertiesEnabled
    108         && a.hasDocumentSecurityOrigin == b.hasDocumentSecurityOrigin
    109         && a.useSystemAppearance == b.useSystemAppearance
    110         && a.aspectRatioEnabled == b.aspectRatioEnabled
    111         && a.overscrollBehaviorEnabled == b.overscrollBehaviorEnabled;
     121    ;
    112122}
    113123
  • trunk/Source/WebCore/css/parser/CSSParserContext.h

    r270613 r272870  
    11/*
    2  * Copyright (C) 2018-2020 Apple Inc. All rights reserved.
     2 * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4242    WTF_MAKE_FAST_ALLOCATED;
    4343public:
    44 
    4544    CSSParserContext(CSSParserMode, const URL& baseURL = URL());
    4645    WEBCORE_EXPORT CSSParserContext(const Document&, const URL& baseURL = URL(), const String& charset = emptyString());
     
    5150    Optional<StyleRuleType> enclosingRuleType;
    5251    bool isHTMLDocument { false };
     52
     53    // This is only needed to support getMatchedCSSRules.
     54    bool hasDocumentSecurityOrigin { false };
     55
     56    bool isContentOpaque { false };
     57    bool useSystemAppearance { false };
     58
     59    // Settings.
     60    bool aspectRatioEnabled { false };
     61    bool colorFilterEnabled { false };
     62    bool constantPropertiesEnabled { false };
     63    bool deferredCSSParserEnabled { false };
     64    bool enforcesCSSMIMETypeInNoQuirksMode { true };
     65    bool individualTransformPropertiesEnabled { false };
     66#if ENABLE(OVERFLOW_SCROLLING_TOUCH)
     67    bool legacyOverflowScrollingTouchEnabled { false };
     68#endif
     69    bool overscrollBehaviorEnabled { false };
     70    bool scrollBehaviorEnabled { false };
     71    bool springTimingFunctionEnabled { false };
    5372#if ENABLE(TEXT_AUTOSIZING)
    5473    bool textAutosizingEnabled { false };
    5574#endif
    56 #if ENABLE(OVERFLOW_SCROLLING_TOUCH)
    57     bool legacyOverflowScrollingTouchEnabled { false };
    58 #endif
    59     bool enforcesCSSMIMETypeInNoQuirksMode { true };
    6075    bool useLegacyBackgroundSizeShorthandBehavior { false };
    61     bool springTimingFunctionEnabled { false };
    62     bool constantPropertiesEnabled { false };
    63     bool colorFilterEnabled { false };
     76
     77    // RuntimeEnabledFeatures.
    6478#if ENABLE(ATTACHMENT_ELEMENT)
    6579    bool attachmentEnabled { false };
    6680#endif
    67     bool deferredCSSParserEnabled { false };
    68     bool scrollBehaviorEnabled { false };
    69     bool individualTransformPropertiesEnabled { false };
    70 
    71     bool overscrollBehaviorEnabled { false };
    72    
    73     // This is only needed to support getMatchedCSSRules.
    74     bool hasDocumentSecurityOrigin { false };
    75    
    76     bool useSystemAppearance { false };
    7781
    7882    URL completeURL(const String& url) const;
    79 
    80     bool isContentOpaque { false };
    81 
    82     bool aspectRatioEnabled { false };
    8383};
    8484
     
    9191    static unsigned hash(const CSSParserContext& key)
    9292    {
     93        // FIXME: Convert this to use WTF::Hasher.
     94
    9395        unsigned hash = 0;
    9496        if (!key.baseURL.isNull())
  • trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp

    r272610 r272870  
    17271727}
    17281728
    1729 static RefPtr<CSSValue> consumeShadow(CSSParserTokenRange& range, CSSParserMode cssParserMode, bool isBoxShadowProperty)
     1729static RefPtr<CSSValue> consumeShadow(CSSParserTokenRange& range, const CSSParserContext& context, bool isBoxShadowProperty)
    17301730{
    17311731    if (range.peek().id() == CSSValueNone)
     
    17341734    RefPtr<CSSValueList> shadowValueList = CSSValueList::createCommaSeparated();
    17351735    do {
    1736         if (RefPtr<CSSShadowValue> shadowValue = consumeSingleShadow(range, cssParserMode, isBoxShadowProperty, isBoxShadowProperty))
    1737             shadowValueList->append(*shadowValue);
     1736        if (auto shadowValue = consumeSingleShadow(range, context, isBoxShadowProperty, isBoxShadowProperty))
     1737            shadowValueList->append(shadowValue.releaseNonNull());
    17381738        else
    17391739            return nullptr;
     
    18141814}
    18151815
    1816 static RefPtr<CSSPrimitiveValue> consumeCaretColor(CSSParserTokenRange& range, CSSParserMode cssParserMode)
     1816static RefPtr<CSSPrimitiveValue> consumeCaretColor(CSSParserTokenRange& range, const CSSParserContext& context)
    18171817{
    18181818    if (range.peek().id() == CSSValueAuto)
    18191819        return consumeIdent(range);
    1820     return consumeColor(range, cssParserMode);
    1821 }
    1822 
    1823 static RefPtr<CSSValue> consumeOutlineColor(CSSParserTokenRange& range, CSSParserMode cssParserMode)
     1820    return consumeColor(range, context);
     1821}
     1822
     1823static RefPtr<CSSValue> consumeOutlineColor(CSSParserTokenRange& range, const CSSParserContext& context)
    18241824{
    18251825    // Allow the special focus color even in HTML Standard parsing mode.
    18261826    if (range.peek().id() == CSSValueWebkitFocusRingColor)
    18271827        return consumeIdent(range);
    1828     return consumeColor(range, cssParserMode);
     1828    return consumeColor(range, context);
    18291829}
    18301830
     
    22292229}
    22302230
    2231 static RefPtr<CSSValue> consumePaintStroke(CSSParserTokenRange& range, CSSParserMode cssParserMode)
     2231static RefPtr<CSSValue> consumePaintStroke(CSSParserTokenRange& range, const CSSParserContext& context)
    22322232{
    22332233    if (range.peek().id() == CSSValueNone)
     
    22392239            parsedValue = consumeIdent(range);
    22402240        else
    2241             parsedValue = consumeColor(range, cssParserMode);
     2241            parsedValue = consumeColor(range, context);
    22422242        if (parsedValue) {
    22432243            RefPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
     
    22482248        return url;
    22492249    }
    2250     return consumeColor(range, cssParserMode);
     2250    return consumeColor(range, context);
    22512251}
    22522252
     
    32593259        return consumeBackgroundSize(property, range, context.mode);
    32603260    case CSSPropertyBackgroundColor:
    3261         return consumeColor(range, context.mode);
     3261        return consumeColor(range, context);
    32623262    default:
    32633263        break;
     
    42424242        return consumePositiveInteger(m_range);
    42434243    case CSSPropertyTextDecorationColor:
    4244         return consumeColor(m_range, m_context.mode);
     4244        return consumeColor(m_range, m_context);
    42454245    case CSSPropertyTextDecorationSkip:
    42464246        return consumeTextDecorationSkip(m_range);
     
    42624262    case CSSPropertyLightingColor:
    42634263    case CSSPropertyColumnRuleColor:
    4264         return consumeColor(m_range, m_context.mode);
     4264        return consumeColor(m_range, m_context);
    42654265    case CSSPropertyCaretColor:
    4266         return consumeCaretColor(m_range, m_context.mode);
     4266        return consumeCaretColor(m_range, m_context);
    42674267    case CSSPropertyColor:
    42684268    case CSSPropertyBackgroundColor:
    4269         return consumeColor(m_range, m_context.mode, inQuirksMode());
     4269        return consumeColor(m_range, m_context, inQuirksMode());
    42704270    case CSSPropertyBorderInlineStartWidth:
    42714271    case CSSPropertyBorderInlineEndWidth:
     
    42794279        bool allowQuirkyColors = inQuirksMode()
    42804280            && (currentShorthand == CSSPropertyInvalid || currentShorthand == CSSPropertyBorderColor);
    4281         return consumeColor(m_range, m_context.mode, allowQuirkyColors);
     4281        return consumeColor(m_range, m_context, allowQuirkyColors);
    42824282    }
    42834283    case CSSPropertyBorderBottomWidth:
     
    42954295    case CSSPropertyBoxShadow:
    42964296    case CSSPropertyWebkitBoxShadow:
    4297         return consumeShadow(m_range, m_context.mode, property == CSSPropertyBoxShadow || property == CSSPropertyWebkitBoxShadow);
     4297        return consumeShadow(m_range, m_context, property == CSSPropertyBoxShadow || property == CSSPropertyWebkitBoxShadow);
    42984298    case CSSPropertyFilter:
    42994299#if ENABLE(FILTERS_LEVEL_2)
     
    43434343    case CSSPropertyFill:
    43444344    case CSSPropertyStroke:
    4345         return consumePaintStroke(m_range, m_context.mode);
     4345        return consumePaintStroke(m_range, m_context);
    43464346    case CSSPropertyGlyphOrientationVertical:
    43474347    case CSSPropertyGlyphOrientationHorizontal:
     
    50945094        }
    50955095        if (!color) {
    5096             color = consumeColor(m_range, m_context.mode);
     5096            color = consumeColor(m_range, m_context);
    50975097            if (color)
    50985098                continue;
  • trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp

    r272436 r272870  
    691691}
    692692
    693 static uint8_t clampRGBComponent(double value, bool isPercentage)
    694 {
    695     if (isPercentage)
     693static Optional<double> consumeOptionalAlpha(CSSParserTokenRange& range)
     694{
     695    if (!consumeSlashIncludingWhitespace(range))
     696        return 1.0;
     697
     698    if (auto alphaParameter = consumeNumberOrPercentDividedBy100Raw(range))
     699        return clampTo(*alphaParameter, 0.0, 1.0);
     700
     701    return WTF::nullopt;
     702}
     703
     704static Optional<double> consumeHue(CSSParserTokenRange& range, const CSSParserContext& context)
     705{
     706    if (auto angle = consumeAngleRaw(range, context.mode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid))
     707        return CSSPrimitiveValue::computeDegrees(angle->type, angle->value);
     708
     709    return consumeNumberRaw(range);
     710}
     711
     712static double normalizeHue(double hue)
     713{
     714    return std::fmod(std::fmod(hue, 360.0) + 360.0, 360.0);
     715}
     716
     717enum class RGBComponentType { Number, Percentage };
     718
     719static uint8_t clampRGBComponent(double value, RGBComponentType componentType)
     720{
     721    if (componentType == RGBComponentType::Percentage)
    696722        value = value / 100.0 * 255.0;
    697723
     
    699725}
    700726
    701 static Color parseRGBParameters(CSSParserTokenRange& range)
     727enum class RGBOrHSLSeparatorSyntax { Commas, WhitespaceSlash };
     728
     729static bool consumeRGBOrHSLSeparator(CSSParserTokenRange& args, RGBOrHSLSeparatorSyntax syntax)
     730{
     731    if (syntax == RGBOrHSLSeparatorSyntax::Commas)
     732        return consumeCommaIncludingWhitespace(args);
     733    return true;
     734}
     735
     736static bool consumeRGBOrHSLAlphaSeparator(CSSParserTokenRange& args, RGBOrHSLSeparatorSyntax syntax)
     737{
     738    if (syntax == RGBOrHSLSeparatorSyntax::Commas)
     739        return consumeCommaIncludingWhitespace(args);
     740    return consumeSlashIncludingWhitespace(args);
     741}
     742
     743static Optional<double> consumeRGBOrHSLOptionalAlpha(CSSParserTokenRange& args, RGBOrHSLSeparatorSyntax syntax)
     744{
     745    if (!consumeRGBOrHSLAlphaSeparator(args, syntax))
     746        return 1.0;
     747
     748    return consumeNumberOrPercentDividedBy100Raw(args);
     749}
     750
     751static Color parseRGBParameters(CSSParserTokenRange& range, const CSSParserContext&)
    702752{
    703753    ASSERT(range.peek().functionId() == CSSValueRgb || range.peek().functionId() == CSSValueRgba);
    704754    auto args = consumeFunction(range);
    705755
    706     bool isPercentage = false;
    707     double colorParameter;
    708     if (auto number = consumeNumberRaw(args))
    709         colorParameter = *number;
    710     else if (auto percent = consumePercentRaw(args)) {
    711         colorParameter = *percent;
    712         isPercentage = true;
    713     } else
    714         return { };
    715 
    716     enum class ColorSyntax {
    717         Commas,
    718         WhitespaceSlash,
     756    struct InitialComponent {
     757        double value;
     758        RGBComponentType type;
    719759    };
    720760
    721     ColorSyntax syntax = ColorSyntax::Commas;
    722     auto consumeSeparator = [&] {
    723         if (syntax == ColorSyntax::Commas)
    724             return consumeCommaIncludingWhitespace(args);
    725        
    726         return true;
     761    auto consumeInitialComponent = [](auto& args) -> Optional<InitialComponent> {
     762        if (auto number = consumeNumberRaw(args))
     763            return { { *number, RGBComponentType::Number } };
     764        if (auto percent = consumePercentRaw(args))
     765            return { { *percent, RGBComponentType::Percentage } };
     766        return WTF::nullopt;
    727767    };
    728768
    729     uint8_t colorArray[3];
    730     colorArray[0] = clampRGBComponent(colorParameter, isPercentage);
    731     for (int i = 1; i < 3; i++) {
    732         if (i == 1)
    733             syntax = consumeCommaIncludingWhitespace(args) ? ColorSyntax::Commas : ColorSyntax::WhitespaceSlash;
    734         else if (!consumeSeparator())
    735             return { };
    736 
    737         if (isPercentage) {
    738             auto percent = consumePercentRaw(args);
    739             if (!percent)
    740                 return { };
    741             colorArray[i] = clampRGBComponent(*percent, true);
    742         } else {
    743             auto number = consumeNumberRaw(args);
    744             if (!number)
    745                 return { };
    746             colorArray[i] = clampRGBComponent(*number, false);
    747         }
    748     }
    749 
    750     // Historically, alpha was only parsed for rgba(), but css-color-4 specifies that rgba() is a simple alias for rgb().
    751     auto consumeAlphaSeparator = [&] {
    752         if (syntax == ColorSyntax::Commas)
    753             return consumeCommaIncludingWhitespace(args);
    754        
    755         return consumeSlashIncludingWhitespace(args);
     769    auto consumeComponent = [](auto& args, auto componentType) {
     770        switch (componentType) {
     771        case RGBComponentType::Percentage:
     772            return consumePercentRaw(args);
     773        case RGBComponentType::Number:
     774            return consumeNumberRaw(args);
     775        }
    756776    };
    757777
    758     uint8_t alphaComponent = 255;
    759     if (consumeAlphaSeparator()) {
    760         auto alpha = consumeNumberOrPercentDividedBy100Raw(args);
    761         if (!alpha)
    762             return { };
    763         alphaComponent = convertFloatAlphaTo<uint8_t>(*alpha);
    764     }
     778    auto initialComponent = consumeInitialComponent(args);
     779    if (!initialComponent)
     780        return { };
     781
     782    auto componentType = initialComponent->type;
     783    auto red = initialComponent->value;
     784
     785    auto syntax = consumeCommaIncludingWhitespace(args) ? RGBOrHSLSeparatorSyntax::Commas : RGBOrHSLSeparatorSyntax::WhitespaceSlash;
     786   
     787    auto green = consumeComponent(args, componentType);
     788    if (!green)
     789        return { };
     790
     791    if (!consumeRGBOrHSLSeparator(args, syntax))
     792        return { };
     793
     794    auto blue = consumeComponent(args, componentType);
     795    if (!blue)
     796        return { };
     797
     798    auto alpha = consumeRGBOrHSLOptionalAlpha(args, syntax);
     799    if (!alpha)
     800        return { };
    765801
    766802    if (!args.atEnd())
    767803        return { };
    768804
    769     return SRGBA<uint8_t> { colorArray[0], colorArray[1], colorArray[2], alphaComponent };
    770 }
    771 
    772 static Color parseHSLParameters(CSSParserTokenRange& range, CSSParserMode cssParserMode)
     805    auto normalizedRed = clampRGBComponent(red, componentType);
     806    auto normalizedGreen = clampRGBComponent(*green, componentType);
     807    auto normalizedBlue = clampRGBComponent(*blue, componentType);
     808    auto normalizedAlpha = convertFloatAlphaTo<uint8_t>(*alpha);
     809
     810    return SRGBA<uint8_t> { normalizedRed, normalizedGreen, normalizedBlue, normalizedAlpha };
     811}
     812
     813static Color parseHSLParameters(CSSParserTokenRange& range, const CSSParserContext& context)
    773814{
    774815    ASSERT(range.peek().functionId() == CSSValueHsl || range.peek().functionId() == CSSValueHsla);
    775816    auto args = consumeFunction(range);
    776817
    777     double hueAngleInDegrees;
    778     if (auto angle = consumeAngleRaw(args, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid))
    779         hueAngleInDegrees = CSSPrimitiveValue::computeDegrees(angle->type, angle->value);
    780     else if (auto number = consumeNumberRaw(args))
    781         hueAngleInDegrees = *number;
    782     else
    783         return { };
    784 
    785     double colorArray[3];
    786     colorArray[0] = fmod(fmod(hueAngleInDegrees, 360.0) + 360.0, 360.0) / 360.0;
    787 
    788     bool requiresCommas = false;
    789     for (int i = 1; i < 3; i++) {
    790         if (consumeCommaIncludingWhitespace(args)) {
    791             if (i != 1 && !requiresCommas)
    792                 return { };
    793             requiresCommas = true;
    794         } else if (requiresCommas || args.atEnd() || (&args.peek() - 1)->type() != WhitespaceToken)
    795             return { };
    796         auto percent = consumePercentRaw(args);
    797         if (!percent)
    798             return { };
    799         colorArray[i] = clampTo<double>(*percent, 0.0, 100.0) / 100.0; // Needs to be value between 0 and 1.0.
    800     }
    801 
    802     bool commaConsumed = consumeCommaIncludingWhitespace(args);
    803     bool slashConsumed = consumeSlashIncludingWhitespace(args);
    804     if ((commaConsumed && !requiresCommas) || (slashConsumed && requiresCommas))
    805         return { };
    806 
    807     double alpha = 1.0;
    808     if (commaConsumed || slashConsumed) {
    809         auto alphaParameter = consumeNumberOrPercentDividedBy100Raw(args);
    810         if (!alphaParameter)
    811             return { };
    812         alpha = clampTo<double>(*alphaParameter, 0.0, 1.0);
    813     }
     818    auto hue = consumeHue(args, context);
     819    if (!hue)
     820        return { };
     821
     822    auto syntax = consumeCommaIncludingWhitespace(args) ? RGBOrHSLSeparatorSyntax::Commas : RGBOrHSLSeparatorSyntax::WhitespaceSlash;
     823
     824    auto saturation = consumePercentRaw(args);
     825    if (!saturation)
     826        return { };
     827
     828    if (!consumeRGBOrHSLSeparator(args, syntax))
     829        return { };
     830
     831    auto lightness = consumePercentRaw(args);
     832    if (!lightness)
     833        return { };
     834
     835    auto alpha = consumeRGBOrHSLOptionalAlpha(args, syntax);
     836    if (!alpha)
     837        return { };
    814838
    815839    if (!args.atEnd())
    816840        return { };
    817841
    818     return convertColor<SRGBA<uint8_t>>(HSLA<float> { static_cast<float>(colorArray[0]), static_cast<float>(colorArray[1]), static_cast<float>(colorArray[2]), static_cast<float>(alpha) });
    819 }
    820 
    821 static Optional<float> parseOptionalAlpha(CSSParserTokenRange& range)
    822 {
    823     if (!consumeSlashIncludingWhitespace(range))
    824         return 1.0f;
    825 
    826     if (auto alphaParameter = consumeNumberOrPercentDividedBy100Raw(range))
    827         return clampTo<float>(*alphaParameter, 0.0, 1.0);
    828 
    829     return WTF::nullopt;
    830 }
    831 
    832 static Color parseHWBParameters(CSSParserTokenRange& range, CSSParserMode cssParserMode)
    833 {
    834     ASSERT(range.peek().functionId() == CSSValueHwb);
    835     auto args = consumeFunction(range);
    836 
    837     double hueAngleInDegrees;
    838     if (auto angle = consumeAngleRaw(args, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid))
    839         hueAngleInDegrees = CSSPrimitiveValue::computeDegrees(angle->type, angle->value);
    840     else if (auto number = consumeNumberRaw(args))
    841         hueAngleInDegrees = *number;
    842     else
    843         return { };
    844 
    845     auto whiteness = consumePercentRaw(args, ValueRangeAll);
    846     if (!whiteness)
    847         return { };
    848 
    849     auto blackness = consumePercentRaw(args, ValueRangeAll);
    850     if (!blackness)
    851         return { };
    852 
    853     auto alpha = parseOptionalAlpha(args);
    854     if (!alpha)
    855         return { };
    856 
    857     if (!args.atEnd())
    858         return { };
    859 
    860     // Normalize hue.
    861 
    862     hueAngleInDegrees = std::fmod(hueAngleInDegrees, 360.0);
    863     if (hueAngleInDegrees < 0.0)
    864         hueAngleInDegrees += 360.0;
    865    
    866     // Convert angle to normalized form from 0 - 1.
    867     auto normalizedHue = hueAngleInDegrees / 360.0;
    868 
    869     // Normalize whiteness/blackness.
     842    auto normalizedHue = normalizeHue(*hue);
     843    auto normalizedSaturation = clampTo<double>(*saturation, 0.0, 100.0);
     844    auto normalizedLightness = clampTo<double>(*lightness, 0.0, 100.0);
     845    auto normalizedAlpha = clampTo<double>(*alpha, 0.0, 1.0);
     846
     847    return convertColor<SRGBA<uint8_t>>(HSLA<float> { static_cast<float>(normalizedHue), static_cast<float>(normalizedSaturation), static_cast<float>(normalizedLightness), static_cast<float>(normalizedAlpha) });
     848}
     849
     850struct WhitenessBlackness {
     851    double whiteness;
     852    double blackness;
     853};
     854static WhitenessBlackness normalizeWhitenessBlackness(double whiteness, double blackness)
     855{
     856    WhitenessBlackness result;
    870857
    871858    //   Values outside of these ranges are not invalid, but are clamped to the
    872859    //   ranges defined here at computed-value time.
    873     auto nomalizedWhiteness = clampTo<double>(*whiteness, 0, 100);
    874     auto nomalizedBlackness = clampTo<double>(*blackness, 0, 100);
     860    result.whiteness = clampTo<double>(whiteness, 0, 100);
     861    result.blackness = clampTo<double>(blackness, 0, 100);
    875862
    876863    //   If the sum of these two arguments is greater than 100%, then at
    877864    //   computed-value time they are further normalized to add up to 100%, with
    878865    //   the same relative ratio.
    879     if (auto sum = nomalizedWhiteness + nomalizedBlackness; sum >= 100) {
    880         nomalizedWhiteness *= 100.0 / sum;
    881         nomalizedBlackness *= 100.0 / sum;
    882     }
    883 
    884     // Convert to normalized form from 0 - 1.
    885     nomalizedWhiteness /= 100.0;
    886     nomalizedBlackness /= 100.0;
    887 
    888     return convertColor<SRGBA<uint8_t>>(HWBA<float> { static_cast<float>(normalizedHue), static_cast<float>(nomalizedWhiteness), static_cast<float>(nomalizedBlackness), static_cast<float>(*alpha) });
    889 }
    890 
    891 static Color parseLabParameters(CSSParserTokenRange& range)
     866    if (auto sum = result.whiteness + result.blackness; sum >= 100) {
     867        result.whiteness *= 100.0 / sum;
     868        result.blackness *= 100.0 / sum;
     869    }
     870
     871    return result;
     872}
     873
     874static Color parseHWBParameters(CSSParserTokenRange& range, const CSSParserContext& context)
     875{
     876    ASSERT(range.peek().functionId() == CSSValueHwb);
     877    auto args = consumeFunction(range);
     878
     879    auto hue = consumeHue(args, context);
     880    if (!hue)
     881        return { };
     882
     883    auto whiteness = consumePercentRaw(args);
     884    if (!whiteness)
     885        return { };
     886
     887    auto blackness = consumePercentRaw(args);
     888    if (!blackness)
     889        return { };
     890
     891    auto alpha = consumeOptionalAlpha(args);
     892    if (!alpha)
     893        return { };
     894
     895    if (!args.atEnd())
     896        return { };
     897
     898    auto normalizedHue = normalizeHue(*hue);
     899    auto [normalizedWhitness, normalizedBlackness] = normalizeWhitenessBlackness(*whiteness, *blackness);
     900
     901    return convertColor<SRGBA<uint8_t>>(HWBA<float> { static_cast<float>(normalizedHue), static_cast<float>(normalizedWhitness), static_cast<float>(normalizedBlackness), static_cast<float>(*alpha) });
     902}
     903
     904static Color parseLabParameters(CSSParserTokenRange& range, const CSSParserContext&)
    892905{
    893906    ASSERT(range.peek().functionId() == CSSValueLab);
    894907    auto args = consumeFunction(range);
    895908
    896     auto lightness = consumePercentRaw(args, ValueRangeAll);
     909    auto lightness = consumePercentRaw(args);
    897910    if (!lightness)
    898911        return { };
    899912
    900     auto aValue = consumeNumberRaw(args, ValueRangeAll);
     913    auto aValue = consumeNumberRaw(args);
    901914    if (!aValue)
    902915        return { };
    903916
    904     auto bValue = consumeNumberRaw(args, ValueRangeAll);
     917    auto bValue = consumeNumberRaw(args);
    905918    if (!bValue)
    906919        return { };
    907920
    908     auto alpha = parseOptionalAlpha(args);
     921    auto alpha = consumeOptionalAlpha(args);
    909922    if (!alpha)
    910923        return { };
     
    913926        return { };
    914927
    915     return Lab<float> { static_cast<float>(*lightness), static_cast<float>(*aValue), static_cast<float>(*bValue), *alpha };
    916 }
    917 
    918 static Color parseLCHParameters(CSSParserTokenRange& range, CSSParserMode cssParserMode)
     928    return Lab<float> { static_cast<float>(*lightness), static_cast<float>(*aValue), static_cast<float>(*bValue), static_cast<float>(*alpha) };
     929}
     930
     931static Color parseLCHParameters(CSSParserTokenRange& range, const CSSParserContext& context)
    919932{
    920933    ASSERT(range.peek().functionId() == CSSValueLch);
    921934    auto args = consumeFunction(range);
    922935
    923     auto lightness = consumePercentRaw(args, ValueRangeAll);
     936    auto lightness = consumePercentRaw(args);
    924937    if (!lightness)
    925938        return { };
    926939
    927     auto chromaValue = consumeNumberRaw(args, ValueRangeAll);
    928     if (!chromaValue)
    929         return { };
    930 
    931     double hueAngleInDegrees;
    932     if (auto angle = consumeAngleRaw(args, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid))
    933         hueAngleInDegrees = CSSPrimitiveValue::computeDegrees(angle->type, angle->value);
    934     else if (auto number = consumeNumberRaw(args, ValueRangeAll))
    935         hueAngleInDegrees = *number;
    936     else
    937         return { };
    938 
    939     hueAngleInDegrees = fmod(hueAngleInDegrees, 360.0);
    940     if (hueAngleInDegrees < 0.0)
    941         hueAngleInDegrees += 360.0;
    942 
    943     auto alpha = parseOptionalAlpha(args);
     940    auto chroma = consumeNumberRaw(args);
     941    if (!chroma)
     942        return { };
     943
     944    auto hue = consumeHue(args, context);
     945    if (!hue)
     946        return { };
     947
     948    auto alpha = consumeOptionalAlpha(args);
    944949    if (!alpha)
    945950        return { };
     
    948953        return { };
    949954
    950     return convertColor<Lab<float>>(LCHA<float> { static_cast<float>(*lightness), static_cast<float>(*chromaValue), static_cast<float>(hueAngleInDegrees), *alpha });
    951 }
    952 
    953 template<typename ColorType>
    954 static Color parseColorFunctionForRGBTypes(CSSParserTokenRange& args)
     955    auto normalizedHue = normalizeHue(*hue);
     956
     957    return convertColor<Lab<float>>(LCHA<float> { static_cast<float>(*lightness), static_cast<float>(*chroma), static_cast<float>(normalizedHue), static_cast<float>(*alpha) });
     958}
     959
     960template<typename ColorType> static Color parseColorFunctionForRGBTypes(CSSParserTokenRange& args)
    955961{
    956962    ASSERT(args.peek().id() == CSSValueA98Rgb || args.peek().id() == CSSValueDisplayP3 || args.peek().id() == CSSValueProphotoRgb || args.peek().id() == CSSValueRec2020 || args.peek().id() == CSSValueSRGB);
     
    965971    }
    966972
    967     auto alpha = parseOptionalAlpha(args);
     973    auto alpha = consumeOptionalAlpha(args);
    968974    if (!alpha)
    969975        return { };
    970976
    971     return ColorType { clampTo<float>(channels[0], 0.0, 1.0), clampTo<float>(channels[1], 0.0, 1.0), clampTo<float>(channels[2], 0.0, 1.0), *alpha };
     977    return ColorType { clampTo<float>(channels[0], 0.0, 1.0), clampTo<float>(channels[1], 0.0, 1.0), clampTo<float>(channels[2], 0.0, 1.0), static_cast<float>(*alpha) };
    972978}
    973979
     
    979985    double channels[3] = { 0, 0, 0 };
    980986    [&] {
    981         auto lightness = consumePercentRaw(args, ValueRangeAll);
     987        auto lightness = consumePercentRaw(args);
    982988        if (!lightness)
    983989            return;
    984990        channels[0] = *lightness;
    985991
    986         auto aValue = consumeNumberRaw(args, ValueRangeAll);
     992        auto aValue = consumeNumberRaw(args);
    987993        if (!aValue)
    988994            return;
    989995        channels[1] = *aValue;
    990996
    991         auto bValue = consumeNumberRaw(args, ValueRangeAll);
     997        auto bValue = consumeNumberRaw(args);
    992998        if (!bValue)
    993999            return;
     
    9951001    }();
    9961002
    997     auto alpha = parseOptionalAlpha(args);
     1003    auto alpha = consumeOptionalAlpha(args);
    9981004    if (!alpha)
    9991005        return { };
    10001006
    1001     return Lab<float> { static_cast<float>(channels[0]), static_cast<float>(channels[1]), static_cast<float>(channels[2]), *alpha };
     1007    return Lab<float> { static_cast<float>(channels[0]), static_cast<float>(channels[1]), static_cast<float>(channels[2]), static_cast<float>(*alpha) };
    10021008}
    10031009
     
    10091015    double channels[3] = { 0, 0, 0 };
    10101016    [&] {
    1011         auto x = consumeNumberRaw(args, ValueRangeAll);
     1017        auto x = consumeNumberRaw(args);
    10121018        if (!x)
    10131019            return;
    10141020        channels[0] = *x;
    10151021
    1016         auto y = consumeNumberRaw(args, ValueRangeAll);
     1022        auto y = consumeNumberRaw(args);
    10171023        if (!y)
    10181024            return;
    10191025        channels[1] = *y;
    10201026
    1021         auto z = consumeNumberRaw(args, ValueRangeAll);
     1027        auto z = consumeNumberRaw(args);
    10221028        if (!z)
    10231029            return;
     
    10251031    }();
    10261032
    1027     auto alpha = parseOptionalAlpha(args);
     1033    auto alpha = consumeOptionalAlpha(args);
    10281034    if (!alpha)
    10291035        return { };
    10301036
    1031     return XYZA<float, WhitePoint::D50> { static_cast<float>(channels[0]), static_cast<float>(channels[1]), static_cast<float>(channels[2]), *alpha };
     1037    return XYZA<float, WhitePoint::D50> { static_cast<float>(channels[0]), static_cast<float>(channels[1]), static_cast<float>(channels[2]), static_cast<float>(*alpha) };
    10321038}
    10331039
     
    11121118}
    11131119
    1114 static Color parseColorFunction(CSSParserTokenRange& range, CSSParserMode cssParserMode)
     1120static Color parseColorFunction(CSSParserTokenRange& range, const CSSParserContext& context)
    11151121{
    11161122    CSSParserTokenRange colorRange = range;
     
    11201126    case CSSValueRgb:
    11211127    case CSSValueRgba:
    1122         color = parseRGBParameters(colorRange);
     1128        color = parseRGBParameters(colorRange, context);
    11231129        break;
    11241130    case CSSValueHsl:
    11251131    case CSSValueHsla:
    1126         color = parseHSLParameters(colorRange, cssParserMode);
     1132        color = parseHSLParameters(colorRange, context);
    11271133        break;
    11281134    case CSSValueHwb:
    1129         color = parseHWBParameters(colorRange, cssParserMode);
     1135        color = parseHWBParameters(colorRange, context);
    11301136        break;
    11311137    case CSSValueLab:
    1132         color = parseLabParameters(colorRange);
     1138        color = parseLabParameters(colorRange, context);
    11331139        break;
    11341140    case CSSValueLch:
    1135         color = parseLCHParameters(colorRange, cssParserMode);
     1141        color = parseLCHParameters(colorRange, context);
    11361142        break;
    11371143    case CSSValueColor:
     
    11461152}
    11471153
    1148 Color consumeColorWorkerSafe(CSSParserTokenRange& range, CSSParserMode cssParserMode)
     1154Color consumeColorWorkerSafe(CSSParserTokenRange& range, const CSSParserContext& context)
    11491155{
    11501156    Color result;
     
    11551161        if (StyleColor::isSystemColor(keyword))
    11561162            return { };
    1157         if (!isValueAllowedInMode(keyword, cssParserMode))
     1163        if (!isValueAllowedInMode(keyword, context.mode))
    11581164            return { };
    11591165        result = StyleColor::colorFromKeyword(keyword, { });
     
    11641170        result = *parsedColor;
    11651171    else
    1166         result = parseColorFunction(range, cssParserMode);
     1172        result = parseColorFunction(range, context);
    11671173
    11681174    if (!range.atEnd())
     
    11721178}
    11731179
    1174 RefPtr<CSSPrimitiveValue> consumeColor(CSSParserTokenRange& range, CSSParserMode cssParserMode, bool acceptQuirkyColors)
     1180RefPtr<CSSPrimitiveValue> consumeColor(CSSParserTokenRange& range, const CSSParserContext& context, bool acceptQuirkyColors)
    11751181{
    11761182    auto keyword = range.peek().id();
    11771183    if (StyleColor::isColorKeyword(keyword)) {
    1178         if (!isValueAllowedInMode(keyword, cssParserMode))
     1184        if (!isValueAllowedInMode(keyword, context.mode))
    11791185            return nullptr;
    11801186        return consumeIdent(range);
     
    11841190        color = *parsedColor;
    11851191    else {
    1186         color = parseColorFunction(range, cssParserMode);
     1192        color = parseColorFunction(range, context);
    11871193        if (!color.isValid())
    11881194            return nullptr;
     
    14141420
    14151421// Used to parse colors for -webkit-gradient(...).
    1416 static RefPtr<CSSPrimitiveValue> consumeDeprecatedGradientStopColor(CSSParserTokenRange& args, CSSParserMode cssParserMode)
     1422static RefPtr<CSSPrimitiveValue> consumeDeprecatedGradientStopColor(CSSParserTokenRange& args, const CSSParserContext& context)
    14171423{
    14181424    if (args.peek().id() == CSSValueCurrentcolor)
    14191425        return nullptr;
    1420     return consumeColor(args, cssParserMode);
    1421 }
    1422 
    1423 static bool consumeDeprecatedGradientColorStop(CSSParserTokenRange& range, CSSGradientColorStop& stop, CSSParserMode cssParserMode)
     1426    return consumeColor(args, context);
     1427}
     1428
     1429static bool consumeDeprecatedGradientColorStop(CSSParserTokenRange& range, CSSGradientColorStop& stop, const CSSParserContext& context)
    14241430{
    14251431    CSSValueID id = range.peek().functionId();
     
    14431449
    14441450    stop.position = CSSValuePool::singleton().createValue(position, CSSUnitType::CSS_NUMBER);
    1445     stop.color = consumeDeprecatedGradientStopColor(args, cssParserMode);
     1451    stop.color = consumeDeprecatedGradientStopColor(args, context);
    14461452    return stop.color && args.atEnd();
    14471453}
    14481454
    1449 static RefPtr<CSSValue> consumeDeprecatedGradient(CSSParserTokenRange& args, CSSParserMode cssParserMode)
     1455static RefPtr<CSSValue> consumeDeprecatedGradient(CSSParserTokenRange& args, const CSSParserContext& context)
    14501456{
    14511457    RefPtr<CSSGradientValue> result;
     
    15001506    CSSGradientColorStop stop;
    15011507    while (consumeCommaIncludingWhitespace(args)) {
    1502         if (!consumeDeprecatedGradientColorStop(args, stop, cssParserMode))
     1508        if (!consumeDeprecatedGradientColorStop(args, stop, context))
    15031509            return nullptr;
    15041510        result->addStop(WTFMove(stop));
     
    15091515}
    15101516
    1511 static bool consumeGradientColorStops(CSSParserTokenRange& range, CSSParserMode mode, CSSGradientValue& gradient)
     1517static bool consumeGradientColorStops(CSSParserTokenRange& range, const CSSParserContext& context, CSSGradientValue& gradient)
    15121518{
    15131519    bool supportsColorHints = gradient.gradientType() == CSSLinearGradient || gradient.gradientType() == CSSRadialGradient || gradient.gradientType() == CSSConicGradient;
     
    15151521    auto consumeStopPosition = [&] {
    15161522        return gradient.gradientType() == CSSConicGradient
    1517             ? consumeAngleOrPercent(range, mode, ValueRangeAll, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow)
    1518             : consumeLengthOrPercent(range, mode, ValueRangeAll);
     1523            ? consumeAngleOrPercent(range, context.mode, ValueRangeAll, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow)
     1524            : consumeLengthOrPercent(range, context.mode, ValueRangeAll);
    15191525    };
    15201526
     
    15221528    bool previousStopWasColorHint = true;
    15231529    do {
    1524         CSSGradientColorStop stop { consumeColor(range, mode), consumeStopPosition(), { } };
     1530        CSSGradientColorStop stop { consumeColor(range, context), consumeStopPosition(), { } };
    15251531        if (!stop.color && !stop.position)
    15261532            return false;
     
    15531559}
    15541560
    1555 static RefPtr<CSSValue> consumeDeprecatedRadialGradient(CSSParserTokenRange& args, CSSParserMode cssParserMode, CSSGradientRepeat repeating)
     1561static RefPtr<CSSValue> consumeDeprecatedRadialGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating)
    15561562{
    15571563    auto result = CSSRadialGradientValue::create(repeating, CSSPrefixedRadialGradient);
    15581564
    1559     auto centerCoordinate = consumeOneOrTwoValuedPositionCoordinates(args, cssParserMode, UnitlessQuirk::Forbid);
     1565    auto centerCoordinate = consumeOneOrTwoValuedPositionCoordinates(args, context.mode, UnitlessQuirk::Forbid);
    15601566    if (centerCoordinate && !consumeCommaIncludingWhitespace(args))
    15611567        return nullptr;
     
    15681574    // Or, two lengths or percentages
    15691575    if (!shape && !sizeKeyword) {
    1570         auto horizontalSize = consumeLengthOrPercent(args, cssParserMode, ValueRangeNonNegative);
     1576        auto horizontalSize = consumeLengthOrPercent(args, context.mode, ValueRangeNonNegative);
    15711577        RefPtr<CSSPrimitiveValue> verticalSize;
    15721578        if (horizontalSize) {
    1573             verticalSize = consumeLengthOrPercent(args, cssParserMode, ValueRangeNonNegative);
     1579            verticalSize = consumeLengthOrPercent(args, context.mode, ValueRangeNonNegative);
    15741580            if (!verticalSize)
    15751581                return nullptr;
     
    15821588    }
    15831589
    1584     if (!consumeGradientColorStops(args, cssParserMode, result))
     1590    if (!consumeGradientColorStops(args, context, result))
    15851591        return nullptr;
    15861592
     
    15971603}
    15981604
    1599 static RefPtr<CSSValue> consumeRadialGradient(CSSParserTokenRange& args, CSSParserMode cssParserMode, CSSGradientRepeat repeating)
     1605static RefPtr<CSSValue> consumeRadialGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating)
    16001606{
    16011607    RefPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating, CSSRadialGradient);
     
    16251631            }
    16261632        } else {
    1627             auto center = consumeLengthOrPercent(args, cssParserMode, ValueRangeNonNegative);
     1633            auto center = consumeLengthOrPercent(args, context.mode, ValueRangeNonNegative);
    16281634            if (!center)
    16291635                break;
     
    16311637                return nullptr;
    16321638            horizontalSize = center;
    1633             center = consumeLengthOrPercent(args, cssParserMode, ValueRangeNonNegative);
     1639            center = consumeLengthOrPercent(args, context.mode, ValueRangeNonNegative);
    16341640            if (center) {
    16351641                verticalSize = center;
     
    16601666        args.consumeIncludingWhitespace();
    16611667       
    1662         auto centerCoordinate = consumePositionCoordinates(args, cssParserMode, UnitlessQuirk::Forbid, PositionSyntax::Position);
     1668        auto centerCoordinate = consumePositionCoordinates(args, context.mode, UnitlessQuirk::Forbid, PositionSyntax::Position);
    16631669        if (!centerCoordinate)
    16641670            return nullptr;
     
    16771683    if ((shape || sizeKeyword || horizontalSize || centerX || centerY) && !consumeCommaIncludingWhitespace(args))
    16781684        return nullptr;
    1679     if (!consumeGradientColorStops(args, cssParserMode, *result))
     1685    if (!consumeGradientColorStops(args, context, *result))
    16801686        return nullptr;
    16811687
     
    16881694}
    16891695
    1690 static RefPtr<CSSValue> consumeLinearGradient(CSSParserTokenRange& args, CSSParserMode cssParserMode, CSSGradientRepeat repeating, CSSGradientType gradientType)
     1696static RefPtr<CSSValue> consumeLinearGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating, CSSGradientType gradientType)
    16911697{
    16921698    RefPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating, gradientType);
    16931699
    16941700    bool expectComma = true;
    1695     RefPtr<CSSPrimitiveValue> angle = consumeAngle(args, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow);
     1701    RefPtr<CSSPrimitiveValue> angle = consumeAngle(args, context.mode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow);
    16961702    if (angle)
    16971703        result->setAngle(angle.releaseNonNull());
     
    17161722    if (expectComma && !consumeCommaIncludingWhitespace(args))
    17171723        return nullptr;
    1718     if (!consumeGradientColorStops(args, cssParserMode, *result))
     1724    if (!consumeGradientColorStops(args, context, *result))
    17191725        return nullptr;
    17201726    return result;
    17211727}
    17221728
    1723 static RefPtr<CSSValue> consumeConicGradient(CSSParserTokenRange& args, CSSParserContext context, CSSGradientRepeat repeating)
     1729static RefPtr<CSSValue> consumeConicGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating)
    17241730{
    17251731#if ENABLE(CSS_CONIC_GRADIENTS)
     
    17551761    if (expectComma && !consumeCommaIncludingWhitespace(args))
    17561762        return nullptr;
    1757     if (!consumeGradientColorStops(args, context.mode, *result))
     1763    if (!consumeGradientColorStops(args, context, *result))
    17581764        return nullptr;
    17591765    return result;
     
    17661772}
    17671773
    1768 RefPtr<CSSValue> consumeImageOrNone(CSSParserTokenRange& range, CSSParserContext context)
     1774RefPtr<CSSValue> consumeImageOrNone(CSSParserTokenRange& range, const CSSParserContext& context)
    17691775{
    17701776    if (range.peek().id() == CSSValueNone)
     
    17731779}
    17741780
    1775 static RefPtr<CSSValue> consumeCrossFade(CSSParserTokenRange& args, CSSParserContext context, bool prefixed)
     1781static RefPtr<CSSValue> consumeCrossFade(CSSParserTokenRange& args, const CSSParserContext& context, bool prefixed)
    17761782{
    17771783    auto fromImageValue = consumeImageOrNone(args, context);
     
    18491855#endif
    18501856
    1851 static RefPtr<CSSValue> consumeGeneratedImage(CSSParserTokenRange& range, CSSParserContext context)
     1857static RefPtr<CSSValue> consumeGeneratedImage(CSSParserTokenRange& range, const CSSParserContext& context)
    18521858{
    18531859    CSSValueID id = range.peek().functionId();
     
    18561862    RefPtr<CSSValue> result;
    18571863    if (id == CSSValueRadialGradient)
    1858         result = consumeRadialGradient(args, context.mode, NonRepeating);
     1864        result = consumeRadialGradient(args, context, NonRepeating);
    18591865    else if (id == CSSValueRepeatingRadialGradient)
    1860         result = consumeRadialGradient(args, context.mode, Repeating);
     1866        result = consumeRadialGradient(args, context, Repeating);
    18611867    else if (id == CSSValueWebkitLinearGradient)
    1862         result = consumeLinearGradient(args, context.mode, NonRepeating, CSSPrefixedLinearGradient);
     1868        result = consumeLinearGradient(args, context, NonRepeating, CSSPrefixedLinearGradient);
    18631869    else if (id == CSSValueWebkitRepeatingLinearGradient)
    1864         result = consumeLinearGradient(args, context.mode, Repeating, CSSPrefixedLinearGradient);
     1870        result = consumeLinearGradient(args, context, Repeating, CSSPrefixedLinearGradient);
    18651871    else if (id == CSSValueRepeatingLinearGradient)
    1866         result = consumeLinearGradient(args, context.mode, Repeating, CSSLinearGradient);
     1872        result = consumeLinearGradient(args, context, Repeating, CSSLinearGradient);
    18671873    else if (id == CSSValueLinearGradient)
    1868         result = consumeLinearGradient(args, context.mode, NonRepeating, CSSLinearGradient);
     1874        result = consumeLinearGradient(args, context, NonRepeating, CSSLinearGradient);
    18691875    else if (id == CSSValueWebkitGradient)
    1870         result = consumeDeprecatedGradient(args, context.mode);
     1876        result = consumeDeprecatedGradient(args, context);
    18711877    else if (id == CSSValueWebkitRadialGradient)
    1872         result = consumeDeprecatedRadialGradient(args, context.mode, NonRepeating);
     1878        result = consumeDeprecatedRadialGradient(args, context, NonRepeating);
    18731879    else if (id == CSSValueWebkitRepeatingRadialGradient)
    1874         result = consumeDeprecatedRadialGradient(args, context.mode, Repeating);
     1880        result = consumeDeprecatedRadialGradient(args, context, Repeating);
    18751881    else if (id == CSSValueConicGradient)
    18761882        result = consumeConicGradient(args, context, NonRepeating);
     
    20182024
    20192025    if (filterType == CSSValueDropShadow)
    2020         parsedValue = consumeSingleShadow(args, context.mode, false, false);
     2026        parsedValue = consumeSingleShadow(args, context, false, false);
    20212027    else {
    20222028        if (args.atEnd())
     
    20652071}
    20662072
    2067 RefPtr<CSSShadowValue> consumeSingleShadow(CSSParserTokenRange& range, CSSParserMode cssParserMode, bool allowInset, bool allowSpread)
     2073RefPtr<CSSShadowValue> consumeSingleShadow(CSSParserTokenRange& range, const CSSParserContext& context, bool allowInset, bool allowSpread)
    20682074{
    20692075    RefPtr<CSSPrimitiveValue> style;
     
    20902096        }
    20912097       
    2092         auto maybeColor = consumeColor(range, cssParserMode);
     2098        auto maybeColor = consumeColor(range, context);
    20932099        if (maybeColor) {
    20942100            // If we just parsed a color but already had one, the given token range is not a valid <shadow>.
     
    21042110            return nullptr;
    21052111        }
    2106         horizontalOffset = consumeLength(range, cssParserMode, ValueRangeAll);
     2112        horizontalOffset = consumeLength(range, context.mode, ValueRangeAll);
    21072113        if (!horizontalOffset)
    21082114            return nullptr;
    2109         verticalOffset = consumeLength(range, cssParserMode, ValueRangeAll);
     2115        verticalOffset = consumeLength(range, context.mode, ValueRangeAll);
    21102116        if (!verticalOffset)
    21112117            return nullptr;
     
    21142120        // The explicit check for calc() is unfortunate. This is ensuring that we only fail parsing if there is a length, but it fails the range check.
    21152121        if (token.type() == DimensionToken || token.type() == NumberToken || (token.type() == FunctionToken && CSSCalcValue::isCalcFunction(token.functionId()))) {
    2116             blurRadius = consumeLength(range, cssParserMode, ValueRangeNonNegative);
     2122            blurRadius = consumeLength(range, context.mode, ValueRangeNonNegative);
    21172123            if (!blurRadius)
    21182124                return nullptr;
     
    21202126
    21212127        if (blurRadius && allowSpread)
    2122             spreadDistance = consumeLength(range, cssParserMode, ValueRangeAll);
     2128            spreadDistance = consumeLength(range, context.mode, ValueRangeAll);
    21232129    }
    21242130   
     
    21292135}
    21302136
    2131 RefPtr<CSSValue> consumeImage(CSSParserTokenRange& range, CSSParserContext context, OptionSet<AllowedImageType> allowedImageTypes)
     2137RefPtr<CSSValue> consumeImage(CSSParserTokenRange& range, const CSSParserContext& context, OptionSet<AllowedImageType> allowedImageTypes)
    21322138{
    21332139    if ((range.peek().type() == StringToken) && (allowedImageTypes.contains(AllowedImageType::RawStringAsURL))) {
  • trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h

    r272121 r272870  
    103103RefPtr<CSSPrimitiveValue> consumeUrl(CSSParserTokenRange&);
    104104
    105 Color consumeColorWorkerSafe(CSSParserTokenRange&, CSSParserMode);
    106 RefPtr<CSSPrimitiveValue> consumeColor(CSSParserTokenRange&, CSSParserMode, bool acceptQuirkyColors = false);
     105Color consumeColorWorkerSafe(CSSParserTokenRange&, const CSSParserContext&);
     106RefPtr<CSSPrimitiveValue> consumeColor(CSSParserTokenRange&, const CSSParserContext&, bool acceptQuirkyColors = false);
    107107
    108108enum class PositionSyntax {
     
    127127};
    128128
    129 RefPtr<CSSValue> consumeImage(CSSParserTokenRange&, CSSParserContext, OptionSet<AllowedImageType> = { AllowedImageType::URLFunction, AllowedImageType::ImageSet, AllowedImageType::GeneratedImage });
    130 
    131 RefPtr<CSSValue> consumeImageOrNone(CSSParserTokenRange&, CSSParserContext);
     129RefPtr<CSSValue> consumeImage(CSSParserTokenRange&, const CSSParserContext&, OptionSet<AllowedImageType> = { AllowedImageType::URLFunction, AllowedImageType::ImageSet, AllowedImageType::GeneratedImage });
     130RefPtr<CSSValue> consumeImageOrNone(CSSParserTokenRange&, const CSSParserContext&);
    132131
    133132enum class AllowedFilterFunctions {
     
    137136
    138137RefPtr<CSSValue> consumeFilter(CSSParserTokenRange&, const CSSParserContext&, AllowedFilterFunctions);
    139 RefPtr<CSSShadowValue> consumeSingleShadow(CSSParserTokenRange&, CSSParserMode, bool allowInset, bool allowSpread);
     138RefPtr<CSSShadowValue> consumeSingleShadow(CSSParserTokenRange&, const CSSParserContext&, bool allowInset, bool allowSpread);
    140139
    141140struct FontStyleRaw {
  • trunk/Source/WebCore/editing/cocoa/DataDetection.mm

    r272436 r272870  
    601601                        // Force the lightness of the underline color to the middle, and multiply the alpha by 38%,
    602602                        // so the color will appear on light and dark backgrounds, since only one color can be specified.
    603                         hsla.lightness = 0.5f;
     603                        hsla.lightness = 50.0f;
    604604                        hsla.alpha *= 0.38f;
    605605                       
  • trunk/Source/WebCore/platform/graphics/ColorConversion.cpp

    r272837 r272870  
    5959        hue -= 360.0f;
    6060
    61     hue /= 360.0f;
    62 
    6361    return { hue, min, max, chroma };
    6462}
     
    7068    auto [hue, min, max, chroma] = calculateHSLHue(color);
    7169
    72     float lightness = 0.5f * (max + min);
     70    float lightness = (0.5f * (max + min)) * 100.0f;
    7371    float saturation;
    7472    if (!chroma)
    7573        saturation = 0;
    76     else if (lightness <= 0.5f)
    77         saturation = (chroma / (max + min));
     74    else if (lightness <= 50.0f)
     75        saturation = (chroma / (max + min)) * 100.0f;
    7876    else
    79         saturation = (chroma / (2.0f - (max + min)));
     77        saturation = (chroma / (2.0f - (max + min))) * 100.0f;
    8078
    8179    return { hue, saturation, lightness, alpha };
     
    8785    auto [hue, saturation, lightness, alpha] = color;
    8886
    89     if (!saturation)
    90         return { lightness, lightness, lightness, alpha };
    91    
    92     float temp2 = lightness <= 0.5f ? lightness * (1.0f + saturation) : lightness + saturation - lightness * saturation;
    93     float temp1 = 2.0f * lightness - temp2;
     87    if (!saturation) {
     88        auto grey = lightness / 100.0f;
     89        return { grey, grey, grey, alpha };
     90    }
     91
     92    // hueToRGB() wants hue in the 0-6 range.
     93    auto normalizedHue = (hue / 360.0f) * 6.0f;
     94    auto normalizedLightness = lightness / 100.0f;
     95    auto normalizedSaturation = saturation / 100.0f;
     96
     97    auto hueForRed = normalizedHue + 2.0f;
     98    auto hueForGreen = normalizedHue;
     99    auto hueForBlue = normalizedHue - 2.0f;
     100    if (hueForRed > 6.0f)
     101        hueForRed -= 6.0f;
     102    else if (hueForBlue < 0.0f)
     103        hueForBlue += 6.0f;
     104
     105    float temp2 = normalizedLightness <= 0.5f ? normalizedLightness * (1.0f + normalizedSaturation) : normalizedLightness + normalizedSaturation - normalizedLightness * normalizedSaturation;
     106    float temp1 = 2.0f * normalizedLightness - temp2;
    94107   
    95108    // Hue is in the range 0-6, other args in 0-1.
     
    104117    };
    105118
     119    return {
     120        hueToRGB(temp1, temp2, hueForRed),
     121        hueToRGB(temp1, temp2, hueForGreen),
     122        hueToRGB(temp1, temp2, hueForBlue),
     123        alpha
     124    };
     125}
     126
     127// MARK: HWB conversions.
     128
     129HWBA<float> ColorConversion<HWBA<float>, SRGBA<float>>::convert(const SRGBA<float>& color)
     130{
     131    // https://drafts.csswg.org/css-color-4/#rgb-to-hwb
     132    auto [hue, min, max, chroma] = calculateHSLHue(color);
     133    auto whiteness = min * 100.0f;
     134    auto blackness = (1.0f - max) * 100.0f;
     135   
     136    return { hue, whiteness, blackness, color.alpha };
     137}
     138
     139SRGBA<float> ColorConversion<SRGBA<float>, HWBA<float>>::convert(const HWBA<float>& color)
     140{
     141    // https://drafts.csswg.org/css-color-4/#hwb-to-rgb
     142    auto [hue, whiteness, blackness, alpha] = color;
     143
     144    if (whiteness + blackness == 100.0f) {
     145        auto grey = whiteness / 100.0f;
     146        return { grey, grey, grey, alpha };
     147    }
     148
    106149    // hueToRGB() wants hue in the 0-6 range.
    107     hue *= 6.0f;
    108 
    109     auto hueForRed = hue + 2.0f;
    110     auto hueForGreen = hue;
    111     auto hueForBlue = hue - 2.0f;
     150    auto normalizedHue = (hue / 360.0f) * 6.0f;
     151
     152    auto hueForRed = normalizedHue + 2.0f;
     153    auto hueForGreen = normalizedHue;
     154    auto hueForBlue = normalizedHue - 2.0f;
    112155    if (hueForRed > 6.0f)
    113156        hueForRed -= 6.0f;
     
    115158        hueForBlue += 6.0f;
    116159
    117     return {
    118         hueToRGB(temp1, temp2, hueForRed),
    119         hueToRGB(temp1, temp2, hueForGreen),
    120         hueToRGB(temp1, temp2, hueForBlue),
    121         alpha
    122     };
    123 }
    124 
    125 // MARK: HWB conversions.
    126 
    127 HWBA<float> ColorConversion<HWBA<float>, SRGBA<float>>::convert(const SRGBA<float>& color)
    128 {
    129     // https://drafts.csswg.org/css-color-4/#rgb-to-hwb
    130     auto [hue, min, max, chroma] = calculateHSLHue(color);
    131     auto whiteness = min;
    132     auto blackness = 1.0f - max;
    133    
    134     return { hue, whiteness, blackness, color.alpha };
    135 }
    136 
    137 SRGBA<float> ColorConversion<SRGBA<float>, HWBA<float>>::convert(const HWBA<float>& color)
    138 {
    139     // https://drafts.csswg.org/css-color-4/#hwb-to-rgb
    140     auto [hue, whiteness, blackness, alpha] = color;
    141 
    142     if (whiteness + blackness == 1.0f)
    143         return { whiteness, whiteness, whiteness, alpha };
     160    auto normalizedWhiteness = whiteness / 100.0f;
     161    auto normalizedBlackness = blackness / 100.0f;
    144162
    145163    // This is the hueToRGB function in convertColor<SRGBA<float>>(const HSLA&) with temp1 == 0
     
    155173    };
    156174
    157     auto applyWhitenessBlackness = [&](float component) {
    158         return (component * (1.0f - color.whiteness - color.blackness)) + color.whiteness;
    159     };
    160 
    161     // hueToRGB() wants hue in the 0-6 range.
    162     hue *= 6.0f;
    163 
    164     auto hueForRed = hue + 2.0f;
    165     auto hueForGreen = hue;
    166     auto hueForBlue = hue - 2.0f;
    167     if (hueForRed > 6.0f)
    168         hueForRed -= 6.0f;
    169     else if (hueForBlue < 0.0f)
    170         hueForBlue += 6.0f;
    171 
    172     return {
    173         applyWhitenessBlackness(hueToRGB(hueForRed)),
    174         applyWhitenessBlackness(hueToRGB(hueForGreen)),
    175         applyWhitenessBlackness(hueToRGB(hueForBlue)),
     175    auto applyWhitenessBlackness = [](float component, auto whiteness, auto blackness) {
     176        return (component * (1.0f - whiteness - blackness)) + whiteness;
     177    };
     178
     179    return {
     180        applyWhitenessBlackness(hueToRGB(hueForRed), normalizedWhiteness, normalizedBlackness),
     181        applyWhitenessBlackness(hueToRGB(hueForGreen), normalizedWhiteness, normalizedBlackness),
     182        applyWhitenessBlackness(hueToRGB(hueForBlue), normalizedWhiteness, normalizedBlackness),
    176183        alpha
    177184    };
  • trunk/Source/WebCore/platform/graphics/ColorModels.h

    r272344 r272870  
    6868template<> struct HSLModel<float> {
    6969    static constexpr std::array<ColorComponentRange<float>, 3> ranges { {
    70         { 0, 1 },
    71         { 0, 1 },
    72         { 0, 1 }
     70        { 0, 360 },
     71        { 0, 100 },
     72        { 0, 100 }
    7373    } };
    7474    static constexpr bool isInvertible = false;
     
    7777template<> struct HWBModel<float> {
    7878    static constexpr std::array<ColorComponentRange<float>, 3> ranges { {
    79         { 0, 1 },
    80         { 0, 1 },
    81         { 0, 1 }
     79        { 0, 360 },
     80        { 0, 100 },
     81        { 0, 100 }
    8282    } };
    8383    static constexpr bool isInvertible = false;
  • trunk/Source/WebCore/rendering/RenderTheme.cpp

    r272749 r272870  
    14231423    auto hsla = textColor.toColorTypeLossy<HSLA<float>>();
    14241424    if (textColor.luminance() < backgroundColor.luminance())
    1425         hsla.lightness += datePlaceholderColorLightnessAdjustmentFactor * (1.0f - hsla.lightness);
     1425        hsla.lightness += datePlaceholderColorLightnessAdjustmentFactor * (100.0f - hsla.lightness);
    14261426    else
    14271427        hsla.lightness *= datePlaceholderColorLightnessAdjustmentFactor;
  • trunk/Tools/ChangeLog

    r272857 r272870  
     12021-02-15  Sam Weinig  <weinig@apple.com>
     2
     3        Prepare for adding relative color support
     4        https://bugs.webkit.org/show_bug.cgi?id=221881
     5
     6        Reviewed by Darin Adler.
     7
     8        * TestWebKitAPI/Tests/WebCore/ColorTests.cpp:
     9        Update HSLA tests to account for HSLA now using 0-360, 0-100, 0-100 bounds rather than 0-1, 0-1, 0-1.
     10
    1112021-02-15  Adam Roben  <aroben@apple.com>
    212
  • trunk/Tools/TestWebKitAPI/Tests/WebCore/ColorTests.cpp

    r272436 r272870  
    4343    EXPECT_FLOAT_EQ(0, hslaColor.hue);
    4444    EXPECT_FLOAT_EQ(0, hslaColor.saturation);
    45     EXPECT_FLOAT_EQ(1, hslaColor.lightness);
     45    EXPECT_FLOAT_EQ(100, hslaColor.lightness);
    4646   
    47     EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
     47    EXPECT_FLOAT_EQ(color.lightness() * 100, hslaColor.lightness);
    4848   
    4949    auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
     
    6161    EXPECT_FLOAT_EQ(0, hslaColor.lightness);
    6262
    63     EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
     63    EXPECT_FLOAT_EQ(color.lightness() * 100, hslaColor.lightness);
    6464
    6565    auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
     
    7474
    7575    EXPECT_FLOAT_EQ(0, hslaColor.hue);
    76     EXPECT_FLOAT_EQ(1, hslaColor.saturation);
    77     EXPECT_FLOAT_EQ(0.5, hslaColor.lightness);
    78 
    79     EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
     76    EXPECT_FLOAT_EQ(100, hslaColor.saturation);
     77    EXPECT_FLOAT_EQ(50, hslaColor.lightness);
     78
     79    EXPECT_FLOAT_EQ(color.lightness() * 100, hslaColor.lightness);
    8080
    8181    auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
     
    8989    auto hslaColor = color.toColorTypeLossy<HSLA<float>>();
    9090
    91     EXPECT_FLOAT_EQ(0.33333334, hslaColor.hue);
    92     EXPECT_FLOAT_EQ(1, hslaColor.saturation);
    93     EXPECT_FLOAT_EQ(0.5, hslaColor.lightness);
    94 
    95     EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
     91    EXPECT_FLOAT_EQ(120, hslaColor.hue);
     92    EXPECT_FLOAT_EQ(100, hslaColor.saturation);
     93    EXPECT_FLOAT_EQ(50, hslaColor.lightness);
     94
     95    EXPECT_FLOAT_EQ(color.lightness() * 100, hslaColor.lightness);
    9696
    9797    auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
     
    105105    auto hslaColor = color.toColorTypeLossy<HSLA<float>>();
    106106
    107     EXPECT_FLOAT_EQ(0.66666669, hslaColor.hue);
    108     EXPECT_FLOAT_EQ(1, hslaColor.saturation);
    109     EXPECT_FLOAT_EQ(0.5, hslaColor.lightness);
    110 
    111     EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
     107    EXPECT_FLOAT_EQ(240, hslaColor.hue);
     108    EXPECT_FLOAT_EQ(100, hslaColor.saturation);
     109    EXPECT_FLOAT_EQ(50, hslaColor.lightness);
     110
     111    EXPECT_FLOAT_EQ(color.lightness() * 100, hslaColor.lightness);
    112112
    113113    auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
     
    123123    EXPECT_FLOAT_EQ(0, hslaColor.hue);
    124124    EXPECT_FLOAT_EQ(0, hslaColor.saturation);
    125     EXPECT_FLOAT_EQ(0.50196078431372548, hslaColor.lightness);
     125    EXPECT_FLOAT_EQ(50.196083, hslaColor.lightness);
    126126   
    127     EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
     127    EXPECT_FLOAT_EQ(color.lightness() * 100, hslaColor.lightness);
    128128
    129129    auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
     
    139139    EXPECT_FLOAT_EQ(0, hslaColor.hue);
    140140    EXPECT_FLOAT_EQ(0, hslaColor.saturation);
    141     EXPECT_FLOAT_EQ(0.62745098039215685, hslaColor.lightness);
    142 
    143     EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
     141    EXPECT_FLOAT_EQ(62.745102, hslaColor.lightness);
     142
     143    EXPECT_FLOAT_EQ(color.lightness() * 100, hslaColor.lightness);
    144144
    145145    auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
     
    155155    EXPECT_FLOAT_EQ(0, hslaColor.hue);
    156156    EXPECT_FLOAT_EQ(0, hslaColor.saturation);
    157     EXPECT_FLOAT_EQ(0.75294117647058822, hslaColor.lightness);
    158 
    159     EXPECT_FLOAT_EQ(color.lightness(), hslaColor.lightness);
     157    EXPECT_FLOAT_EQ(75.294121, hslaColor.lightness);
     158
     159    EXPECT_FLOAT_EQ(color.lightness() * 100, hslaColor.lightness);
    160160
    161161    auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
Note: See TracChangeset for help on using the changeset viewer.