include/svx/sdr/contact/displayinfo.hxx | 6 include/svx/sdrpagewindow.hxx | 4 include/svx/svdpagv.hxx | 3 include/tools/gen.hxx | 9 + include/vcl/canvastools.hxx | 3 svx/source/sdr/contact/displayinfo.cxx | 5 svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx | 17 ++ svx/source/svdraw/sdrpagewindow.cxx | 9 + svx/source/svdraw/svdpagv.cxx | 14 + sw/inc/swrect.hxx | 4 sw/source/core/access/accfrmobj.cxx | 7 sw/source/core/access/accmap.cxx | 147 ++++++++----------- sw/source/core/draw/dcontact.cxx | 61 +------ sw/source/core/inc/viewimp.hxx | 1 sw/source/core/layout/anchoreddrawobject.cxx | 7 sw/source/core/layout/fly.cxx | 4 sw/source/core/layout/paintfrm.cxx | 14 + sw/source/core/view/vdraw.cxx | 8 - sw/source/uibase/utlui/content.cxx | 2 vcl/source/helper/canvastools.cxx | 11 + 20 files changed, 181 insertions(+), 155 deletions(-)
New commits: commit ae06f4be6bbdebc10a88c386064d548848e57f80 Author: Michael Stahl <mst...@redhat.com> Date: Wed Dec 7 14:04:24 2016 +0100 tdf#101464 tdf#91260 sw: a11y for partially off-page drawing object The problem is that the drawing object in the bugdoc is not disposed when the document view is closed at a scroll position that does not show the page with the anchor frame of the drawing object, but does show the top of the following page, because it will only be disposed via its anchor page. SwAccessibleChild::GetBox() must take into account that the model-determined bounding box of the SdrObject can be partially outside the page where the object is anchored since commit a4dee94afed9ade6ac50237c8d99a6e49d3bebc1. Change-Id: I4276ee636d054320977e2a0ed0f69e53bbc778a3 diff --git a/sw/source/core/access/accfrmobj.cxx b/sw/source/core/access/accfrmobj.cxx index cf3e295..bc7f06d 100644 --- a/sw/source/core/access/accfrmobj.cxx +++ b/sw/source/core/access/accfrmobj.cxx @@ -258,6 +258,13 @@ SwRect SwAccessibleChild::GetBox( const SwAccessibleMap& rAccMap ) const else if( mpDrawObj ) { aBox = SwRect( mpDrawObj->GetCurrentBoundRect() ); + SwDrawContact const*const pContact(dynamic_cast<SwDrawContact const*>(::GetUserCall(mpDrawObj))); + // assume that a) the SwVirt* objects that don't have this are handled + // by the mpFrame case above b) for genuine SdrObject this must be set + // if it's connected to layout + assert(pContact); + // tdf#91260 drawing object may be partially off-page + aBox.Intersection(pContact->GetPageFrame()->Frame()); } else if ( mpWindow ) { commit 4cda288e06146416c762dbc82132a1083b86c630 Author: Michael Stahl <mst...@redhat.com> Date: Wed Dec 7 13:49:48 2016 +0100 sw: remove some copypasta in SwDrawContact with const_casts Change-Id: Ib9b1b578cb111ba47e04d844d5afa9984bac89f3 diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx index 1ee4787..2dad7ea 100644 --- a/sw/source/core/draw/dcontact.cxx +++ b/sw/source/core/draw/dcontact.cxx @@ -697,37 +697,9 @@ const SwAnchoredObject* SwDrawContact::GetAnchoredObj( const SdrObject* _pSdrObj return pRetAnchoredObj; } -SwAnchoredObject* SwDrawContact::GetAnchoredObj( SdrObject* _pSdrObj ) +SwAnchoredObject* SwDrawContact::GetAnchoredObj(SdrObject *const pSdrObj) { - // handle default parameter value - if ( !_pSdrObj ) - { - _pSdrObj = GetMaster(); - } - - OSL_ENSURE( _pSdrObj, - "<SwDrawContact::GetAnchoredObj(..)> - no object provided" ); - OSL_ENSURE( dynamic_cast<const SwDrawVirtObj*>( _pSdrObj) != nullptr || - ( dynamic_cast<const SdrVirtObj*>( _pSdrObj) == nullptr && dynamic_cast<const SwDrawVirtObj*>( _pSdrObj) == nullptr), - "<SwDrawContact::GetAnchoredObj(..)> - wrong object type object provided" ); - OSL_ENSURE( GetUserCall( _pSdrObj ) == this || _pSdrObj == GetMaster(), - "<SwDrawContact::GetAnchoredObj(..)> - provided object doesn't belongs to this contact" ); - - SwAnchoredObject* pRetAnchoredObj = nullptr; - - if ( _pSdrObj ) - { - if ( dynamic_cast<const SwDrawVirtObj*>( _pSdrObj) != nullptr ) - { - pRetAnchoredObj = &(static_cast<SwDrawVirtObj*>(_pSdrObj)->AnchoredObj()); - } - else if ( dynamic_cast<const SdrVirtObj*>( _pSdrObj) == nullptr && dynamic_cast<const SwDrawVirtObj*>( _pSdrObj) == nullptr) - { - pRetAnchoredObj = &maAnchoredDrawObj; - } - } - - return pRetAnchoredObj; + return const_cast<SwAnchoredObject*>(const_cast<SwDrawContact const*>(this)->GetAnchoredObj(pSdrObj)); } const SdrObject* SwDrawContact::GetMaster() const @@ -769,39 +741,22 @@ const SwFrame* SwDrawContact::GetAnchorFrame( const SdrObject* _pDrawObj ) const if ( !_pDrawObj || _pDrawObj == GetMaster() || ( !_pDrawObj->GetUserCall() && - GetUserCall( _pDrawObj ) == static_cast<const SwContact* const>(this) ) ) + GetUserCall( _pDrawObj ) == this ) ) { pAnchorFrame = maAnchoredDrawObj.GetAnchorFrame(); } - else if ( dynamic_cast<const SwDrawVirtObj*>( _pDrawObj) != nullptr ) - { - pAnchorFrame = static_cast<const SwDrawVirtObj*>(_pDrawObj)->GetAnchorFrame(); - } else { - OSL_FAIL( "<SwDrawContact::GetAnchorFrame(..)> - unknown drawing object." ); + assert(dynamic_cast<SwDrawVirtObj const*>(_pDrawObj) != nullptr); + pAnchorFrame = static_cast<const SwDrawVirtObj*>(_pDrawObj)->GetAnchorFrame(); } return pAnchorFrame; } -SwFrame* SwDrawContact::GetAnchorFrame( SdrObject* _pDrawObj ) -{ - SwFrame* pAnchorFrame = nullptr; - if ( !_pDrawObj || - _pDrawObj == GetMaster() || - ( !_pDrawObj->GetUserCall() && - GetUserCall( _pDrawObj ) == this ) ) - { - pAnchorFrame = maAnchoredDrawObj.AnchorFrame(); - } - else - { - OSL_ENSURE( dynamic_cast<const SwDrawVirtObj*>( _pDrawObj) != nullptr, - "<SwDrawContact::GetAnchorFrame(..)> - unknown drawing object." ); - pAnchorFrame = static_cast<SwDrawVirtObj*>(_pDrawObj)->AnchorFrame(); - } - return pAnchorFrame; +SwFrame* SwDrawContact::GetAnchorFrame(SdrObject *const pDrawObj) +{ + return const_cast<SwFrame *>(const_cast<SwDrawContact const*>(this)->GetAnchorFrame(pDrawObj)); } /// create a new 'virtual' drawing object. commit 689cead9e0837dc932e3a4cd765f7d319b529018 Author: Michael Stahl <mst...@redhat.com> Date: Tue Dec 6 22:59:40 2016 +0100 tdf#91260 svx, sw: don't paint off-page part of drawing object Since commit a4dee94afed9ade6ac50237c8d99a6e49d3bebc1 Writer 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 commit 8af09bf33291df2fb2bfbbd6e42f9bf074fcc4fc, 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 diff --git a/include/svx/sdr/contact/displayinfo.hxx b/include/svx/sdr/contact/displayinfo.hxx index b474cae..b498180 100644 --- a/include/svx/sdr/contact/displayinfo.hxx +++ b/include/svx/sdr/contact/displayinfo.hxx @@ -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; } diff --git a/include/svx/sdrpagewindow.hxx b/include/svx/sdrpagewindow.hxx index 0adc7e4..ca55b11 100644 --- a/include/svx/sdrpagewindow.hxx +++ b/include/svx/sdrpagewindow.hxx @@ -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); diff --git a/include/svx/svdpagv.hxx b/include/svx/svdpagv.hxx index c7ab36f..039dcd4 100644 --- a/include/svx/svdpagv.hxx +++ b/include/svx/svdpagv.hxx @@ -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; diff --git a/svx/source/sdr/contact/displayinfo.cxx b/svx/source/sdr/contact/displayinfo.cxx index fd6fc10..7904fa1 100644 --- a/svx/source/sdr/contact/displayinfo.cxx +++ b/svx/source/sdr/contact/displayinfo.cxx @@ -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) diff --git a/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx b/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx index 836925c..fca9e8d 100644 --- a/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx +++ b/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx @@ -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); diff --git a/svx/source/svdraw/sdrpagewindow.cxx b/svx/source/svdraw/sdrpagewindow.cxx index e6db452..292bbde 100644 --- a/svx/source/svdraw/sdrpagewindow.cxx +++ b/svx/source/svdraw/sdrpagewindow.cxx @@ -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); } diff --git a/svx/source/svdraw/svdpagv.cxx b/svx/source/svdraw/svdpagv.cxx index fabe609..544bf48 100644 --- a/svx/source/svdraw/svdpagv.cxx +++ b/svx/source/svdraw/svdpagv.cxx @@ -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); } } } diff --git a/sw/source/core/inc/viewimp.hxx b/sw/source/core/inc/viewimp.hxx index 465a68f..87b7b24 100644 --- a/sw/source/core/inc/viewimp.hxx +++ b/sw/source/core/inc/viewimp.hxx @@ -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, diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx index 34f2f2dc..90cfe69 100644 --- a/sw/source/core/layout/paintfrm.cxx +++ b/sw/source/core/layout/paintfrm.cxx @@ -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 ); diff --git a/sw/source/core/view/vdraw.cxx b/sw/source/core/view/vdraw.cxx index 2f20aeb..eb4ad07 100644 --- a/sw/source/core/view/vdraw.cxx +++ b/sw/source/core/view/vdraw.cxx @@ -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. commit b346439637b7d03a3eb1d6e67dfb585b357567f4 Author: Michael Stahl <mst...@redhat.com> Date: Mon Dec 5 17:26:06 2016 +0100 tdf#101464 sw: if a drawing object is moved, notify SwAccessibleMap When a drawing object is moved from one SwPageFrame to another, of course its position is going to change, but unfortunately nobody tells the a11y code about it, so it may happen that the document view is closed but there is still an entry in SwAccessibleMap::mpShapeMap referencing the possibly dead SdrObject. So we need to add a notification somewhere here: 0 in SwSortedObjs::Remove(SwAnchoredObject&) (this=0x398fd60, _rAnchoredObj=...) at sw/source/core/layout/sortedobjs.cxx:234 1 in SwPageFrame::RemoveDrawObjFromPage(SwAnchoredObject&) (this=0x3fc1130, _rToRemoveObj=...) at sw/source/core/layout/flylay.cxx:849 2 in SwAnchoredDrawObject::RegisterAtCorrectPage() (this=0x4251040) at sw/source/core/layout/anchoreddrawobject.cxx:841 3 in SwAnchoredObject::SetVertPosOrientFrame(SwLayoutFrame const&) (this=this@entry=0x4251040, _rVertPosOrientFrame=...) at sw/source/core/layout/anchoredobject.cxx:194 4 in SwAnchoredDrawObject::MakeObjPosAnchoredAtPara() (this=this@entry=0x4251040) at sw/source/core/layout/anchoreddrawobject.cxx:419 5 in SwAnchoredDrawObject::MakeObjPos() (this=0x4251040) at sw/source/core/layout/anchoreddrawobject.cxx:313 6 in SwObjectFormatter::FormatObj_(SwAnchoredObject&) (this=this@entry=0x35da590, _rAnchoredObj=...) at sw/source/core/layout/objectformatter.cxx:375 For comparison, for text frames the stack looks a bit different and the a11y notification happens here: 0 in SwAccessibleMap::InvalidatePosOrSize(SwFrame const*, SdrObject const*, vcl::Window*, SwRect const&) (this=0x36a92e0, pFrame=pFrame@entry=0x4845b30, pObj=pObj@entry=0x0, pWindow=pWindow@entry=0x0, rOldBox=SwRect = {...}) at sw/source/core/access/accmap.cxx:2352 1 in SwViewShellImp::MoveAccessible(SwFrame const*, SdrObject const*, SwRect const&) (this=this@entry=0x45a5ea0, pFrame=pFrame@entry=0x4845b30, pObj=pObj@entry=0x0, rOldFrame=SwRect = {...}) at sw/source/core/view/viewimp.cxx:324 2 in SwViewShellImp::AddAccessibleFrame(SwFrame const*) (this=0x45a5ea0, pFrame=pFrame@entry=0x4845b30) at sw/source/core/inc/viewimp.hxx:298 3 in SwPageFrame::MoveFly(SwFlyFrame*, SwPageFrame*) (this=0x4597d10, pToMove=pToMove@entry=0x4845b30, pDest=pDest@entry=0x480cb40) at sw/source/core/layout/flylay.cxx:759 4 in SwFlyAtContentFrame::RegisterAtCorrectPage() (this=0x4845b30) at sw/source/core/layout/flycnt.cxx:1399 5 in SwAnchoredObject::SetVertPosOrientFrame(SwLayoutFrame const&) (this=this@entry=0x4845c18, _rVertPosOrientFrame=...) at sw/source/core/layout/anchoredobject.cxx:194 6 in SwFlyAtContentFrame::MakeObjPos() (this=0x4845b30) at sw/source/core/layout/flycnt.cxx:1433 7 in SwFlyFreeFrame::MakeAll(OutputDevice*) (this=this@entry=0x4845b30) at sw/source/core/layout/flylay.cxx:186 8 in SwFlyAtContentFrame::MakeAll(OutputDevice*) (this=0x4845b30, pRenderContext=0x459ea80) at sw/source/core/layout/flycnt.cxx:389 9 in SwFrame::PrepareMake(OutputDevice*) (this=0x4845b30, pRenderContext=0x459ea80) at sw/source/core/layout/calcmove.cxx:345 10 in SwFlyFrame::Calc(OutputDevice*) const (this=<optimized out>, pRenderContext=<optimized out>) at sw/source/core/layout/fly.cxx:2641 Change-Id: Iac33a7527dd514f150b2f2f4b0daa0a8a1fc23b6 diff --git a/sw/source/core/layout/anchoreddrawobject.cxx b/sw/source/core/layout/anchoreddrawobject.cxx index 9559b30..acaebcb 100644 --- a/sw/source/core/layout/anchoreddrawobject.cxx +++ b/sw/source/core/layout/anchoreddrawobject.cxx @@ -31,6 +31,7 @@ #include <DocumentSettingManager.hxx> #include <IDocumentState.hxx> #include <txtfly.hxx> +#include <viewimp.hxx> using namespace ::com::sun::star; @@ -113,6 +114,12 @@ SwPosNotify::~SwPosNotify() mpAnchoredDrawObj->AnchorFrame()->InvalidatePos(); } } + // tdf#101464 notify SwAccessibleMap about new drawing object position + if (mpOldPageFrame->getRootFrame()->IsAnyShellAccessible()) + { + mpOldPageFrame->getRootFrame()->GetCurrShell()->Imp()->MoveAccessible( + nullptr, mpAnchoredDrawObj->GetDrawObj(), maOldObjRect); + } } // --> #i32795# commit 474051a0efad9d4e7825ab78625b0fc561837c68 Author: Michael Stahl <mst...@redhat.com> Date: Fri Dec 2 16:00:53 2016 +0100 sw: fix indentation Change-Id: Id08434483e0d3f71d9770be7627250c74c142f90 diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx index 523e1a1..1ab6bd1 100644 --- a/sw/source/core/layout/fly.cxx +++ b/sw/source/core/layout/fly.cxx @@ -2135,7 +2135,9 @@ void SwFrame::AppendDrawObj( SwAnchoredObject& _rNewObj ) { SwRootFrame* pLayout = getRootFrame(); if( pLayout && pLayout->IsAnyShellAccessible() ) - pSh->Imp()->AddAccessibleObj( _rNewObj.GetDrawObj() ); + { + pSh->Imp()->AddAccessibleObj( _rNewObj.GetDrawObj() ); + } } assert(!mpDrawObjs || mpDrawObjs->is_sorted()); commit 69062c3255f136d13444e1a48a3a4126444a317f Author: Michael Stahl <mst...@redhat.com> Date: Fri Dec 2 15:49:02 2016 +0100 SwContentTree: another wrong assert Change-Id: Ie00f89275662d46cf8434b71f0a3c4b5425a18e2 diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 56cd415..dd3d339 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -1320,7 +1320,7 @@ void SwContentTree::RequestingChildren( SvTreeListEntry* pParent ) else { pChild = Prev(pChild); - assert(!pChild || dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pChild->GetUserData()))); + assert(!pChild || lcl_IsContentType(pChild) || dynamic_cast<SwOutlineContent*>(static_cast<SwTypeNumber*>(pChild->GetUserData()))); while(pChild && lcl_IsContent(pChild) && !(static_cast<SwOutlineContent*>(pChild->GetUserData())->GetOutlineLevel() < nLevel) commit 025f1c8d53b5f89777b016c48f8dad4e38294efc Author: Michael Stahl <mst...@redhat.com> Date: Fri Dec 2 11:59:39 2016 +0100 simplify SwAccessibleMap::GetContext() Change-Id: I78e7e25c12181fb854134d92059ddd083261be1e diff --git a/sw/source/core/access/accmap.cxx b/sw/source/core/access/accmap.cxx index 22fa43f..d2090e0 100644 --- a/sw/source/core/access/accmap.cxx +++ b/sw/source/core/access/accmap.cxx @@ -1914,43 +1914,40 @@ uno::Reference< XAccessible> SwAccessibleMap::GetContext( const SwFrame *pFrame, default: break; } xAcc = pAcc; + assert(xAcc.is()); - OSL_ENSURE( xAcc.is(), "unknown frame type" ); - if( xAcc.is() ) + if( aIter != mpFrameMap->end() ) { - if( aIter != mpFrameMap->end() ) - { - (*aIter).second = xAcc; - } - else - { - SwAccessibleContextMap_Impl::value_type aEntry( pFrame, xAcc ); - mpFrameMap->insert( aEntry ); - } + (*aIter).second = xAcc; + } + else + { + SwAccessibleContextMap_Impl::value_type aEntry( pFrame, xAcc ); + mpFrameMap->insert( aEntry ); + } - if( pAcc->HasCursor() && - !AreInSameTable( mxCursorContext, pFrame ) ) - { - // If the new context has the focus, and if we know - // another context that had the focus, then the focus - // just moves from the old context to the new one. We - // then have to send a focus event and a caret event for - // the old context. We have to do that now, - // because after we have left this method, anyone might - // call getStates for the new context and will get a - // focused state then. Sending the focus changes event - // after that seems to be strange. However, we cannot - // send a focus event for the new context now, because - // no one except us knows it. In any case, we remember - // the new context as the one that has the focus - // currently. - - xOldCursorAcc = mxCursorContext; - mxCursorContext = xAcc; - - bOldShapeSelected = mbShapeSelected; - mbShapeSelected = false; - } + if( pAcc->HasCursor() && + !AreInSameTable( mxCursorContext, pFrame ) ) + { + // If the new context has the focus, and if we know + // another context that had the focus, then the focus + // just moves from the old context to the new one. We + // then have to send a focus event and a caret event for + // the old context. We have to do that now, + // because after we have left this method, anyone might + // call getStates for the new context and will get a + // focused state then. Sending the focus changes event + // after that seems to be strange. However, we cannot + // send a focus event for the new context now, because + // no one except us knows it. In any case, we remember + // the new context as the one that has the focus + // currently. + + xOldCursorAcc = mxCursorContext; + mxCursorContext = xAcc; + + bOldShapeSelected = mbShapeSelected; + mbShapeSelected = false; } } } @@ -2014,25 +2011,20 @@ uno::Reference< XAccessible> SwAccessibleMap::GetContext( aShapeInfo, mpShapeMap->GetInfo() ); } xAcc = pAcc.get(); - - OSL_ENSURE( xAcc.is(), "unknown shape type" ); - if( xAcc.is() ) + assert(xAcc.is()); + pAcc->Init(); + if( aIter != mpShapeMap->end() ) { - pAcc->Init(); - if( aIter != mpShapeMap->end() ) - { - (*aIter).second = xAcc; - } - else - { - SwAccessibleShapeMap_Impl::value_type aEntry( pObj, - xAcc ); - mpShapeMap->insert( aEntry ); - } - // TODO: focus!!! + (*aIter).second = xAcc; + } + else + { + SwAccessibleShapeMap_Impl::value_type aEntry( pObj, + xAcc ); + mpShapeMap->insert( aEntry ); } - if (xAcc.is()) - AddGroupContext(pObj, xAcc); + // TODO: focus!!! + AddGroupContext(pObj, xAcc); } } } commit 3de93c85c7d7a0cf47000311757265c9bb7acd9d Author: Michael Stahl <mst...@redhat.com> Date: Fri Dec 2 11:52:58 2016 +0100 simplify SwAccessibleMap::GetPreviewPageSize() Change-Id: I92a6281623e536a37ded559bcbe5e833adc881bb diff --git a/sw/source/core/access/accmap.cxx b/sw/source/core/access/accmap.cxx index 95c1a4b..22fa43f 100644 --- a/sw/source/core/access/accmap.cxx +++ b/sw/source/core/access/accmap.cxx @@ -3319,19 +3319,11 @@ void SwAccessibleMap::GetMapMode( const Point& _rPoint, _orMapMode = aMapMode; } -Size SwAccessibleMap::GetPreviewPageSize( sal_uInt16 _nPreviewPageNum ) const +Size SwAccessibleMap::GetPreviewPageSize(sal_uInt16 const nPreviewPageNum) const { - OSL_ENSURE( mpVSh->IsPreview(), "no page preview accessible." ); - OSL_ENSURE( mpVSh->IsPreview() && ( mpPreview != nullptr ), - "missing accessible preview data at page preview" ); - if ( mpVSh->IsPreview() && ( mpPreview != nullptr ) ) - { - return mpVSh->PagePreviewLayout()->GetPreviewPageSizeByPageNum( _nPreviewPageNum ); - } - else - { - return Size( 0, 0 ); - } + assert(mpVSh->IsPreview()); + assert(mpPreview != nullptr); + return mpVSh->PagePreviewLayout()->GetPreviewPageSizeByPageNum(nPreviewPageNum); } /** method to build up a new data structure of the accessible paragraphs, commit eff042edd76c141eaa81664bca0e4822aae8d2df Author: Michael Stahl <mst...@redhat.com> Date: Fri Dec 2 11:51:22 2016 +0100 SwAccessibleMap convert some obvious OSL_ENSURE to assert Change-Id: Ie28b4d9febab28ded47d1532f38584513d78246a diff --git a/sw/source/core/access/accmap.cxx b/sw/source/core/access/accmap.cxx index 411eaed..95c1a4b 100644 --- a/sw/source/core/access/accmap.cxx +++ b/sw/source/core/access/accmap.cxx @@ -314,7 +314,7 @@ SwAccessibleObjShape_Impl } ++aIter; } - OSL_ENSURE( pSelShape == pShape, "copying shapes went wrong!" ); + assert(pSelShape == pShape); } if( pSelStart ) @@ -552,9 +552,9 @@ void SwAccessibleEventList_Impl::MoveMissingXAccToEnd() else ++li; } - OSL_ENSURE(size() + lstEvent.size() == nSize ,""); + assert(size() + lstEvent.size() == nSize); maEvents.insert(end(),lstEvent.begin(),lstEvent.end()); - OSL_ENSURE(size() == nSize ,""); + assert(size() == nSize); } struct SwAccessibleChildFunc @@ -751,7 +751,7 @@ void SwAccPreviewData::Update( const SwAccessibleMap& rAccMap, void SwAccPreviewData::InvalidateSelection( const SwPageFrame* _pSelectedPageFrame ) { mpSelPage = _pSelectedPageFrame; - OSL_ENSURE( mpSelPage, "selected page not found" ); + assert(mpSelPage); } struct ContainsPredicate @@ -905,8 +905,7 @@ void SwAccessibleMap::FireEvent( const SwAccessibleEvent_Impl& rEvent ) rEvent.GetOldBox() ); break; case SwAccessibleEvent_Impl::DISPOSE: - OSL_ENSURE( xAccImpl.is(), - "dispose event has been stored" ); + assert(!"dispose event has been stored"); break; case SwAccessibleEvent_Impl::INVALID_ATTR: // nothing to do here - handled above @@ -969,7 +968,7 @@ void SwAccessibleMap::AppendEvent( const SwAccessibleEvent_Impl& rEvent ) if( aIter != mpEventMap->end() ) { SwAccessibleEvent_Impl aEvent( *(*aIter).second ); - OSL_ENSURE( aEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE, + assert( aEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE && "dispose events should not be stored" ); bool bAppendEvent = true; switch( rEvent.GetType() ) @@ -1062,8 +1061,8 @@ void SwAccessibleMap::InvalidateCursorPosition( { SwAccessibleContext *pAccImpl = static_cast< SwAccessibleContext *>( rAcc.get() ); - OSL_ENSURE( pAccImpl, "no caret context" ); - OSL_ENSURE( pAccImpl->GetFrame(), "caret context is disposed" ); + assert(pAccImpl); + assert(pAccImpl->GetFrame()); if( GetShell()->ActionPend() ) { SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES, @@ -1770,7 +1769,7 @@ uno::Reference< XAccessible > SwAccessibleMap::GetDocumentView_( } #if OSL_DEBUG_LEVEL > 0 - OSL_ENSURE( !mpFrameMap->mbLocked, "Map is locked" ); + assert(!mpFrameMap->mbLocked); mpFrameMap->mbLocked = true; #endif @@ -3026,8 +3025,8 @@ void SwAccessibleMap::UpdatePreview( const std::vector<PreviewPage*>& _rPreviewP void SwAccessibleMap::InvalidatePreviewSelection( sal_uInt16 nSelPage ) { - OSL_ENSURE( GetShell()->IsPreview(), "no preview?" ); - OSL_ENSURE( mpPreview != nullptr, "no preview data?" ); + assert(GetShell()->IsPreview()); + assert(mpPreview != nullptr); mpPreview->InvalidateSelection( GetShell()->GetLayout()->GetPageByPageNum( nSelPage ) ); @@ -3314,8 +3313,7 @@ void SwAccessibleMap::GetMapMode( const Point& _rPoint, MapMode aMapMode = GetShell()->GetWin()->GetMapMode(); if( GetShell()->IsPreview() ) { - OSL_ENSURE( mpPreview != nullptr, "need preview data" ); - + assert(mpPreview != nullptr); mpPreview->AdjustMapMode( aMapMode, _rPoint ); } _orMapMode = aMapMode; @@ -3534,8 +3532,7 @@ void SwAccessibleMap::InvalidateTextSelectionOfAllParas() const SwRect& SwAccessibleMap::GetVisArea() const { - OSL_ENSURE( !GetShell()->IsPreview() || (mpPreview != nullptr), - "preview without preview data?" ); + assert(!GetShell()->IsPreview() || (mpPreview != nullptr)); return GetShell()->IsPreview() ? mpPreview->GetVisArea() commit f9f16649ff4efc5c06e61cd72a160090499fe24d Author: Michael Stahl <mst...@redhat.com> Date: Fri Dec 2 11:31:16 2016 +0100 Revert "sw: partially revert commit d0b09f41efe938e94a84e783c9ff5742edcbfba8" This reverts commit 2934f6bcc75c781cdf9e614b9d7d8533eb680b3f. What i forgot is that if the mpFrameMap assertion fails in JunitTest_toolkit_unoapi_1, then a segfault is likely to follow, probably due to some use-after-free, so this really should be an assert(). Change-Id: I696e18be44632089304dfed2b88ec4b9a580ba16 diff --git a/sw/source/core/access/accmap.cxx b/sw/source/core/access/accmap.cxx index 02b7a49..411eaed 100644 --- a/sw/source/core/access/accmap.cxx +++ b/sw/source/core/access/accmap.cxx @@ -1690,8 +1690,6 @@ SwAccessibleMap::~SwAccessibleMap() { osl::MutexGuard aGuard( maMutex ); #if OSL_DEBUG_LEVEL > 0 - SAL_WARN_IF(!(!mpFrameMap || mpFrameMap->empty()), "sw.a11y", - "Frame map should be empty after disposing the root frame"); if( mpFrameMap ) { SwAccessibleContextMap_Impl::iterator aIter = mpFrameMap->begin(); @@ -1707,8 +1705,8 @@ SwAccessibleMap::~SwAccessibleMap() ++aIter; } } - SAL_WARN_IF(!(!mpShapeMap || mpShapeMap->empty()), "sw.a11y", - "Object map should be empty after disposing the root frame"); + assert((!mpFrameMap || mpFrameMap->empty()) && + "Frame map should be empty after disposing the root frame"); if( mpShapeMap ) { SwAccessibleShapeMap_Impl::iterator aIter = mpShapeMap->begin(); @@ -1724,6 +1722,8 @@ SwAccessibleMap::~SwAccessibleMap() ++aIter; } } + assert((!mpShapeMap || mpShapeMap->empty()) && + "Object map should be empty after disposing the root frame"); #endif delete mpFrameMap; mpFrameMap = nullptr; commit 1980d92a78445958ff57e26d065b9c471e3fd38d Author: Michael Stahl <mst...@redhat.com> Date: Tue Dec 6 22:38:24 2016 +0100 vcl: add b2IPointFromPoint and b2IRectangleFromRectangle Change-Id: I3e964c0e5b0d54784cd392c6b430c6f30b7e6b75 diff --git a/include/vcl/canvastools.hxx b/include/vcl/canvastools.hxx index 196e7a1..aedcff7 100644 --- a/include/vcl/canvastools.hxx +++ b/include/vcl/canvastools.hxx @@ -24,6 +24,7 @@ #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/rendering/XColorSpace.hpp> #include <basegfx/numeric/ftools.hxx> +#include <basegfx/range/b2irectangle.hxx> #include <vcl/dllapi.h> @@ -165,6 +166,8 @@ namespace vcl // basegfx::B2I Point VCL_DLLPUBLIC pointFromB2IPoint( const basegfx::B2IPoint& ); Rectangle VCL_DLLPUBLIC rectangleFromB2IRectangle( const basegfx::B2IRange& ); + basegfx::B2IPoint VCL_DLLPUBLIC b2IPointFromPoint(const Point&); + basegfx::B2IRectangle VCL_DLLPUBLIC b2IRectangleFromRectangle(const Rectangle&); } } diff --git a/vcl/source/helper/canvastools.cxx b/vcl/source/helper/canvastools.cxx index a25b983..a81ec6b 100644 --- a/vcl/source/helper/canvastools.cxx +++ b/vcl/source/helper/canvastools.cxx @@ -362,6 +362,11 @@ namespace vcl rPoint.getY() ); } + basegfx::B2IPoint b2IPointFromPoint(Point const& rPoint) + { + return basegfx::B2IPoint(rPoint.X(), rPoint.Y()); + } + Rectangle rectangleFromB2IRectangle( const basegfx::B2IRange& rRect ) { return ::Rectangle( rRect.getMinX(), @@ -370,6 +375,12 @@ namespace vcl rRect.getMaxY() ); } + basegfx::B2IRectangle b2IRectangleFromRectangle(Rectangle const& rRect) + { + return basegfx::B2IRectangle(rRect.Left(), rRect.Top(), + rRect.Right(), rRect.Bottom()); + } + basegfx::B2DVector b2DSizeFromSize( const ::Size& rSize ) { return basegfx::B2DVector( rSize.Width(), commit c43fdd0d179b2c0e8e3cb890eb2694723ff87b4c Author: Michael Stahl <mst...@redhat.com> Date: Tue Dec 6 22:49:09 2016 +0100 tools: document our favorite rectangle class too Change-Id: Id7698a1e2a8fc1ca6bf35868311fc5b284d45145 diff --git a/include/tools/gen.hxx b/include/tools/gen.hxx index 142f82c..bebc350 100644 --- a/include/tools/gen.hxx +++ b/include/tools/gen.hxx @@ -330,6 +330,15 @@ inline std::basic_ostream<charT, traits> & operator <<( #define RECT_MAX LONG_MAX #define RECT_MIN LONG_MIN +/// Note: this class is a true marvel of engineering: because the author +/// could not decide whether it's better to have a closed or half-open +/// interval, they just implemented *both* in the same class! +/// +/// If you have the misfortune of having to use this class, don't immediately +/// despair but first take note that the uppercase GetWidth() / GetHeight() +/// etc. methods interpret the interval as closed, while the lowercase +/// getWidth() / getHeight() etc. methods interpret the interval as half-open. +/// Ok, now is the time for despair. class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Rectangle { public: commit 9fb1919a65267dea1a07a76c4e8d32901dc0822a Author: Michael Stahl <mst...@redhat.com> Date: Tue Dec 6 22:40:00 2016 +0100 sw: document our second favorite rectangle class a little Change-Id: I0d7dbfd0bc2d563a39c560dbebfd400cb7c35faa diff --git a/sw/inc/swrect.hxx b/sw/inc/swrect.hxx index e2be41a..2e0b0b2 100644 --- a/sw/inc/swrect.hxx +++ b/sw/inc/swrect.hxx @@ -26,6 +26,10 @@ class SvStream; +/// *Of course* Writer needs its own rectangles. +/// This is half-open so m_Point.X() + m_Size.getWidth() is *not* included. +/// Note the tools Rectangle is (usually? sometimes?) closed so there's a +/// SVRect() to subtract 1 for the conversion. class SAL_WARN_UNUSED SwRect { Point m_Point; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits