Title: [226315] trunk
Revision
226315
Author
[email protected]
Date
2018-01-01 11:53:39 -0800 (Mon, 01 Jan 2018)

Log Message

SVG lighting colors need to be converted into linearSRGB
https://bugs.webkit.org/show_bug.cgi?id=181196

Reviewed by Dan Bates.

Source/WebCore:

SVG filters, like feLighting, that poke values directly into buffers rather than going
through CG like feFlood, need to convert colors into the operating color space. So add
conversion functions to go between linear and sRGB colors, and use these in feLighting,
and in ImageBuffer (which is only used for non-CG platforms).

Tests: svg/filters/feSpotLight-color.svg

* platform/graphics/ColorUtilities.cpp:
(WebCore::linearToSRGBColorComponent):
(WebCore::sRGBToLinearColorComponent):
(WebCore::linearToSRGBColor):
(WebCore::sRGBToLinearColor):
* platform/graphics/ColorUtilities.h:
* platform/graphics/ImageBuffer.cpp:
(WebCore::ImageBuffer::transformColorSpace):
* platform/graphics/filters/FELighting.cpp:
(WebCore::FELighting::drawLighting):

LayoutTests:

Compare a far-away green spotlight with a green flood. The bottom right pixel always
has the wrong color (webkit.org/b/181203), so mask it out.

* svg/filters/feSpotLight-color-expected.svg: Added.
* svg/filters/feSpotLight-color.svg: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (226314 => 226315)


--- trunk/LayoutTests/ChangeLog	2017-12-31 09:25:47 UTC (rev 226314)
+++ trunk/LayoutTests/ChangeLog	2018-01-01 19:53:39 UTC (rev 226315)
@@ -1,3 +1,16 @@
+2017-12-30  Simon Fraser  <[email protected]>
+
+        SVG lighting colors need to be converted into linearSRGB
+        https://bugs.webkit.org/show_bug.cgi?id=181196
+
+        Reviewed by Dan Bates.
+
+        Compare a far-away green spotlight with a green flood. The bottom right pixel always
+        has the wrong color (webkit.org/b/181203), so mask it out.
+
+        * svg/filters/feSpotLight-color-expected.svg: Added.
+        * svg/filters/feSpotLight-color.svg: Added.
+
 2017-12-28  Zalan Bujtas  <[email protected]>
 
         RenderTreeUpdater::GeneratedContent should hold a weak reference to RenderQuote.

Added: trunk/LayoutTests/svg/filters/feSpotLight-color-expected.svg (0 => 226315)


--- trunk/LayoutTests/svg/filters/feSpotLight-color-expected.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/filters/feSpotLight-color-expected.svg	2018-01-01 19:53:39 UTC (rev 226315)
@@ -0,0 +1,10 @@
+<svg width="480px" height="600px" xmlns="http://www.w3.org/2000/svg">
+<defs>
+    <filter id="filter" filterUnits="objectBoundingBox" x="0" y="0" width="100%" height="100%">
+        <feFlood flood-color="rgb(0, 128, 0)"/>
+    </filter>
+</defs>
+<rect x="0" y="00" width="400" height="400" filter="url(#filter)"/>
+<!-- Mask out a small difference in the bottom right corner -->
+<rect x="385" y="385" width="20" height="20" fill="black"/>
+</svg>

Added: trunk/LayoutTests/svg/filters/feSpotLight-color.svg (0 => 226315)


--- trunk/LayoutTests/svg/filters/feSpotLight-color.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/filters/feSpotLight-color.svg	2018-01-01 19:53:39 UTC (rev 226315)
@@ -0,0 +1,12 @@
+<svg width="480px" height="600px" xmlns="http://www.w3.org/2000/svg">
+<defs>
+    <filter id="filter" filterUnits="objectBoundingBox" x="0" y="0" width="100%" height="100%">
+        <feDiffuseLighting lighting-color="rgb(0, 128, 0)">
+            <feSpotLight x="200" y="200" z="500000000" />
+        </feDiffuseLighting>
+    </filter>
+</defs>
+<rect x="0" y="0" width="400" height="400" filter="url(#filter)"/>
+<!-- Mask out a small difference in the bottom right corner -->
+<rect x="385" y="385" width="20" height="20" fill="black"/>
+</svg>

Modified: trunk/Source/WebCore/ChangeLog (226314 => 226315)


--- trunk/Source/WebCore/ChangeLog	2017-12-31 09:25:47 UTC (rev 226314)
+++ trunk/Source/WebCore/ChangeLog	2018-01-01 19:53:39 UTC (rev 226315)
@@ -1,3 +1,28 @@
+2017-12-30  Simon Fraser  <[email protected]>
+
+        SVG lighting colors need to be converted into linearSRGB
+        https://bugs.webkit.org/show_bug.cgi?id=181196
+
+        Reviewed by Dan Bates.
+
+        SVG filters, like feLighting, that poke values directly into buffers rather than going
+        through CG like feFlood, need to convert colors into the operating color space. So add
+        conversion functions to go between linear and sRGB colors, and use these in feLighting,
+        and in ImageBuffer (which is only used for non-CG platforms).
+
+        Tests: svg/filters/feSpotLight-color.svg
+
+        * platform/graphics/ColorUtilities.cpp:
+        (WebCore::linearToSRGBColorComponent):
+        (WebCore::sRGBToLinearColorComponent):
+        (WebCore::linearToSRGBColor):
+        (WebCore::sRGBToLinearColor):
+        * platform/graphics/ColorUtilities.h:
+        * platform/graphics/ImageBuffer.cpp:
+        (WebCore::ImageBuffer::transformColorSpace):
+        * platform/graphics/filters/FELighting.cpp:
+        (WebCore::FELighting::drawLighting):
+
 2017-12-31  Jiewen Tan  <[email protected]>
 
         [WebCrypto] Avoid promises being destroyed in secondary threads

