summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@gmail.com>2017-06-15 21:46:53 +0200
committerwolfbeast <mcwerewolf@gmail.com>2018-02-02 20:06:07 +0100
commitd61fde6e94bce9f920e9fcc55a43f94c23c40a01 (patch)
tree5cde7d634707b7a1b1865ae9518de9603e2ae985
parentc0c702a5e3284e843e680064b4c6a7280242c567 (diff)
downloadUXP-d61fde6e94bce9f920e9fcc55a43f94c23c40a01.tar
UXP-d61fde6e94bce9f920e9fcc55a43f94c23c40a01.tar.gz
UXP-d61fde6e94bce9f920e9fcc55a43f94c23c40a01.tar.lz
UXP-d61fde6e94bce9f920e9fcc55a43f94c23c40a01.tar.xz
UXP-d61fde6e94bce9f920e9fcc55a43f94c23c40a01.zip
CSS: Stop using premultiplied color space for gradients.
-rw-r--r--layout/base/nsCSSRendering.cpp88
-rw-r--r--layout/reftests/css-gradients/linear-premul-ref.html1
-rw-r--r--layout/reftests/css-gradients/linear-premul.html1
-rw-r--r--layout/reftests/css-gradients/radial-premul-ref.html1
-rw-r--r--layout/reftests/css-gradients/radial-premul.html1
-rw-r--r--layout/reftests/css-gradients/reftest.list2
6 files changed, 4 insertions, 90 deletions
diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp
index 1c6d97395..5b8a884a1 100644
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -2268,14 +2268,8 @@ ComputeRadialGradientLine(nsPresContext* aPresContext,
*aLineEnd = *aLineStart + gfxPoint(radiusX*cos(-angle), radiusY*sin(-angle));
}
-
-static float Interpolate(float aF1, float aF2, float aFrac)
-{
- return aF1 + aFrac * (aF2 - aF1);
-}
-
// Returns aFrac*aC2 + (1 - aFrac)*C1. The interpolation is done
-// in unpremultiplied space, which is what SVG gradients and cairo
+// in RGBA color space, which is what SVG gradients and cairo
// gradients expect.
static Color
InterpolateColor(const Color& aC1, const Color& aC2, float aFrac)
@@ -2435,79 +2429,6 @@ static void ResolveMidpoints(nsTArray<ColorStop>& stops)
}
}
-static Color
-Premultiply(const Color& aColor)
-{
- gfx::Float a = aColor.a;
- return Color(aColor.r * a, aColor.g * a, aColor.b * a, a);
-}
-
-static Color
-Unpremultiply(const Color& aColor)
-{
- gfx::Float a = aColor.a;
- return (a > 0.f)
- ? Color(aColor.r / a, aColor.g / a, aColor.b / a, a)
- : aColor;
-}
-
-static Color
-TransparentColor(Color aColor) {
- aColor.a = 0;
- return aColor;
-}
-
-// Adjusts and adds color stops in such a way that drawing the gradient with
-// unpremultiplied interpolation looks nearly the same as if it were drawn with
-// premultiplied interpolation.
-static const float kAlphaIncrementPerGradientStep = 0.1f;
-static void
-ResolvePremultipliedAlpha(nsTArray<ColorStop>& aStops)
-{
- for (size_t x = 1; x < aStops.Length(); x++) {
- const ColorStop leftStop = aStops[x - 1];
- const ColorStop rightStop = aStops[x];
-
- // if the left and right stop have the same alpha value, we don't need
- // to do anything
- if (leftStop.mColor.a == rightStop.mColor.a) {
- continue;
- }
-
- // Is the stop on the left 100% transparent? If so, have it adopt the color
- // of the right stop
- if (leftStop.mColor.a == 0) {
- aStops[x - 1].mColor = TransparentColor(rightStop.mColor);
- continue;
- }
-
- // Is the stop on the right completely transparent?
- // If so, duplicate it and assign it the color on the left.
- if (rightStop.mColor.a == 0) {
- ColorStop newStop = rightStop;
- newStop.mColor = TransparentColor(leftStop.mColor);
- aStops.InsertElementAt(x, newStop);
- x++;
- continue;
- }
-
- // Now handle cases where one or both of the stops are partially transparent.
- if (leftStop.mColor.a != 1.0f || rightStop.mColor.a != 1.0f) {
- Color premulLeftColor = Premultiply(leftStop.mColor);
- Color premulRightColor = Premultiply(rightStop.mColor);
- // Calculate how many extra steps. We do a step per 10% transparency.
- size_t stepCount = NSToIntFloor(fabsf(leftStop.mColor.a - rightStop.mColor.a) / kAlphaIncrementPerGradientStep);
- for (size_t y = 1; y < stepCount; y++) {
- float frac = static_cast<float>(y) / stepCount;
- ColorStop newStop(Interpolate(leftStop.mPosition, rightStop.mPosition, frac), false,
- Unpremultiply(InterpolateColor(premulLeftColor, premulRightColor, frac)));
- aStops.InsertElementAt(x, newStop);
- x++;
- }
- }
- }
-}
-
static ColorStop
InterpolateColorStop(const ColorStop& aFirst, const ColorStop& aSecond,
double aPosition, const Color& aDefault)
@@ -2522,9 +2443,9 @@ InterpolateColorStop(const ColorStop& aFirst, const ColorStop& aSecond,
}
return ColorStop(aPosition, false,
- Unpremultiply(InterpolateColor(Premultiply(aFirst.mColor),
- Premultiply(aSecond.mColor),
- (aPosition - aFirst.mPosition) / delta)));
+ InterpolateColor(aFirst.mColor,
+ aSecond.mColor,
+ (aPosition - aFirst.mPosition) / delta));
}
// Clamp and extend the given ColorStop array in-place to fit exactly into the
@@ -2924,7 +2845,6 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
}
ResolveMidpoints(stops);
- ResolvePremultipliedAlpha(stops);
bool isRepeat = aGradient->mRepeating || forceRepeatToCoverTiles;
diff --git a/layout/reftests/css-gradients/linear-premul-ref.html b/layout/reftests/css-gradients/linear-premul-ref.html
deleted file mode 100644
index bf0b12c33..000000000
--- a/layout/reftests/css-gradients/linear-premul-ref.html
+++ /dev/null
@@ -1 +0,0 @@
-<div style="background: linear-gradient(to right, rgba(255, 0, 0, .9) 0% , rgba(255, 0, 0, 0) 50%, rgba(0, 0, 255, 0) 50%, rgba(0, 0, 255, 1) 100%) no-repeat; width: 300px; height: 300px;"><br></div>
diff --git a/layout/reftests/css-gradients/linear-premul.html b/layout/reftests/css-gradients/linear-premul.html
deleted file mode 100644
index 20c7c276a..000000000
--- a/layout/reftests/css-gradients/linear-premul.html
+++ /dev/null
@@ -1 +0,0 @@
-<div style="background: linear-gradient(to right, rgba(255, 0, 0, .9) 0% , rgba(0, 255, 0, 0) 50%, rgba(0, 0, 255, 1) 100%) no-repeat; width: 300px; height: 300px;"><br></div>
diff --git a/layout/reftests/css-gradients/radial-premul-ref.html b/layout/reftests/css-gradients/radial-premul-ref.html
deleted file mode 100644
index 1424f4373..000000000
--- a/layout/reftests/css-gradients/radial-premul-ref.html
+++ /dev/null
@@ -1 +0,0 @@
-<div style="background: radial-gradient(rgba(255, 0, 0, .9) 0% , rgba(255, 0, 0, 0) 50%, rgba(0, 0, 255, 0) 50%, rgba(0, 0, 255, 1) 100%) no-repeat; width: 300px; height: 300px;"><br></div>
diff --git a/layout/reftests/css-gradients/radial-premul.html b/layout/reftests/css-gradients/radial-premul.html
deleted file mode 100644
index 33b89c72b..000000000
--- a/layout/reftests/css-gradients/radial-premul.html
+++ /dev/null
@@ -1 +0,0 @@
-<div style="background: radial-gradient(rgba(255, 0, 0, .9) 0% , rgba(0, 255, 0, 0) 50%, rgba(0, 0, 255, 1) 100%) no-repeat; width: 300px; height: 300px;"><br></div>
diff --git a/layout/reftests/css-gradients/reftest.list b/layout/reftests/css-gradients/reftest.list
index a93070752..729bc6058 100644
--- a/layout/reftests/css-gradients/reftest.list
+++ b/layout/reftests/css-gradients/reftest.list
@@ -16,7 +16,6 @@ fuzzy-if(!contentSameGfxBackendAsCanvas,4,92400) fuzzy-if(azureSkiaGL||skiaConte
== linear-diagonal-4a.html linear-diagonal-4-ref.html
== linear-diagonal-4b.html linear-diagonal-4-ref.html
== linear-diagonal-4c.html linear-diagonal-4-ref.html
-== linear-premul.html linear-premul-ref.html
# these tests uses a similar gradient over different bounds. It's perfectly
# reasonable to expect implementations to give slightly different results
@@ -92,7 +91,6 @@ fuzzy-if(Android,4,248) == radial-zero-length-1g.html radial-zero-length-1-ref.h
fuzzy-if(Android,4,248) == radial-zero-length-1h.html radial-zero-length-1-ref.html
fuzzy-if(Android,4,248) == radial-zero-length-1i.html radial-zero-length-1-ref.html
fuzzy-if(Android,4,248) == radial-zero-length-1j.html radial-zero-length-1-ref.html
-== radial-premul.html radial-premul-ref.html
== repeated-final-stop-1.html repeated-final-stop-1-ref.html
== repeating-linear-1a.html repeating-linear-1-ref.html
== repeating-linear-1b.html repeating-linear-1-ref.html