poppler/OutputDev.h | 4 ++++ qt5/src/ArthurOutputDev.cc | 18 ++++++++++++++++++ qt5/src/ArthurOutputDev.h | 1 + qt5/tests/check_stroke_opacity.cpp | 26 ++++++++++++++++++-------- 4 files changed, 41 insertions(+), 8 deletions(-)
New commits: commit 8775587096dacd2757917e493f25ca038f169294 Author: Oliver Sander <[email protected]> Date: Fri Apr 17 22:09:17 2020 +0200 [arthur] Implement the clipToStrokePath method diff --git a/qt5/src/ArthurOutputDev.cc b/qt5/src/ArthurOutputDev.cc index d535a8fa..e9ebcc92 100644 --- a/qt5/src/ArthurOutputDev.cc +++ b/qt5/src/ArthurOutputDev.cc @@ -882,6 +882,24 @@ void ArthurOutputDev::eoClip(GfxState *state) m_painter.top()->setClipPath(convertPath( state, state->getPath(), Qt::OddEvenFill ), Qt::IntersectClip ); } +void ArthurOutputDev::clipToStrokePath(GfxState *state) +{ + QPainterPath clipPath = convertPath( state, state->getPath(), Qt::WindingFill ); + + // Get the outline of 'clipPath' as a separate path + QPainterPathStroker stroker; + stroker.setWidth( state->getLineWidth() ); + stroker.setCapStyle( m_currentPen.capStyle() ); + stroker.setJoinStyle( m_currentPen.joinStyle() ); + stroker.setMiterLimit( state->getMiterLimit() ); + stroker.setDashPattern( m_currentPen.dashPattern() ); + stroker.setDashOffset( m_currentPen.dashOffset() ); + QPainterPath clipPathOutline = stroker.createStroke ( clipPath ); + + // The interior of the outline is the desired clipping region + m_painter.top()->setClipPath(clipPathOutline, Qt::IntersectClip ); +} + void ArthurOutputDev::drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, diff --git a/qt5/src/ArthurOutputDev.h b/qt5/src/ArthurOutputDev.h index 046f51dd..971ba3f9 100644 --- a/qt5/src/ArthurOutputDev.h +++ b/qt5/src/ArthurOutputDev.h @@ -125,6 +125,7 @@ public: //----- path clipping void clip(GfxState *state) override; void eoClip(GfxState *state) override; + void clipToStrokePath(GfxState *state) override; //----- text drawing // virtual void drawString(GfxState *state, GooString *s); diff --git a/qt5/tests/check_stroke_opacity.cpp b/qt5/tests/check_stroke_opacity.cpp index e278c16e..32434adf 100644 --- a/qt5/tests/check_stroke_opacity.cpp +++ b/qt5/tests/check_stroke_opacity.cpp @@ -47,16 +47,14 @@ void TestStrokeOpacity::checkStrokeOpacity() // The actual tests start here - // Splash and QPainter backends implement shadings slightly differently, - // hence we cannot expect to get precisely the same colors. - // Allow a tolerance up to '3' per channel. - int tolerance = 3; + // Allow a tolerance. + int tolerance; auto approximatelyEqual = [&tolerance](QRgb c0, const QColor& c1) { - return std::abs(qAlpha(c0) - c1.alpha() ) < tolerance - && std::abs(qRed(c0) - c1.red() ) < tolerance - && std::abs(qGreen(c0) - c1.green() ) < tolerance - && std::abs(qBlue(c0) - c1.blue() ) < tolerance; + return std::abs(qAlpha(c0) - c1.alpha() ) <= tolerance + && std::abs(qRed(c0) - c1.red() ) <= tolerance + && std::abs(qGreen(c0) - c1.green() ) <= tolerance + && std::abs(qBlue(c0) - c1.blue() ) <= tolerance; }; // At the lower left of the test document is a square with an axial shading, @@ -64,7 +62,19 @@ void TestStrokeOpacity::checkStrokeOpacity() // Check that with a sample pixel auto pixel = image.pixel(70,160); + // Splash and QPainter backends implement shadings slightly differently, + // hence we cannot expect to get precisely the same colors. + tolerance = 2; QVERIFY(approximatelyEqual(pixel, QColor(253,233,196,255))); + + // At the upper left of the test document is a stroked square with an axial shading. + // This is implemented by filling a clip region defined by a stroke outline. + // Check whether the backend really only renders the stroke, not the region + // surrounded by the stroke. + auto pixelUpperLeftInterior = image.pixel(70,70); + + tolerance = 0; + QVERIFY(approximatelyEqual(pixelUpperLeftInterior, Qt::white)); } QTEST_GUILESS_MAIN(TestStrokeOpacity) commit 6c82422498a2d02fd8acea005e7d6fa843caa1d8 Author: Oliver Sander <[email protected]> Date: Fri Apr 17 22:04:45 2020 +0200 Document the purpose of the clipToStrokePath method diff --git a/poppler/OutputDev.h b/poppler/OutputDev.h index edc66a23..942320b7 100644 --- a/poppler/OutputDev.h +++ b/poppler/OutputDev.h @@ -251,6 +251,10 @@ public: // inside the clipping region if a ray from it to infinity will cross the clipping // path an odd number of times (disregarding the path orientation). virtual void eoClip(GfxState * /*state*/) {} + + // Update the clipping path. Unlike for the previous two methods, the clipping region + // is not the region surrounded by the path in 'state', but rather the path itself, + // rendered with the current pen settings. virtual void clipToStrokePath(GfxState * /*state*/) {} //----- text drawing _______________________________________________ poppler mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/poppler
