summaryrefslogtreecommitdiffstats
path: root/layout/painting/nsCSSRenderingGradients.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:35:49 +0000
commitd8bbc7858622b6d9c278469aab701ca0b609cddf (patch)
treeeff41dc61d9f714852212739e6b3738b82a2af87 /layout/painting/nsCSSRenderingGradients.cpp
parentReleasing progress-linux version 125.0.3-1~progress7.99u1. (diff)
downloadfirefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.tar.xz
firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.zip
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--layout/painting/nsCSSRenderingGradients.cpp30
1 files changed, 23 insertions, 7 deletions
diff --git a/layout/painting/nsCSSRenderingGradients.cpp b/layout/painting/nsCSSRenderingGradients.cpp
index 2fb2f0b024..db30d4fefc 100644
--- a/layout/painting/nsCSSRenderingGradients.cpp
+++ b/layout/painting/nsCSSRenderingGradients.cpp
@@ -1195,15 +1195,16 @@ class MOZ_STACK_CLASS WrColorStopInterpolator
WrColorStopInterpolator(
const nsTArray<ColorStop>& aStops,
const StyleColorInterpolationMethod& aStyleColorInterpolationMethod,
- float aOpacity, nsTArray<wr::GradientStop>& aResult)
- : ColorStopInterpolator(aStops, aStyleColorInterpolationMethod),
+ float aOpacity, nsTArray<wr::GradientStop>& aResult, bool aExtendLastStop)
+ : ColorStopInterpolator(aStops, aStyleColorInterpolationMethod,
+ aExtendLastStop),
mResult(aResult),
mOpacity(aOpacity),
mOutputStop(0) {}
void CreateStops() {
mResult.SetLengthAndRetainStorage(0);
- // we always emit at least two stops (start and end) for each input stop,
+ // We always emit at least two stops (start and end) for each input stop,
// which avoids ambiguity with incomplete oklch/lch/hsv/hsb color stops for
// the last stop pair, where the last color stop can't be interpreted on its
// own because it actually depends on the previous stop.
@@ -1257,11 +1258,26 @@ void nsCSSGradientRenderer::BuildWebRenderParameters(
// * https://bugzilla.mozilla.org/show_bug.cgi?id=1248178
StyleColorInterpolationMethod styleColorInterpolationMethod =
mGradient->ColorInterpolationMethod();
- if (mStops.Length() >= 2 &&
- (styleColorInterpolationMethod.space != StyleColorSpace::Srgb ||
- gfxPlatform::GetCMSMode() == CMSMode::All)) {
+ // For colorspaces supported by WebRender (Srgb, Hsl, Hwb) we technically do
+ // not need to add extra stops, but the only one of those colorspaces that
+ // appears frequently is Srgb, and Srgb still needs extra stops if CMS is
+ // enabled. Hsl/Hwb need extra stops if StyleHueInterpolationMethod is not
+ // Shorter, or if CMS is enabled.
+ //
+ // It's probably best to keep this logic as simple as possible, see
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1885716 for an example of
+ // what can happen if we try to be clever here.
+ if (styleColorInterpolationMethod.space != StyleColorSpace::Srgb ||
+ gfxPlatform::GetCMSMode() == CMSMode::All) {
+ // For the specific case of longer hue interpolation on a CSS non-repeating
+ // gradient, we have to pretend there is another stop at position=1.0 that
+ // duplicates the last stop, this is probably only used for things like a
+ // color wheel. No such problem for SVG as it doesn't have that complexity.
+ bool extendLastStop = aMode == wr::ExtendMode::Clamp &&
+ styleColorInterpolationMethod.hue ==
+ StyleHueInterpolationMethod::Longer;
WrColorStopInterpolator interpolator(mStops, styleColorInterpolationMethod,
- aOpacity, aStops);
+ aOpacity, aStops, extendLastStop);
interpolator.CreateStops();
} else {
aStops.SetLength(mStops.Length());