Modified: trunk/Source/WebCore/platform/graphics/ColorUtilities.cpp (226314 => 226315)


--- trunk/Source/WebCore/platform/graphics/ColorUtilities.cpp	2017-12-31 09:25:47 UTC (rev 226314)
+++ trunk/Source/WebCore/platform/graphics/ColorUtilities.cpp	2018-01-01 19:53:39 UTC (rev 226315)
@@ -26,6 +26,9 @@
 #include "config.h"
 #include "ColorUtilities.h"
 
+#include "Color.h"
+#include <wtf/MathExtras.h>
+
 namespace WebCore {
 
 ColorComponents::ColorComponents(const FloatComponents& floatComponents)
@@ -36,4 +39,43 @@
     components[3] = clampedColorComponent(floatComponents.components[3]);
 }
 
+// These are the standard sRGB <-> linearRGB conversion functions (https://en.wikipedia.org/wiki/SRGB).
+float linearToSRGBColorComponent(float c)
+{
+    if (c < 0.0031308)
+        return 12.92 * c;
+
+    return clampTo<float>(1.055 * powf(c, 1.0 / 2.4) - 0.055, 0, 1);
+}
+
+float sRGBToLinearColorComponent(float c)
+{
+    if (c <= 0.04045)
+        return c / 12.92;
+
+    return clampTo<float>(powf((c + 0.055) / 1.055, 2.4), 0, 1);
+}
+
+Color linearToSRGBColor(const Color& color)
+{
+    float r, g, b, a;
+    color.getRGBA(r, g, b, a);
+    r = linearToSRGBColorComponent(r);
+    g = linearToSRGBColorComponent(g);
+    b = linearToSRGBColorComponent(b);
+
+    return Color(r, g, b, a);
+}
+
+Color sRGBToLinearColor(const Color& color)
+{
+    float r, g, b, a;
+    color.getRGBA(r, g, b, a);
+    r = sRGBToLinearColorComponent(r);
+    g = sRGBToLinearColorComponent(g);
+    b = sRGBToLinearColorComponent(b);
+
+    return Color(r, g, b, a);
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/ColorUtilities.h (226314 => 226315)


--- trunk/Source/WebCore/platform/graphics/ColorUtilities.h	2017-12-31 09:25:47 UTC (rev 226314)
+++ trunk/Source/WebCore/platform/graphics/ColorUtilities.h	2018-01-01 19:53:39 UTC (rev 226315)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include "Color.h"
 #include <algorithm>
 #include <math.h>
 
@@ -147,5 +148,12 @@
     return x * bytesPerPixel + y * rowBytes;
 }
 
+// 0-1 components, result is clamped.
+float linearToSRGBColorComponent(float);
+float sRGBToLinearColorComponent(float);
+    
+Color linearToSRGBColor(const Color&);
+Color sRGBToLinearColor(const Color&);
+
 } // namespace WebCore
 

Modified: trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp (226314 => 226315)


--- trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp	2017-12-31 09:25:47 UTC (rev 226314)
+++ trunk/Source/WebCore/platform/graphics/ImageBuffer.cpp	2018-01-01 19:53:39 UTC (rev 226315)
@@ -28,6 +28,7 @@
 #include "config.h"
 #include "ImageBuffer.h"
 
+#include "ColorUtilities.h"
 #include "GraphicsContext.h"
 #include "IntRect.h"
 #include <wtf/MathExtras.h>
@@ -135,9 +136,7 @@
             std::array<uint8_t, 256> array;
             for (unsigned i = 0; i < 256; i++) {
                 float color = i / 255.0f;
-                color = (color <= 0.04045f ? color / 12.92f : pow((color + 0.055f) / 1.055f, 2.4f));
-                color = std::max(0.0f, color);
-                color = std::min(1.0f, color);
+                color = sRGBToLinearColorComponent(color);
                 array[i] = static_cast<uint8_t>(round(color * 255));
             }
             return array;
@@ -148,9 +147,7 @@
             std::array<uint8_t, 256> array;
             for (unsigned i = 0; i < 256; i++) {
                 float color = i / 255.0f;
-                color = (powf(color, 1.0f / 2.4f) * 1.055f) - 0.055f;
-                color = std::max(0.0f, color);
-                color = std::min(1.0f, color);
+                color = linearToSRGBColorComponent(color);
                 array[i] = static_cast<uint8_t>(round(color * 255));
             }
             return array;

Modified: trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp (226314 => 226315)


--- trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp	2017-12-31 09:25:47 UTC (rev 226314)
+++ trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp	2018-01-01 19:53:39 UTC (rev 226315)
@@ -27,6 +27,7 @@
 #include "config.h"
 #include "FELighting.h"
 
+#include "ColorUtilities.h"
 #include "FELightingNEON.h"
 #include <wtf/ParallelJobs.h>
 
@@ -397,7 +398,9 @@
     data.widthMultipliedByPixelSize = width * cPixelSize;
     data.widthDecreasedByOne = width - 1;
     data.heightDecreasedByOne = height - 1;
-    paintingData.intialLightingData.colorVector = FloatPoint3D(m_lightingColor.red(), m_lightingColor.green(), m_lightingColor.blue());
+    
+    Color lightColor = (operatingColorSpace() == ColorSpaceLinearRGB) ? sRGBToLinearColor(m_lightingColor) : m_lightingColor;
+    paintingData.intialLightingData.colorVector = FloatPoint3D(lightColor.red(), lightColor.green(), lightColor.blue());
     m_lightSource->initPaintingData(paintingData);
 
     // Top left.
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to