Changeset 271362 in webkit


Ignore:
Timestamp:
Jan 11, 2021 8:56:58 AM (18 months ago)
Author:
weinig@apple.com
Message:

LayoutTests/imported/w3c:
Support lab(), lch(), gray() and color(lab ...) colors
https://bugs.webkit.org/show_bug.cgi?id=205675

Reviewed by Simon Fraser.

Update tests to use rectangles rather than text to make anti-aliasing differences
not cause failures. These changes will be upstreamed to the WebPlatformTests.

  • web-platform-tests/css/css-color/lab-001-expected.html:
  • web-platform-tests/css/css-color/lab-001.html:
  • web-platform-tests/css/css-color/lab-002-expected.html:
  • web-platform-tests/css/css-color/lab-002.html:
  • web-platform-tests/css/css-color/lab-003-expected.html:
  • web-platform-tests/css/css-color/lab-003.html:
  • web-platform-tests/css/css-color/lab-004-expected.html:
  • web-platform-tests/css/css-color/lab-004.html:
  • web-platform-tests/css/css-color/lab-005-expected.html:
  • web-platform-tests/css/css-color/lab-005.html:
  • web-platform-tests/css/css-color/lab-006-expected.html:
  • web-platform-tests/css/css-color/lab-006.html:
  • web-platform-tests/css/css-color/lab-007-expected.html:
  • web-platform-tests/css/css-color/lab-007.html:
  • web-platform-tests/css/css-color/lch-001-expected.html:
  • web-platform-tests/css/css-color/lch-001.html:
  • web-platform-tests/css/css-color/lch-002-expected.html:
  • web-platform-tests/css/css-color/lch-002.html:
  • web-platform-tests/css/css-color/lch-003-expected.html:
  • web-platform-tests/css/css-color/lch-003.html:
  • web-platform-tests/css/css-color/lch-004-expected.html:
  • web-platform-tests/css/css-color/lch-004.html:
  • web-platform-tests/css/css-color/lch-005-expected.html:
  • web-platform-tests/css/css-color/lch-005.html:
  • web-platform-tests/css/css-color/lch-006-expected.html:
  • web-platform-tests/css/css-color/lch-006.html:
  • web-platform-tests/css/css-color/lch-007-expected.html:
  • web-platform-tests/css/css-color/lch-007.html:

Source/WebCore:
Support lab(), lch() and color(lab ...) colors
https://bugs.webkit.org/show_bug.cgi?id=205675

Reviewed by Simon Fraser.

Original patch by Simon Fraser.

