tdf#91260 svx, sw: don't paint off-page part of drawing object
Since commita4dee94afeWriter no longer forces drawing objects to be entirely on one page. However since there is only one SdrPage for the entire document, a drawing object dangleing off the bottom of one page will be painted again on the next page, which is clearly undesirable since Word doesn't do that (and it also destroys the nice invariant that a fly on page N never overlaps a fly on page N+1). So force the SdrPageView code to ignore the drawing object on the next page, by passing in the area of the page frame so that ViewObjectContactOfSdrObj::isPrimitiveVisible() can verify that the anchor position of the SdrObject is actually on the painted page. This requires passing in another parameter; in the usual case the DisplayInfo::maRedrawArea already contains the page frame since commit8af09bf332, but there are special cases in SwFrame::Retouch() and SwFlyFrameFormat::MakeGraphic() where some sub-area is passed in, which cannot be used to check the anchor. Change-Id: Ia0476216ca41dbdaa3de1063fa18cb94fe2e5ae8
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include <svx/svdsob.hxx>
|
||||
#include <vcl/region.hxx>
|
||||
#include <svx/svxdllapi.h>
|
||||
#include <basegfx/range/b2irectangle.hxx>
|
||||
|
||||
namespace sdr
|
||||
{
|
||||
@@ -37,6 +38,8 @@ namespace sdr
|
||||
// is empty, everything needs to be redrawn
|
||||
vcl::Region maRedrawArea;
|
||||
|
||||
/// only for Writer: current page being painted
|
||||
basegfx::B2IRectangle m_WriterPageFrame;
|
||||
|
||||
// Internal flag to know when the control layer is painted. Default is
|
||||
// false. If set to true, painting of the page, page borders and
|
||||
@@ -78,6 +81,9 @@ namespace sdr
|
||||
void SetRedrawArea(const vcl::Region& rRegion);
|
||||
const vcl::Region& GetRedrawArea() const { return maRedrawArea; }
|
||||
|
||||
void SetWriterPageFrame(basegfx::B2IRectangle const& rPageFrame);
|
||||
basegfx::B2IRectangle const& GetWriterPageFrame() const { return m_WriterPageFrame; }
|
||||
|
||||
// Access to ControlLayerProcessingActive flag
|
||||
void SetControlLayerProcessingActive(bool bDoPaint);
|
||||
bool GetControlLayerProcessingActive() const { return mbControlLayerProcessingActive; }
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace sdr
|
||||
}
|
||||
}
|
||||
|
||||
namespace basegfx { class B2DRange; }
|
||||
namespace basegfx { class B2DRange; class B2IRange; }
|
||||
|
||||
class SdrPaintWindow;
|
||||
class SdrPageView;
|
||||
@@ -74,7 +74,7 @@ public:
|
||||
void PrePaint();
|
||||
void PrepareRedraw(const vcl::Region& rReg);
|
||||
void RedrawAll( sdr::contact::ViewObjectContactRedirector* pRedirector );
|
||||
void RedrawLayer( const SdrLayerID* pId, sdr::contact::ViewObjectContactRedirector* pRedirector );
|
||||
void RedrawLayer( const SdrLayerID* pId, sdr::contact::ViewObjectContactRedirector* pRedirector, basegfx::B2IRange const*);
|
||||
|
||||
// Invalidate call, used from ObjectContact(OfPageView) in InvalidatePartOfView(...)
|
||||
void InvalidatePageWindow(const basegfx::B2DRange& rRange);
|
||||
|
||||
@@ -162,7 +162,8 @@ public:
|
||||
void setPreparedPageWindow(SdrPageWindow* pKnownTarget);
|
||||
|
||||
void DrawLayer(SdrLayerID nID, OutputDevice* pGivenTarget, sdr::contact::ViewObjectContactRedirector* pRedirector = nullptr,
|
||||
const Rectangle& rRect = Rectangle());
|
||||
const Rectangle& rRect = Rectangle(),
|
||||
basegfx::B2IRange const* pPageFrame = nullptr);
|
||||
void DrawPageViewGrid(OutputDevice& rOut, const Rectangle& rRect, Color aColor = Color( COL_BLACK ) );
|
||||
|
||||
Rectangle GetPageRect() const;
|
||||
|
||||
@@ -50,6 +50,11 @@ namespace sdr
|
||||
maRedrawArea = rRegion;
|
||||
}
|
||||
|
||||
void DisplayInfo::SetWriterPageFrame(basegfx::B2IRectangle const& rPageFrame)
|
||||
{
|
||||
m_WriterPageFrame = rPageFrame;
|
||||
}
|
||||
|
||||
void DisplayInfo::SetControlLayerProcessingActive(bool bDoProcess)
|
||||
{
|
||||
if((bool)mbControlLayerProcessingActive != bDoProcess)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <svx/svdoole2.hxx>
|
||||
#include <svx/svdview.hxx>
|
||||
#include <vcl/outdev.hxx>
|
||||
#include <vcl/canvastools.hxx>
|
||||
|
||||
#include "fmobj.hxx"
|
||||
|
||||
@@ -139,6 +140,22 @@ bool ViewObjectContactOfSdrObj::isPrimitiveVisible(const DisplayInfo& rDisplayIn
|
||||
}
|
||||
}
|
||||
|
||||
// tdf#91260 check if the object is anchored on a different Writer page
|
||||
// than the one being painted, and if so ignore it (Writer has only one
|
||||
// SdrPage, so the part of the object that should be visible will be
|
||||
// painted on the page where it is anchored)
|
||||
// Note that we cannot check the ViewInformation2D ViewPort for this
|
||||
// because it is only the part of the page that is currently visible.
|
||||
basegfx::B2IPoint const& rAnchor(vcl::unotools::b2IPointFromPoint(getSdrObject().GetAnchorPos()));
|
||||
if (rAnchor.getX() || rAnchor.getY()) // only Writer sets anchor position
|
||||
{
|
||||
if (!rDisplayInfo.GetWriterPageFrame().isEmpty() &&
|
||||
!rDisplayInfo.GetWriterPageFrame().isInside(rAnchor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this object is in the visible range.
|
||||
const drawinglayer::geometry::ViewInformation2D& rViewInfo = GetObjectContact().getViewInformation2D();
|
||||
basegfx::B2DRange aObjRange = GetViewContact().getRange(rViewInfo);
|
||||
|
||||
@@ -352,7 +352,9 @@ void SdrPageWindow::RedrawAll( sdr::contact::ViewObjectContactRedirector* pRedir
|
||||
#endif // CLIPPER_TEST
|
||||
}
|
||||
|
||||
void SdrPageWindow::RedrawLayer( const SdrLayerID* pId, sdr::contact::ViewObjectContactRedirector* pRedirector )
|
||||
void SdrPageWindow::RedrawLayer(const SdrLayerID* pId,
|
||||
sdr::contact::ViewObjectContactRedirector* pRedirector,
|
||||
basegfx::B2IRectangle const*const pPageFrame)
|
||||
{
|
||||
// set redirector
|
||||
GetObjectContact().SetViewObjectContactRedirector(pRedirector);
|
||||
@@ -395,6 +397,11 @@ void SdrPageWindow::RedrawLayer( const SdrLayerID* pId, sdr::contact::ViewObject
|
||||
// #i72889# no page painting for layer painting
|
||||
aDisplayInfo.SetPageProcessingActive(false);
|
||||
|
||||
if (pPageFrame) // Writer page frame for anchor based clipping
|
||||
{
|
||||
aDisplayInfo.SetWriterPageFrame(*pPageFrame);
|
||||
}
|
||||
|
||||
// paint page
|
||||
GetObjectContact().ProcessDisplay(aDisplayInfo);
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <svx/sdrpagewindow.hxx>
|
||||
#include <svx/sdrpaintwindow.hxx>
|
||||
#include <comphelper/lok.hxx>
|
||||
#include <basegfx/range/b2irectangle.hxx>
|
||||
|
||||
using namespace ::com::sun::star;
|
||||
|
||||
@@ -305,7 +306,9 @@ void SdrPageView::setPreparedPageWindow(SdrPageWindow* pKnownTarget)
|
||||
mpPreparedPageWindow = pKnownTarget;
|
||||
}
|
||||
|
||||
void SdrPageView::DrawLayer( SdrLayerID nID, OutputDevice* pGivenTarget, sdr::contact::ViewObjectContactRedirector* pRedirector, const Rectangle& rRect )
|
||||
void SdrPageView::DrawLayer(SdrLayerID nID, OutputDevice* pGivenTarget,
|
||||
sdr::contact::ViewObjectContactRedirector* pRedirector,
|
||||
const Rectangle& rRect, basegfx::B2IRectangle const*const pPageFrame)
|
||||
{
|
||||
if(GetPage())
|
||||
{
|
||||
@@ -316,7 +319,7 @@ void SdrPageView::DrawLayer( SdrLayerID nID, OutputDevice* pGivenTarget, sdr::co
|
||||
if(pKnownTarget)
|
||||
{
|
||||
// paint known target
|
||||
pKnownTarget->RedrawLayer(&nID, pRedirector);
|
||||
pKnownTarget->RedrawLayer(&nID, pRedirector, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -346,12 +349,11 @@ void SdrPageView::DrawLayer( SdrLayerID nID, OutputDevice* pGivenTarget, sdr::co
|
||||
aTemporaryPaintWindow.SetRedrawRegion(rExistingRegion);
|
||||
else
|
||||
aTemporaryPaintWindow.SetRedrawRegion(vcl::Region(rRect));
|
||||
|
||||
// patch the ExistingPageWindow
|
||||
pPreparedTarget->patchPaintWindow(aTemporaryPaintWindow);
|
||||
|
||||
// redraw the layer
|
||||
pPreparedTarget->RedrawLayer(&nID, pRedirector);
|
||||
pPreparedTarget->RedrawLayer(&nID, pRedirector, pPageFrame);
|
||||
|
||||
// restore the ExistingPageWindow
|
||||
pPreparedTarget->unpatchPaintWindow();
|
||||
@@ -377,7 +379,7 @@ void SdrPageView::DrawLayer( SdrLayerID nID, OutputDevice* pGivenTarget, sdr::co
|
||||
aTemporaryPaintWindow.SetRedrawRegion(rExistingRegion);
|
||||
}
|
||||
|
||||
aTemporaryPageWindow.RedrawLayer(&nID, pRedirector);
|
||||
aTemporaryPageWindow.RedrawLayer(&nID, pRedirector, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -387,7 +389,7 @@ void SdrPageView::DrawLayer( SdrLayerID nID, OutputDevice* pGivenTarget, sdr::co
|
||||
for(sal_uInt32 a(0L); a < PageWindowCount(); a++)
|
||||
{
|
||||
SdrPageWindow* pTarget = GetPageWindow(a);
|
||||
pTarget->RedrawLayer(&nID, pRedirector);
|
||||
pTarget->RedrawLayer(&nID, pRedirector, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +169,7 @@ public:
|
||||
*/
|
||||
void PaintLayer( const SdrLayerID _nLayerID,
|
||||
SwPrintData const*const pPrintData,
|
||||
SwPageFrame const& rPageFrame,
|
||||
const SwRect& _rRect,
|
||||
const Color* _pPageBackgrdColor,
|
||||
const bool _bIsPageRightToLeft = false,
|
||||
|
||||
@@ -3357,7 +3357,7 @@ void SwRootFrame::Paint(vcl::RenderContext& rRenderContext, SwRect const& rRect,
|
||||
const IDocumentDrawModelAccess& rIDDMA = pSh->getIDocumentDrawModelAccess();
|
||||
pSh->Imp()->PaintLayer( rIDDMA.GetHellId(),
|
||||
pPrintData,
|
||||
pPage->Frame(),
|
||||
*pPage, pPage->Frame(),
|
||||
&aPageBackgrdColor,
|
||||
pPage->IsRightToLeft(),
|
||||
&aSwRedirector );
|
||||
@@ -3404,7 +3404,7 @@ void SwRootFrame::Paint(vcl::RenderContext& rRenderContext, SwRect const& rRect,
|
||||
// OD 09.12.2002 #103045# - add 4th parameter for horizontal text direction.
|
||||
pSh->Imp()->PaintLayer( pSh->GetDoc()->getIDocumentDrawModelAccess().GetHeavenId(),
|
||||
pPrintData,
|
||||
pPage->Frame(),
|
||||
*pPage, pPage->Frame(),
|
||||
&aPageBackgrdColor,
|
||||
pPage->IsRightToLeft(),
|
||||
&aSwRedirector );
|
||||
@@ -7414,11 +7414,11 @@ void SwFrame::Retouch( const SwPageFrame * pPage, const SwRect &rRect ) const
|
||||
// <--
|
||||
|
||||
pSh->Imp()->PaintLayer( rIDDMA.GetHellId(), nullptr,
|
||||
rRetouche, &aPageBackgrdColor,
|
||||
*pPage, rRetouche, &aPageBackgrdColor,
|
||||
pPage->IsRightToLeft(),
|
||||
&aSwRedirector );
|
||||
pSh->Imp()->PaintLayer( rIDDMA.GetHeavenId(), nullptr,
|
||||
rRetouche, &aPageBackgrdColor,
|
||||
*pPage, rRetouche, &aPageBackgrdColor,
|
||||
pPage->IsRightToLeft(),
|
||||
&aSwRedirector );
|
||||
}
|
||||
@@ -7702,7 +7702,8 @@ Graphic SwFlyFrameFormat::MakeGraphic( ImageMap* pMap )
|
||||
// --> OD #i76669#
|
||||
SwViewObjectContactRedirector aSwRedirector( *pSh );
|
||||
// <--
|
||||
pImp->PaintLayer( rIDDMA.GetHellId(), nullptr, aOut, &aPageBackgrdColor,
|
||||
pImp->PaintLayer( rIDDMA.GetHellId(), nullptr,
|
||||
*pFlyPage, aOut, &aPageBackgrdColor,
|
||||
pFlyPage->IsRightToLeft(),
|
||||
&aSwRedirector );
|
||||
gProp.pSLines->PaintLines( pDev, gProp );
|
||||
@@ -7710,7 +7711,8 @@ Graphic SwFlyFrameFormat::MakeGraphic( ImageMap* pMap )
|
||||
pFly->Paint( *pDev, aOut );
|
||||
gProp.pSLines->PaintLines( pDev, gProp );
|
||||
// OD 30.08.2002 #102450# - add 3rd parameter
|
||||
pImp->PaintLayer( rIDDMA.GetHeavenId(), nullptr, aOut, &aPageBackgrdColor,
|
||||
pImp->PaintLayer( rIDDMA.GetHeavenId(), nullptr,
|
||||
*pFlyPage, aOut, &aPageBackgrdColor,
|
||||
pFlyPage->IsRightToLeft(),
|
||||
&aSwRedirector );
|
||||
gProp.pSLines->PaintLines( pDev, gProp );
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
#include "flyfrm.hxx"
|
||||
#include <vcl/svapp.hxx>
|
||||
#include <vcl/settings.hxx>
|
||||
#include <vcl/canvastools.hxx>
|
||||
|
||||
#include <basegfx/range/b2irectangle.hxx>
|
||||
|
||||
#include <IDocumentDrawModelAccess.hxx>
|
||||
|
||||
@@ -84,6 +87,7 @@ void SwViewShellImp::UnlockPaint()
|
||||
|
||||
void SwViewShellImp::PaintLayer( const SdrLayerID _nLayerID,
|
||||
SwPrintData const*const pPrintData,
|
||||
SwPageFrame const& rPageFrame,
|
||||
const SwRect& aPaintRect,
|
||||
const Color* _pPageBackgrdColor,
|
||||
const bool _bIsPageRightToLeft,
|
||||
@@ -137,7 +141,9 @@ void SwViewShellImp::PaintLayer( const SdrLayerID _nLayerID,
|
||||
SdrView &rSdrView = const_cast< SdrView & >(GetPageView()->GetView());
|
||||
rSdrView.setHideDraw( !pPrintData->IsPrintDraw() );
|
||||
}
|
||||
GetPageView()->DrawLayer( _nLayerID, pOutDev, pRedirector, aPaintRect.SVRect() );
|
||||
basegfx::B2IRectangle const pageFrame(
|
||||
vcl::unotools::b2IRectangleFromRectangle(rPageFrame.Frame().SVRect()));
|
||||
GetPageView()->DrawLayer(_nLayerID, pOutDev, pRedirector, aPaintRect.SVRect(), &pageFrame);
|
||||
pOutDev->Pop();
|
||||
|
||||
// reset background color of the outliner & default horiz. text dir.
|
||||
|
||||
Reference in New Issue
Block a user