Commit c97d3153 authored by Oliver Sander's avatar Oliver Sander
Browse files

Use additional samples to test for constant parts of an axial gradient

The method doAxialShFill does adaptive sampling of gradients.
If the gradient color is found to be the same at two consecutive
sampling locations then the gradient is concluded to be constant
between the two locations.

Of course, this conclusion may be wrong; one instance of this
happening is

  poppler/poppler#938

This patch fixes rendering of the test file in issue 938 by doing
one more sampling when a part of the gradient is suspected to be
constant.  Of course it is easily possible to create gradients
also misrender with the additional sampling point.  Should such
gradients ever appear in actual non-synthetic documents the code
can now easily handle yet more sample points.

Fixes: poppler/poppler#938
parent 13c95f25
Pipeline #364368 passed with stage
in 6 minutes and 28 seconds
......@@ -2712,8 +2712,35 @@ void Gfx::doAxialShFill(GfxAxialShading *shading)
} else {
tt = t0 + (t1 - t0) * ta[j];
}
// Try to determine whether the color map is constant between ta[i] and ta[j].
// In the strict sense this question cannot be answered by sampling alone.
// We try an educated guess in form of 2 samples.
// See https://gitlab.freedesktop.org/poppler/poppler/issues/938 for a file where one sample was not enough.
// The first test sample at 1.0 (i.e., ta[j]) is coded separately, because we may
// want to reuse the color later
shading->getColor(tt, &color1);
if (isSameGfxColor(color1, color0, nComps, axialColorDelta)) {
bool isPatchOfConstantColor = isSameGfxColor(color1, color0, nComps, axialColorDelta);
if (isPatchOfConstantColor) {
// TODO: Use std::clamp here once C++17 is allowed.
double previousStop = std::min(t1, std::max(t0, t0 + (t1 - t0) * ta[i]));
// Add more sample locations here if required
for (double l : { 0.5 }) {
GfxColor tmpColor;
double x = previousStop + l * (tt - previousStop);
shading->getColor(x, &tmpColor);
if (!isSameGfxColor(tmpColor, color0, nComps, axialColorDelta)) {
isPatchOfConstantColor = false;
break;
}
}
}
if (isPatchOfConstantColor) {
// in these two if what we guarantee is that if we are skipping lots of
// positions because the colors are the same, we still create a region
// with vertexs passing by bboxIntersections[1] and bboxIntersections[2]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment