зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1892653 - Fix repeating oklch gradients r=gfx-reviewers,lsalzman
Differential Revision: https://phabricator.services.mozilla.com/D208960
This commit is contained in:
Родитель
13bb51755d
Коммит
fd063f4485
|
@ -1195,8 +1195,9 @@ 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) {}
|
||||
|
@ -1268,8 +1269,15 @@ void nsCSSGradientRenderer::BuildWebRenderParameters(
|
|||
// 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());
|
||||
|
|
|
@ -44,21 +44,27 @@ class MOZ_STACK_CLASS ColorStopInterpolator {
|
|||
public:
|
||||
ColorStopInterpolator(
|
||||
const nsTArray<ColorStop>& aStops,
|
||||
const StyleColorInterpolationMethod& aStyleColorInterpolationMethod)
|
||||
const StyleColorInterpolationMethod& aStyleColorInterpolationMethod,
|
||||
bool aExtendLastStop)
|
||||
: mStyleColorInterpolationMethod(aStyleColorInterpolationMethod),
|
||||
mStops(aStops) {}
|
||||
mStops(aStops),
|
||||
mExtendLastStop(aExtendLastStop) {}
|
||||
|
||||
void CreateStops() {
|
||||
// This loop intentionally iterates the last stop.
|
||||
for (uint32_t i = 0; i < mStops.Length(); i++) {
|
||||
// This loop intentionally iterates the last stop if extending.
|
||||
uint32_t iterStops = mStops.Length() - (mExtendLastStop ? 0 : 1);
|
||||
for (uint32_t i = 0; i < iterStops; i++) {
|
||||
auto nextindex = i + 1 < mStops.Length() ? i + 1 : i;
|
||||
const auto& start = mStops[i];
|
||||
const auto& end = mStops[nextindex];
|
||||
float startPosition = start.mPosition;
|
||||
float endPosition = end.mPosition;
|
||||
// For the sake of StyleHueInterpolationMethod == Longer we have to
|
||||
// pretend there is a stop beyond the last stop
|
||||
if (i == mStops.Length() - 1) {
|
||||
// For CSS non-repeating gradients with longer hue specified, we have to
|
||||
// pretend there is a stop beyond the last stop. This is never the case
|
||||
// on SVG gradients as they only use shorter hue.
|
||||
//
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1885716 for more info.
|
||||
if (i == mStops.Length() - 1 && mExtendLastStop) {
|
||||
endPosition = 1.0f;
|
||||
}
|
||||
uint32_t extraStops =
|
||||
|
@ -82,6 +88,10 @@ class MOZ_STACK_CLASS ColorStopInterpolator {
|
|||
protected:
|
||||
StyleColorInterpolationMethod mStyleColorInterpolationMethod;
|
||||
const nsTArray<ColorStop>& mStops;
|
||||
// This indicates that we want to extend the endPosition on the last stop,
|
||||
// which only matters if this is a CSS non-repeating gradient with
|
||||
// StyleHueInterpolationMethod::Longer (only valid for hsl/hwb/lch/oklch).
|
||||
bool mExtendLastStop;
|
||||
|
||||
// This could be made tunable, but at 1.0/128 the error is largely
|
||||
// irrelevant, as WebRender re-encodes it to 128 pairs of stops.
|
||||
|
|
|
@ -244,8 +244,10 @@ class MOZ_STACK_CLASS SVGColorStopInterpolator
|
|||
public:
|
||||
SVGColorStopInterpolator(
|
||||
gfxPattern* aGradient, const nsTArray<ColorStop>& aStops,
|
||||
const StyleColorInterpolationMethod& aStyleColorInterpolationMethod)
|
||||
: ColorStopInterpolator(aStops, aStyleColorInterpolationMethod),
|
||||
const StyleColorInterpolationMethod& aStyleColorInterpolationMethod,
|
||||
bool aExtendLastStop)
|
||||
: ColorStopInterpolator(aStops, aStyleColorInterpolationMethod,
|
||||
aExtendLastStop),
|
||||
mGradient(aGradient) {}
|
||||
|
||||
void CreateStop(float aPosition, DeviceColor aColor) {
|
||||
|
@ -327,7 +329,8 @@ already_AddRefed<gfxPattern> SVGGradientFrame::GetPaintServerPattern(
|
|||
if (StyleSVG()->mColorInterpolation == StyleColorInterpolation::Linearrgb) {
|
||||
static constexpr auto interpolationMethod = StyleColorInterpolationMethod{
|
||||
StyleColorSpace::SrgbLinear, StyleHueInterpolationMethod::Shorter};
|
||||
SVGColorStopInterpolator interpolator(gradient, stops, interpolationMethod);
|
||||
SVGColorStopInterpolator interpolator(gradient, stops, interpolationMethod,
|
||||
false);
|
||||
interpolator.CreateStops();
|
||||
} else {
|
||||
// setup standard sRGB stops
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Repeating linear gradients in HSL and OKLCH space</title>
|
||||
<link rel="author" title="Ashley Hale" href="mailto:ahale@mozilla.com">
|
||||
<style>
|
||||
body {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.a {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: repeating-linear-gradient(
|
||||
to bottom,
|
||||
hsl(180 50% 70%) 0px 20px,
|
||||
hsl(0 50% 50%) 20px 40px,
|
||||
hsl(180 50% 70%) 40px 60px,
|
||||
hsl(0 50% 50%) 60px 80px,
|
||||
hsl(180 50% 70%) 80px 100px
|
||||
);
|
||||
}
|
||||
|
||||
.b {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: repeating-linear-gradient(
|
||||
to bottom,
|
||||
oklch(70% 50% 180) 0px 20px,
|
||||
oklch(50% 50% 0) 20px 40px,
|
||||
oklch(70% 50% 180) 40px 60px,
|
||||
oklch(50% 50% 0) 60px 80px,
|
||||
oklch(70% 50% 180) 80px 100px
|
||||
);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>repeating-linear-gradient with HSL</p>
|
||||
<div class="a"></div>
|
||||
<p>repeating-linear-gradient with OKLCH</p>
|
||||
<div class="b"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,44 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Repeating linear gradients in HSL and OKLCH space</title>
|
||||
<link rel="author" title="Ashley Hale" href="mailto:ahale@mozilla.com">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-color-4/#interpolation">
|
||||
<meta name="assert" content="Tests that a multi-stop shorter hue gradient and a single-stop longer hue (wrapping) gradient match in appearance">
|
||||
<link rel="match" href="repeating-gradient-hsl-and-oklch-ref.html">
|
||||
<style>
|
||||
body {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.a {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: repeating-linear-gradient(
|
||||
to bottom,
|
||||
hsl(180 50% 70%) 0px 20px,
|
||||
hsl(0 50% 50%) 20px 40px
|
||||
);
|
||||
}
|
||||
|
||||
.b {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: repeating-linear-gradient(
|
||||
to bottom,
|
||||
oklch(70% 50% 180) 0px 20px,
|
||||
oklch(50% 50% 0) 20px 40px
|
||||
);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>repeating-linear-gradient with HSL</p>
|
||||
<div class="a"></div>
|
||||
<p>repeating-linear-gradient with OKLCH</p>
|
||||
<div class="b"></div>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче