summaryrefslogtreecommitdiff
path: root/layout/base/nsCSSRendering.cpp
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 /layout/base/nsCSSRendering.cpp
parentc0c702a5e3284e843e680064b4c6a7280242c567 (diff)
downloaduxp-d61fde6e94bce9f920e9fcc55a43f94c23c40a01.tar.gz
CSS: Stop using premultiplied color space for gradients.
Diffstat (limited to 'layout/base/nsCSSRendering.cpp')
-rw-r--r--layout/base/nsCSSRendering.cpp88
1 files changed, 4 insertions, 84 deletions
diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp
index 1c6d97395a..5b8a884a1b 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;