diff options
author | Armin Le Grand (Collabora) <Armin.Le.Grand@me.com> | 2024-09-03 13:36:17 +0200 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@me.com> | 2024-09-03 15:58:37 +0200 |
commit | c37d18c0a8dbe77ead043a1f3dce86192ca74a79 (patch) | |
tree | 251fa46bdf0275fced0819561fb4ecceebfd621e /drawinglayer/source/processor2d | |
parent | 1d31fb085c93218fddecc5de75f3c38a16c87b38 (diff) |
CairoSDPR: Fixed a problem with cairo_clip (see comments)
Change-Id: I14d477dbeb9a18cc6f9d750b5d1f837117c22eaf
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172798
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'drawinglayer/source/processor2d')
-rw-r--r-- | drawinglayer/source/processor2d/cairopixelprocessor2d.cxx | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx index ba8d5fb73261..34438eb95f95 100644 --- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx @@ -874,6 +874,7 @@ CairoPixelProcessor2D::CairoPixelProcessor2D(const geometry::ViewInformation2D& officecfg::Office::Common::Drawinglayer::RenderSimpleTextDirect::get()) , mbRenderDecoratedTextDirect( officecfg::Office::Common::Drawinglayer::RenderDecoratedTextDirect::get()) + , mnClipRecurstionCount(0) { if (pTarget) { @@ -1448,16 +1449,16 @@ void CairoPixelProcessor2D::processMaskPrimitive2D( return; } - basegfx::B2DPolyPolygon aMask(rMaskCandidate.getMask()); + const basegfx::B2DPolyPolygon& rMask(rMaskCandidate.getMask()); - if (!aMask.count()) + if (!rMask.count()) { // no mask (so nothing inside), done return; } // calculate visible range - basegfx::B2DRange aMaskRange(aMask.getB2DRange()); + basegfx::B2DRange aMaskRange(rMask.getB2DRange()); aMaskRange.transform(getViewInformation2D().getObjectToViewTransformation()); if (!getDiscreteViewRange(mpRT).overlaps(aMaskRange)) { @@ -1479,20 +1480,40 @@ void CairoPixelProcessor2D::processMaskPrimitive2D( // create path geometry and put mask as path cairo_new_path(mpRT); - getOrCreateFillGeometry(mpRT, aMask); + getOrCreateFillGeometry(mpRT, rMask); - // clip to this mask (also reset path, cairo_clip does not consume it) + // clip to this mask cairo_clip(mpRT); - cairo_new_path(mpRT); // reset transformation to not have it set when processing // child content below (was only used to set clip path) cairo_identity_matrix(mpRT); // process sub-content (that shall be masked) + mnClipRecurstionCount++; process(rMaskCandidate.getChildren()); + mnClipRecurstionCount--; cairo_restore(mpRT); + + if (0 == mnClipRecurstionCount) + { + // for *some* reason Cairo seems to have problems using cairo_clip + // recursively, in combination with cairo_save/cairo_restore. I think + // it *should* work as used here, see + // https://www.cairographics.org/manual/cairo-cairo-t.html#cairo-clip + // where this combination is explicitely mentioned/explained. It may + // just be a error in cairo, too (?). + // The error is that without that for some reason the last clip is not + // restored but *stays*, so e.g. when having a shape filled with + // 'tux.svg' and an ellipse overlapping in front, suddenly (but not + // always?) the ellipse gets 'clipped' against the shape filled with + // the tux graphic. + // What helps is to count the clip recursion for each incarnation of + // CairoPixelProcessor2D/cairo_t used and call/use cairo_reset_clip + // when last clip is left. + cairo_reset_clip(mpRT); + } } void CairoPixelProcessor2D::processModifiedColorPrimitive2D( @@ -3463,6 +3484,8 @@ void CairoPixelProcessor2D::processSvgRadialGradientPrimitive2D( void CairoPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { + const cairo_status_t aStart(cairo_status(mpRT)); + switch (rCandidate.getPrimitive2DID()) { // geometry that *has* to be processed @@ -3630,6 +3653,13 @@ void CairoPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimit break; } } + + const cairo_status_t aEnd(cairo_status(mpRT)); + + if (aStart != aEnd) + { + SAL_WARN("drawinglayer", "CairoSDPR: Cairo status problem (!)"); + } } } // end of namespace |