This adds parsing support for lab(), lch() and color(lab ...) CSS colors
(https://www.w3.org/TR/css-color-4/) and color type, conversion, and serialization
support for Lab and color type and conversion support for LCH (we store these color
canonically as Lab<float>, so serialization of LCH is never needed, much like HSL).

This change does not add support for the host platform layer (e.g. CoreGraphics, etc)
understanding of the Lab colorspace, and as such, when creating host color objects
(for instance via the cachedCGColor() helper) Lab<float> colors are converted to sRGB
first and then the host color is made. The ramification of this is for platforms that
use backingstores with greater than sRGB gamuts, Lab colors will be clampted to sRGB.
This should be rectified in a follow up change that adds proper creation of these host
objects but is being left off the initial change to limit changes.

Some of the imported tests have been updated to use rectangles rather than text to
avoid anti-aliasing issues and will be upstreamed to WPT following landing.

Tests:

fast/css/parsing-lab-colors.html
imported/w3c/web-platform-tests/css/css-color/lab-001.html
imported/w3c/web-platform-tests/css/css-color/lab-002.html
imported/w3c/web-platform-tests/css/css-color/lab-003.html
imported/w3c/web-platform-tests/css/css-color/lab-004.html
imported/w3c/web-platform-tests/css/css-color/lab-005.html
imported/w3c/web-platform-tests/css/css-color/lab-006.html
imported/w3c/web-platform-tests/css/css-color/lab-007.html
imported/w3c/web-platform-tests/css/css-color/lch-001.html
imported/w3c/web-platform-tests/css/css-color/lch-002.html
imported/w3c/web-platform-tests/css/css-color/lch-003.html
imported/w3c/web-platform-tests/css/css-color/lch-004.html
imported/w3c/web-platform-tests/css/css-color/lch-005.html
imported/w3c/web-platform-tests/css/css-color/lch-006.html
imported/w3c/web-platform-tests/css/css-color/lch-007.html

  • css/CSSValueKeywords.in:

Add "lab" and "lch" keywords.

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

(WebCore::CSSPropertyParserHelpers::parseOptionalAlpha):
(WebCore::CSSPropertyParserHelpers::parseLabParameters):
(WebCore::CSSPropertyParserHelpers::parseLCHParameters):
(WebCore::CSSPropertyParserHelpers::parseGrayParameters):
(WebCore::CSSPropertyParserHelpers::parseColorFunctionParameters):
(WebCore::CSSPropertyParserHelpers::parseColorFunction):
Add support for parsing "lab(...)", "lch(...)", "gray(...)"
and "color(lab ...)", all of which create Lab<float> colors.

Also adds explicit UnitlessZeroQuirk flag to angle parsing to
allow parsing of newer specs that don't want to allow unitless zero
for angles. For now, I have left FIXMEs for the properties that
should probably disable it. This was not strictly necessary for this
change (as lch actaully allows unitless angles now), but it seems
like a solid move forward.

  • platform/graphics/Color.h:

(WebCore::Color::Color):
Add overload of the Color constructor that takes a Lab<float> matching other
ColorSpace types.

  • platform/graphics/ColorConversion.cpp:

(WebCore::convertFromD50WhitePointToD65WhitePoint):
(WebCore::convertFromD65WhitePointToD50WhitePoint):
(WebCore::toXYZA):
(WebCore::toLab):
(WebCore::toLCHA):

  • platform/graphics/ColorConversion.h:

(WebCore::toLab):
(WebCore::toLCHA):
Add conversions to/from Lab to D65 white point XYZA (the white point we expect XYZA to be in), and conversion
from Lch to/from Lab.

  • platform/graphics/ColorSerialization.cpp:

(WebCore::serialization):
(WebCore::serializationForCSS):
(WebCore::serializationForHTML):
(WebCore::serializationForRenderTreeAsText):

  • platform/graphics/ColorSerialization.h:

Add serialization for Lab colors. We currently always serialize using the lab()
notation, which appears to be correct for at least colors declared using lab(),
lch() and gray(). Unclear if it is correct for colors declared with color(lab ...).
Opened https://github.com/w3c/csswg-drafts/issues/5825 to track getting a resolution
for "color(lab ...)".

  • platform/graphics/ColorSpace.cpp:

(WebCore::operator<<):

  • platform/graphics/ColorSpace.h:

Add Lab as a ColorSpace and text stream dumping for it.

  • platform/graphics/ColorTypes.h:

(WebCore::Lab::Lab):
(WebCore::asColorComponents):
(WebCore::asLab):
Add Lab color type.

(WebCore::LCHA::LCHA):
(WebCore::asLCHA):
Add LCHA color type.

(WebCore::callWithColorType):
Add Lab to callWithColorType since it is now a valid ColorSpace.

  • platform/graphics/cg/ColorSpaceCG.cpp:

(WebCore::labColorSpaceRef):

  • platform/graphics/cg/ColorSpaceCG.h:

(WebCore::cachedCGColorSpace):
For now, return the sRGB color space to indicate to callers that they should do a conversion.

LayoutTests:
Support lab(), lch(), gray() and color(lab ...) colors
https://bugs.webkit.org/show_bug.cgi?id=205675

Reviewed by Simon Fraser.

Original patch by Simon Fraser.

Parsing tests for lab/lch/gray colors.

  • TestExpectations: Unskip lab/lch tests.
  • fast/css/parsing-lab-colors-expected.txt: Added.
  • fast/css/parsing-lab-colors.html: Added.
Location:
trunk
Files:
2 added
46 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r271350 r271362  
     12021-01-11  Sam Weinig  <weinig@apple.com>
     2
     3        Support lab(), lch(), gray() and color(lab ...) colors
     4        https://bugs.webkit.org/show_bug.cgi?id=205675
     5
     6        Reviewed by Simon Fraser.
     7
     8        Original patch by Simon Fraser.
     9
     10        Parsing tests for lab/lch/gray colors.
     11
     12        * TestExpectations: Unskip lab/lch tests.
     13        * fast/css/parsing-lab-colors-expected.txt: Added.
     14        * fast/css/parsing-lab-colors.html: Added.
     15
    1162021-01-10  Antti Koivisto  <antti@apple.com>
    217
  • trunk/LayoutTests/TestExpectations

    r271350 r271362  
    20172017webkit.org/b/148801 imported/w3c/web-platform-tests/css/css-color/t425-hsla-onscreen-multiple-boxes-c.xht [ ImageOnlyFailure ]
    20182018webkit.org/b/148801 imported/w3c/web-platform-tests/css/css-color/t425-hsla-onscreen-b.xht [ ImageOnlyFailure Pass ]
    2019 
    2020 # lab/lch not supported
    2021 imported/w3c/web-platform-tests/css/css-color/lab-001.html [ Skip ]
    2022 imported/w3c/web-platform-tests/css/css-color/lab-002.html [ Skip ]
    2023 imported/w3c/web-platform-tests/css/css-color/lab-003.html [ Skip ]
    2024 imported/w3c/web-platform-tests/css/css-color/lab-004.html [ Skip ]
    2025 imported/w3c/web-platform-tests/css/css-color/lab-005.html [ Skip ]
    2026 imported/w3c/web-platform-tests/css/css-color/lab-006.html [ Skip ]
    2027 imported/w3c/web-platform-tests/css/css-color/lab-007.html [ Skip ]
    2028 imported/w3c/web-platform-tests/css/css-color/lch-001.html [ Skip ]
    2029 imported/w3c/web-platform-tests/css/css-color/lch-002.html [ Skip ]
    2030 imported/w3c/web-platform-tests/css/css-color/lch-003.html [ Skip ]
    2031 imported/w3c/web-platform-tests/css/css-color/lch-004.html [ Skip ]
    2032 imported/w3c/web-platform-tests/css/css-color/lch-005.html [ Skip ]
    2033 imported/w3c/web-platform-tests/css/css-color/lch-006.html [ Skip ]
    2034 imported/w3c/web-platform-tests/css/css-color/lch-007.html [ Skip ]
    20352019
    20362020# Initial failures on the import of css-color
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r271320 r271362  
     12021-01-11  Sam Weinig  <weinig@apple.com>
     2
     3        Support lab(), lch(), gray() and color(lab ...) colors
     4        https://bugs.webkit.org/show_bug.cgi?id=205675
     5
     6        Reviewed by Simon Fraser.
     7
     8        Update tests to use rectangles rather than text to make anti-aliasing differences
     9        not cause failures. These changes will be upstreamed to the WebPlatformTests.
     10
     11        * web-platform-tests/css/css-color/lab-001-expected.html:
     12        * web-platform-tests/css/css-color/lab-001.html:
     13        * web-platform-tests/css/css-color/lab-002-expected.html:
     14        * web-platform-tests/css/css-color/lab-002.html:
     15        * web-platform-tests/css/css-color/lab-003-expected.html:
     16        * web-platform-tests/css/css-color/lab-003.html:
     17        * web-platform-tests/css/css-color/lab-004-expected.html:
     18        * web-platform-tests/css/css-color/lab-004.html:
     19        * web-platform-tests/css/css-color/lab-005-expected.html:
     20        * web-platform-tests/css/css-color/lab-005.html:
     21        * web-platform-tests/css/css-color/lab-006-expected.html:
     22        * web-platform-tests/css/css-color/lab-006.html:
     23        * web-platform-tests/css/css-color/lab-007-expected.html:
     24        * web-platform-tests/css/css-color/lab-007.html:
     25        * web-platform-tests/css/css-color/lch-001-expected.html:
     26        * web-platform-tests/css/css-color/lch-001.html:
     27        * web-platform-tests/css/css-color/lch-002-expected.html:
     28        * web-platform-tests/css/css-color/lch-002.html:
     29        * web-platform-tests/css/css-color/lch-003-expected.html:
     30        * web-platform-tests/css/css-color/lch-003.html:
     31        * web-platform-tests/css/css-color/lch-004-expected.html:
     32        * web-platform-tests/css/css-color/lch-004.html:
     33        * web-platform-tests/css/css-color/lch-005-expected.html:
     34        * web-platform-tests/css/css-color/lch-005.html:
     35        * web-platform-tests/css/css-color/lch-006-expected.html:
     36        * web-platform-tests/css/css-color/lch-006.html:
     37        * web-platform-tests/css/css-color/lch-007-expected.html:
     38        * web-platform-tests/css/css-color/lch-007.html:
     39
    1402021-01-08  Alex Christensen  <achristensen@webkit.org>
    241
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lab-001-expected.html

    r230861 r271362  
    11<!DOCTYPE html>
    22<meta charset="utf-8">
    3 <title>Green text reference</title>
     3<title>Green square reference</title>
    44<style>
    5     .test { color: #008000}
     5    .test { background-color: #008000; width: 12em; height: 12em;}
    66</style>
    77<body>
    8     <p class="test">Test passes if this text is green</p>
     8    <p>Test passes if you see a green square, and no red.</p>
     9    <div class="test"></div>
    910</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lab-001.html

    r262646 r271362  
    44<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
    55<link rel="help" href="https://drafts.csswg.org/css-color-4/#specifying-lab-lch">
    6 <link rel="match" href="greentext-ref.html">
     6<link rel="match" href="greensquare-ref.html">
    77<meta name="assert" content="lab() with no alpha">
    88<style>
    9     .test {color: lab(46.277% -47.562 48.583)} /* green (sRGB #008000) converted to Lab */
     9    .test { background-color: red; width: 12em; height: 6em; margin-top:0}
     10    .ref { background-color: #008000; width: 12em; height: 6em; margin-bottom: 0}
     11    .test { background-color: lab(46.277% -47.562 48.583)} /* green (sRGB #008000) converted to Lab */
    1012</style>
    1113<body>
    12     <p class="test">Test passes if this text is green</p>
     14    <p>Test passes if you see a green square, and no red.</p>
     15    <p class="ref"> </p>
     16    <p class="test"> </p>
    1317</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lab-002-expected.html

    r230861 r271362  
    11<!DOCTYPE html>
    22<meta charset="utf-8">
    3 <title>Black text reference</title>
     3<title>Black block reference</title>
    44<style>
    5     .test { color: #000000}
     5    .test { background-color: #000000; width: 12em; height: 12em;}
    66</style>
    77<body>
    8     <p class="test">Test passes if this text is black</p>
     8    <p>Test passes if you see a black square, and no red.</p>
     9    <p class="test"> </p>
    910</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lab-002.html

    r262646 r271362  
    44<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
    55<link rel="help" href="https://drafts.csswg.org/css-color-4/#specifying-lab-lch">
    6 <link rel="match" href="blacktext-ref.html">
     6<link rel="match" href="blackblock-ref.html">
    77<meta name="assert" content="lab() with no alpha">
    88<style>
    9     .test { color: red; }
    10     .test { color: lab(0% 0 0)} /* black (sRGB #000000) converted to Lab */
     9    .test { background-color: red; width: 12em; height: 12em; }
     10    .test { background-color: lab(0% 0 0) } /* black (sRGB #000000) converted to Lab */
    1111</style>
    1212<body>
    13     <p class="test">Test passes if this text is black</p>
     13    <p>Test passes if you see a black square, and no red.</p>
     14    <p class="test"> </p>
    1415</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lab-003-expected.html

    r230861 r271362  
    11<!DOCTYPE html>
    22<meta charset="utf-8">
    3 <title>White text reference</title>
     3<title>White block reference</title>
    44<style>
    5     .test { color: #FFFFFF; background-color: #333; padding: 3px}
     5    body { background-color: grey; }
     6    .test { background-color: #FFFFFF; width: 12em; height: 12em;}
    67</style>
    78<body>
    8     <p class="test">Test passes if this text is white</p>
     9    <p>Test passes if you see a white square, and no red.</p>
     10    <p class="test"> </p>
    911</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lab-003.html

    r262646 r271362  
    44<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
    55<link rel="help" href="https://drafts.csswg.org/css-color-4/#specifying-lab-lch">
    6 <link rel="match" href="whitetext-ref.html">
     6<link rel="match" href="whiteblock-ref.html">
    77<meta name="assert" content="lab() with no alpha">
    88<style>
    9     .test { color: red; background-color: #333; padding: 3px;}
    10     .test { color: lab(100% 0 0);} /* white (sRGB #FFFFFF) converted to Lab */
     9    body { background-color: grey; }
     10    .test { background-color: red; width: 12em; height: 12em; }
     11    .test { background-color: lab(100% 0 0);} /* white (sRGB #FFFFFF) converted to Lab */
    1112</style>
    1213<body>
    13     <p class="test">Test passes if this text is white</p>
     14    <p>Test passes if you see a white square, and no red.</p>
     15    <p class="test"> </p>
    1416</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lab-004-expected.html

    r232903 r271362  
    33<title>CSS Color 4: Specifying Lab and LCH</title>
    44<style>
    5     .match { color: rgb(75.62% 30.45% 47.56%)} /* lab(50 50 0) converted to sRGB */
     5    .test { background-color:rgb(75.62% 30.45% 47.56%); width: 12em; height: 12em;} /* lab(50 50 0) converted to sRGB */
    66</style>
    77<body>
    8     <p>Test passes if the two lines of filler text are the same color.</p>
    9     <p class="match">Filler text. Filler text. Filler text. </p>
    10     <p class="match">Filler text. Filler text. Filler text. </p>
     8    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     9    <p class="test"> </p>
    1110</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lab-004.html

    r262646 r271362  
    77<meta name="assert" content="lab() with no alpha, positive a axis">
    88<style>
    9     .test { color: red; }
    10     .test { color: lab(50% 50 0)}
    11     .match { color: rgb(75.62%, 30.45%, 47.56%)} /* lab(50 50 0) converted to sRGB */
     9    .test { background-color: red; width: 12em; height: 6em; margin-top:0}
     10    .ref { background-color: rgb(75.62%, 30.45%, 47.56%); width: 12em; height: 6em; margin-bottom: 0}/* lab(50 50 0) converted to sRGB */
     11    .test { background-color: lab(50% 50 0)}
    1212</style>
    1313<body>
    14     <p>Test passes if the two lines of filler text are the same color.</p>
    15     <p class="test">Filler text. Filler text. Filler text. </p>
    16     <p class="match">Filler text. Filler text. Filler text. </p>
     14    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     15    <p class="ref"> </p>
     16    <p class="test"> </p>
    1717</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lab-005-expected.html

    r232903 r271362  
    33<title>CSS Color 4: Specifying Lab and LCH</title>
    44<style>
    5     .match { color: rgb(10.79%, 75.55%, 66.40%)} /* lab(70 -45 0) converted to sRGB */
     5    .test { background-color: rgb(10.79%, 75.55%, 66.40%); width: 12em; height: 12em;} /* lab(70 -45 0) converted to sRGB */
    66</style>
    77<body>
    8     <p>Test passes if the two lines of filler text are the same color.</p>
    9     <p class="match">Filler text. Filler text. Filler text. </p>
    10     <p class="match">Filler text. Filler text. Filler text. </p>
     8    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     9    <p class="test"> </p>
    1110</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lab-005.html

    r262646 r271362  
    77<meta name="assert" content="lab() with no alpha, negative a axis">
    88<style>
    9     .test { color: red; }
    10     .test { color: lab(70% -45 0)}
    11     .match { color: rgb(10.79%, 75.55%, 66.40%)} /* lab(70 -45 0) converted to sRGB */
     9    .test { background-color: red; width: 12em; height: 6em; margin-top:0}
     10    .ref { background-color: rgb(10.79%, 75.55%, 66.40%); width: 12em; height: 6em; margin-bottom: 0} /* lab(70 -45 0) converted to sRGB */
     11    .test { background-color: lab(70% -45 0)}
    1212</style>
    1313<body>
    14     <p>Test passes if the two lines of filler text are the same color.</p>
    15     <p class="test">Filler text. Filler text. Filler text. </p>
    16     <p class="match">Filler text. Filler text. Filler text. </p>
     14    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     15    <p class="ref"> </p>
     16    <p class="test"> </p>
    1717</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lab-006-expected.html

    r232903 r271362  
    33<title>CSS Color 4: Specifying Lab and LCH</title>
    44<style>
    5     .match { color: rgb(76.62%, 66.36%, 5.58%)} /* lab(70 0 70) converted to sRGB */
     5    .test { background-color: rgb(76.62%, 66.36%, 5.58%); width: 12em; height: 12em;} /* lab(70 0 70) converted to sRGB */
    66</style>
    77<body>
    8     <p>Test passes if the two lines of filler text are the same color.</p>
    9     <p class="match">Filler text. Filler text. Filler text. </p>
    10     <p class="match">Filler text. Filler text. Filler text. </p>
     8    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     9    <p class="test"> </p>
    1110</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lab-006.html

    r262646 r271362  
    77<meta name="assert" content="lab() with no alpha, positive b axis">
    88<style>
    9     .test { color: red; }
    10     .test { color: lab(70% 0 70)}
    11     .match { color: rgb(76.62%, 66.36%, 5.58%)} /* lab(70 0 70) converted to sRGB */
     9    .test { background-color: red; width: 12em; height: 6em; margin-top:0}
     10    .ref { background-color: rgb(76.62%, 66.36%, 5.58%); width: 12em; height: 6em; margin-bottom: 0} /* lab(70 0 70) converted to sRGB */
     11    .test { background-color: lab(70% 0 70)}
    1212</style>
    1313<body>
    14     <p>Test passes if the two lines of filler text are the same color.</p>
    15     <p class="test">Filler text. Filler text. Filler text. </p>
    16     <p class="match">Filler text. Filler text. Filler text. </p>
     14    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     15    <p class="ref"> </p>
     16    <p class="test"> </p>
    1717</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lab-007-expected.html

    r232903 r271362  
    33<title>CSS Color 4: Specifying Lab and LCH</title>
    44<style>
    5     .match { color: rgb(12.81%, 53.10%, 92.76%)} /* lab(55 0 -60) converted to sRGB */
     5    .test { background-color: rgb(12.81%, 53.10%, 92.76%); width: 12em; height: 12em;} /* lab(55 0 -60) converted to sRGB */
    66</style>
    77<body>
    8     <p>Test passes if the two lines of filler text are the same color.</p>
    9     <p class="match">Filler text. Filler text. Filler text. </p>
    10     <p class="match">Filler text. Filler text. Filler text. </p>
     8    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     9    <p class="test"> </p>
    1110</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lab-007.html

    r262646 r271362  
    77<meta name="assert" content="lab() with no alpha, negative b axis">
    88<style>
    9     .test { color: red; }
    10     .test { color: lab(55% 0 -60)}
    11     .match { color: rgb(12.81%, 53.10%, 92.76%)} /* lab(55 0 -60) converted to sRGB */
     9    .test { background-color: red; width: 12em; height: 6em; margin-top:0}
     10    .ref { background-color: rgb(12.81%, 53.10%, 92.76%); width: 12em; height: 6em; margin-bottom: 0} /* lab(55 0 -60) converted to sRGB */
     11    .test { background-color: lab(55% 0 -60)}
    1212</style>
    1313<body>
    14     <p>Test passes if the two lines of filler text are the same color.</p>
    15     <p class="test">Filler text. Filler text. Filler text. </p>
    16     <p class="match">Filler text. Filler text. Filler text. </p>
     14    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     15    <p class="ref"> </p>
     16    <p class="test"> </p>
    1717</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lch-001-expected.html

    r230861 r271362  
    11<!DOCTYPE html>
    22<meta charset="utf-8">
    3 <title>Green text reference</title>
     3<title>Green block reference</title>
    44<style>
     5    .test { background-color: #008000; width: 12em; height: 12em;}
    56    .test { color: #008000}
    67</style>
    78<body>
    8     <p class="test">Test passes if this text is green</p>
     9    <p>Test passes if you see a green square, and no red.</p>
     10    <div class="test"></div>
    911</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lch-001.html

    r262646 r271362  
    44<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
    55<link rel="help" href="https://drafts.csswg.org/css-color-4/#specifying-lab-lch">
    6 <link rel="match" href="greentext-ref.html">
     6<link rel="match" href="greenblock-ref.html">
    77<meta name="assert" content="lch() with no alpha">
    88<style>
    9     .test {color: lch(46.277% 67.945 134.427)} /* green (sRGB #008000) converted to LCH */
     9    .test { background-color: red; width: 12em; height: 6em; margin-top:0}
     10    .ref { background-color: #008000; width: 12em; height: 6em; margin-bottom: 0}
     11    .test { background-color: lch(46.277% 67.945 134.427)} /* green (sRGB #008000) converted to LCH */
    1012</style>
    1113<body>
    12     <p class="test">Test passes if this text is green</p>
     14    <p>Test passes if you see a green square, and no red.</p>
     15    <p class="ref"> </p>
     16    <p class="test"> </p>
    1317</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lch-002-expected.html

    r230861 r271362  
    11<!DOCTYPE html>
    22<meta charset="utf-8">
    3 <title>Black text reference</title>
     3<title>Black block reference</title>
    44<style>
    5     .test { color: #000000}
     5    .test { background-color: #000000; width: 12em; height: 12em;}
    66</style>
    77<body>
    8     <p class="test">Test passes if this text is black</p>
     8    <p>Test passes if you see a black square, and no red.</p>
     9    <p class="test"> </p>
    910</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lch-002.html

    r262646 r271362  
    44<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
    55<link rel="help" href="https://drafts.csswg.org/css-color-4/#specifying-lab-lch">
    6 <link rel="match" href="blacktext-ref.html">
     6<link rel="match" href="blackblock-ref.html">
    77<meta name="assert" content="lch() with no alpha">
    88<style>
    9     .test { color: red; }
    10     .test { color: lch(0% 0 0)} /* black (sRGB #000000) converted to LCH */
     9    .test { background-color: red; width: 12em; height: 12em; }
     10    .test { background-color: lch(0% 0 0) } /* black (sRGB #000000) converted to Lab */
    1111</style>
    1212<body>
    13     <p class="test">Test passes if this text is black</p>
     13    <p>Test passes if you see a black square, and no red.</p>
     14    <p class="test"> </p>
    1415</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lch-003-expected.html

    r230861 r271362  
    11<!DOCTYPE html>
    22<meta charset="utf-8">
    3 <title>White text reference</title>
     3<title>White block reference</title>
    44<style>
    5     .test { color: #FFFFFF; background-color: #333; padding: 3px}
     5    body { background-color: grey; }
     6    .test { background-color: #FFFFFF; width: 12em; height: 12em;}
    67</style>
    78<body>
    8     <p class="test">Test passes if this text is white</p>
     9    <p>Test passes if you see a white square, and no red.</p>
     10    <p class="test"> </p>
    911</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lch-003.html

    r262646 r271362  
    77<meta name="assert" content="lch() with no alpha">
    88<style>
    9     .test { color: red; background-color: #333; padding: 3px;}
    10     .test { color: lch(100% 0 0);} /* white (sRGB #FFFFFF) converted to LCH */
     9    body { background-color: grey; }
     10    .test { background-color: red; width: 12em; height: 12em; }
     11    .test { background-color: lch(100% 0 0);} /* white (sRGB #FFFFFF) converted to Lab */
    1112</style>
    1213<body>
    13     <p class="test">Test passes if this text is white</p>
     14    <p>Test passes if you see a white square, and no red.</p>
     15    <p class="test"> </p>
    1416</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lch-004-expected.html

    r232903 r271362  
    33<title>CSS Color 4: Specifying Lab and LCH</title>
    44<style>
    5     .match { color: rgb(75.62% 30.45% 47.56%)} /* lab(50 50 0) converted to sRGB */
     5    .test { background-color:rgb(75.62% 30.45% 47.56%); width: 12em; height: 12em;} /* lch(50 50 0) converted to sRGB (happens to be the same as lab(50 50 0)*/
    66</style>
    77<body>
    8     <p>Test passes if the two lines of filler text are the same color.</p>
    9     <p class="match">Filler text. Filler text. Filler text. </p>
    10     <p class="match">Filler text. Filler text. Filler text. </p>
     8    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     9    <p class="test"> </p>
    1110</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lch-004.html

    r262646 r271362  
    44<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
    55<link rel="help" href="https://drafts.csswg.org/css-color-4/#specifying-lab-lch">
    6 <link rel="match" href="lab-004-ref.html">
     6<link rel="match" href="lch-004-ref.html">
    77<meta name="assert" content="lch() with no alpha, positive a axis">
    88<style>
    9     .test { color: red; }
    10     .test { color: lch(50% 50 0)}
    11     .match { color: rgb(75.62%, 30.45%, 47.56%)} /* lch(50 50 0) converted to sRGB (happens to be the same as lab(50 50 0)*/
     9    .test { background-color: red; width: 12em; height: 6em; margin-top:0}
     10    .ref { background-color: rgb(75.62%, 30.45%, 47.56%); width: 12em; height: 6em; margin-bottom: 0} /* lch(50 50 0) converted to sRGB (happens to be the same as lab(50 50 0)*/
     11    .test { background-color: lch(50% 50 0)}
    1212</style>
    1313<body>
    14     <p>Test passes if the two lines of filler text are the same color.</p>
    15     <p class="test">Filler text. Filler text. Filler text. </p>
    16     <p class="match">Filler text. Filler text. Filler text. </p>
     14    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     15    <p class="ref"> </p>
     16    <p class="test"> </p>
    1717</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lch-005-expected.html

    r232903 r271362  
    33<title>CSS Color 4: Specifying Lab and LCH</title>
    44<style>
    5     .match { color: rgb(10.79%, 75.55%, 66.40%)} /* lab(70 -45 0) converted to sRGB */
     5    .test { background-color: rgb(10.79%, 75.55%, 66.40%); width: 12em; height: 12em;} /* lch(70 45 180) converted to sRGB */
    66</style>
    77<body>
    8     <p>Test passes if the two lines of filler text are the same color.</p>
    9     <p class="match">Filler text. Filler text. Filler text. </p>
    10     <p class="match">Filler text. Filler text. Filler text. </p>
     8    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     9    <p class="test"> </p>
    1110</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lch-005.html

    r262646 r271362  
    44<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
    55<link rel="help" href="https://drafts.csswg.org/css-color-4/#specifying-lab-lch">
    6 <link rel="match" href="lab-005-ref.html">
     6<link rel="match" href="lch-005-ref.html">
    77<meta name="assert" content="lch() with no alpha, negative a axis">
    88<style>
    9     .test { color: red; }
    10     .test { color: lch(70% 45 -180)}
    11     .match { color: rgb(10.79%, 75.55%, 66.40%)} /* lch(70 45 180) converted to sRGB */
     9    .test { background-color: red; width: 12em; height: 6em; margin-top:0}
     10    .ref { background-color: rgb(10.79%, 75.55%, 66.40%); width: 12em; height: 6em; margin-bottom: 0} /* lch(70 45 180) converted to sRGB */
     11    .test { background-color: lch(70% 45 -180)}
    1212</style>
    1313<body>
    14     <p>Test passes if the two lines of filler text are the same color.</p>
    15     <p class="test">Filler text. Filler text. Filler text. </p>
    16     <p class="match">Filler text. Filler text. Filler text. </p>
     14    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     15    <p class="ref"> </p>
     16    <p class="test"> </p>
    1717</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lch-006-expected.html

    r232903 r271362  
    33<title>CSS Color 4: Specifying Lab and LCH</title>
    44<style>
    5     .match { color: rgb(76.62%, 66.36%, 5.58%)} /* lab(70 0 70) converted to sRGB */
     5    .test { background-color: rgb(76.62%, 66.36%, 5.58%); width: 12em; height: 12em;} /* lch(70 70 90) converted to sRGB */
    66</style>
    77<body>
    8     <p>Test passes if the two lines of filler text are the same color.</p>
    9     <p class="match">Filler text. Filler text. Filler text. </p>
    10     <p class="match">Filler text. Filler text. Filler text. </p>
     8    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     9    <p class="test"> </p>
    1110</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lch-006.html

    r262646 r271362  
    44<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
    55<link rel="help" href="https://drafts.csswg.org/css-color-4/#specifying-lab-lch">
    6 <link rel="match" href="lab-006-ref.html">
     6<link rel="match" href="lch-006-ref.html">
    77<meta name="assert" content="lch() with no alpha, positive b axis">
    88<style>
    9     .test { color: red; }
    10     .test { color: lch(70% 70 90)}
    11     .match { color: rgb(76.62%, 66.36%, 5.58%)} /* lch(70 70 90) converted to sRGB */
     9    .test { background-color: red; width: 12em; height: 6em; margin-top:0}
     10    .ref { background-color: rgb(76.62%, 66.36%, 5.58%); width: 12em; height: 6em; margin-bottom: 0} /* lch(70 70 90) converted to sRGB */
     11    .test { background-color: lch(70% 70 90)}
    1212</style>
    1313<body>
    14     <p>Test passes if the two lines of filler text are the same color.</p>
    15     <p class="test">Filler text. Filler text. Filler text. </p>
    16     <p class="match">Filler text. Filler text. Filler text. </p>
     14    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     15    <p class="ref"> </p>
     16    <p class="test"> </p>
    1717</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lch-007-expected.html

    r232903 r271362  
    33<title>CSS Color 4: Specifying Lab and LCH</title>
    44<style>
    5     .match { color: rgb(12.81%, 53.10%, 92.76%)} /* lab(55 0 -60) converted to sRGB */
     5    .test { background-color: rgb(27.38% 51.92% 91.25%); width: 12em; height: 12em;} /* lch(55% 58 275) converted to sRGB */
    66</style>
    77<body>
    8     <p>Test passes if the two lines of filler text are the same color.</p>
    9     <p class="match">Filler text. Filler text. Filler text. </p>
    10     <p class="match">Filler text. Filler text. Filler text. </p>
     8    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     9    <p class="test"> </p>
    1110</body>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-color/lch-007.html

    r262646 r271362  
    44<link rel="author" title="Chris Lilley" href="mailto:chris@w3.org">
    55<link rel="help" href="https://drafts.csswg.org/css-color-4/#specifying-lab-lch">
    6 <link rel="match" href="lab-007-ref.html">
     6<link rel="match" href="lch-007-ref.html">
    77<meta name="assert" content="lab() with no alpha, negative b axis">
    88<style>
    9     .test { color: red; }
    10     .test { color: lch(56% 58 275)}
    11     .match { color: rgb(12.81%, 53.10%, 92.76%)} /* lch(56 58 275) converted to sRGB */
     9    .test { background-color: red; width: 12em; height: 6em; margin-top:0}
     10    .ref { background-color: rgb(27.38% 51.92% 91.25%); width: 12em; height: 6em; margin-bottom: 0} /* lch(55% 58 275) converted to sRGB */
     11    .test { background-color: lch(55% 58 275)}
    1212</style>
    1313<body>
    14     <p>Test passes if the two lines of filler text are the same color.</p>
    15     <p class="test">Filler text. Filler text. Filler text. </p>
    16     <p class="match">Filler text. Filler text. Filler text. </p>
     14    <p>Test passes if you see a single square, and not two rectangles of different colors.</p>
     15    <p class="ref"> </p>
     16    <p class="test"> </p>
    1717</body>
  • trunk/Source/WebCore/ChangeLog

    r271360 r271362  
     12021-01-11  Sam Weinig  <weinig@apple.com>
     2
     3        Support lab(), lch() and color(lab ...) colors
     4        https://bugs.webkit.org/show_bug.cgi?id=205675
     5
     6        Reviewed by Simon Fraser.
     7
     8        Original patch by Simon Fraser.
     9
     10        This adds parsing support for lab(), lch() and color(lab ...) CSS colors
     11        (https://www.w3.org/TR/css-color-4/) and color type, conversion, and serialization
     12        support for Lab and color type and conversion support for LCH (we store these color
     13        canonically as Lab<float>, so serialization of LCH is never needed, much like HSL).
     14
     15        This change does not add support for the host platform layer (e.g. CoreGraphics, etc)
     16        understanding of the Lab colorspace, and as such, when creating host color objects
     17        (for instance via the cachedCGColor() helper) Lab<float> colors are converted to sRGB
     18        first and then the host color is made. The ramification of this is for platforms that
     19        use backingstores with greater than sRGB gamuts, Lab colors will be clampted to sRGB.
     20        This should be rectified in a follow up change that adds proper creation of these host
     21        objects but is being left off the initial change to limit changes.
     22
     23        Some of the imported tests have been updated to use rectangles rather than text to
     24        avoid anti-aliasing issues and will be upstreamed to WPT following landing.
     25
     26        Tests:
     27            fast/css/parsing-lab-colors.html
     28            imported/w3c/web-platform-tests/css/css-color/lab-001.html
     29            imported/w3c/web-platform-tests/css/css-color/lab-002.html
     30            imported/w3c/web-platform-tests/css/css-color/lab-003.html
     31            imported/w3c/web-platform-tests/css/css-color/lab-004.html
     32            imported/w3c/web-platform-tests/css/css-color/lab-005.html
     33            imported/w3c/web-platform-tests/css/css-color/lab-006.html
     34            imported/w3c/web-platform-tests/css/css-color/lab-007.html
     35            imported/w3c/web-platform-tests/css/css-color/lch-001.html
     36            imported/w3c/web-platform-tests/css/css-color/lch-002.html
     37            imported/w3c/web-platform-tests/css/css-color/lch-003.html
     38            imported/w3c/web-platform-tests/css/css-color/lch-004.html
     39            imported/w3c/web-platform-tests/css/css-color/lch-005.html
     40            imported/w3c/web-platform-tests/css/css-color/lch-006.html
     41            imported/w3c/web-platform-tests/css/css-color/lch-007.html
     42
     43        * css/CSSValueKeywords.in:
     44        Add "lab" and "lch" keywords.
     45
     46        * css/parser/CSSPropertyParser.cpp:
     47        * css/parser/CSSPropertyParserHelpers.h:
     48        * css/parser/CSSPropertyParserHelpers.cpp:
     49        (WebCore::CSSPropertyParserHelpers::parseOptionalAlpha):
     50        (WebCore::CSSPropertyParserHelpers::parseLabParameters):
     51        (WebCore::CSSPropertyParserHelpers::parseLCHParameters):
     52        (WebCore::CSSPropertyParserHelpers::parseGrayParameters):
     53        (WebCore::CSSPropertyParserHelpers::parseColorFunctionParameters):
     54        (WebCore::CSSPropertyParserHelpers::parseColorFunction):
     55        Add support for parsing "lab(...)", "lch(...)", "gray(...)"
     56        and "color(lab ...)", all of which create Lab<float> colors.
     57
     58        Also adds explicit UnitlessZeroQuirk flag to angle parsing to
     59        allow parsing of newer specs that don't want to allow unitless zero
     60        for angles. For now, I have left FIXMEs for the properties that
     61        should probably disable it. This was not strictly necessary for this
     62        change (as lch actaully allows unitless angles now), but it seems
     63        like a solid move forward.
     64
     65        * platform/graphics/Color.h:
     66        (WebCore::Color::Color):
     67        Add overload of the Color constructor that takes a Lab<float> matching other
     68        ColorSpace types.
     69
     70        * platform/graphics/ColorConversion.cpp:
     71        (WebCore::convertFromD50WhitePointToD65WhitePoint):
     72        (WebCore::convertFromD65WhitePointToD50WhitePoint):
     73        (WebCore::toXYZA):
     74        (WebCore::toLab):
     75        (WebCore::toLCHA):
     76        * platform/graphics/ColorConversion.h:
     77        (WebCore::toLab):
     78        (WebCore::toLCHA):
     79        Add conversions to/from Lab to D65 white point XYZA (the white point we expect XYZA to be in), and conversion
     80        from Lch to/from Lab.
     81
     82        * platform/graphics/ColorSerialization.cpp:
     83        (WebCore::serialization):
     84        (WebCore::serializationForCSS):
     85        (WebCore::serializationForHTML):
     86        (WebCore::serializationForRenderTreeAsText):
     87        * platform/graphics/ColorSerialization.h:
     88        Add serialization for Lab colors. We currently always serialize using the lab()
     89        notation, which appears to be correct for at least colors declared using lab(),
     90        lch() and gray(). Unclear if it is correct for colors declared with color(lab ...).
     91        Opened https://github.com/w3c/csswg-drafts/issues/5825 to track getting a resolution
     92        for "color(lab ...)".
     93
     94        * platform/graphics/ColorSpace.cpp:
     95        (WebCore::operator<<):
     96        * platform/graphics/ColorSpace.h:
     97        Add Lab as a ColorSpace and text stream dumping for it.
     98
     99        * platform/graphics/ColorTypes.h:
     100        (WebCore::Lab::Lab):
     101        (WebCore::asColorComponents):
     102        (WebCore::asLab):
     103        Add Lab color type.
     104
     105        (WebCore::LCHA::LCHA):
     106        (WebCore::asLCHA):
     107        Add LCHA color type.
     108       
     109        (WebCore::callWithColorType):
     110        Add Lab to callWithColorType since it is now a valid ColorSpace.
     111
     112        * platform/graphics/cg/ColorSpaceCG.cpp:
     113        (WebCore::labColorSpaceRef):
     114        * platform/graphics/cg/ColorSpaceCG.h:
     115        (WebCore::cachedCGColorSpace):
     116        For now, return the sRGB color space to indicate to callers that they should do a conversion.
     117
    11182021-01-11  Yoshiaki Jitsukawa  <yoshiaki.jitsukawa@sony.com>
    2119
  • trunk/Source/WebCore/css/CSSValueKeywords.in

    r270823 r271362  
    12651265hsl
    12661266hsla
     1267lab
     1268lch
    12671269//color
    12681270
  • trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp

    r270613 r271362  
    982982        return CSSFontStyleRangeValue::create(keyword.releaseNonNull());
    983983
    984     if (auto firstAngle = consumeAngle(range, cssParserMode)) {
     984    // FIXME: This should probably not allow the unitless zero.
     985    if (auto firstAngle = consumeAngle(range, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow)) {
    985986        auto firstAngleInDegrees = firstAngle->doubleValue(CSSUnitType::CSS_DEG);
    986987        if (!isFontStyleAngleInRange(firstAngleInDegrees))
     
    991992            return CSSFontStyleRangeValue::create(keyword.releaseNonNull(), WTFMove(result));
    992993        }
    993         auto secondAngle = consumeAngle(range, cssParserMode);
     994
     995        // FIXME: This should probably not allow the unitless zero.
     996        auto secondAngle = consumeAngle(range, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow);
    994997        if (!secondAngle)
    995998            return nullptr;
     
    19011904    case CSSValueSkewY:
    19021905    case CSSValueSkew:
    1903         parsedValue = consumeAngle(args, cssParserMode, UnitlessQuirk::Forbid);
     1906        parsedValue = consumeAngle(args, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow);
    19041907        if (!parsedValue)
    19051908            return nullptr;
    19061909        if (functionId == CSSValueSkew && consumeCommaIncludingWhitespace(args)) {
    19071910            transformValue->append(*parsedValue);
    1908             parsedValue = consumeAngle(args, cssParserMode, UnitlessQuirk::Forbid);
     1911            parsedValue = consumeAngle(args, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow);
    19091912            if (!parsedValue)
    19101913                return nullptr;
     
    19571960        if (!consumeNumbers(args, transformValue, 3) || !consumeCommaIncludingWhitespace(args))
    19581961            return nullptr;
    1959         parsedValue = consumeAngle(args, cssParserMode, UnitlessQuirk::Forbid);
     1962        parsedValue = consumeAngle(args, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow);
    19601963        if (!parsedValue)
    19611964            return nullptr;
     
    21232126        // Then, attempt to parse an angle. We try this as a fallback rather than the first option because
    21242127        // a unitless 0 angle would be consumed as an angle.
    2125         parsedValue = consumeAngle(range, cssParserMode, UnitlessQuirk::Forbid);
     2128        parsedValue = consumeAngle(range, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow);
    21262129        if (parsedValue) {
    21272130            // If we had already parsed an angle or numbers but not 3 in a row, this value is invalid.
     
    22432246    }
    22442247   
    2245     return consumeAngle(range, mode, UnitlessQuirk::Allow);
     2248    return consumeAngle(range, mode, UnitlessQuirk::Allow, UnitlessZeroQuirk::Allow);
    22462249}
    22472250
  • trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp

    r270167 r271362  
    297297}
    298298
    299 inline bool shouldAcceptUnitlessValue(double value, CSSParserMode cssParserMode, UnitlessQuirk unitless)
     299inline bool shouldAcceptUnitlessValue(double value, CSSParserMode cssParserMode, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero)
    300300{
    301301    // FIXME: Presentational HTML attributes shouldn't use the CSS parser for lengths
    302     return value == 0
    303         || isUnitLessValueParsingEnabledForMode(cssParserMode)
    304         || (cssParserMode == HTMLQuirksMode && unitless == UnitlessQuirk::Allow);
     302
     303    if (value == 0 && unitlessZero == UnitlessZeroQuirk::Allow)
     304        return true;
     305
     306    if (isUnitLessValueParsingEnabledForMode(cssParserMode))
     307        return true;
     308   
     309    return cssParserMode == HTMLQuirksMode && unitless == UnitlessQuirk::Allow;
    305310}
    306311
     
    340345    }
    341346    if (token.type() == NumberToken) {
    342         if (!shouldAcceptUnitlessValue(token.numericValue(), cssParserMode, unitless)
     347        if (!shouldAcceptUnitlessValue(token.numericValue(), cssParserMode, unitless, UnitlessZeroQuirk::Allow)
    343348            || (valueRange == ValueRangeNonNegative && token.numericValue() < 0))
    344349            return WTF::nullopt;
     
    465470}
    466471
    467 Optional<AngleRaw> consumeAngleRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless)
     472Optional<AngleRaw> consumeAngleRaw(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero)
    468473{
    469474    const CSSParserToken& token = range.peek();
     
    481486    }
    482487
    483     if (token.type() == NumberToken && shouldAcceptUnitlessValue(token.numericValue(), cssParserMode, unitless))
     488    if (token.type() == NumberToken && shouldAcceptUnitlessValue(token.numericValue(), cssParserMode, unitless, unitlessZero))
    484489        return { { CSSUnitType::CSS_DEG, range.consumeIncludingWhitespace().numericValue() } };
    485490
     
    491496}
    492497
    493 RefPtr<CSSPrimitiveValue> consumeAngle(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless)
     498RefPtr<CSSPrimitiveValue> consumeAngle(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero)
    494499{
    495500    const CSSParserToken& token = range.peek();
     
    503508    }
    504509
    505     if (auto angle = consumeAngleRaw(range, cssParserMode, unitless))
     510    if (auto angle = consumeAngleRaw(range, cssParserMode, unitless, unitlessZero))
    506511        return CSSValuePool::singleton().createValue(angle->value, angle->type);
    507512
     
    509514}
    510515
    511 static RefPtr<CSSPrimitiveValue> consumeAngleOrPercent(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless)
     516static RefPtr<CSSPrimitiveValue> consumeAngleOrPercent(CSSParserTokenRange& range, CSSParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless, UnitlessZeroQuirk unitlessZero)
    512517{
    513518    const CSSParserToken& token = range.peek();
     
    523528        }
    524529    }
    525     if (token.type() == NumberToken && shouldAcceptUnitlessValue(token.numericValue(), cssParserMode, unitless))
     530    if (token.type() == NumberToken && shouldAcceptUnitlessValue(token.numericValue(), cssParserMode, unitless, unitlessZero))
    526531        return CSSValuePool::singleton().createValue(range.consumeIncludingWhitespace().numericValue(), CSSUnitType::CSS_DEG);
    527532
     
    550555    const CSSParserToken& token = range.peek();
    551556    CSSUnitType unit = token.unitType();
    552     bool acceptUnitless = token.type() == NumberToken && unitless == UnitlessQuirk::Allow && shouldAcceptUnitlessValue(token.numericValue(), cssParserMode, unitless);
     557    bool acceptUnitless = token.type() == NumberToken && unitless == UnitlessQuirk::Allow && shouldAcceptUnitlessValue(token.numericValue(), cssParserMode, unitless, UnitlessZeroQuirk::Allow);
    553558    if (acceptUnitless)
    554559        unit = CSSUnitType::CSS_MS;
     
    749754    CSSParserTokenRange args = consumeFunction(range);
    750755    double angleInDegrees;
    751     if (auto angle = consumeAngleRaw(args, cssParserMode, UnitlessQuirk::Forbid))
     756    if (auto angle = consumeAngleRaw(args, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid))
    752757        angleInDegrees = CSSPrimitiveValue::computeDegrees(angle->type, angle->value);
    753758    else {
     
    793798}
    794799
     800static Optional<float> parseOptionalAlpha(CSSParserTokenRange& range)
     801{
     802    if (!consumeSlashIncludingWhitespace(range))
     803        return 1.0f;
     804
     805    if (auto alphaParameter = consumePercentRaw(range, ValueRangeAll))
     806        return clampTo<float>(*alphaParameter / 100.0, 0.0, 1.0);
     807
     808    double alphaParameter;
     809    if (!consumeNumberRaw(range, alphaParameter, ValueRangeAll))
     810        return WTF::nullopt;
     811
     812    return clampTo<float>(alphaParameter, 0.0, 1.0);
     813}
     814
     815static Color parseLabParameters(CSSParserTokenRange& range)
     816{
     817    ASSERT(range.peek().functionId() == CSSValueLab);
     818    CSSParserTokenRange args = consumeFunction(range);
     819
     820    auto lightness = consumePercentRaw(args, ValueRangeAll);
     821    if (!lightness)
     822        return { };
     823
     824    double aValue;
     825    if (!consumeNumberRaw(args, aValue, ValueRangeAll))
     826        return { };
     827
     828    double bValue;
     829    if (!consumeNumberRaw(args, bValue, ValueRangeAll))
     830        return { };
     831
     832    auto alpha = parseOptionalAlpha(args);
     833    if (!alpha)
     834        return { };
     835
     836    if (!args.atEnd())
     837        return { };
     838
     839    return Lab<float> { static_cast<float>(*lightness), static_cast<float>(aValue), static_cast<float>(bValue), *alpha };
     840}
     841
     842static Color parseLCHParameters(CSSParserTokenRange& range, CSSParserMode cssParserMode)
     843{
     844    ASSERT(range.peek().functionId() == CSSValueLch);
     845    CSSParserTokenRange args = consumeFunction(range);
     846
     847    auto lightness = consumePercentRaw(args, ValueRangeAll);
     848    if (!lightness)
     849        return Color();
     850
     851    double chromaValue;
     852    if (!consumeNumberRaw(args, chromaValue, ValueRangeAll))
     853        return { };
     854
     855    double angleInDegrees;
     856    if (auto hueValue = consumeAngleRaw(args, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Forbid))
     857        angleInDegrees = CSSPrimitiveValue::computeDegrees(hueValue->type, hueValue->value);
     858    else {
     859        if (!consumeNumberRaw(args, angleInDegrees, ValueRangeAll))
     860            return { };
     861    }
     862
     863    angleInDegrees = fmod(angleInDegrees, 360.0);
     864    if (angleInDegrees < 0.0)
     865        angleInDegrees += 360.0;
     866
     867    auto alpha = parseOptionalAlpha(args);
     868    if (!alpha)
     869        return { };
     870
     871    if (!args.atEnd())
     872        return { };
     873
     874    return toLab(LCHA<float> { static_cast<float>(*lightness), static_cast<float>(chromaValue), static_cast<float>(angleInDegrees), *alpha });
     875}
     876
     877template<typename ColorType>
     878static Color parseColorFunctionForSRGBOrDisplayP3Parameters(CSSParserTokenRange& args)
     879{
     880    ASSERT(args.peek().id() == CSSValueSRGB || args.peek().id() == CSSValueDisplayP3);
     881    consumeIdentRaw(args);
     882
     883    double colorChannels[3] = { 0, 0, 0 };
     884    for (int i = 0; i < 3; ++i) {
     885        double value;
     886        if (consumeNumberRaw(args, value))
     887            colorChannels[i] = value;
     888        else
     889            break;
     890    }
     891
     892    auto alpha = parseOptionalAlpha(args);
     893    if (!alpha)
     894        return { };
     895
     896    return ColorType { clampTo<float>(colorChannels[0], 0.0, 1.0), clampTo<float>(colorChannels[1], 0.0, 1.0), clampTo<float>(colorChannels[2], 0.0, 1.0), *alpha };
     897}
     898
     899static Color parseColorFunctionForLabParameters(CSSParserTokenRange& args)
     900{
     901    ASSERT(args.peek().id() == CSSValueLab);
     902    consumeIdentRaw(args);
     903
     904    auto lightness = consumePercentRaw(args, ValueRangeAll);
     905    if (!lightness)
     906        return { };
     907
     908    double aValue;
     909    if (!consumeNumberRaw(args, aValue, ValueRangeAll))
     910        return { };
     911
     912    double bValue;
     913    if (!consumeNumberRaw(args, bValue, ValueRangeAll))
     914        return { };
     915
     916    auto alpha = parseOptionalAlpha(args);
     917    if (!alpha)
     918        return { };
     919
     920    return Lab<float> { static_cast<float>(*lightness), static_cast<float>(aValue), static_cast<float>(bValue), *alpha };
     921}
     922
    795923static Color parseColorFunctionParameters(CSSParserTokenRange& range)
    796924{
     
    798926    CSSParserTokenRange args = consumeFunction(range);
    799927
    800     ColorSpace colorSpace;
     928    Color color;
    801929    switch (args.peek().id()) {
    802930    case CSSValueSRGB:
    803         colorSpace = ColorSpace::SRGB;
     931        color = parseColorFunctionForSRGBOrDisplayP3Parameters<SRGBA<float>>(args);
    804932        break;
    805933    case CSSValueDisplayP3:
    806         colorSpace = ColorSpace::DisplayP3;
     934        color = parseColorFunctionForSRGBOrDisplayP3Parameters<DisplayP3<float>>(args);
     935        break;
     936    case CSSValueLab:
     937        color = parseColorFunctionForLabParameters(args);
    807938        break;
    808939    default:
    809940        return { };
    810941    }
    811     consumeIdent(args);
    812 
    813     double colorChannels[4] = { 0, 0, 0, 1 };
    814     for (int i = 0; i < 3; ++i) {
    815         double value;
    816         if (consumeNumberRaw(args, value))
    817             colorChannels[i] = std::max(0.0, std::min(1.0, value));
    818         else
    819             break;
    820     }
    821 
    822     if (consumeSlashIncludingWhitespace(args)) {
    823         auto alphaParameter = consumePercent(args, ValueRangeAll);
    824         if (!alphaParameter)
    825             alphaParameter = consumeNumber(args, ValueRangeAll);
    826         if (!alphaParameter)
    827             return { };
    828 
    829         colorChannels[3] = std::max(0.0, std::min(1.0, alphaParameter->isPercentage() ? (alphaParameter->doubleValue() / 100) : alphaParameter->doubleValue()));
    830     }
     942
     943    if (!color.isValid())
     944        return { };
    831945
    832946    // FIXME: Support the comma-separated list of fallback color values.
     
    835949        return { };
    836950
    837     return Color { ColorComponents { static_cast<float>(colorChannels[0]), static_cast<float>(colorChannels[1]), static_cast<float>(colorChannels[2]), static_cast<float>(colorChannels[3]) }, colorSpace };
     951    return color;
    838952}
    839953
     
    8891003        color = parseHSLParameters(colorRange, cssParserMode);
    8901004        break;
     1005    case CSSValueLab:
     1006        color = parseLabParameters(colorRange);
     1007        break;
     1008    case CSSValueLch:
     1009        color = parseLCHParameters(colorRange, cssParserMode);
     1010        break;
    8911011    case CSSValueColor:
    8921012        color = parseColorFunctionParameters(colorRange);
     
    12731393    auto consumeStopPosition = [&] {
    12741394        return gradient.gradientType() == CSSConicGradient
    1275             ? consumeAngleOrPercent(range, mode, ValueRangeAll, UnitlessQuirk::Forbid)
     1395            ? consumeAngleOrPercent(range, mode, ValueRangeAll, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow)
    12761396            : consumeLengthOrPercent(range, mode, ValueRangeAll);
    12771397    };
     
    14471567
    14481568    bool expectComma = true;
    1449     RefPtr<CSSPrimitiveValue> angle = consumeAngle(args, cssParserMode, UnitlessQuirk::Forbid);
     1569    RefPtr<CSSPrimitiveValue> angle = consumeAngle(args, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow);
    14501570    if (angle)
    14511571        result->setAngle(angle.releaseNonNull());
     
    14831603    if (args.peek().type() == IdentToken) {
    14841604        if (consumeIdent<CSSValueFrom>(args)) {
    1485             auto angle = consumeAngle(args, context.mode, UnitlessQuirk::Forbid);
     1605            // FIXME: Unlike linear-gradient, conic-gradients are not specified to allow unitless 0 angles - https://www.w3.org/TR/css-images-4/#valdef-conic-gradient-angle.
     1606            auto angle = consumeAngle(args, context.mode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow);
    14861607            if (!angle)
    14871608                return nullptr;
     
    17831904
    17841905        if (filterType == CSSValueHueRotate)
    1785             parsedValue = consumeAngle(args, context.mode, UnitlessQuirk::Forbid);
     1906            parsedValue = consumeAngle(args, context.mode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow);
    17861907        else if (filterType == CSSValueBlur)
    17871908            parsedValue = consumeLength(args, HTMLStandardMode, ValueRangeNonNegative);
     
    19582079#if ENABLE(VARIATION_FONTS)
    19592080    if (!range.atEnd()) {
    1960         if (auto angle = consumeAngleRaw(range, cssParserMode)) {
     2081        // FIXME: This angle does specify that unitless 0 is allowed - see https://drafts.csswg.org/css-fonts-4/#valdef-font-style-oblique-angle
     2082        if (auto angle = consumeAngleRaw(range, cssParserMode, UnitlessQuirk::Forbid, UnitlessZeroQuirk::Allow)) {
    19612083            if (isFontStyleAngleInRange(CSSPrimitiveValue::computeDegrees(angle->type, angle->value)))
    19622084                return { { CSSValueOblique, WTFMove(angle) } };
  • trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h

    r270167 r271362  
    5656
    5757enum class UnitlessQuirk { Allow, Forbid };
     58enum class UnitlessZeroQuirk { Allow, Forbid };
    5859enum class AllowXResolutionUnit { Allow, Forbid };
    5960
     
    8283Optional<LengthOrPercentRaw> consumeLengthOrPercentRaw(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
    8384RefPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
    84 Optional<AngleRaw> consumeAngleRaw(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk = UnitlessQuirk::Forbid);
    85 RefPtr<CSSPrimitiveValue> consumeAngle(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk = UnitlessQuirk::Forbid);
     85Optional<AngleRaw> consumeAngleRaw(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk = UnitlessQuirk::Forbid, UnitlessZeroQuirk = UnitlessZeroQuirk::Forbid);
     86RefPtr<CSSPrimitiveValue> consumeAngle(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk = UnitlessQuirk::Forbid, UnitlessZeroQuirk = UnitlessZeroQuirk::Forbid);
    8687RefPtr<CSSPrimitiveValue> consumeTime(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
    8788RefPtr<CSSPrimitiveValue> consumeResolution(CSSParserTokenRange&, AllowXResolutionUnit = AllowXResolutionUnit::Forbid);
  • trunk/Source/WebCore/platform/graphics/Color.h

    r271093 r271362  
    5959//    - 4x float (0-1) Linear sRGBA, stored in a reference counted sub-object
    6060//    - 4x float (0-1) DisplayP3, stored in a reference counted sub-object
     61//    - 4x float (0-1) Lab, stored in a reference counted sub-object
    6162//
    6263// Additionally, the inline 8-bit sRGBA can have an optional "semantic" bit set on it,
  • trunk/Source/WebCore/platform/graphics/ColorConversion.cpp

    r271089 r271362  
    2929#include "ColorComponents.h"
    3030#include "ColorMatrix.h"
    31 #include "ColorTypes.h"
     31#include <wtf/MathExtras.h>
    3232
    3333namespace WebCore {
     
    133133    };
    134134    return asXYZA(linearDisplayP3ToXYZMatrix.transformedColorComponents(asColorComponents(color)));
     135}
     136
     137static XYZA<float> convertFromD50WhitePointToD65WhitePoint(const XYZA<float>& color)
     138{
     139    // http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html
     140    constexpr ColorMatrix<3, 3> D50ToD65Matrix {
     141         0.9555766f, -0.0230393f, 0.0631636f,
     142        -0.0282895f,  1.0099416f, 0.0210077f,
     143         0.0122982f, -0.0204830f, 1.3299098f
     144    };
     145    return asXYZA(D50ToD65Matrix.transformedColorComponents(asColorComponents(color)));
     146}
     147
     148static XYZA<float> convertFromD65WhitePointToD50WhitePoint(const XYZA<float>& color)
     149{
     150    // http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html
     151    constexpr ColorMatrix<3, 3> D65ToD50Matrix {
     152         1.0478112f, 0.0228866f, -0.0501270f,
     153         0.0295424f, 0.9904844f, -0.0170491f,
     154        -0.0092345f, 0.0150436f,  0.7521316f
     155    };
     156    return asXYZA(D65ToD50Matrix.transformedColorComponents(asColorComponents(color)));
     157}
     158
     159static constexpr float LABe = 216.0f / 24389.0f;
     160static constexpr float LABk = 24389.0f / 27.0f;
     161static constexpr float D50WhiteValues[] = { 0.96422f, 1.0f, 0.82521f };
     162
     163XYZA<float> toXYZA(const Lab<float>& color)
     164{
     165    float f1 = (color.lightness + 16.0f) / 116.0f;
     166    float f0 = f1 + (color.a / 500.0f);
     167    float f2 = f1 - (color.b / 200.0f);
     168
     169    auto computeXAndZ = [](float t) {
     170        float tCubed = t * t * t;
     171        if (tCubed > LABe)
     172            return tCubed;
     173
     174        return (116.0f * t - 16.0f) / LABk;
     175    };
     176
     177    auto computeY = [](float t) {
     178        if (t > (LABk * LABe)) {
     179            float value = (t + 16.0) / 116.0;
     180            return value * value * value;
     181        }
     182
     183        return t / LABk;
     184    };
     185
     186    float x = D50WhiteValues[0] * computeXAndZ(f0);
     187    float y = D50WhiteValues[1] * computeY(color.lightness);
     188    float z = D50WhiteValues[2] * computeXAndZ(f2);
     189
     190    XYZA<float> result { x, y, z, color.alpha };
     191
     192    // We expect XYZA colors to be using the D65 white point, unlike Lab, which uses a
     193    // D50 white point, so as a final step, use the Bradford transform to convert the
     194    // resulting XYZA color to a D65 white point.
     195    return convertFromD50WhitePointToD65WhitePoint(result);
     196}
     197
     198Lab<float> toLab(const XYZA<float>& color)
     199{
     200    // We expect XYZA colors to be using the D65 white point, unlike Lab, which uses a
     201    // D50 white point, so as a first step, use the Bradford transform to convert the
     202    // incoming XYZA color to D50 white point.
     203    auto colorWithD50WhitePoint = convertFromD65WhitePointToD50WhitePoint(color);
     204
     205    float x = colorWithD50WhitePoint.x / D50WhiteValues[0];
     206    float y = colorWithD50WhitePoint.y / D50WhiteValues[1];
     207    float z = colorWithD50WhitePoint.z / D50WhiteValues[2];
     208
     209    auto fTransform = [](float value) {
     210        return value > LABe ? std::cbrt(value) : (LABk * value + 16.0f) / 116.0f;
     211    };
     212
     213    float f0 = fTransform(x);
     214    float f1 = fTransform(y);
     215    float f2 = fTransform(z);
     216
     217    float lightness = (116.0f * f1) - 16.0f;
     218    float a = 500.0f * (f0 - f1);
     219    float b = 200.0f * (f1 - f2);
     220
     221    return { lightness, a, b, colorWithD50WhitePoint.alpha };
     222}
     223
     224LCHA<float> toLCHA(const Lab<float>& color)
     225{
     226    // https://www.w3.org/TR/css-color-4/#lab-to-lch
     227    float hue = rad2deg(atan2(color.b, color.a));
     228
     229    return {
     230        color.lightness,
     231        std::hypot(color.a, color.b),
     232        hue >= 0 ? hue : hue + 360,
     233        color.alpha
     234    };
     235}
     236
     237Lab<float> toLab(const LCHA<float>& color)
     238{
     239    // https://www.w3.org/TR/css-color-4/#lch-to-lab
     240    float hueAngleRadians = deg2rad(color.hue);
     241
     242    return {
     243        color.lightness,
     244        color.chroma * std::cos(hueAngleRadians),
     245        color.chroma * std::sin(hueAngleRadians),
     246        color.alpha
     247    };
    135248}
    136249
     
    264377}
    265378
     379XYZA<float> toXYZA(const LCHA<float>& color)
     380{
     381    return toXYZA(toLab(color));
     382}
     383
     384LCHA<float> toLCHA(const XYZA<float>& color)
     385{
     386    return toLCHA(toLab(color));
     387}
     388
    266389XYZA<float> toXYZA(const HSLA<float>& color)
    267390{
  • trunk/Source/WebCore/platform/graphics/ColorConversion.h

    r271095 r271362  
    7272
    7373
     74// Lab
     75WEBCORE_EXPORT XYZA<float> toXYZA(const Lab<float>&);
     76WEBCORE_EXPORT Lab<float> toLab(const XYZA<float>&);
     77// Additions
     78WEBCORE_EXPORT LCHA<float> toLCHA(const Lab<float>&);
     79
     80
     81// LCHA
     82WEBCORE_EXPORT XYZA<float> toXYZA(const LCHA<float>&);
     83WEBCORE_EXPORT LCHA<float> toLCHA(const XYZA<float>&);
     84// Additions
     85WEBCORE_EXPORT Lab<float> toLab(const LCHA<float>&);
     86
     87
    7488// HSLA
    7589WEBCORE_EXPORT XYZA<float> toXYZA(const HSLA<float>&);
     
    92106constexpr DisplayP3<float> toDisplayP3(const DisplayP3<float>& color) { return color; }
    93107constexpr LinearDisplayP3<float> toLinearDisplayP3(const LinearDisplayP3<float>& color) { return color; }
     108constexpr Lab<float> toLab(const Lab<float>& color) { return color; }
     109constexpr LCHA<float> toLCHA(const LCHA<float>& color) { return color; }
    94110constexpr HSLA<float> toHSLA(const HSLA<float>& color) { return color; }
    95111constexpr CMYKA<float> toCMYKA(const CMYKA<float>& color) { return color; }
     
    122138}
    123139
     140template<typename T> Lab<float> toLab(const T& color)
     141{
     142    return toLab(toXYZA(color));
     143}
     144
     145template<typename T> LCHA<float> toLCHA(const T& color)
     146{
     147    return toLCHA(toXYZA(color));
     148}
     149
    124150template<typename T> HSLA<float> toHSLA(const T& color)
    125151{
  • trunk/Source/WebCore/platform/graphics/ColorSerialization.cpp

    r264332 r271362  
    9797    case ColorSpace::DisplayP3:
    9898        return "display-p3"_s;
     99    case ColorSpace::Lab:
     100        return "lab"_s;
    99101    }
    100102
     
    162164}
    163165
     166// Lab<float> overloads
     167
     168String serializationForCSS(const Lab<float>& color)
     169{
     170    // https://www.w3.org/TR/css-color-4/#serializing-lab-lch
     171
     172    auto [c1, c2, c3, alpha] = color;
     173    if (WTF::areEssentiallyEqual(alpha, 1.0f))
     174        return makeString("lab(", c1, "% ", c2, ' ', c3, ')');
     175    return makeString("lab(", c1, "% ", c2, ' ', c3, " / ", alpha, ')');
     176}
     177
     178String serializationForHTML(const Lab<float>& color)
     179{
     180    return serializationForCSS(color);
     181}
     182
     183String serializationForRenderTreeAsText(const Lab<float>& color)
     184{
     185    return serializationForCSS(color);
     186}
    164187
    165188// Color overloads
  • trunk/Source/WebCore/platform/graphics/ColorSerialization.h

    r264533 r271362  
    3333
    3434template<typename> struct DisplayP3;
     35template<typename> struct Lab;
    3536template<typename> struct LinearSRGBA;
    3637template<typename> struct SRGBA;
     
    5657WEBCORE_EXPORT String serializationForRenderTreeAsText(const DisplayP3<float>&);
    5758
     59WEBCORE_EXPORT String serializationForCSS(const Lab<float>&);
     60WEBCORE_EXPORT String serializationForHTML(const Lab<float>&);
     61WEBCORE_EXPORT String serializationForRenderTreeAsText(const Lab<float>&);
     62
    5863WEBCORE_EXPORT String serializationForCSS(const Color&);
    5964WEBCORE_EXPORT String serializationForHTML(const Color&);
  • trunk/Source/WebCore/platform/graphics/ColorSpace.cpp

    r271089 r271362  
    4343        ts << "DisplayP3";
    4444        break;
     45    case ColorSpace::Lab:
     46        ts << "L*a*b";
     47        break;
    4548    }
    4649    return ts;
  • trunk/Source/WebCore/platform/graphics/ColorSpace.h

    r271089 r271362  
    3535    SRGB,
    3636    LinearRGB,
    37     DisplayP3
     37    DisplayP3,
     38    Lab
    3839};
    3940
  • trunk/Source/WebCore/platform/graphics/ColorTypes.h

    r271094 r271362  
    248248
    249249
     250template<typename T> struct Lab : ColorWithAlphaHelper<Lab<T>> {
     251    using ComponentType = T;
     252    static constexpr auto colorSpace = ColorSpace::Lab;
     253
     254    constexpr Lab(T lightness, T a, T b, T alpha = ComponentTraits<T>::maxValue)
     255        : lightness { lightness }
     256        , a { a }
     257        , b { b }
     258        , alpha { alpha }
     259    {
     260    }
     261
     262    constexpr Lab()
     263        : Lab { ComponentTraits<T>::minValue, ComponentTraits<T>::minValue, ComponentTraits<T>::minValue, ComponentTraits<T>::minValue }
     264    {
     265    }
     266
     267    T lightness;
     268    T a;
     269    T b;
     270    T alpha;
     271};
     272
     273template<typename T> constexpr ColorComponents<T> asColorComponents(const Lab<T>& c)
     274{
     275    return { c.lightness, c.a, c.b, c.alpha };
     276}
     277
     278template<typename T> constexpr Lab<T> asLab(const ColorComponents<T>& c)
     279{
     280    return { c[0], c[1], c[2], c[3] };
     281}
     282
     283template<typename T> constexpr bool operator==(const Lab<T>& a, const Lab<T>& b)
     284{
     285    return asColorComponents(a) == asColorComponents(b);
     286}
     287
     288template<typename T> constexpr bool operator!=(const Lab<T>& a, const Lab<T>& b)
     289{
     290    return !(a == b);
     291}
     292
     293
     294template<typename T> struct LCHA : ColorWithAlphaHelper<LCHA<T>> {
     295    using ComponentType = T;
     296
     297    constexpr LCHA(T lightness, T chroma, T hue, T alpha = ComponentTraits<T>::maxValue)
     298        : lightness { lightness }
     299        , chroma { chroma }
     300        , hue { hue }
     301        , alpha { alpha }
     302    {
     303    }
     304
     305    constexpr LCHA()
     306        : LCHA { ComponentTraits<T>::minValue, ComponentTraits<T>::minValue, ComponentTraits<T>::minValue, ComponentTraits<T>::minValue }
     307    {
     308    }
     309
     310    T lightness;
     311    T chroma;
     312    T hue;
     313    T alpha;
     314};
     315
     316template<typename T> constexpr ColorComponents<T> asColorComponents(const LCHA<T>& c)
     317{
     318    return { c.lightness, c.chroma, c.hue, c.alpha };
     319}
     320
     321template<typename T> constexpr LCHA<T> asLCHA(const ColorComponents<T>& c)
     322{
     323    return { c[0], c[1], c[2], c[3] };
     324}
     325
     326template<typename T> constexpr bool operator==(const LCHA<T>& a, const LCHA<T>& b)
     327{
     328    return asColorComponents(a) == asColorComponents(b);
     329}
     330
     331template<typename T> constexpr bool operator!=(const LCHA<T>& a, const LCHA<T>& b)
     332{
     333    return !(a == b);
     334}
     335
     336
    250337template<typename T> struct HSLA : ColorWithAlphaHelper<HSLA<T>> {
    251338    using ComponentType = T;
     
    380467    case ColorSpace::DisplayP3:
    381468        return std::invoke(std::forward<Functor>(functor), asDisplayP3(components));
     469    case ColorSpace::Lab:
     470        return std::invoke(std::forward<Functor>(functor), asLab(components));
    382471    }
    383472
  • trunk/Source/WebCore/platform/graphics/cg/ColorSpaceCG.cpp

    r271089 r271362  
    8383}
    8484
     85CGColorSpaceRef labColorSpaceRef()
     86{
     87    // FIXME: Add support for conversion to Lab on supported platforms.
     88    return sRGBColorSpaceRef();
     89}
     90
    8591CGColorSpaceRef extendedSRGBColorSpaceRef()
    8692{
  • trunk/Source/WebCore/platform/graphics/cg/ColorSpaceCG.h

    r271089 r271362  
    3535WEBCORE_EXPORT CGColorSpaceRef linearRGBColorSpaceRef();
    3636WEBCORE_EXPORT CGColorSpaceRef displayP3ColorSpaceRef();
     37WEBCORE_EXPORT CGColorSpaceRef labColorSpaceRef();
    3738WEBCORE_EXPORT CGColorSpaceRef extendedSRGBColorSpaceRef();
    3839
     
    4647    case ColorSpace::DisplayP3:
    4748        return displayP3ColorSpaceRef();
     49    case ColorSpace::Lab:
     50        return labColorSpaceRef();
    4851    }
    4952    ASSERT_NOT_REACHED();
Note: See TracChangeset for help on using the changeset viewer.