[poppler] poppler/SplashOutputDev.cc qt5/src qt5/tests splash/Splash.cc splash/Splash.h

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Apr 22 07:49:36 UTC 2020


 poppler/SplashOutputDev.cc         |    9 +++++++--
 qt5/src/ArthurOutputDev.cc         |    5 ++++-
 qt5/tests/check_stroke_opacity.cpp |    7 +++++++
 splash/Splash.cc                   |    8 +++++---
 splash/Splash.h                    |    6 +++++-
 5 files changed, 28 insertions(+), 7 deletions(-)

New commits:
commit 846575911483787a0fe28d76c4e9b51a644d7152
Author: Oliver Sander <oliver.sander at tu-dresden.de>
Date:   Tue Apr 21 16:03:37 2020 +0200

    [splash, arthur] Use stroking opacity when clipping to a stroke path
    
    When filling a region that is clipped to a stroke path, then the
    stroking opacity shall be used rather than the fill opacity.
    I couldn't find this in the spec, but it seems to be what
    Acrobat does.
    
    BUG: https://gitlab.freedesktop.org/poppler/poppler/-/issues/178

diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index 346e836d..2bcabc99 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -42,6 +42,7 @@
 // Copyright (C) 2018, 2019 Stefan Brüns <stefan.bruens at rwth-aachen.de>
 // Copyright (C) 2018 Adam Reichold <adam.reichold at t-online.de>
 // Copyright (C) 2019 Christian Persch <chpe at src.gnome.org>
+// Copyright (C) 2020 Oliver Sander <oliver.sander at tu-dresden.de>
 //
 // To see a description of the changes please see the Changelog file that
 // came with your tarball or type make ChangeLog if you are building from git
@@ -4609,7 +4610,9 @@ bool SplashOutputDev::univariateShadedFill(GfxState *state, SplashUnivariatePatt
   pattern->getShading()->getColorSpace()->createMapping(bitmap->getSeparationList(), SPOT_NCOMPS);
   setOverprintMask(pattern->getShading()->getColorSpace(), state->getFillOverprint(),
 		   state->getOverprintMode(), nullptr);
-  retVal = (splash->shadedFill(&path, pattern->getShading()->getHasBBox(), pattern) == splashOk);
+  // If state->getStrokePattern() is set, then the current clipping region
+  // is a stroke path.
+  retVal = (splash->shadedFill(&path, pattern->getShading()->getHasBBox(), pattern, (state->getStrokePattern()!=nullptr)) == splashOk);
   state->clearPath();
   setVectorAntialias(vaa);
 
@@ -4670,7 +4673,9 @@ bool SplashOutputDev::functionShadedFill(GfxState *state, GfxFunctionShading *sh
   pattern->getShading()->getColorSpace()->createMapping(bitmap->getSeparationList(), SPOT_NCOMPS);
   setOverprintMask(pattern->getShading()->getColorSpace(), state->getFillOverprint(),
 		   state->getOverprintMode(), nullptr);
-  retVal = (splash->shadedFill(&path, pattern->getShading()->getHasBBox(), pattern) == splashOk);
+  // If state->getStrokePattern() is set, then the current clipping region
+  // is a stroke path.
+  retVal = (splash->shadedFill(&path, pattern->getShading()->getHasBBox(), pattern, (state->getStrokePattern()!=nullptr)) == splashOk);
   state->clearPath();
   setVectorAntialias(vaa);
 
diff --git a/qt5/src/ArthurOutputDev.cc b/qt5/src/ArthurOutputDev.cc
index e9ebcc92..3ec8cfab 100644
--- a/qt5/src/ArthurOutputDev.cc
+++ b/qt5/src/ArthurOutputDev.cc
@@ -767,7 +767,10 @@ bool ArthurOutputDev::axialShadedFill(GfxState *state, GfxAxialShading *shading,
 
   // Number of color space components
   auto nComps = shading->getColorSpace()->getNComps();
-  auto opacity = state->getFillOpacity();
+  // If the clipping region is a stroke, then the current operation counts as a stroke
+  // rather than as a fill, and the opacity has to be set accordingly.
+  // See https://gitlab.freedesktop.org/poppler/poppler/-/issues/178
+  auto opacity = (state->getStrokePattern()) ? state->getStrokeOpacity() : state->getFillOpacity();
 
   // Helper function to test two color objects for 'almost-equality'
   auto isSameGfxColor = [&nComps,&colorDelta](const GfxColor &colorA, const GfxColor &colorB)
diff --git a/qt5/tests/check_stroke_opacity.cpp b/qt5/tests/check_stroke_opacity.cpp
index 32434adf..b4cff022 100644
--- a/qt5/tests/check_stroke_opacity.cpp
+++ b/qt5/tests/check_stroke_opacity.cpp
@@ -75,6 +75,13 @@ void TestStrokeOpacity::checkStrokeOpacity()
 
     tolerance = 0;
     QVERIFY(approximatelyEqual(pixelUpperLeftInterior, Qt::white));
+
+    // Now check whether that stroke is semi-transparent.
+    // Bug https://gitlab.freedesktop.org/poppler/poppler/-/issues/178
+    auto pixelUpperLeftOnStroke = image.pixel(70,20);
+
+    tolerance = 2;
+    QVERIFY(approximatelyEqual(pixelUpperLeftOnStroke, QColor(253,233,196,255)));
 }
 
 QTEST_GUILESS_MAIN(TestStrokeOpacity)
diff --git a/splash/Splash.cc b/splash/Splash.cc
index 70584ec4..feb738bb 100644
--- a/splash/Splash.cc
+++ b/splash/Splash.cc
@@ -21,7 +21,7 @@
 // Copyright (C) 2012 Matthias Kramm <kramm at quiss.org>
 // Copyright (C) 2018, 2019 Stefan Brüns <stefan.bruens at rwth-aachen.de>
 // Copyright (C) 2018 Adam Reichold <adam.reichold at t-online.de>
-// Copyright (C) 2019 Oliver Sander <oliver.sander at tu-dresden.de>
+// Copyright (C) 2019, 2020 Oliver Sander <oliver.sander at tu-dresden.de>
 // Copyright (C) 2019 Marek Kasik <mkasik at redhat.com>
 //
 // To see a description of the changes please see the Changelog file that
@@ -6356,7 +6356,8 @@ void Splash::dumpXPath(SplashXPath *path) {
 }
 
 SplashError Splash::shadedFill(SplashPath *path, bool hasBBox,
-                               SplashPattern *pattern) {
+                               SplashPattern *pattern,
+                               bool clipToStrokePath) {
   SplashPipe pipe;
   int xMinI, yMinI, xMaxI, yMaxI, x0, x1, y;
   SplashClipResult clipRes;
@@ -6397,7 +6398,8 @@ SplashError Splash::shadedFill(SplashPath *path, bool hasBBox,
       yMaxI = state->clip->getYMaxI();
     }
 
-    pipeInit(&pipe, 0, yMinI, pattern, nullptr, (unsigned char)splashRound(state->fillAlpha * 255), vectorAntialias && !hasBBox, false);
+    unsigned char alpha = splashRound((clipToStrokePath) ? state->strokeAlpha * 255 : state->fillAlpha * 255);
+    pipeInit(&pipe, 0, yMinI, pattern, nullptr, alpha, vectorAntialias && !hasBBox, false);
 
     // draw the spans
     if (vectorAntialias) {
diff --git a/splash/Splash.h b/splash/Splash.h
index 28ea4e5d..16b41c0a 100644
--- a/splash/Splash.h
+++ b/splash/Splash.h
@@ -16,6 +16,7 @@
 // Copyright (C) 2010-2013, 2015 Thomas Freitag <Thomas.Freitag at alfa.de>
 // Copyright (C) 2010 Christian Feuersänger <cfeuersaenger at googlemail.com>
 // Copyright (C) 2012, 2017 Adrian Johnson <ajohnson at redneon.com>
+// Copyright (C) 2020 Oliver Sander <oliver.sander at tu-dresden.de>
 //
 // To see a description of the changes please see the Changelog file that
 // came with your tarball or type make ChangeLog if you are building from git
@@ -264,8 +265,11 @@ public:
 #endif
 
   // Do shaded fills with dynamic patterns
+  //
+  // clipToStrokePath: Whether the current clip region is a stroke path.
+  //   In that case, strokeAlpha is used rather than fillAlpha.
   SplashError shadedFill(SplashPath *path, bool hasBBox,
-                         SplashPattern *pattern);
+                         SplashPattern *pattern, bool clipToStrokePath);
   // Draw a gouraud triangle shading.
   bool gouraudTriangleShadedFill(SplashGouraudColor *shading);
 


More information about the poppler mailing list