summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2017-05-26 13:54:27 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2017-05-31 16:18:43 +0200
commit096bda90377caa7a3e2a7c52cbbd8553901dfb88 (patch)
treebf5003a91f4faf17d232772255735126fc4fcaf0
parent50f309b15f4f47cb357fff04503390f65ae08de1 (diff)
tdf#108056 sw SubtractFlys: work with a polypolygon directly
In case the intention is that the clip rectangle should include the page, except a fly frame, we built a list of rectangles that covered this area. This introduces the problem if adjacent rectangles don't join perfectly. Instead allow lcl_SubtractFlys() to work on a clip state directly, this way the clip polypolygon will only contain two paths (the page rectangle and the rectangle of the fly), so rounding errors can't happen. Change-Id: I5b2e9a382aa7d16f3b16509670de754b5e00bd6d Reviewed-on: https://gerrit.libreoffice.org/38066 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org> (cherry picked from commit 87d62a6222932d36c91d7b69240c7bccbf4e46be)
-rw-r--r--sw/source/core/doc/notxtfrm.cxx3
-rw-r--r--sw/source/core/inc/frmtool.hxx2
-rw-r--r--sw/source/core/layout/paintfrm.cxx28
3 files changed, 16 insertions, 17 deletions
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx
index 5ac99b8da9be..aafbdbf04471 100644
--- a/sw/source/core/doc/notxtfrm.cxx
+++ b/sw/source/core/doc/notxtfrm.cxx
@@ -186,7 +186,8 @@ static void lcl_ClearArea( const SwFrame &rFrame,
if ( rFrame.GetBackgroundBrush( aFillAttributes, pItem, pCol, aOrigRect, false ) )
{
SwRegionRects const region(rPtArea);
- const bool bDone(::DrawFillAttributes(aFillAttributes, aOrigRect, region, rOut));
+ basegfx::tools::B2DClipState aClipState;
+ const bool bDone(::DrawFillAttributes(aFillAttributes, aOrigRect, region, aClipState, rOut));
if(!bDone)
{
diff --git a/sw/source/core/inc/frmtool.hxx b/sw/source/core/inc/frmtool.hxx
index e01595783154..c428e42c2117 100644
--- a/sw/source/core/inc/frmtool.hxx
+++ b/sw/source/core/inc/frmtool.hxx
@@ -27,6 +27,7 @@
#include <editeng/lrspitem.hxx>
#include <swfont.hxx>
#include <flyfrm.hxx>
+#include <basegfx/tools/b2dclipstate.hxx>
class SwPageFrame;
class SwFlyFrame;
@@ -68,6 +69,7 @@ bool DrawFillAttributes(
const drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes,
const SwRect& rOriginalLayoutRect,
const SwRegionRects& rPaintRegion,
+ const basegfx::tools::B2DClipState& rClipState,
OutputDevice& rOut);
void paintGraphicUsingPrimitivesHelper(
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index d8d6cc79340d..a2b9df5e4360 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -1538,7 +1538,7 @@ static void lcl_ExtendLeftAndRight( SwRect& _rRect,
}
static void lcl_SubtractFlys( const SwFrame *pFrame, const SwPageFrame *pPage,
- const SwRect &rRect, SwRegionRects &rRegion, SwPaintProperties & rProperties)
+ const SwRect &rRect, SwRegionRects &rRegion, basegfx::tools::B2DClipState& rClipState, SwPaintProperties & rProperties)
{
const SwSortedObjs& rObjs = *pPage->GetSortedObjs();
const SwFlyFrame* pSelfFly = pFrame->IsInFly() ? pFrame->FindFlyFrame() : gProp.pSRetoucheFly2;
@@ -1671,6 +1671,7 @@ static void lcl_SubtractFlys( const SwFrame *pFrame, const SwPageFrame *pPage,
const SwBorderAttrs &rAttrs = *aAccess.Get();
::lcl_CalcBorderRect( aRect, pFly, rAttrs, true, rProperties );
rRegion -= aRect;
+ rClipState.subtractRange(basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom()));
continue;
}
else
@@ -1688,12 +1689,14 @@ static void lcl_SubtractFlys( const SwFrame *pFrame, const SwPageFrame *pPage,
const SwBorderAttrs &rAttrs = *aAccess.Get();
::lcl_CalcBorderRect( aRect, pFly, rAttrs, true, rProperties );
rRegion -= aRect;
+ rClipState.subtractRange(basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom()));
}
else
{
SwRect aRect( pFly->Prt() );
aRect += pFly->Frame().Pos();
rRegion -= aRect;
+ rClipState.subtractRange(basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom()));
}
}
if (gProp.pSRetoucheFly == gProp.pSRetoucheFly2)
@@ -1859,6 +1862,7 @@ bool DrawFillAttributes(
const drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes,
const SwRect& rOriginalLayoutRect,
const SwRegionRects& rPaintRegion,
+ const basegfx::tools::B2DClipState& rClipState,
vcl::RenderContext& rOut)
{
if(rFillAttributes.get() && rFillAttributes->isUsed())
@@ -1921,18 +1925,7 @@ bool DrawFillAttributes(
// tdf#86578 the awful lcl_SubtractFlys hack
if (rPaintRegion.size() > 1 || rPaintRegion[0] != rPaintRegion.GetOrigin())
{
- tools::PolyPolygon tempRegion;
- for (size_t i = 0; i < rPaintRegion.size(); ++i)
- {
- // Don't use SwRect::SvRect() here, as the clip
- // rectangle is supposed to cover everything outside
- // the flys, so the Width() - 1 isn't correct.
- const SwRect& rRect = rPaintRegion[i];
- tools::Rectangle aRectangle(rRect.Pos().getX(), rRect.Pos().getY(), rRect.Pos().getX() + rRect.SSize().getWidth(), rRect.Pos().getY() + rRect.SSize().getHeight());
- tempRegion.Insert(tools::Polygon(aRectangle));
- }
- basegfx::B2DPolyPolygon const maskRegion( tempRegion.getB2DPolyPolygon());
-
+ basegfx::B2DPolyPolygon const maskRegion(rClipState.getClipPoly());
primitives.resize(1);
primitives[0] = new drawinglayer::primitive2d::MaskPrimitive2D(
maskRegion, rSequence);
@@ -4680,7 +4673,8 @@ void SwFrame::PaintBorderLine( const SwRect& rRect,
pPage->GetFormat()->GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::SUBTRACT_FLYS))
{
SwRegionRects aRegion( aOut, 4 );
- ::lcl_SubtractFlys( this, pPage, aOut, aRegion, gProp );
+ basegfx::tools::B2DClipState aClipState;
+ ::lcl_SubtractFlys( this, pPage, aOut, aRegion, aClipState, gProp );
for ( size_t i = 0; i < aRegion.size(); ++i )
gProp.pSLines->AddLineRect( aRegion[i], pColor, nStyle, pTab, nSubCol, gProp );
}
@@ -6590,10 +6584,12 @@ void SwFrame::PaintBackground( const SwRect &rRect, const SwPageFrame *pPage,
}
SwRegionRects aRegion( aRect );
+ basegfx::B2DPolygon aB2DPolygon{tools::Polygon(aRect.SVRect()).getB2DPolygon()};
+ basegfx::tools::B2DClipState aClipState{basegfx::B2DPolyPolygon(aB2DPolygon)};
if (pPage->GetSortedObjs() &&
pSh->GetDoc()->getIDocumentSettingAccess().get(DocumentSettingId::SUBTRACT_FLYS))
{
- ::lcl_SubtractFlys( this, pPage, aRect, aRegion, gProp );
+ ::lcl_SubtractFlys( this, pPage, aRect, aRegion, aClipState, gProp );
}
// OD 06.08.2002 #99657# - determine, if background transparency
@@ -6610,7 +6606,7 @@ void SwFrame::PaintBackground( const SwRect &rRect, const SwPageFrame *pPage,
if(aFillAttributes->isUsed())
{
// check if really something is painted
- bDone = DrawFillAttributes(aFillAttributes, aOrigBackRect, aRegion, *pOut);
+ bDone = DrawFillAttributes(aFillAttributes, aOrigBackRect, aRegion, aClipState, *pOut);
}
if(!bDone)