diff options
author | Noel Power <noel.power@suse.com> | 2012-11-27 17:56:33 +0000 |
---|---|---|
committer | Noel Power <noel.power@suse.com> | 2012-11-28 14:50:25 +0000 |
commit | c4e649f0cd013e86adbd794859bcc3cb9ee3aa61 (patch) | |
tree | 41038de6c78c01a15e730d218ea5a61a28de8fdd /svx/source/svdraw/svdmrkv.cxx | |
parent | 24c0e7ed9971663dfcaf9c4c1182dd6da9df005f (diff) |
Sync draw object to calc grid for better alignment when zooming
There can be some serious rounding errors involved when calculating where to
draw the grid lines for the various row heights in a document. This can be
especially true for a document that has many different row heights.
This results in draw objects appearing to move relative to the grid line at
different zoom levels. This patch attempts to fix this problem adjusting
the position of the shapes as they are drawn to ensure their position
relative to grid appears to be stable. We do this by translating the position
of the shape to the corrosponding position of it's cell anchor. Of course not
all shapes are cell anchored and in this case we position the shape relative
a temporary synthesized cell anchor.
The patch essentially does the following
a) calculates the offset to be applied for each shape at the current zoom level
to ensure that the shape will be drawn relative to the correct cell grid
see drwlayer.cxx, drawview.cxx & gridwin3.cxx, svdobj.[ch]xx
b) apply the offset in the drawing layer for each of the different drawing
primitives see svx/source/sdr/contact/*
c) making sure the position and size of the newly created shape ( at any zoom
level ) are still as expected when zoom level is changed.
see. sc/source/ui/drawfunc/fuco*.cxx &
d) making sure that overlays and handles are displayed at the correct position
see svx/source/svdraw/*
it could also be that a full blown transform might be needed to additionally
scale the object ( to ensure that the edges of the object stay stable relative
to ajacent grid lines ) If necessary we could do that in a later step.
Change-Id: I02232f8ba192d58dbf96b80adf66c281cd0f65e8
Diffstat (limited to 'svx/source/svdraw/svdmrkv.cxx')
-rw-r--r-- | svx/source/svdraw/svdmrkv.cxx | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx index d789f2904d92..dcf57db1301f 100644 --- a/svx/source/svdraw/svdmrkv.cxx +++ b/svx/source/svdraw/svdmrkv.cxx @@ -440,9 +440,9 @@ sal_Bool SdrMarkView::BegMarkGluePoints(const Point& rPnt, sal_Bool bUnmark) BrkAction(); DBG_ASSERT(0L == mpMarkGluePointsOverlay, "SdrMarkView::BegMarkObj: There exists a mpMarkGluePointsOverlay (!)"); + basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y()); mpMarkGluePointsOverlay = new ImplMarkingOverlay(*this, aStartPos, bUnmark); - aDragStat.Reset(rPnt); aDragStat.NextPoint(); aDragStat.SetMinMove(nMinMovLog); @@ -616,10 +616,13 @@ void SdrMarkView::SetMarkHandles() } } + // apply calc offset to marked object rect + // ( necessary for handles to be displayed in + // correct position ) + Point aGridOff = GetGridOffset(); if (bFrmHdl) { Rectangle aRect(GetMarkedObjRect()); - // #i33755# const sal_Bool bHideHandlesWhenInTextEdit( ((SdrView*)this)->IsTextEdit() @@ -648,6 +651,7 @@ void SdrMarkView::SetMarkHandles() { SdrHdl* pHdl=aHdl.GetHdl(i); pHdl->SetObj(pMarkedObj); + pHdl->SetPos( pHdl->GetPos() + aGridOff ); pHdl->SetPageView(pMarkedPV); pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0)); } @@ -705,6 +709,7 @@ void SdrMarkView::SetMarkHandles() for (sal_uIntPtr i=nSiz0; i<nSiz1; i++) { SdrHdl* pHdl=aHdl.GetHdl(i); + pHdl->SetPos( pHdl->GetPos() + aGridOff ); pHdl->SetObj(pObj); pHdl->SetPageView(pPV); pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0)); @@ -1520,6 +1525,8 @@ SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nT const bool bTXT(pObj->ISA(SdrTextObj) && ((SdrTextObj*)pObj)->IsTextFrame()); SdrObject* pRet=NULL; Rectangle aRect(pObj->GetCurrentBoundRect()); + // hack for calc grid sync + aRect += pObj->GetGridOffset(); sal_uInt16 nTol2(nTol); // double tolerance for OLE, text frames and objects in @@ -1872,25 +1879,47 @@ Rectangle SdrMarkView::GetMarkedObjBoundRect() const SdrMark* pM=GetSdrMarkByIndex(nm); SdrObject* pO=pM->GetMarkedSdrObj(); Rectangle aR1(pO->GetCurrentBoundRect()); + // Ensure marked area includes the calc offset + // ( if applicable ) to sync to grid + aR1 += pO->GetGridOffset(); if (aRect.IsEmpty()) aRect=aR1; else aRect.Union(aR1); } return aRect; } +Point SdrMarkView::GetGridOffset() const +{ + Point aOffset; + // calculate the area occupied by the union of each marked object + // ( synced to grid ) and compare to the same unsynced area to calculate + // the offset. Hopefully that's the sensible thing to do + const Rectangle& aGroupSyncedRect = GetMarkedObjRect(); + aOffset = aGroupSyncedRect.TopLeft() - aMarkedObjRectNoOffset.TopLeft(); + return aOffset; +} + const Rectangle& SdrMarkView::GetMarkedObjRect() const { if (bMarkedObjRectDirty) { ((SdrMarkView*)this)->bMarkedObjRectDirty=sal_False; Rectangle aRect; + Rectangle aRect2; for (sal_uIntPtr nm=0; nm<GetMarkedObjectCount(); nm++) { SdrMark* pM=GetSdrMarkByIndex(nm); SdrObject* pO=pM->GetMarkedSdrObj(); Rectangle aR1(pO->GetSnapRect()); + // apply calc offset to marked object rect + // ( necessary for handles to be displayed in + // correct position ) + if (aRect2.IsEmpty()) aRect2=aR1; + else aRect2.Union( aR1 ); + aR1 += pO->GetGridOffset(); if (aRect.IsEmpty()) aRect=aR1; else aRect.Union(aR1); } ((SdrMarkView*)this)->aMarkedObjRect=aRect; + ((SdrMarkView*)this)->aMarkedObjRectNoOffset=aRect2; } return aMarkedObjRect; } |