summaryrefslogtreecommitdiff
path: root/drawinglayer/source/processor2d
diff options
context:
space:
mode:
authorArmin Le Grand (Collabora) <Armin.Le.Grand@me.com>2024-09-03 13:36:17 +0200
committerArmin Le Grand <Armin.Le.Grand@me.com>2024-09-03 15:58:37 +0200
commitc37d18c0a8dbe77ead043a1f3dce86192ca74a79 (patch)
tree251fa46bdf0275fced0819561fb4ecceebfd621e /drawinglayer/source/processor2d
parent1d31fb085c93218fddecc5de75f3c38a16c87b38 (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.cxx42
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