Changeset 272870 in webkit
- Timestamp:
- Feb 15, 2021 11:24:12 AM (3 years ago)
- Location:
- trunk
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r272866 r272870 1 2021-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 1 86 2021-02-15 Antoine Quint <graouts@webkit.org> 2 87 -
trunk/Source/WebCore/css/parser/CSSParser.cpp
r269957 r272870 118 118 range.consumeWhitespace(); 119 119 120 return CSSPropertyParserHelpers::consumeColorWorkerSafe(range, HTMLStandardMode);120 return CSSPropertyParserHelpers::consumeColorWorkerSafe(range, strictCSSParserContext()); 121 121 } 122 122 -
trunk/Source/WebCore/css/parser/CSSParserContext.cpp
r270613 r272870 1 1 /* 2 * Copyright (C) 2018-202 0Apple Inc. All rights reserved.2 * Copyright (C) 2018-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 48 48 } 49 49 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) 51 static bool shouldEnableLegacyOverflowScrollingTouch(const Document& document) 56 52 { 57 enforcesCSSMIMETypeInNoQuirksMode = document.settings().enforceCSSMIMETypeInNoQuirksMode();58 useLegacyBackgroundSizeShorthandBehavior = document.settings().useLegacyBackgroundSizeShorthandBehavior();59 #if ENABLE(TEXT_AUTOSIZING)60 textAutosizingEnabled = document.settings().textAutosizingEnabled();61 #endif62 #if ENABLE(OVERFLOW_SCROLLING_TOUCH)63 legacyOverflowScrollingTouchEnabled = document.settings().legacyOverflowScrollingTouchEnabled();64 53 // The legacy -webkit-overflow-scrolling: touch behavior may have been disabled through the website policy, 65 54 // in that case we want to disable the legacy behavior regardless of what the setting says. 66 55 if (auto* loader = document.loader()) { 67 56 if (loader->legacyOverflowScrollingTouchPolicy() == LegacyOverflowScrollingTouchPolicy::Disable) 68 legacyOverflowScrollingTouchEnabled =false;57 return false; 69 58 } 59 return document.settings().legacyOverflowScrollingTouchEnabled(); 60 } 70 61 #endif 71 springTimingFunctionEnabled = document.settings().springTimingFunctionEnabled(); 72 constantPropertiesEnabled = document.settings().constantPropertiesEnabled(); 73 colorFilterEnabled = document.settings().colorFilterEnabled(); 62 63 CSSParserContext::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() } 74 86 #if ENABLE(ATTACHMENT_ELEMENT) 75 attachmentEnabled = RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled();87 , attachmentEnabled { RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled() } 76 88 #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 { 83 90 } 84 91 … … 88 95 && a.charset == b.charset 89 96 && a.mode == b.mode 97 && a.enclosingRuleType == b.enclosingRuleType 90 98 && 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 91 114 #if ENABLE(TEXT_AUTOSIZING) 92 115 && a.textAutosizingEnabled == b.textAutosizingEnabled 93 116 #endif 94 #if ENABLE(OVERFLOW_SCROLLING_TOUCH)95 && a.legacyOverflowScrollingTouchEnabled == b.legacyOverflowScrollingTouchEnabled96 #endif97 && a.enforcesCSSMIMETypeInNoQuirksMode == b.enforcesCSSMIMETypeInNoQuirksMode98 117 && a.useLegacyBackgroundSizeShorthandBehavior == b.useLegacyBackgroundSizeShorthandBehavior 99 && a.springTimingFunctionEnabled == b.springTimingFunctionEnabled100 && a.constantPropertiesEnabled == b.constantPropertiesEnabled101 && a.colorFilterEnabled == b.colorFilterEnabled102 118 #if ENABLE(ATTACHMENT_ELEMENT) 103 119 && a.attachmentEnabled == b.attachmentEnabled 104 120 #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 ; 112 122 } 113 123 -
trunk/Source/WebCore/css/parser/CSSParserContext.h
r270613 r272870 1 1 /* 2 * Copyright (C) 2018-202 0Apple Inc. All rights reserved.2 * Copyright (C) 2018-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 42 42 WTF_MAKE_FAST_ALLOCATED; 43 43 public: 44 45 44 CSSParserContext(CSSParserMode, const URL& baseURL = URL()); 46 45 WEBCORE_EXPORT CSSParserContext(const Document&, const URL& baseURL = URL(), const String& charset = emptyString()); … … 51 50 Optional<StyleRuleType> enclosingRuleType; 52 51 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 }; 53 72 #if ENABLE(TEXT_AUTOSIZING) 54 73 bool textAutosizingEnabled { false }; 55 74 #endif 56 #if ENABLE(OVERFLOW_SCROLLING_TOUCH)57 bool legacyOverflowScrollingTouchEnabled { false };58 #endif59 bool enforcesCSSMIMETypeInNoQuirksMode { true };60 75 bool useLegacyBackgroundSizeShorthandBehavior { false }; 61 bool springTimingFunctionEnabled { false }; 62 bool constantPropertiesEnabled { false }; 63 bool colorFilterEnabled { false }; 76 77 // RuntimeEnabledFeatures. 64 78 #if ENABLE(ATTACHMENT_ELEMENT) 65 79 bool attachmentEnabled { false }; 66 80 #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 };77 81 78 82 URL completeURL(const String& url) const; 79 80 bool isContentOpaque { false };81 82 bool aspectRatioEnabled { false };83 83 }; 84 84 … … 91 91 static unsigned hash(const CSSParserContext& key) 92 92 { 93 // FIXME: Convert this to use WTF::Hasher. 94 93 95 unsigned hash = 0; 94 96 if (!key.baseURL.isNull()) -
trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp
r272610 r272870 1727 1727 } 1728 1728 1729 static RefPtr<CSSValue> consumeShadow(CSSParserTokenRange& range, CSSParserMode cssParserMode, bool isBoxShadowProperty)1729 static RefPtr<CSSValue> consumeShadow(CSSParserTokenRange& range, const CSSParserContext& context, bool isBoxShadowProperty) 1730 1730 { 1731 1731 if (range.peek().id() == CSSValueNone) … … 1734 1734 RefPtr<CSSValueList> shadowValueList = CSSValueList::createCommaSeparated(); 1735 1735 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()); 1738 1738 else 1739 1739 return nullptr; … … 1814 1814 } 1815 1815 1816 static RefPtr<CSSPrimitiveValue> consumeCaretColor(CSSParserTokenRange& range, CSSParserMode cssParserMode)1816 static RefPtr<CSSPrimitiveValue> consumeCaretColor(CSSParserTokenRange& range, const CSSParserContext& context) 1817 1817 { 1818 1818 if (range.peek().id() == CSSValueAuto) 1819 1819 return consumeIdent(range); 1820 return consumeColor(range, c ssParserMode);1821 } 1822 1823 static RefPtr<CSSValue> consumeOutlineColor(CSSParserTokenRange& range, CSSParserMode cssParserMode)1820 return consumeColor(range, context); 1821 } 1822 1823 static RefPtr<CSSValue> consumeOutlineColor(CSSParserTokenRange& range, const CSSParserContext& context) 1824 1824 { 1825 1825 // Allow the special focus color even in HTML Standard parsing mode. 1826 1826 if (range.peek().id() == CSSValueWebkitFocusRingColor) 1827 1827 return consumeIdent(range); 1828 return consumeColor(range, c ssParserMode);1828 return consumeColor(range, context); 1829 1829 } 1830 1830 … … 2229 2229 } 2230 2230 2231 static RefPtr<CSSValue> consumePaintStroke(CSSParserTokenRange& range, CSSParserMode cssParserMode)2231 static RefPtr<CSSValue> consumePaintStroke(CSSParserTokenRange& range, const CSSParserContext& context) 2232 2232 { 2233 2233 if (range.peek().id() == CSSValueNone) … … 2239 2239 parsedValue = consumeIdent(range); 2240 2240 else 2241 parsedValue = consumeColor(range, c ssParserMode);2241 parsedValue = consumeColor(range, context); 2242 2242 if (parsedValue) { 2243 2243 RefPtr<CSSValueList> values = CSSValueList::createSpaceSeparated(); … … 2248 2248 return url; 2249 2249 } 2250 return consumeColor(range, c ssParserMode);2250 return consumeColor(range, context); 2251 2251 } 2252 2252 … … 3259 3259 return consumeBackgroundSize(property, range, context.mode); 3260 3260 case CSSPropertyBackgroundColor: 3261 return consumeColor(range, context .mode);3261 return consumeColor(range, context); 3262 3262 default: 3263 3263 break; … … 4242 4242 return consumePositiveInteger(m_range); 4243 4243 case CSSPropertyTextDecorationColor: 4244 return consumeColor(m_range, m_context .mode);4244 return consumeColor(m_range, m_context); 4245 4245 case CSSPropertyTextDecorationSkip: 4246 4246 return consumeTextDecorationSkip(m_range); … … 4262 4262 case CSSPropertyLightingColor: 4263 4263 case CSSPropertyColumnRuleColor: 4264 return consumeColor(m_range, m_context .mode);4264 return consumeColor(m_range, m_context); 4265 4265 case CSSPropertyCaretColor: 4266 return consumeCaretColor(m_range, m_context .mode);4266 return consumeCaretColor(m_range, m_context); 4267 4267 case CSSPropertyColor: 4268 4268 case CSSPropertyBackgroundColor: 4269 return consumeColor(m_range, m_context .mode, inQuirksMode());4269 return consumeColor(m_range, m_context, inQuirksMode()); 4270 4270 case CSSPropertyBorderInlineStartWidth: 4271 4271 case CSSPropertyBorderInlineEndWidth: … … 4279 4279 bool allowQuirkyColors = inQuirksMode() 4280 4280 && (currentShorthand == CSSPropertyInvalid || currentShorthand == CSSPropertyBorderColor); 4281 return consumeColor(m_range, m_context .mode, allowQuirkyColors);4281 return consumeColor(m_range, m_context, allowQuirkyColors); 4282 4282 } 4283 4283 case CSSPropertyBorderBottomWidth: … … 4295 4295 case CSSPropertyBoxShadow: 4296 4296 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); 4298 4298 case CSSPropertyFilter: 4299 4299 #if ENABLE(FILTERS_LEVEL_2) … … 4343 4343 case CSSPropertyFill: 4344 4344 case CSSPropertyStroke: 4345 return consumePaintStroke(m_range, m_context .mode);4345 return consumePaintStroke(m_range, m_context); 4346 4346 case CSSPropertyGlyphOrientationVertical: 4347 4347 case CSSPropertyGlyphOrientationHorizontal: … … 5094 5094 } 5095 5095 if (!color) { 5096 color = consumeColor(m_range, m_context .mode);5096 color = consumeColor(m_range, m_context); 5097 5097 if (color) 5098 5098 continue; -
trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp
r272436 r272870 691 691 } 692 692 693 static uint8_t clampRGBComponent(double value, bool isPercentage) 694 { 695 if (isPercentage) 693 static 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 704 static 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 712 static double normalizeHue(double hue) 713 { 714 return std::fmod(std::fmod(hue, 360.0) + 360.0, 360.0); 715 } 716 717 enum class RGBComponentType { Number, Percentage }; 718 719 static uint8_t clampRGBComponent(double value, RGBComponentType componentType) 720 { 721 if (componentType == RGBComponentType::Percentage) 696 722 value = value / 100.0 * 255.0; 697 723 … … 699 725 } 700 726 701 static Color parseRGBParameters(CSSParserTokenRange& range) 727 enum class RGBOrHSLSeparatorSyntax { Commas, WhitespaceSlash }; 728 729 static bool consumeRGBOrHSLSeparator(CSSParserTokenRange& args, RGBOrHSLSeparatorSyntax syntax) 730 { 731 if (syntax == RGBOrHSLSeparatorSyntax::Commas) 732 return consumeCommaIncludingWhitespace(args); 733 return true; 734 } 735 736 static bool consumeRGBOrHSLAlphaSeparator(CSSParserTokenRange& args, RGBOrHSLSeparatorSyntax syntax) 737 { 738 if (syntax == RGBOrHSLSeparatorSyntax::Commas) 739 return consumeCommaIncludingWhitespace(args); 740 return consumeSlashIncludingWhitespace(args); 741 } 742 743 static Optional<double> consumeRGBOrHSLOptionalAlpha(CSSParserTokenRange& args, RGBOrHSLSeparatorSyntax syntax) 744 { 745 if (!consumeRGBOrHSLAlphaSeparator(args, syntax)) 746 return 1.0; 747 748 return consumeNumberOrPercentDividedBy100Raw(args); 749 } 750 751 static Color parseRGBParameters(CSSParserTokenRange& range, const CSSParserContext&) 702 752 { 703 753 ASSERT(range.peek().functionId() == CSSValueRgb || range.peek().functionId() == CSSValueRgba); 704 754 auto args = consumeFunction(range); 705 755 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; 719 759 }; 720 760 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; 727 767 }; 728 768 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 } 756 776 }; 757 777 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 { }; 765 801 766 802 if (!args.atEnd()) 767 803 return { }; 768 804 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 813 static Color parseHSLParameters(CSSParserTokenRange& range, const CSSParserContext& context) 773 814 { 774 815 ASSERT(range.peek().functionId() == CSSValueHsl || range.peek().functionId() == CSSValueHsla); 775 816 auto args = consumeFunction(range); 776 817 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 { }; 814 838 815 839 if (!args.atEnd()) 816 840 return { }; 817 841 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 850 struct WhitenessBlackness { 851 double whiteness; 852 double blackness; 853 }; 854 static WhitenessBlackness normalizeWhitenessBlackness(double whiteness, double blackness) 855 { 856 WhitenessBlackness result; 870 857 871 858 // Values outside of these ranges are not invalid, but are clamped to the 872 859 // 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); 875 862 876 863 // If the sum of these two arguments is greater than 100%, then at 877 864 // computed-value time they are further normalized to add up to 100%, with 878 865 // 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 874 static 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 904 static Color parseLabParameters(CSSParserTokenRange& range, const CSSParserContext&) 892 905 { 893 906 ASSERT(range.peek().functionId() == CSSValueLab); 894 907 auto args = consumeFunction(range); 895 908 896 auto lightness = consumePercentRaw(args , ValueRangeAll);909 auto lightness = consumePercentRaw(args); 897 910 if (!lightness) 898 911 return { }; 899 912 900 auto aValue = consumeNumberRaw(args , ValueRangeAll);913 auto aValue = consumeNumberRaw(args); 901 914 if (!aValue) 902 915 return { }; 903 916 904 auto bValue = consumeNumberRaw(args , ValueRangeAll);917 auto bValue = consumeNumberRaw(args); 905 918 if (!bValue) 906 919 return { }; 907 920 908 auto alpha = parseOptionalAlpha(args);921 auto alpha = consumeOptionalAlpha(args); 909 922 if (!alpha) 910 923 return { }; … … 913 926 return { }; 914 927 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 931 static Color parseLCHParameters(CSSParserTokenRange& range, const CSSParserContext& context) 919 932 { 920 933 ASSERT(range.peek().functionId() == CSSValueLch); 921 934 auto args = consumeFunction(range); 922 935 923 auto lightness = consumePercentRaw(args , ValueRangeAll);936 auto lightness = consumePercentRaw(args); 924 937 if (!lightness) 925 938 return { }; 926 939 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); 944 949 if (!alpha) 945 950 return { }; … … 948 953 return { }; 949 954 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 960 template<typename ColorType> static Color parseColorFunctionForRGBTypes(CSSParserTokenRange& args) 955 961 { 956 962 ASSERT(args.peek().id() == CSSValueA98Rgb || args.peek().id() == CSSValueDisplayP3 || args.peek().id() == CSSValueProphotoRgb || args.peek().id() == CSSValueRec2020 || args.peek().id() == CSSValueSRGB); … … 965 971 } 966 972 967 auto alpha = parseOptionalAlpha(args);973 auto alpha = consumeOptionalAlpha(args); 968 974 if (!alpha) 969 975 return { }; 970 976 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) }; 972 978 } 973 979 … … 979 985 double channels[3] = { 0, 0, 0 }; 980 986 [&] { 981 auto lightness = consumePercentRaw(args , ValueRangeAll);987 auto lightness = consumePercentRaw(args); 982 988 if (!lightness) 983 989 return; 984 990 channels[0] = *lightness; 985 991 986 auto aValue = consumeNumberRaw(args , ValueRangeAll);992 auto aValue = consumeNumberRaw(args); 987 993 if (!aValue) 988 994 return; 989 995 channels[1] = *aValue; 990 996 991 auto bValue = consumeNumberRaw(args , ValueRangeAll);997 auto bValue = consumeNumberRaw(args); 992 998 if (!bValue) 993 999 return; … … 995 1001 }(); 996 1002 997 auto alpha = parseOptionalAlpha(args);1003 auto alpha = consumeOptionalAlpha(args); 998 1004 if (!alpha) 999 1005 return { }; 1000 1006 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) }; 1002 1008 } 1003 1009 … … 1009 1015 double channels[3] = { 0, 0, 0 }; 1010 1016 [&] { 1011 auto x = consumeNumberRaw(args , ValueRangeAll);1017 auto x = consumeNumberRaw(args); 1012 1018 if (!x) 1013 1019 return; 1014 1020 channels[0] = *x; 1015 1021 1016 auto y = consumeNumberRaw(args , ValueRangeAll);1022 auto y = consumeNumberRaw(args); 1017 1023 if (!y) 1018 1024 return; 1019 1025 channels[1] = *y; 1020 1026 1021 auto z = consumeNumberRaw(args , ValueRangeAll);1027 auto z = consumeNumberRaw(args); 1022 1028 if (!z) 1023 1029 return; … … 1025 1031 }(); 1026 1032 1027 auto alpha = parseOptionalAlpha(args);1033 auto alpha = consumeOptionalAlpha(args); 1028 1034 if (!alpha) 1029 1035 return { }; 1030 1036 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) }; 1032 1038 } 1033 1039 … … 1112 1118 } 1113 1119 1114 static Color parseColorFunction(CSSParserTokenRange& range, CSSParserMode cssParserMode)1120 static Color parseColorFunction(CSSParserTokenRange& range, const CSSParserContext& context) 1115 1121 { 1116 1122 CSSParserTokenRange colorRange = range; … … 1120 1126 case CSSValueRgb: 1121 1127 case CSSValueRgba: 1122 color = parseRGBParameters(colorRange );1128 color = parseRGBParameters(colorRange, context); 1123 1129 break; 1124 1130 case CSSValueHsl: 1125 1131 case CSSValueHsla: 1126 color = parseHSLParameters(colorRange, c ssParserMode);1132 color = parseHSLParameters(colorRange, context); 1127 1133 break; 1128 1134 case CSSValueHwb: 1129 color = parseHWBParameters(colorRange, c ssParserMode);1135 color = parseHWBParameters(colorRange, context); 1130 1136 break; 1131 1137 case CSSValueLab: 1132 color = parseLabParameters(colorRange );1138 color = parseLabParameters(colorRange, context); 1133 1139 break; 1134 1140 case CSSValueLch: 1135 color = parseLCHParameters(colorRange, c ssParserMode);1141 color = parseLCHParameters(colorRange, context); 1136 1142 break; 1137 1143 case CSSValueColor: … … 1146 1152 } 1147 1153 1148 Color consumeColorWorkerSafe(CSSParserTokenRange& range, CSSParserMode cssParserMode)1154 Color consumeColorWorkerSafe(CSSParserTokenRange& range, const CSSParserContext& context) 1149 1155 { 1150 1156 Color result; … … 1155 1161 if (StyleColor::isSystemColor(keyword)) 1156 1162 return { }; 1157 if (!isValueAllowedInMode(keyword, c ssParserMode))1163 if (!isValueAllowedInMode(keyword, context.mode)) 1158 1164 return { }; 1159 1165 result = StyleColor::colorFromKeyword(keyword, { }); … … 1164 1170 result = *parsedColor; 1165 1171 else 1166 result = parseColorFunction(range, c ssParserMode);1172 result = parseColorFunction(range, context); 1167 1173 1168 1174 if (!range.atEnd()) … … 1172 1178 } 1173 1179 1174 RefPtr<CSSPrimitiveValue> consumeColor(CSSParserTokenRange& range, CSSParserMode cssParserMode, bool acceptQuirkyColors)1180 RefPtr<CSSPrimitiveValue> consumeColor(CSSParserTokenRange& range, const CSSParserContext& context, bool acceptQuirkyColors) 1175 1181 { 1176 1182 auto keyword = range.peek().id(); 1177 1183 if (StyleColor::isColorKeyword(keyword)) { 1178 if (!isValueAllowedInMode(keyword, c ssParserMode))1184 if (!isValueAllowedInMode(keyword, context.mode)) 1179 1185 return nullptr; 1180 1186 return consumeIdent(range); … … 1184 1190 color = *parsedColor; 1185 1191 else { 1186 color = parseColorFunction(range, c ssParserMode);1192 color = parseColorFunction(range, context); 1187 1193 if (!color.isValid()) 1188 1194 return nullptr; … … 1414 1420 1415 1421 // Used to parse colors for -webkit-gradient(...). 1416 static RefPtr<CSSPrimitiveValue> consumeDeprecatedGradientStopColor(CSSParserTokenRange& args, CSSParserMode cssParserMode)1422 static RefPtr<CSSPrimitiveValue> consumeDeprecatedGradientStopColor(CSSParserTokenRange& args, const CSSParserContext& context) 1417 1423 { 1418 1424 if (args.peek().id() == CSSValueCurrentcolor) 1419 1425 return nullptr; 1420 return consumeColor(args, c ssParserMode);1421 } 1422 1423 static bool consumeDeprecatedGradientColorStop(CSSParserTokenRange& range, CSSGradientColorStop& stop, CSSParserMode cssParserMode)1426 return consumeColor(args, context); 1427 } 1428 1429 static bool consumeDeprecatedGradientColorStop(CSSParserTokenRange& range, CSSGradientColorStop& stop, const CSSParserContext& context) 1424 1430 { 1425 1431 CSSValueID id = range.peek().functionId(); … … 1443 1449 1444 1450 stop.position = CSSValuePool::singleton().createValue(position, CSSUnitType::CSS_NUMBER); 1445 stop.color = consumeDeprecatedGradientStopColor(args, c ssParserMode);1451 stop.color = consumeDeprecatedGradientStopColor(args, context); 1446 1452 return stop.color && args.atEnd(); 1447 1453 } 1448 1454 1449 static RefPtr<CSSValue> consumeDeprecatedGradient(CSSParserTokenRange& args, CSSParserMode cssParserMode)1455 static RefPtr<CSSValue> consumeDeprecatedGradient(CSSParserTokenRange& args, const CSSParserContext& context) 1450 1456 { 1451 1457 RefPtr<CSSGradientValue> result; … … 1500 1506 CSSGradientColorStop stop; 1501 1507 while (consumeCommaIncludingWhitespace(args)) { 1502 if (!consumeDeprecatedGradientColorStop(args, stop, c ssParserMode))1508 if (!consumeDeprecatedGradientColorStop(args, stop, context)) 1503 1509 return nullptr; 1504 1510 result->addStop(WTFMove(stop)); … … 1509 1515 } 1510 1516 1511 static bool consumeGradientColorStops(CSSParserTokenRange& range, CSSParserMode mode, CSSGradientValue& gradient)1517 static bool consumeGradientColorStops(CSSParserTokenRange& range, const CSSParserContext& context, CSSGradientValue& gradient) 1512 1518 { 1513 1519 bool supportsColorHints = gradient.gradientType() == CSSLinearGradient || gradient.gradientType() == CSSRadialGradient || gradient.gradientType() == CSSConicGradient; … … 1515 1521 auto consumeStopPosition = [&] { 1516 1522 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); 1519 1525 }; 1520 1526 … … 1522 1528 bool previousStopWasColorHint = true; 1523 1529 do { 1524 CSSGradientColorStop stop { consumeColor(range, mode), consumeStopPosition(), { } };1530 CSSGradientColorStop stop { consumeColor(range, context), consumeStopPosition(), { } }; 1525 1531 if (!stop.color && !stop.position) 1526 1532 return false; … … 1553 1559 } 1554 1560 1555 static RefPtr<CSSValue> consumeDeprecatedRadialGradient(CSSParserTokenRange& args, CSSParserMode cssParserMode, CSSGradientRepeat repeating)1561 static RefPtr<CSSValue> consumeDeprecatedRadialGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating) 1556 1562 { 1557 1563 auto result = CSSRadialGradientValue::create(repeating, CSSPrefixedRadialGradient); 1558 1564 1559 auto centerCoordinate = consumeOneOrTwoValuedPositionCoordinates(args, c ssParserMode, UnitlessQuirk::Forbid);1565 auto centerCoordinate = consumeOneOrTwoValuedPositionCoordinates(args, context.mode, UnitlessQuirk::Forbid); 1560 1566 if (centerCoordinate && !consumeCommaIncludingWhitespace(args)) 1561 1567 return nullptr; … … 1568 1574 // Or, two lengths or percentages 1569 1575 if (!shape && !sizeKeyword) { 1570 auto horizontalSize = consumeLengthOrPercent(args, c ssParserMode, ValueRangeNonNegative);1576 auto horizontalSize = consumeLengthOrPercent(args, context.mode, ValueRangeNonNegative); 1571 1577 RefPtr<CSSPrimitiveValue> verticalSize; 1572 1578 if (horizontalSize) { 1573 verticalSize = consumeLengthOrPercent(args, c ssParserMode, ValueRangeNonNegative);1579 verticalSize = consumeLengthOrPercent(args, context.mode, ValueRangeNonNegative); 1574 1580 if (!verticalSize) 1575 1581 return nullptr; … … 1582 1588 } 1583 1589 1584 if (!consumeGradientColorStops(args, c ssParserMode, result))1590 if (!consumeGradientColorStops(args, context, result)) 1585 1591 return nullptr; 1586 1592 … … 1597 1603 } 1598 1604 1599 static RefPtr<CSSValue> consumeRadialGradient(CSSParserTokenRange& args, CSSParserMode cssParserMode, CSSGradientRepeat repeating)1605 static RefPtr<CSSValue> consumeRadialGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating) 1600 1606 { 1601 1607 RefPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating, CSSRadialGradient); … … 1625 1631 } 1626 1632 } else { 1627 auto center = consumeLengthOrPercent(args, c ssParserMode, ValueRangeNonNegative);1633 auto center = consumeLengthOrPercent(args, context.mode, ValueRangeNonNegative); 1628 1634 if (!center) 1629 1635 break; … … 1631 1637 return nullptr; 1632 1638 horizontalSize = center; 1633 center = consumeLengthOrPercent(args, c ssParserMode, ValueRangeNonNegative);1639 center = consumeLengthOrPercent(args, context.mode, ValueRangeNonNegative); 1634 1640 if (center) { 1635 1641 verticalSize = center; … … 1660 1666 args.consumeIncludingWhitespace(); 1661 1667 1662 auto centerCoordinate = consumePositionCoordinates(args, c ssParserMode, UnitlessQuirk::Forbid, PositionSyntax::Position);1668 auto centerCoordinate = consumePositionCoordinates(args, context.mode, UnitlessQuirk::Forbid, PositionSyntax::Position); 1663 1669 if (!centerCoordinate) 1664 1670 return nullptr; … … 1677 1683 if ((shape || sizeKeyword || horizontalSize || centerX || centerY) && !consumeCommaIncludingWhitespace(args)) 1678 1684 return nullptr; 1679 if (!consumeGradientColorStops(args, c ssParserMode, *result))1685 if (!consumeGradientColorStops(args, context, *result)) 1680 1686 return nullptr; 1681 1687 … … 1688 1694 } 1689 1695 1690 static RefPtr<CSSValue> consumeLinearGradient(CSSParserTokenRange& args, CSSParserMode cssParserMode, CSSGradientRepeat repeating, CSSGradientType gradientType)1696 static RefPtr<CSSValue> consumeLinearGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating, CSSGradientType gradientType) 1691 1697 { 1692 1698 RefPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating, gradientType); 1693 1699 1694 1700 bool expectComma = true; 1695 RefPtr<CSSPrimitiveValue> angle = consumeAngle(args, c ssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow);1701 RefPtr<CSSPrimitiveValue> angle = consumeAngle(args, context.mode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow); 1696 1702 if (angle) 1697 1703 result->setAngle(angle.releaseNonNull()); … … 1716 1722 if (expectComma && !consumeCommaIncludingWhitespace(args)) 1717 1723 return nullptr; 1718 if (!consumeGradientColorStops(args, c ssParserMode, *result))1724 if (!consumeGradientColorStops(args, context, *result)) 1719 1725 return nullptr; 1720 1726 return result; 1721 1727 } 1722 1728 1723 static RefPtr<CSSValue> consumeConicGradient(CSSParserTokenRange& args, CSSParserContextcontext, CSSGradientRepeat repeating)1729 static RefPtr<CSSValue> consumeConicGradient(CSSParserTokenRange& args, const CSSParserContext& context, CSSGradientRepeat repeating) 1724 1730 { 1725 1731 #if ENABLE(CSS_CONIC_GRADIENTS) … … 1755 1761 if (expectComma && !consumeCommaIncludingWhitespace(args)) 1756 1762 return nullptr; 1757 if (!consumeGradientColorStops(args, context .mode, *result))1763 if (!consumeGradientColorStops(args, context, *result)) 1758 1764 return nullptr; 1759 1765 return result; … … 1766 1772 } 1767 1773 1768 RefPtr<CSSValue> consumeImageOrNone(CSSParserTokenRange& range, CSSParserContextcontext)1774 RefPtr<CSSValue> consumeImageOrNone(CSSParserTokenRange& range, const CSSParserContext& context) 1769 1775 { 1770 1776 if (range.peek().id() == CSSValueNone) … … 1773 1779 } 1774 1780 1775 static RefPtr<CSSValue> consumeCrossFade(CSSParserTokenRange& args, CSSParserContextcontext, bool prefixed)1781 static RefPtr<CSSValue> consumeCrossFade(CSSParserTokenRange& args, const CSSParserContext& context, bool prefixed) 1776 1782 { 1777 1783 auto fromImageValue = consumeImageOrNone(args, context); … … 1849 1855 #endif 1850 1856 1851 static RefPtr<CSSValue> consumeGeneratedImage(CSSParserTokenRange& range, CSSParserContextcontext)1857 static RefPtr<CSSValue> consumeGeneratedImage(CSSParserTokenRange& range, const CSSParserContext& context) 1852 1858 { 1853 1859 CSSValueID id = range.peek().functionId(); … … 1856 1862 RefPtr<CSSValue> result; 1857 1863 if (id == CSSValueRadialGradient) 1858 result = consumeRadialGradient(args, context .mode, NonRepeating);1864 result = consumeRadialGradient(args, context, NonRepeating); 1859 1865 else if (id == CSSValueRepeatingRadialGradient) 1860 result = consumeRadialGradient(args, context .mode, Repeating);1866 result = consumeRadialGradient(args, context, Repeating); 1861 1867 else if (id == CSSValueWebkitLinearGradient) 1862 result = consumeLinearGradient(args, context .mode, NonRepeating, CSSPrefixedLinearGradient);1868 result = consumeLinearGradient(args, context, NonRepeating, CSSPrefixedLinearGradient); 1863 1869 else if (id == CSSValueWebkitRepeatingLinearGradient) 1864 result = consumeLinearGradient(args, context .mode, Repeating, CSSPrefixedLinearGradient);1870 result = consumeLinearGradient(args, context, Repeating, CSSPrefixedLinearGradient); 1865 1871 else if (id == CSSValueRepeatingLinearGradient) 1866 result = consumeLinearGradient(args, context .mode, Repeating, CSSLinearGradient);1872 result = consumeLinearGradient(args, context, Repeating, CSSLinearGradient); 1867 1873 else if (id == CSSValueLinearGradient) 1868 result = consumeLinearGradient(args, context .mode, NonRepeating, CSSLinearGradient);1874 result = consumeLinearGradient(args, context, NonRepeating, CSSLinearGradient); 1869 1875 else if (id == CSSValueWebkitGradient) 1870 result = consumeDeprecatedGradient(args, context .mode);1876 result = consumeDeprecatedGradient(args, context); 1871 1877 else if (id == CSSValueWebkitRadialGradient) 1872 result = consumeDeprecatedRadialGradient(args, context .mode, NonRepeating);1878 result = consumeDeprecatedRadialGradient(args, context, NonRepeating); 1873 1879 else if (id == CSSValueWebkitRepeatingRadialGradient) 1874 result = consumeDeprecatedRadialGradient(args, context .mode, Repeating);1880 result = consumeDeprecatedRadialGradient(args, context, Repeating); 1875 1881 else if (id == CSSValueConicGradient) 1876 1882 result = consumeConicGradient(args, context, NonRepeating); … … 2018 2024 2019 2025 if (filterType == CSSValueDropShadow) 2020 parsedValue = consumeSingleShadow(args, context .mode, false, false);2026 parsedValue = consumeSingleShadow(args, context, false, false); 2021 2027 else { 2022 2028 if (args.atEnd()) … … 2065 2071 } 2066 2072 2067 RefPtr<CSSShadowValue> consumeSingleShadow(CSSParserTokenRange& range, CSSParserMode cssParserMode, bool allowInset, bool allowSpread)2073 RefPtr<CSSShadowValue> consumeSingleShadow(CSSParserTokenRange& range, const CSSParserContext& context, bool allowInset, bool allowSpread) 2068 2074 { 2069 2075 RefPtr<CSSPrimitiveValue> style; … … 2090 2096 } 2091 2097 2092 auto maybeColor = consumeColor(range, c ssParserMode);2098 auto maybeColor = consumeColor(range, context); 2093 2099 if (maybeColor) { 2094 2100 // If we just parsed a color but already had one, the given token range is not a valid <shadow>. … … 2104 2110 return nullptr; 2105 2111 } 2106 horizontalOffset = consumeLength(range, c ssParserMode, ValueRangeAll);2112 horizontalOffset = consumeLength(range, context.mode, ValueRangeAll); 2107 2113 if (!horizontalOffset) 2108 2114 return nullptr; 2109 verticalOffset = consumeLength(range, c ssParserMode, ValueRangeAll);2115 verticalOffset = consumeLength(range, context.mode, ValueRangeAll); 2110 2116 if (!verticalOffset) 2111 2117 return nullptr; … … 2114 2120 // 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. 2115 2121 if (token.type() == DimensionToken || token.type() == NumberToken || (token.type() == FunctionToken && CSSCalcValue::isCalcFunction(token.functionId()))) { 2116 blurRadius = consumeLength(range, c ssParserMode, ValueRangeNonNegative);2122 blurRadius = consumeLength(range, context.mode, ValueRangeNonNegative); 2117 2123 if (!blurRadius) 2118 2124 return nullptr; … … 2120 2126 2121 2127 if (blurRadius && allowSpread) 2122 spreadDistance = consumeLength(range, c ssParserMode, ValueRangeAll);2128 spreadDistance = consumeLength(range, context.mode, ValueRangeAll); 2123 2129 } 2124 2130 … … 2129 2135 } 2130 2136 2131 RefPtr<CSSValue> consumeImage(CSSParserTokenRange& range, CSSParserContextcontext, OptionSet<AllowedImageType> allowedImageTypes)2137 RefPtr<CSSValue> consumeImage(CSSParserTokenRange& range, const CSSParserContext& context, OptionSet<AllowedImageType> allowedImageTypes) 2132 2138 { 2133 2139 if ((range.peek().type() == StringToken) && (allowedImageTypes.contains(AllowedImageType::RawStringAsURL))) { -
trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h
r272121 r272870 103 103 RefPtr<CSSPrimitiveValue> consumeUrl(CSSParserTokenRange&); 104 104 105 Color consumeColorWorkerSafe(CSSParserTokenRange&, CSSParserMode);106 RefPtr<CSSPrimitiveValue> consumeColor(CSSParserTokenRange&, CSSParserMode, bool acceptQuirkyColors = false);105 Color consumeColorWorkerSafe(CSSParserTokenRange&, const CSSParserContext&); 106 RefPtr<CSSPrimitiveValue> consumeColor(CSSParserTokenRange&, const CSSParserContext&, bool acceptQuirkyColors = false); 107 107 108 108 enum class PositionSyntax { … … 127 127 }; 128 128 129 RefPtr<CSSValue> consumeImage(CSSParserTokenRange&, CSSParserContext, OptionSet<AllowedImageType> = { AllowedImageType::URLFunction, AllowedImageType::ImageSet, AllowedImageType::GeneratedImage }); 130 131 RefPtr<CSSValue> consumeImageOrNone(CSSParserTokenRange&, CSSParserContext); 129 RefPtr<CSSValue> consumeImage(CSSParserTokenRange&, const CSSParserContext&, OptionSet<AllowedImageType> = { AllowedImageType::URLFunction, AllowedImageType::ImageSet, AllowedImageType::GeneratedImage }); 130 RefPtr<CSSValue> consumeImageOrNone(CSSParserTokenRange&, const CSSParserContext&); 132 131 133 132 enum class AllowedFilterFunctions { … … 137 136 138 137 RefPtr<CSSValue> consumeFilter(CSSParserTokenRange&, const CSSParserContext&, AllowedFilterFunctions); 139 RefPtr<CSSShadowValue> consumeSingleShadow(CSSParserTokenRange&, CSSParserMode, bool allowInset, bool allowSpread);138 RefPtr<CSSShadowValue> consumeSingleShadow(CSSParserTokenRange&, const CSSParserContext&, bool allowInset, bool allowSpread); 140 139 141 140 struct FontStyleRaw { -
trunk/Source/WebCore/editing/cocoa/DataDetection.mm
r272436 r272870 601 601 // Force the lightness of the underline color to the middle, and multiply the alpha by 38%, 602 602 // 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; 604 604 hsla.alpha *= 0.38f; 605 605 -
trunk/Source/WebCore/platform/graphics/ColorConversion.cpp
r272837 r272870 59 59 hue -= 360.0f; 60 60 61 hue /= 360.0f;62 63 61 return { hue, min, max, chroma }; 64 62 } … … 70 68 auto [hue, min, max, chroma] = calculateHSLHue(color); 71 69 72 float lightness = 0.5f * (max + min);70 float lightness = (0.5f * (max + min)) * 100.0f; 73 71 float saturation; 74 72 if (!chroma) 75 73 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; 78 76 else 79 saturation = (chroma / (2.0f - (max + min))) ;77 saturation = (chroma / (2.0f - (max + min))) * 100.0f; 80 78 81 79 return { hue, saturation, lightness, alpha }; … … 87 85 auto [hue, saturation, lightness, alpha] = color; 88 86 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; 94 107 95 108 // Hue is in the range 0-6, other args in 0-1. … … 104 117 }; 105 118 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 129 HWBA<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 139 SRGBA<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 106 149 // 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; 112 155 if (hueForRed > 6.0f) 113 156 hueForRed -= 6.0f; … … 115 158 hueForBlue += 6.0f; 116 159 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; 144 162 145 163 // This is the hueToRGB function in convertColor<SRGBA<float>>(const HSLA&) with temp1 == 0 … … 155 173 }; 156 174 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), 176 183 alpha 177 184 }; -
trunk/Source/WebCore/platform/graphics/ColorModels.h
r272344 r272870 68 68 template<> struct HSLModel<float> { 69 69 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 } 73 73 } }; 74 74 static constexpr bool isInvertible = false; … … 77 77 template<> struct HWBModel<float> { 78 78 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 } 82 82 } }; 83 83 static constexpr bool isInvertible = false; -
trunk/Source/WebCore/rendering/RenderTheme.cpp
r272749 r272870 1423 1423 auto hsla = textColor.toColorTypeLossy<HSLA<float>>(); 1424 1424 if (textColor.luminance() < backgroundColor.luminance()) 1425 hsla.lightness += datePlaceholderColorLightnessAdjustmentFactor * (1 .0f - hsla.lightness);1425 hsla.lightness += datePlaceholderColorLightnessAdjustmentFactor * (100.0f - hsla.lightness); 1426 1426 else 1427 1427 hsla.lightness *= datePlaceholderColorLightnessAdjustmentFactor; -
trunk/Tools/ChangeLog
r272857 r272870 1 2021-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 1 11 2021-02-15 Adam Roben <aroben@apple.com> 2 12 -
trunk/Tools/TestWebKitAPI/Tests/WebCore/ColorTests.cpp
r272436 r272870 43 43 EXPECT_FLOAT_EQ(0, hslaColor.hue); 44 44 EXPECT_FLOAT_EQ(0, hslaColor.saturation); 45 EXPECT_FLOAT_EQ(1 , hslaColor.lightness);45 EXPECT_FLOAT_EQ(100, hslaColor.lightness); 46 46 47 EXPECT_FLOAT_EQ(color.lightness() , hslaColor.lightness);47 EXPECT_FLOAT_EQ(color.lightness() * 100, hslaColor.lightness); 48 48 49 49 auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor); … … 61 61 EXPECT_FLOAT_EQ(0, hslaColor.lightness); 62 62 63 EXPECT_FLOAT_EQ(color.lightness() , hslaColor.lightness);63 EXPECT_FLOAT_EQ(color.lightness() * 100, hslaColor.lightness); 64 64 65 65 auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor); … … 74 74 75 75 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); 80 80 81 81 auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor); … … 89 89 auto hslaColor = color.toColorTypeLossy<HSLA<float>>(); 90 90 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); 96 96 97 97 auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor); … … 105 105 auto hslaColor = color.toColorTypeLossy<HSLA<float>>(); 106 106 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); 112 112 113 113 auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor); … … 123 123 EXPECT_FLOAT_EQ(0, hslaColor.hue); 124 124 EXPECT_FLOAT_EQ(0, hslaColor.saturation); 125 EXPECT_FLOAT_EQ( 0.50196078431372548, hslaColor.lightness);125 EXPECT_FLOAT_EQ(50.196083, hslaColor.lightness); 126 126 127 EXPECT_FLOAT_EQ(color.lightness() , hslaColor.lightness);127 EXPECT_FLOAT_EQ(color.lightness() * 100, hslaColor.lightness); 128 128 129 129 auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor); … … 139 139 EXPECT_FLOAT_EQ(0, hslaColor.hue); 140 140 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); 144 144 145 145 auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor); … … 155 155 EXPECT_FLOAT_EQ(0, hslaColor.hue); 156 156 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); 160 160 161 161 auto roundTrippedColor = convertColor<SRGBA<uint8_t>>(hslaColor);
Note: See TracChangeset
for help on using the changeset viewer.