- 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.