poppler/Gfx.cc |   27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

New commits:
commit fc3afe21523b3fdc3a27254a3ef8139a82d35385
Author: Oliver Sander <oliver.san...@tu-dresden.de>
Date:   Thu Jul 15 11:01:33 2021 +0200

    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
    
      https://gitlab.freedesktop.org/poppler/poppler/-/issues/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: https://gitlab.freedesktop.org/poppler/poppler/-/issues/938

diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index 4a6b21db..681fe2f7 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -2688,6 +2688,7 @@ void Gfx::doAxialShFill(GfxAxialShading *shading)
 
         // bisect until color difference is small enough or we hit the
         // bisection limit
+        const double previousStop = tt;
         j = next[i];
         while (j > i + 1) {
             if (ta[j] < 0) {
@@ -2697,8 +2698,32 @@ 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) {
+
+                // 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]
_______________________________________________
poppler mailing list
poppler@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to