Bug 1793611 - Handle degenerate (0-length) color line in extend-pad mode for radial gradients. r=lsalzman

Includes reftest; there's fuzz at the color transitions, when compared to a CSS-backgrounds simulation,
but in the case of "real" failure there'd be many more pixels of mismatch, and max-difference would be 255.

Differential Revision: https://phabricator.services.mozilla.com/D158579
This commit is contained in:
Jonathan Kew 2022-10-05 00:35:24 +00:00
Родитель a8ed973eea
Коммит 395783fdcf
4 изменённых файлов: 68 добавлений и 9 удалений

Просмотреть файл

@ -666,6 +666,8 @@ struct ColorLineT {
}
// Normalize stops to the range 0.0 .. 1.0, and return the original
// start & end.
// Note that if all stops are at the same offset, no normalization
// will be done.
*aFirstStop = aStops[0].offset;
*aLastStop = aStops.LastElement().offset;
if ((*aLastStop > *aFirstStop) &&
@ -1043,16 +1045,25 @@ struct PaintRadialGradient : public PaintPatternBase {
if (aColorLine->extend != T::EXTEND_PAD) {
return MakeUnique<ColorPattern>(DeviceColor());
}
} else {
// Adjust centers along the vector between them, and scale radii for
// gradient line defined from 0.0 to 1.0.
Point vec = c2 - c1;
c1 += vec * firstStop;
c2 -= vec * (1.0f - lastStop);
float deltaR = r2 - r1;
r1 = r1 + deltaR * firstStop;
r2 = r2 - deltaR * (1.0f - lastStop);
// For extend-pad, when the color line is zero-length, we add a "fake"
// color stop to ensure we'll maintain the orientation of the cone,
// otherwise when we adjust circles to account for the normalized color
// stops, the centers will coalesce and the cone or cylinder collapses.
for (auto& gs : stopArray) {
gs.offset = 0.0f;
}
stopArray.AppendElement(
GradientStop{1.0f, stopArray.LastElement().color});
lastStop += 1.0f;
}
// Adjust centers along the vector between them, and scale radii for
// gradient line defined from 0.0 to 1.0.
Point vec = c2 - c1;
c1 += vec * firstStop;
c2 -= vec * (1.0f - lastStop);
float deltaR = r2 - r1;
r1 = r1 + deltaR * firstStop;
r2 = r2 - deltaR * (1.0f - lastStop);
}
if ((r1 < 0.0f || r2 < 0.0f) && aColorLine->extend == T::EXTEND_PAD) {
// For EXTEND_PAD, we can restrict the gradient definition to just its
@ -1119,6 +1130,9 @@ struct PaintRadialGradient : public PaintPatternBase {
c2 += vec;
}
RefPtr stops = aColorLine->MakeGradientStops(aState, stopArray);
if (!stops) {
return MakeUnique<ColorPattern>(DeviceColor());
}
return MakeUnique<RadialGradientPattern>(c1, c2, r1, r2, std::move(stops),
Matrix::Scaling(1.0, -1.0));
}

Просмотреть файл

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<meta charset=utf-8>
<title>COLRv1 font test: radial gradient with degenerate color line</title>
<style>
p { margin: 0; }
div { height: 100px; position: relative; }
/* Use CSS backgrounds to imitate the expected CAhem glyph rendering.
Antialiasing will differ, but otherwise the results should match. */
span { display: inline-block; height: 40px; position: absolute; overflow: clip; }
span.bg { width: 100px; top: 30px; background: red; }
span.a { background: blue; border-radius: 20px; left: 30px; width: 200px; }
span.b { background: blue; border-radius: 20px; left: 10px; width: 200px; }
span.c { background: blue; border-radius: 20px; left: 50px; width: 200px; }
span.d { background: blue; border-radius: 20px; left: 60px; width: 200px; }
</style>
<div><span class=bg><span class=a></span></span></div>
<div><span class=bg><span class=b></span></span></div>
<div><span class=bg><span class=c></span></span></div>
<div><span class=bg><span class=d></span></span></div>

Просмотреть файл

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<meta charset=utf-8>
<title>COLRv1 font test: radial gradient with degenerate color line</title>
<style>
@font-face {
font-family: CAhem;
src: url("CAhem.ttf");
}
p { margin: 0; }
span { font: 100px/1 CAhem; }
.a { font-variation-settings: "GRX0" 400, "GRR0" 200, "GRX1" 600, "GRR1" 200, "COL1" 0.5, "COL2" 0.5, "COL3" 0.5; }
.b { font-variation-settings: "GRX0" 400, "GRR0" 200, "GRX1" 600, "GRR1" 200, "COL1" -0.5, "COL2" -0.5, "COL3" -0.5; }
.c { font-variation-settings: "GRX0" 400, "GRR0" 200, "GRX1" 600, "GRR1" 200, "COL1" 1.5, "COL2" 1.5, "COL3" 1.5; }
.d { font-variation-settings: "GRX0" 400, "GRR0" 200, "GRX1" 600, "GRR1" 200, "COL1" 2.0, "COL2" 2.0, "COL3" 2.0; }
</style>
<div>
<div><span class=a>@</div>
<div><span class=b>@</div>
<div><span class=c>@</div>
<div><span class=d>@</div>
</div>

Просмотреть файл

@ -191,6 +191,7 @@ skip-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy(0-1,0-1) == colrv1-03.h
skip-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy(0-1,0-1800) fuzzy-if(Android,0-64,0-37100) == colrv1-04.html colrv1-04-ref.html
skip-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(Android,8-8,1484-1484) == colrv1-05.html colrv1-05-ref.html
skip-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy(0-1,0-291) == colrv1-06.html colrv1-06-ref.html
skip-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy(0-128,0-264) == colrv1-07.html colrv1-07-ref.html
defaults
# Check that the tech(color-COLRv1) function responds to whether COLRv1 support is enabled.