diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-05-26 13:54:27 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-05-26 17:25:44 +0200 |
commit | 87d62a6222932d36c91d7b69240c7bccbf4e46be (patch) | |
tree | 209b37f3ad692183cf57e425269c5f33614b2d28 /sw | |
parent | e60529fdfe0502f64e3c975f71539b28146943e8 (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>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/doc/notxtfrm.cxx | 3 | ||||
-rw-r--r-- | sw/source/core/inc/frmtool.hxx | 2 | ||||
-rw-r--r-- | sw/source/core/layout/paintfrm.cxx | 28 |
3 files changed, 16 insertions, 17 deletions
diff --git a/sw/source/core/doc/notxtfrm.cxx b/sw/source/core/doc/notxtfrm.cxx index 87a7b43c9055..4156753cf966 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 81453b10487c..b9093eb523c5 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 1cd629dacba3..bb6ca5a7e2eb 100644 --- a/sw/source/core/layout/paintfrm.cxx +++ b/sw/source/core/layout/paintfrm.cxx @@ -1533,7 +1533,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; @@ -1666,6 +1666,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 @@ -1683,12 +1684,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) @@ -1854,6 +1857,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()) @@ -1916,18 +1920,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); @@ -4681,7 +4674,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 ); } @@ -6588,10 +6582,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 @@ -6608,7 +6604,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) |