Diff
Modified: trunk/Source/WebCore/ChangeLog (262809 => 262810)
--- trunk/Source/WebCore/ChangeLog 2020-06-09 21:04:09 UTC (rev 262809)
+++ trunk/Source/WebCore/ChangeLog 2020-06-09 21:05:09 UTC (rev 262810)
@@ -1,3 +1,53 @@
+2020-06-09 Sam Weinig <[email protected]>
+
+ Extended Color: Streamline SimpleColor premulitply/unpremultiply code
+ https://bugs.webkit.org/show_bug.cgi?id=212945
+
+ Reviewed by Darin Adler.
+
+ Simplify / streamline the premulitply/unpremultiply code by:
+ - Removing the overloads that didn't take individual components, keeping
+ only the ones taking a SimpleColor.
+ - Replacing the "ceiling" bool in makePremultipliedSimpleColor and converting
+ it into two functions.
+ - Simplifying the names from makePremultipliedSimpleColor/makeUnpremultipliedSimpleColor
+ to premultiplyFlooring/premultiplyCeiling/unpremultiply.
+ - Where component order is important, use valueAsARGB() explicitly to
+ show what the resulting value's format will be.
+
+ * platform/graphics/Color.cpp:
+ (WebCore::blend):
+ Update to call premultiplyCeiling/unpremultiply.
+
+ * platform/graphics/ImageBackingStore.h:
+ (WebCore::ImageBackingStore::blendPixel):
+ (WebCore::ImageBackingStore::pixelValue const):
+ Update to call premultiplyFlooring/unpremultiply and valueAsARGB().
+
+ * platform/graphics/SimpleColor.h:
+ * platform/graphics/SimpleColor.cpp:
+ (WebCore::premultiplyFlooring):
+ (WebCore::premultiplyCeiling):
+ (WebCore::unpremultiplyChannel):
+ (WebCore::unpremultiply):
+ (WebCore::premultipliedChannel): Deleted.
+ (WebCore::unpremultipliedChannel): Deleted.
+ (WebCore::makePremultipliedSimpleColor): Deleted.
+ (WebCore::makeUnpremultipliedSimpleColor): Deleted.
+ Simplify premulitply/unpremultiply interfaces. Use structured bindings to make
+ the code a bit easier to follow as well.
+
+ * platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp:
+ (WebCore::ImageBufferCairoImageSurfaceBackend::platformTransformColorSpace):
+ Update to call premultiplyFlooring/unpremultiply and valueAsARGB().
+
+ * platform/graphics/cairo/NativeImageCairo.cpp:
+ (WebCore::nativeImageSinglePixelSolidColor):
+ Update to call premultiplyFlooring/unpremultiply and valueAsARGB(). Also removes
+ reinterpret cast to SimpleColor, instead following the model in ImageBufferCairoImageSurfaceBackend
+ and casting to unsigned, and building the SimpleColor from that. This will allow
+ SimpleColor to change its underlying representation in the future without breaking things.
+
2020-06-09 Commit Queue <[email protected]>
Unreviewed, reverting r261841.
Modified: trunk/Source/WebCore/platform/graphics/Color.cpp (262809 => 262810)
--- trunk/Source/WebCore/platform/graphics/Color.cpp 2020-06-09 21:04:09 UTC (rev 262809)
+++ trunk/Source/WebCore/platform/graphics/Color.cpp 2020-06-09 21:05:09 UTC (rev 262810)
@@ -266,18 +266,18 @@
if (progress == 1 && !to.isValid())
return { };
- // Since makePremultipliedSimpleColor() bails on zero alpha, special-case that.
- auto premultFrom = from.alpha() ? makePremultipliedSimpleColor(from.toSRGBASimpleColorLossy()) : Color::transparent;
- auto premultTo = to.alpha() ? makePremultipliedSimpleColor(to.toSRGBASimpleColorLossy()) : Color::transparent;
+ // Since premultiplyCeiling() bails on zero alpha, special-case that.
+ auto premultipliedFrom = from.alpha() ? premultiplyCeiling(from.toSRGBASimpleColorLossy()) : Color::transparent;
+ auto premultipliedTo = to.alpha() ? premultiplyCeiling(to.toSRGBASimpleColorLossy()) : Color::transparent;
SimpleColor premultBlended = makeSimpleColor(
- WebCore::blend(premultFrom.redComponent(), premultTo.redComponent(), progress),
- WebCore::blend(premultFrom.greenComponent(), premultTo.greenComponent(), progress),
- WebCore::blend(premultFrom.blueComponent(), premultTo.blueComponent(), progress),
- WebCore::blend(premultFrom.alphaComponent(), premultTo.alphaComponent(), progress)
+ WebCore::blend(premultipliedFrom.redComponent(), premultipliedTo.redComponent(), progress),
+ WebCore::blend(premultipliedFrom.greenComponent(), premultipliedTo.greenComponent(), progress),
+ WebCore::blend(premultipliedFrom.blueComponent(), premultipliedTo.blueComponent(), progress),
+ WebCore::blend(premultipliedFrom.alphaComponent(), premultipliedTo.alphaComponent(), progress)
);
- return makeUnpremultipliedSimpleColor(premultBlended);
+ return unpremultiply(premultBlended);
}
Color blendWithoutPremultiply(const Color& from, const Color& to, double progress)
Modified: trunk/Source/WebCore/platform/graphics/ImageBackingStore.h (262809 => 262810)
--- trunk/Source/WebCore/platform/graphics/ImageBackingStore.h 2020-06-09 21:04:09 UTC (rev 262809)
+++ trunk/Source/WebCore/platform/graphics/ImageBackingStore.h 2020-06-09 21:05:09 UTC (rev 262810)
@@ -160,7 +160,7 @@
}
if (!m_premultiplyAlpha)
- pixel = makePremultipliedSimpleColor(pixel.redComponent(), pixel.greenComponent(), pixel.blueComponent(), pixel.alphaComponent(), false);
+ pixel = premultiplyFlooring(pixel);
unsigned d = 255 - a;
@@ -169,10 +169,12 @@
b = fastDivideBy255(b * a + pixel.blueComponent() * d);
a += fastDivideBy255(d * pixel.alphaComponent());
- if (m_premultiplyAlpha)
- *dest = makeSimpleColor(r, g, b, a).value();
- else
- *dest = makeUnpremultipliedSimpleColor(r, g, b, a).value();
+ auto result = makeSimpleColor(r, g, b, a);
+
+ if (!m_premultiplyAlpha)
+ result = unpremultiply(result);
+
+ *dest = result.valueAsARGB();
}
static bool isOverSize(const IntSize& size)
@@ -224,10 +226,12 @@
if (m_premultiplyAlpha && !a)
return 0;
+ auto result = makeSimpleColor(r, g, b, a);
+
if (m_premultiplyAlpha && a < 255)
- return makePremultipliedSimpleColor(r, g, b, a, false).value();
+ result = premultiplyFlooring(result);
- return makeSimpleColor(r, g, b, a).value();
+ return result.valueAsARGB();
}
RefPtr<SharedBuffer::DataSegment> m_pixels;
Modified: trunk/Source/WebCore/platform/graphics/SimpleColor.cpp (262809 => 262810)
--- trunk/Source/WebCore/platform/graphics/SimpleColor.cpp 2020-06-09 21:04:09 UTC (rev 262809)
+++ trunk/Source/WebCore/platform/graphics/SimpleColor.cpp 2020-06-09 21:05:09 UTC (rev 262810)
@@ -33,40 +33,35 @@
namespace WebCore {
-static inline unsigned premultipliedChannel(unsigned c, unsigned a, bool ceiling = true)
+SimpleColor premultiplyFlooring(SimpleColor color)
{
- return fastDivideBy255(ceiling ? c * a + 254 : c * a);
+ auto [r, g, b, a] = color;
+ if (!a || a == 255)
+ return color;
+ return makeSimpleColor(fastDivideBy255(r * a), fastDivideBy255(g * a), fastDivideBy255(b * a), a);
}
-static inline unsigned unpremultipliedChannel(unsigned c, unsigned a)
+SimpleColor premultiplyCeiling(SimpleColor color)
{
- return (fastMultiplyBy255(c) + a - 1) / a;
+ auto [r, g, b, a] = color;
+ if (!a || a == 255)
+ return color;
+ return makeSimpleColor(fastDivideBy255(r * a + 254), fastDivideBy255(g * a + 254), fastDivideBy255(b * a + 254), a);
}
-SimpleColor makePremultipliedSimpleColor(int r, int g, int b, int a, bool ceiling)
+static inline uint16_t unpremultiplyChannel(uint8_t c, uint8_t a)
{
- return makeSimpleColor(premultipliedChannel(r, a, ceiling), premultipliedChannel(g, a, ceiling), premultipliedChannel(b, a, ceiling), a);
+ return (fastMultiplyBy255(c) + a - 1) / a;
}
-SimpleColor makePremultipliedSimpleColor(SimpleColor pixelColor)
+SimpleColor unpremultiply(SimpleColor color)
{
- if (pixelColor.isOpaque())
- return pixelColor;
- return makePremultipliedSimpleColor(pixelColor.redComponent(), pixelColor.greenComponent(), pixelColor.blueComponent(), pixelColor.alphaComponent());
+ auto [r, g, b, a] = color;
+ if (!a || a == 255)
+ return color;
+ return makeSimpleColor(unpremultiplyChannel(r, a), unpremultiplyChannel(g, a), unpremultiplyChannel(b, a), a);
}
-SimpleColor makeUnpremultipliedSimpleColor(int r, int g, int b, int a)
-{
- return makeSimpleColor(unpremultipliedChannel(r, a), unpremultipliedChannel(g, a), unpremultipliedChannel(b, a), a);
-}
-
-SimpleColor makeUnpremultipliedSimpleColor(SimpleColor pixelColor)
-{
- if (pixelColor.isVisible() && !pixelColor.isOpaque())
- return makeUnpremultipliedSimpleColor(pixelColor.redComponent(), pixelColor.greenComponent(), pixelColor.blueComponent(), pixelColor.alphaComponent());
- return pixelColor;
-}
-
SimpleColor makeSimpleColorFromCMYKA(float c, float m, float y, float k, float a)
{
float colors = 1 - k;
Modified: trunk/Source/WebCore/platform/graphics/SimpleColor.h (262809 => 262810)
--- trunk/Source/WebCore/platform/graphics/SimpleColor.h 2020-06-09 21:04:09 UTC (rev 262809)
+++ trunk/Source/WebCore/platform/graphics/SimpleColor.h 2020-06-09 21:05:09 UTC (rev 262810)
@@ -98,10 +98,9 @@
SimpleColor makeSimpleColorFromFloats(float r, float g, float b, float a);
SimpleColor makeSimpleColorFromCMYKA(float c, float m, float y, float k, float a);
-SimpleColor makePremultipliedSimpleColor(int r, int g, int b, int a, bool ceiling = true);
-SimpleColor makePremultipliedSimpleColor(SimpleColor);
-SimpleColor makeUnpremultipliedSimpleColor(int r, int g, int b, int a);
-SimpleColor makeUnpremultipliedSimpleColor(SimpleColor);
+SimpleColor premultiplyFlooring(SimpleColor);
+SimpleColor premultiplyCeiling(SimpleColor);
+SimpleColor unpremultiply(SimpleColor);
inline bool operator==(SimpleColor a, SimpleColor b)
{
Modified: trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp (262809 => 262810)
--- trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp 2020-06-09 21:04:09 UTC (rev 262809)
+++ trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairoImageSurfaceBackend.cpp 2020-06-09 21:05:09 UTC (rev 262810)
@@ -80,9 +80,9 @@
unsigned* row = reinterpret_cast_ptr<unsigned*>(dataSrc + stride * y);
for (int x = 0; x < m_logicalSize.width(); x++) {
unsigned* pixel = row + x;
- auto pixelColor = makeUnpremultipliedSimpleColor(*pixel);
+ auto pixelColor = unpremultiply(SimpleColor { *pixel });
pixelColor = makeSimpleColor(lookUpTable[pixelColor.redComponent()], lookUpTable[pixelColor.greenComponent()], lookUpTable[pixelColor.blueComponent()], pixelColor.alphaComponent());
- *pixel = makePremultipliedSimpleColor(pixelColor).value();
+ *pixel = premultiplyCeiling(pixelColor).valueAsARGB();
}
}
cairo_surface_mark_dirty_rectangle(m_surface.get(), 0, 0, m_logicalSize.width(), m_logicalSize.height());
Modified: trunk/Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp (262809 => 262810)
--- trunk/Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp 2020-06-09 21:04:09 UTC (rev 262809)
+++ trunk/Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp 2020-06-09 21:05:09 UTC (rev 262810)
@@ -53,8 +53,8 @@
if (cairo_surface_get_type(image.get()) != CAIRO_SURFACE_TYPE_IMAGE)
return Color();
- SimpleColor* pixel = reinterpret_cast_ptr<SimpleColor*>(cairo_image_surface_get_data(image.get()));
- return makeUnpremultipliedSimpleColor(*pixel);
+ unsigned* pixel = reinterpret_cast_ptr<unsigned*>(cairo_image_surface_get_data(image.get()));
+ return unpremultiply(SimpleColor { *pixel });
}
void drawNativeImage(const NativeImagePtr& image, GraphicsContext& context, const FloatRect& destRect, const FloatRect& srcRect, const IntSize& imageSize, const ImagePaintingOptions& options)