summaryrefslogtreecommitdiff
path: root/svx/source/svdraw
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2018-10-12 11:13:09 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2018-11-27 11:33:10 +0100
commitd464d505fbf6e53a38afdd3661d320fac8c760d6 (patch)
tree3bf7db8591172bf948198f19d36df5df886486bb /svx/source/svdraw
parent3e1e2b6687b0259ae28441cc0d314de0d908776b (diff)
Refactor calc non-linear ViewToDevice transform
This change solves the non-linear World-To-View trans- formation that calc uses due to it's screen rendering as good as currently possible (AFAIK). Calcv view is layouted on pixel base (due to better homogen distances and full pixel lines between cells), but this leads to having a non-linear transformation between discrete units (pixels, view) and model coordinates (World). In principle, each cell has it's own (so called) ViewTransformation -> the position on screen depends on the mappings of all cells top/left from it. This is obvioulsly non-linear and can sometimes be seen by producing 'offset' errors when many cells (small and thin) are shown in low zoom stages. No better solution for this comes to mind easily. The extremes are - on the one hand AntiAliasing the whole calc edit view and accept 'unsharp/AAed' lines - on the other hand what we have now. Maybe a future solution could find a mapping that gets close to linear mapping for the full view. On the long run this state is hard to keep correct. Even with this extended solution the mapping of SdrObjects spawning mutiple cells is assumed 'linear' in that area - which is in reality currently not the case (!) Note: This is only true for the screen visualization, print and/or PDF export do not do that pixel-based layouting. Note2: This mechanism is general in DrawingLayer (look for '.*GridOffset.*'. If it is deactivated by providing no offsets, the result is the unchanged, linear mapping. First step: Add interfaces to get a possible GridOffset at ViewObjectContact. There it belongs, we have a view- dependent offset per object and view. Add mechanisms to create on-demand and reach back to the view (aka calc's derivation of it). Second step: Implement the on-demand creation, adapt to use it in ViewObjectContact::getPrimitive2DSequence, add stuff to reset on zoom change, disable temporarily old mechanism -> paint already works. Need to adapt the places from old mechanism where the GridOffset was used, but no longer the geometry creations. Third step: Isolated and disabled old mechanism (by already removing SetGridOffset). Marked all places that possibly need change with '//Z' tag. Main work now will be to adapt in the SdrView implementations in svx to know about having a SdrObject-dependent ViewTransformation at all (currently not known, was hard-coded at some places from the old code, ViewTransformation set as MapMode at a target OutputDevice, not member at SdrView at all...). Fourth step: Adapt the Handles and OverlayObjects to use an evtl. existing GridOffset. The mechanism is that the SdrHdl(s) can be seen as 'Model-Objects', these get converted to OverlayObjects in the ::CreateB2dIAObject() implementations, for all SdrMarkView and SdrPageView, so this is the place where the ObjectContact is known (the SdrPageWindow *is* a ObjectContact) and the view- dependent GridOffset can be calculated per SdrObject. I modified OverlayObject to be able to work with a set Offset that embeds the created visualization using this additionally. Handles get now correctly set and have a working HitTest (due to that already using the primitives). Some inter- action stuff already working, some will need more adaption. We simply have no concept for this stuff... Refactored to not get dependencies to SdrObject in ObjectContact. Fifth Step: Make HitTest work by adding the View-And- Object dependent GridOffset in the View when HitTest is triggered. This is in SdrMarkView::CheckSingleSdrObjectHit where pObj->GetCurrentBoundRect() is used that gets the view-independent form. To make HitTest work, add a possible GridOffset. Since this will be necessary more often in SdrView hierarchy, added a tooling method (getPossibleGridOffsetForSdrObject) at that level after checking that at that level will be reachable at all potential spots. Inside that method the correct ObjectContact will be identified and the object-specific offset requested there. Sixth Step: Adaptions and started some cleanups. Still some adaptions needed: - After creation of new object, need to relocate from used GridOffset setting to WorldCoordinates - Interactions, e.g. start with dragging handles or full object/points Seventh Step: React on EndCreateObj. Here, the created SdrObject is in model coordinates and needs to be adapted to evtl. GridOffset. This is 'tricky' due to calculating the possible offset based on new coordinates 'close' to the target position, but may be in the wrong cell. Nonetheless this is the best we can do here. Last (hopefully) missing are now all interaction viszualizations. They already work and are applied correctly, but wrong visualized. Have taken the time to unify adding OverlayObjects for selection visualization to OverlayManager, see handleNewOverlayObject. This does all needed when adding OverlayObjects in one place where the GridOffset can also be handled. It makles things more safe - not possible to forget one of the three steps for others. Eighth Step: Do the same unification for creating the OverlayGeometry, also rename methods to make usage more clear. We now have SdrHdl::insertNewlyCreatedOverlayObjectForSdrHdl SdrDragMethod::insertNewlyCreatedOverlayObjectForSdrDragMethod which can do the needed GridOffset changes centralized. Needed to get a ObjectContact for this at SdrDragMethod, so adapted ::CreateOverlayGeometry implementations accordingly. Missing is now the implementation in insertNewlyCreatedOverlayObjectForSdrDragMethod to add the GridOffset - if used. This has no SdrObject at this time, so we will need a fallback to do the same using a Range (Rectangle). The stuff doing this for SdrObject already has a fallback and is based on using the Rectangle from the SdrObject anyways, so this will be possible. Ninth Step: Cleanup of old stuff (no more //Z), adapted some usages of OverlayObject creations to use getViewIndependentPrimitive2DContainer instead of the view dependent parts so that offset applied to drag-overlays is correct and not already added. Adapted insertNewlyCreatedOverlayObjectForSdrDragMethod to use calculateGridOffsetForB2DRange. Use now that instead of SdrObject-based approach in calc - is more generic. Getting closer, but still not complete - there is an error with dragging the grepped handle somehow - the offset for drag is somehow wrong. Tenth Step: Corrected that offset error. Of course at interaction start and progress (move) the coordinates are in GrifOffset coordinates and need to be corrected to Model coordinates. Done that at ::BegDragObj and ::MovDragObj, works well. Of course there are exceptions for the crop-handles, so needed to add setting the correct parameters at SdrHdl when these got created, then all works as expected. The strategy is to *not* change the model data itself in any way, instead do all changes/adaptions in the view-only code. This has minimal impact and is needed due to having a 1:n relationship between model and views anyways. There are two directions: All visualizations are adapted to take the GridOffset into account (SdrObjects, overlay, handles, InteractionObjects, ...). In the other direction input like MousePosition is in principle in calc EditView in 'GridOffset'-coordinates and needs to be mapped back before usage. Change-Id: I2ecdd409def96a7248a26a65a22e59eb962880a0 Reviewed-on: https://gerrit.libreoffice.org/64057 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Diffstat (limited to 'svx/source/svdraw')
-rw-r--r--svx/source/svdraw/sdrpagewindow.cxx18
-rw-r--r--svx/source/svdraw/svdcrtv.cxx33
-rw-r--r--svx/source/svdraw/svddrgmt.cxx124
-rw-r--r--svx/source/svdraw/svddrgv.cxx61
-rw-r--r--svx/source/svdraw/svdedtv1.cxx2
-rw-r--r--svx/source/svdraw/svdedxv.cxx37
-rw-r--r--svx/source/svdraw/svdhdl.cxx131
-rw-r--r--svx/source/svdraw/svdmrkv.cxx161
-rw-r--r--svx/source/svdraw/svdobj.cxx6
-rw-r--r--svx/source/svdraw/svdorect.cxx4
-rw-r--r--svx/source/svdraw/svdpagv.cxx2
-rw-r--r--svx/source/svdraw/svdview.cxx8
12 files changed, 425 insertions, 162 deletions
diff --git a/svx/source/svdraw/sdrpagewindow.cxx b/svx/source/svdraw/sdrpagewindow.cxx
index c722fa883e49..80369f6dbd66 100644
--- a/svx/source/svdraw/sdrpagewindow.cxx
+++ b/svx/source/svdraw/sdrpagewindow.cxx
@@ -32,7 +32,7 @@
#include <svx/svdview.hxx>
#include <svx/svdpagv.hxx>
#include <svx/sdrpaintwindow.hxx>
-#include <sdr/contact/objectcontactofpageview.hxx>
+#include <svx/sdr/contact/objectcontactofpageview.hxx>
#include <svx/sdr/contact/displayinfo.hxx>
#include <svx/fmview.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
@@ -43,7 +43,7 @@ using namespace ::com::sun::star;
struct SdrPageWindow::Impl
{
// #110094# ObjectContact section
- mutable sdr::contact::ObjectContactOfPageView* mpObjectContact;
+ mutable sdr::contact::ObjectContact* mpObjectContact;
// the SdrPageView this window belongs to
SdrPageView& mrPageView;
@@ -456,8 +456,11 @@ void SdrPageWindow::InvalidatePageWindow(const basegfx::B2DRange& rRange)
const sdr::contact::ObjectContact& SdrPageWindow::GetObjectContact() const
{
if (!mpImpl->mpObjectContact)
- mpImpl->mpObjectContact = new sdr::contact::ObjectContactOfPageView(
- const_cast<SdrPageWindow&>(*this), "svx::svdraw::SdrPageWindow mpObjectContact" );
+ {
+ mpImpl->mpObjectContact = GetPageView().GetView().createViewSpecificObjectContact(
+ const_cast<SdrPageWindow&>(*this),
+ "svx::svdraw::SdrPageWindow mpObjectContact");
+ }
return *mpImpl->mpObjectContact;
}
@@ -465,8 +468,11 @@ const sdr::contact::ObjectContact& SdrPageWindow::GetObjectContact() const
sdr::contact::ObjectContact& SdrPageWindow::GetObjectContact()
{
if (!mpImpl->mpObjectContact)
- mpImpl->mpObjectContact = new sdr::contact::ObjectContactOfPageView(
- *this, "svx::svdraw::SdrPageWindow mpObjectContact" );
+ {
+ mpImpl->mpObjectContact = GetPageView().GetView().createViewSpecificObjectContact(
+ *this,
+ "svx::svdraw::SdrPageWindow mpObjectContact" );
+ }
return *mpImpl->mpObjectContact;
}
diff --git a/svx/source/svdraw/svdcrtv.cxx b/svx/source/svdraw/svdcrtv.cxx
index 5578cb193198..911481038d79 100644
--- a/svx/source/svdraw/svdcrtv.cxx
+++ b/svx/source/svdraw/svdcrtv.cxx
@@ -641,6 +641,31 @@ bool SdrCreateView::EndCreateObj(SdrCreateCmd eCmd)
if(!bSceneIntoScene)
{
+ // Here an interactively created SdrObject gets added, so
+ // take into account that interaction created an object in
+ // model coordinates. If we have e.g. a GirdOffset, this is a
+ // little bit tricky - we have an object in model coordinates,
+ // so the fetched offset is at the wrong point in principle
+ // since we need to 'substract' the offset here to get to
+ // 'real' model coordinates. But we have nothing better here,
+ // so go for it.
+ // The 2nd a little tricky thing is that this will early-create
+ // a ViewObjectContact for the new SdrObject, but these VOCs
+ // are anyways layouted for being create-on-demand. This will
+ // be adapted/replaced corretly later on.
+ // This *should* be the right place for getting all interactively
+ // created objects, see InsertObjectAtView below that calls
+ // CreateUndoNewObject.
+ basegfx::B2DVector aGridOffset(0.0, 0.0);
+ if(getPossibleGridOffsetForSdrObject(aGridOffset, pObj, pCreatePV))
+ {
+ const Size aOffset(
+ basegfx::fround(-aGridOffset.getX()),
+ basegfx::fround(-aGridOffset.getY()));
+
+ pObj->NbcMove(aOffset);
+ }
+
// do the same as before
InsertObjectAtView(pObj, *pCreatePV);
}
@@ -802,12 +827,8 @@ void SdrCreateView::ShowCreateObj(/*OutputDevice* pOut, sal_Bool bFull*/)
}
else
{
- ::basegfx::B2DPolyPolygon aPoly = pCurrentCreate->TakeCreatePoly(maDragStat);
- Point aGridOff = pCurrentCreate->GetGridOffset();
- // Hack for calc, transform position of create placeholder
- // object according to current zoom so as objects relative
- // position to grid appears stable
- aPoly.transform( basegfx::utils::createTranslateB2DHomMatrix( aGridOff.X(), aGridOff.Y() ) );
+ const ::basegfx::B2DPolyPolygon aPoly(pCurrentCreate->TakeCreatePoly(maDragStat));
+
mpCreateViewExtraData->CreateAndShowOverlay(*this, nullptr, aPoly);
}
diff --git a/svx/source/svdraw/svddrgmt.cxx b/svx/source/svdraw/svddrgmt.cxx
index 2c89ca4aabcb..13ee857e655f 100644
--- a/svx/source/svdraw/svddrgmt.cxx
+++ b/svx/source/svdraw/svddrgmt.cxx
@@ -135,11 +135,12 @@ drawinglayer::primitive2d::Primitive2DContainer SdrDragEntryPolyPolygon::createP
}
-SdrDragEntrySdrObject::SdrDragEntrySdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact, bool bModify)
+SdrDragEntrySdrObject::SdrDragEntrySdrObject(
+ const SdrObject& rOriginal,
+ bool bModify)
: SdrDragEntry(),
maOriginal(rOriginal),
mpClone(nullptr),
- mrObjectContact(rObjectContact),
mbModify(bModify)
{
// add SdrObject parts to transparent overlay stuff
@@ -185,16 +186,9 @@ drawinglayer::primitive2d::Primitive2DContainer SdrDragEntrySdrObject::createPri
pSource = mpClone;
}
- // get VOC and Primitive2DContainer
- sdr::contact::ViewContact& rVC = pSource->GetViewContact();
- sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(mrObjectContact);
- sdr::contact::DisplayInfo aDisplayInfo;
-
- // Do not use the last ViewPort set at the OC from the last ProcessDisplay(),
- // here we want the complete primitive sequence without visibility clippings
- mrObjectContact.resetViewPort();
-
- return rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo);
+ // use the view-independent primitive representation (without
+ // evtl. GridOffset, that may be applied to the DragEntry individually)
+ return pSource->GetViewContact().getViewIndependentPrimitive2DContainer();
}
@@ -338,11 +332,46 @@ void SdrDragMethod::createSdrDragEntries()
}
}
-void SdrDragMethod::createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact)
+void SdrDragMethod::createSdrDragEntryForSdrObject(const SdrObject& rOriginal)
{
// add full object drag; Clone() at the object has to work
// for this
- addSdrDragEntry(std::unique_ptr<SdrDragEntry>(new SdrDragEntrySdrObject(rOriginal, rObjectContact, true/*bModify*/)));
+ addSdrDragEntry(std::unique_ptr<SdrDragEntry>(new SdrDragEntrySdrObject(rOriginal, true/*bModify*/)));
+}
+
+void SdrDragMethod::insertNewlyCreatedOverlayObjectForSdrDragMethod(
+ std::unique_ptr<sdr::overlay::OverlayObject> pOverlayObject,
+ const sdr::contact::ObjectContact& rObjectContact,
+ sdr::overlay::OverlayManager& rOverlayManager)
+{
+ // check if we have an OverlayObject
+ if(!pOverlayObject)
+ {
+ return;
+ }
+
+ // add to OverlayManager
+ rOverlayManager.add(*pOverlayObject);
+
+ // Add GridOffset for non-linear ViewToDevice transformation (calc)
+ if(rObjectContact.supportsGridOffsets())
+ {
+ const basegfx::B2DRange& rNewRange(pOverlayObject->getBaseRange());
+
+ if(!rNewRange.isEmpty())
+ {
+ basegfx::B2DVector aOffset(0.0, 0.0);
+ rObjectContact.calculateGridOffsetForB2DRange(aOffset, rNewRange);
+
+ if(!aOffset.equalZero())
+ {
+ pOverlayObject->setOffset(aOffset);
+ }
+ }
+ }
+
+ // add to local OverlayObjectList - ownership change (!)
+ maOverlayObjectList.append(std::move(pOverlayObject));
}
void SdrDragMethod::createSdrDragEntries_SolidDrag()
@@ -364,7 +393,6 @@ void SdrDragMethod::createSdrDragEntries_SolidDrag()
{
if(pPV->PageWindowCount())
{
- sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact();
SdrObjListIter aIter(*pObject);
while(aIter.IsMore())
@@ -386,7 +414,7 @@ void SdrDragMethod::createSdrDragEntries_SolidDrag()
{
// add full object drag; Clone() at the object has to work
// for this
- createSdrDragEntryForSdrObject(*pCandidate, rOC);
+ createSdrDragEntryForSdrObject(*pCandidate);
}
if(bAddWireframe)
@@ -654,7 +682,9 @@ void SdrDragMethod::CancelSdrDrag()
typedef std::map< const SdrObject*, SdrObject* > SdrObjectAndCloneMap;
-void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlayManager)
+void SdrDragMethod::CreateOverlayGeometry(
+ sdr::overlay::OverlayManager& rOverlayManager,
+ const sdr::contact::ObjectContact& rObjectContact)
{
// create SdrDragEntries on demand
if(maSdrDragEntries.empty())
@@ -764,9 +794,14 @@ void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlay
if(!aResult.empty())
{
- std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(new sdr::overlay::OverlayPrimitive2DSequenceObject(aResult));
- rOverlayManager.add(*pNewOverlayObject);
- addToOverlayObjectList(std::move(pNewOverlayObject));
+ std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(
+ new sdr::overlay::OverlayPrimitive2DSequenceObject(
+ aResult));
+
+ insertNewlyCreatedOverlayObjectForSdrDragMethod(
+ std::move(pNewOverlayObject),
+ rObjectContact,
+ rOverlayManager);
}
if(!aResultTransparent.empty())
@@ -774,9 +809,14 @@ void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlay
drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparencePrimitive2D(new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(aResultTransparent, 0.5));
aResultTransparent = drawinglayer::primitive2d::Primitive2DContainer { aUnifiedTransparencePrimitive2D };
- std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(new sdr::overlay::OverlayPrimitive2DSequenceObject(aResultTransparent));
- rOverlayManager.add(*pNewOverlayObject);
- addToOverlayObjectList(std::move(pNewOverlayObject));
+ std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(
+ new sdr::overlay::OverlayPrimitive2DSequenceObject(
+ aResultTransparent));
+
+ insertNewlyCreatedOverlayObjectForSdrDragMethod(
+ std::move(pNewOverlayObject),
+ rObjectContact,
+ rOverlayManager);
}
}
@@ -788,11 +828,17 @@ void SdrDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlay
const basegfx::B2DPoint aTopLeft(aActionRectangle.Left(), aActionRectangle.Top());
const basegfx::B2DPoint aBottomRight(aActionRectangle.Right(), aActionRectangle.Bottom());
- std::unique_ptr<sdr::overlay::OverlayRollingRectangleStriped> pNew(new sdr::overlay::OverlayRollingRectangleStriped(
- aTopLeft, aBottomRight, true, false));
+ std::unique_ptr<sdr::overlay::OverlayRollingRectangleStriped> pNew(
+ new sdr::overlay::OverlayRollingRectangleStriped(
+ aTopLeft,
+ aBottomRight,
+ true,
+ false));
- rOverlayManager.add(*pNew);
- addToOverlayObjectList(std::move(pNew));
+ insertNewlyCreatedOverlayObjectForSdrDragMethod(
+ std::move(pNew),
+ rObjectContact,
+ rOverlayManager);
}
}
@@ -1159,8 +1205,7 @@ void SdrDragObjOwn::createSdrDragEntries()
if(pPV && pPV->PageWindowCount())
{
- sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact();
- addSdrDragEntry(std::unique_ptr<SdrDragEntry>(new SdrDragEntrySdrObject(*mpClone, rOC, false)));
+ addSdrDragEntry(std::unique_ptr<SdrDragEntry>(new SdrDragEntrySdrObject(*mpClone, false)));
// potentially no wireframe needed, full drag works
bAddWireframe = false;
@@ -1417,19 +1462,15 @@ Pointer SdrDragObjOwn::GetSdrDragPointer() const
}
-void SdrDragMove::createSdrDragEntryForSdrObject(const SdrObject& rOriginal, sdr::contact::ObjectContact& rObjectContact)
+void SdrDragMove::createSdrDragEntryForSdrObject(const SdrObject& rOriginal)
{
- // for SdrDragMove, use current Primitive2DContainer of SdrObject visualization
- // in given ObjectContact directly
- sdr::contact::ViewContact& rVC = rOriginal.GetViewContact();
- sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(rObjectContact);
- sdr::contact::DisplayInfo aDisplayInfo;
+ // use the view-independent primitive representation (without
+ // evtl. GridOffset, that may be applied to the DragEntry individually)
+ addSdrDragEntry(
+ std::unique_ptr<SdrDragEntry>(
+ new SdrDragEntryPrimitive2DSequence(
+ rOriginal.GetViewContact().getViewIndependentPrimitive2DContainer())));
- // Do not use the last ViewPort set at the OC from the last ProcessDisplay(),
- // here we want the complete primitive sequence without visible clippings
- rObjectContact.resetViewPort();
-
- addSdrDragEntry(std::unique_ptr<SdrDragEntry>(new SdrDragEntryPrimitive2DSequence(rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo))));
}
void SdrDragMove::applyCurrentTransformationToSdrObject(SdrObject& rTarget)
@@ -1766,8 +1807,7 @@ bool SdrDragResize::BeginSdrDrag()
if (pRefHdl!=nullptr && !getSdrDragView().IsResizeAtCenter())
{
- // Calc hack to adjust for calc grid
- DragStat().SetRef1(pRefHdl->GetPos() - getSdrDragView().GetGridOffset());
+ DragStat().SetRef1(pRefHdl->GetPos());
}
else
{
diff --git a/svx/source/svdraw/svddrgv.cxx b/svx/source/svdraw/svddrgv.cxx
index 20f14af9c5ce..31132a5bbdef 100644
--- a/svx/source/svdraw/svddrgv.cxx
+++ b/svx/source/svdraw/svddrgv.cxx
@@ -40,6 +40,7 @@
#include <svx/polypolygoneditor.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <svx/sdrpagewindow.hxx>
using namespace sdr;
@@ -220,6 +221,19 @@ bool SdrDragView::BegDragObj(const Point& rPnt, OutputDevice* pOut, SdrHdl* pHdl
}
Point aPnt(rPnt);
+ basegfx::B2DVector aGridOffset(0.0, 0.0);
+
+ // Coordinate maybe affected by GridOffset, so we may need to
+ // adapt to Model-coordinates here
+ if(getPossibleGridOffsetForPosition(
+ aGridOffset,
+ basegfx::B2DPoint(aPnt.X(), aPnt.Y()),
+ GetSdrPageView()))
+ {
+ aPnt.AdjustX(basegfx::fround(-aGridOffset.getX()));
+ aPnt.AdjustY(basegfx::fround(-aGridOffset.getY()));
+ }
+
if(pHdl == nullptr
|| pHdl->GetKind() == SdrHdlKind::Move
|| pHdl->GetKind() == SdrHdlKind::MirrorAxis
@@ -508,6 +522,19 @@ void SdrDragView::MovDragObj(const Point& rPnt)
if (mpCurrentSdrDragMethod)
{
Point aPnt(rPnt);
+ basegfx::B2DVector aGridOffset(0.0, 0.0);
+
+ // Coordinate maybe affected by GridOffset, so we may need to
+ // adapt to Model-coordinates here
+ if(getPossibleGridOffsetForPosition(
+ aGridOffset,
+ basegfx::B2DPoint(aPnt.X(), aPnt.Y()),
+ GetSdrPageView()))
+ {
+ aPnt.AdjustX(basegfx::fround(-aGridOffset.getX()));
+ aPnt.AdjustY(basegfx::fround(-aGridOffset.getY()));
+ }
+
ImpLimitToWorkArea(aPnt);
mpCurrentSdrDragMethod->MoveSdrDrag(aPnt); // this call already makes a Hide()/Show combination
}
@@ -780,17 +807,35 @@ void SdrDragView::ShowDragObj()
{
if(mpCurrentSdrDragMethod && !maDragStat.IsShown())
{
- for(sal_uInt32 a(0); a < PaintWindowCount(); a++)
+ // Changed for the GridOffset stuff: No longer iterate over
+ // SdrPaintWindow(s), but now over SdrPageWindow(s), so doing the
+ // same as the SdrHdl visualizations (see ::CreateB2dIAObject) do.
+ // This is needed to get access to a ObjectContact which is needed
+ // to evtl. process that GridOffset in CreateOverlayGeometry
+ SdrPageView* pPageView(GetSdrPageView());
+
+ if(nullptr != pPageView)
{
- SdrPaintWindow* pCandidate = GetPaintWindow(a);
- const rtl::Reference<sdr::overlay::OverlayManager>& xOverlayManager = pCandidate->GetOverlayManager();
-
- if (xOverlayManager.is())
+ for(sal_uInt32 a(0); a < pPageView->PageWindowCount(); a++)
{
- mpCurrentSdrDragMethod->CreateOverlayGeometry(*xOverlayManager);
+ const SdrPageWindow& rPageWindow(*pPageView->GetPageWindow(a));
+ const SdrPaintWindow& rPaintWindow(rPageWindow.GetPaintWindow());
- // #i101679# Force changed overlay to be shown
- xOverlayManager->flush();
+ if(rPaintWindow.OutputToWindow())
+ {
+ const rtl::Reference<sdr::overlay::OverlayManager>& xOverlayManager(
+ rPaintWindow.GetOverlayManager());
+
+ if(xOverlayManager.is())
+ {
+ mpCurrentSdrDragMethod->CreateOverlayGeometry(
+ *xOverlayManager.get(),
+ rPageWindow.GetObjectContact());
+
+ // #i101679# Force changed overlay to be shown
+ xOverlayManager->flush();
+ }
+ }
}
}
diff --git a/svx/source/svdraw/svdedtv1.cxx b/svx/source/svdraw/svdedtv1.cxx
index 960dd2c58269..1acf37cd3771 100644
--- a/svx/source/svdraw/svdedtv1.cxx
+++ b/svx/source/svdraw/svdedtv1.cxx
@@ -1259,8 +1259,6 @@ SfxItemSet SdrEditView::GetGeoAttrFromMarked() const
{
SfxItemSet aMarkAttr(GetAttrFromMarked(false)); // because of AutoGrowHeight and corner radius
tools::Rectangle aRect(GetMarkedObjRect());
- // restore position to that before calc hack
- aRect -= GetGridOffset();
if(GetSdrPageView())
{
diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx
index 0f7361bbd6d8..66a409c8cfae 100644
--- a/svx/source/svdraw/svdedxv.cxx
+++ b/svx/source/svdraw/svdedxv.cxx
@@ -261,13 +261,20 @@ void SdrObjEditView::ModelHasChanged()
tools::Rectangle aEditArea1;
tools::Rectangle aMinArea1;
pTextObj->TakeTextEditArea(&aPaperMin1,&aPaperMax1,&aEditArea1,&aMinArea1);
-
Point aPvOfs(pTextObj->GetTextEditOffset());
- // Hack for calc, transform position of edit object according
- // to current zoom so as objects relative position to grid
- // appears stable
- aEditArea1 += pTextObj->GetGridOffset();
- aMinArea1 += pTextObj->GetGridOffset();
+
+ // add possible GridOffset to up-to-now view-independent EditAreas
+ basegfx::B2DVector aGridOffset(0.0, 0.0);
+ if(getPossibleGridOffsetForSdrObject(aGridOffset, pTextObj, GetSdrPageView()))
+ {
+ const Point aOffset(
+ basegfx::fround(aGridOffset.getX()),
+ basegfx::fround(aGridOffset.getY()));
+
+ aEditArea1 += aOffset;
+ aMinArea1 += aOffset;
+ }
+
aEditArea1.Move(aPvOfs.X(),aPvOfs.Y());
aMinArea1.Move(aPvOfs.X(),aPvOfs.Y());
tools::Rectangle aNewArea(aMinArea1);
@@ -494,7 +501,7 @@ namespace
if (!maRange.equal(maLastRange) || maLastTextPrimitives != maTextPrimitives)
{
// conditions of last local decomposition have changed, delete to force new evaluation
- const_cast<TextEditOverlayObject*>(this)->setPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DContainer());
+ const_cast<TextEditOverlayObject*>(this)->resetPrimitive2DSequence();
}
}
@@ -1148,14 +1155,20 @@ bool SdrObjEditView::SdrBeginTextEdit(
aTextEditArea = aTextRect;
- // Hack for calc, transform position of edit object according
- // to current zoom so as objects relative position to grid
- // appears stable
+ // add possible GridOffset to up-to-now view-independent EditAreas
+ basegfx::B2DVector aGridOffset(0.0, 0.0);
+ if(getPossibleGridOffsetForSdrObject(aGridOffset, pTextObj, pPV))
+ {
+ const Point aOffset(
+ basegfx::fround(aGridOffset.getX()),
+ basegfx::fround(aGridOffset.getY()));
+
+ aTextEditArea += aOffset;
+ aMinTextEditArea += aOffset;
+ }
Point aPvOfs(pTextObj->GetTextEditOffset());
- aTextEditArea += pTextObj->GetGridOffset();
aTextEditArea.Move(aPvOfs.X(),aPvOfs.Y());
- aMinTextEditArea += pTextObj->GetGridOffset();
aMinTextEditArea.Move(aPvOfs.X(),aPvOfs.Y());
pTextEditCursorBuffer=pWin->GetCursor();
diff --git a/svx/source/svdraw/svdhdl.cxx b/svx/source/svdraw/svdhdl.cxx
index 93621e714802..0a51a0a580ef 100644
--- a/svx/source/svdraw/svdhdl.cxx
+++ b/svx/source/svdraw/svdhdl.cxx
@@ -56,6 +56,8 @@
#include <svx/sdr/overlay/overlaypolypolygon.hxx>
#include <vcl/lazydelete.hxx>
#include <vcl/BitmapTools.hxx>
+#include <svx/sdr/contact/objectcontact.hxx>
+#include <svx/sdr/contact/viewcontact.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
@@ -612,12 +614,12 @@ void SdrHdl::CreateB2dIAObject()
aPosition, eColIndex, eKindOfMarker,
aMoveOutsideOffset);
}
+
// OVERLAYMANAGER
- if (pNewOverlayObject)
- {
- xManager->add(*pNewOverlayObject);
- maOverlayGroup.append(std::move(pNewOverlayObject));
- }
+ insertNewlyCreatedOverlayObjectForSdrHdl(
+ std::move(pNewOverlayObject),
+ rPageWindow.GetObjectContact(),
+ *xManager.get());
}
}
}
@@ -1070,6 +1072,39 @@ BitmapEx SdrHdl::createGluePointBitmap()
return ImpGetBitmapEx(BitmapMarkerKind::Glue_Deselected, BitmapColorIndex::LightGreen);
}
+void SdrHdl::insertNewlyCreatedOverlayObjectForSdrHdl(
+ std::unique_ptr<sdr::overlay::OverlayObject> pOverlayObject,
+ const sdr::contact::ObjectContact& rObjectContact,
+ sdr::overlay::OverlayManager& rOverlayManager)
+{
+ // check if we have an OverlayObject
+ if(!pOverlayObject)
+ {
+ return;
+ }
+
+ // Add GridOffset for non-linear ViewToDevice transformation (calc)
+ if(nullptr != GetObj() && rObjectContact.supportsGridOffsets())
+ {
+ basegfx::B2DVector aOffset(0.0, 0.0);
+ const sdr::contact::ViewObjectContact& rVOC(GetObj()->GetViewContact().GetViewObjectContact(
+ const_cast<sdr::contact::ObjectContact&>(rObjectContact)));
+
+ rObjectContact.calculateGridOffsetForViewOjectContact(aOffset, rVOC);
+
+ if(!aOffset.equalZero())
+ {
+ pOverlayObject->setOffset(aOffset);
+ }
+ }
+
+ // add to OverlayManager
+ rOverlayManager.add(*pOverlayObject);
+
+ // add to local OverlayObjectList - ownership change (!)
+ maOverlayGroup.append(std::move(pOverlayObject));
+}
+
SdrHdlColor::SdrHdlColor(const Point& rRef, Color aCol, const Size& rSize, bool bLum)
: SdrHdl(rRef, SdrHdlKind::Color),
aMarkerSize(rSize),
@@ -1121,8 +1156,10 @@ void SdrHdlColor::CreateB2dIAObject()
));
// OVERLAYMANAGER
- xManager->add(*pNewOverlayObject);
- maOverlayGroup.append(std::move(pNewOverlayObject));
+ insertNewlyCreatedOverlayObjectForSdrHdl(
+ std::move(pNewOverlayObject),
+ rPageWindow.GetObjectContact(),
+ *xManager.get());
}
}
}
@@ -1280,8 +1317,12 @@ void SdrHdlGradient::CreateB2dIAObject()
));
pNewOverlayObject->setBaseColor(IsGradient() ? COL_BLACK : COL_BLUE);
- xManager->add(*pNewOverlayObject);
- maOverlayGroup.append(std::move(pNewOverlayObject));
+
+ // OVERLAYMANAGER
+ insertNewlyCreatedOverlayObjectForSdrHdl(
+ std::move(pNewOverlayObject),
+ rPageWindow.GetObjectContact(),
+ *xManager.get());
// arrowhead
Point aLeft(aMidPoint.X() + static_cast<sal_Int32>(aPerpend.getX() * fHalfArrowWidth),
@@ -1301,8 +1342,11 @@ void SdrHdlGradient::CreateB2dIAObject()
IsGradient() ? COL_BLACK : COL_BLUE
));
- xManager->add(*pNewOverlayObject);
- maOverlayGroup.append(std::move(pNewOverlayObject));
+ // OVERLAYMANAGER
+ insertNewlyCreatedOverlayObjectForSdrHdl(
+ std::move(pNewOverlayObject),
+ rPageWindow.GetObjectContact(),
+ *xManager.get());
}
}
}
@@ -1425,12 +1469,14 @@ void SdrHdlLine::CreateB2dIAObject()
aPosition2
));
- // OVERLAYMANAGER
// color(?)
pNewOverlayObject->setBaseColor(COL_LIGHTRED);
- xManager->add(*pNewOverlayObject);
- maOverlayGroup.append(std::move(pNewOverlayObject));
+ // OVERLAYMANAGER
+ insertNewlyCreatedOverlayObjectForSdrHdl(
+ std::move(pNewOverlayObject),
+ rPageWindow.GetObjectContact(),
+ *xManager.get());
}
}
}
@@ -1482,15 +1528,18 @@ void SdrHdlBezWgt::CreateB2dIAObject()
aPosition1,
aPosition2
));
- // OVERLAYMANAGER
+
// line part is not hittable
pNewOverlayObject->setHittable(false);
// color(?)
pNewOverlayObject->setBaseColor(COL_LIGHTBLUE);
- xManager->add(*pNewOverlayObject);
- maOverlayGroup.append(std::move(pNewOverlayObject));
+ // OVERLAYMANAGER
+ insertNewlyCreatedOverlayObjectForSdrHdl(
+ std::move(pNewOverlayObject),
+ rPageWindow.GetObjectContact(),
+ *xManager.get());
}
}
}
@@ -1532,11 +1581,13 @@ void E3dVolumeMarker::CreateB2dIAObject()
sdr::overlay::OverlayPolyPolygonStripedAndFilled(
aWireframePoly));
- // OVERLAYMANAGER
pNewOverlayObject->setBaseColor(COL_BLACK);
- xManager->add(*pNewOverlayObject);
- maOverlayGroup.append(std::move(pNewOverlayObject));
+ // OVERLAYMANAGER
+ insertNewlyCreatedOverlayObjectForSdrHdl(
+ std::move(pNewOverlayObject),
+ rPageWindow.GetObjectContact(),
+ *xManager.get());
}
}
}
@@ -1597,11 +1648,10 @@ void ImpEdgeHdl::CreateB2dIAObject()
eKindOfMarker));
// OVERLAYMANAGER
- if (pNewOverlayObject)
- {
- xManager->add(*pNewOverlayObject);
- maOverlayGroup.append(std::move(pNewOverlayObject));
- }
+ insertNewlyCreatedOverlayObjectForSdrHdl(
+ std::move(pNewOverlayObject),
+ rPageWindow.GetObjectContact(),
+ *xManager.get());
}
}
}
@@ -1713,11 +1763,10 @@ void ImpMeasureHdl::CreateB2dIAObject()
eKindOfMarker));
// OVERLAYMANAGER
- if (pNewOverlayObject)
- {
- xManager->add(*pNewOverlayObject);
- maOverlayGroup.append(std::move(pNewOverlayObject));
- }
+ insertNewlyCreatedOverlayObjectForSdrHdl(
+ std::move(pNewOverlayObject),
+ rPageWindow.GetObjectContact(),
+ *xManager.get());
}
}
}
@@ -1784,10 +1833,13 @@ void ImpTextframeHdl::CreateB2dIAObject()
nRotationAngle * -F_PI18000,
true)); // allow animation; the Handle is not shown at text edit time
- // OVERLAYMANAGER
pNewOverlayObject->setHittable(false);
- xManager->add(*pNewOverlayObject);
- maOverlayGroup.append(std::move(pNewOverlayObject));
+
+ // OVERLAYMANAGER
+ insertNewlyCreatedOverlayObjectForSdrHdl(
+ std::move(pNewOverlayObject),
+ rPageWindow.GetObjectContact(),
+ *xManager.get());
}
}
}
@@ -2395,8 +2447,10 @@ void SdrCropHdl::CreateB2dIAObject()
}
// OVERLAYMANAGER
- xManager->add(*pOverlayObject);
- maOverlayGroup.append(std::move(pOverlayObject));
+ insertNewlyCreatedOverlayObjectForSdrHdl(
+ std::move(pOverlayObject),
+ rPageWindow.GetObjectContact(),
+ *xManager.get());
}
}
}
@@ -2608,8 +2662,11 @@ void SdrCropViewHdl::CreateB2dIAObject()
// only informative object, no hit
pNew->setHittable(false);
- xManager->add(*pNew);
- maOverlayGroup.append(std::move(pNew));
+ // OVERLAYMANAGER
+ insertNewlyCreatedOverlayObjectForSdrHdl(
+ std::move(pNew),
+ rPageWindow.GetObjectContact(),
+ *xManager.get());
}
}
}
diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx
index bbad824d3267..8a55f973873d 100644
--- a/svx/source/svdraw/svdmrkv.cxx
+++ b/svx/source/svdraw/svdmrkv.cxx
@@ -43,6 +43,7 @@
#include <svx/svdovirt.hxx>
#include <sdr/overlay/overlayrollingrectangle.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <svx/sdr/contact/viewcontact.hxx>
#include <svx/sdrpaintwindow.hxx>
#include <svx/sdrpagewindow.hxx>
#include <svx/sdrhittesthelper.hxx>
@@ -675,11 +676,6 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell)
}
}
- // apply calc offset to marked object rect
- // ( necessary for handles to be displayed in
- // correct position )
- Point aGridOff = GetGridOffset();
-
// There can be multiple mark views, but we're only interested in the one that has a window associated.
const bool bTiledRendering = comphelper::LibreOfficeKit::isActive() && GetFirstOutputDevice() && GetFirstOutputDevice()->GetOutDevType() == OUTDEV_WINDOW;
@@ -804,20 +800,13 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell)
if (bFrmHdl)
{
if(!aRect.IsEmpty())
- { // otherwise nothing is found
+ {
+ // otherwise nothing is found
+ const size_t nSiz0(maHdlList.GetHdlCount());
+
if( bSingleTextObjMark )
{
- const size_t nSiz0=maHdlList.GetHdlCount();
mpMarkedObj->AddToHdlList(maHdlList);
- const size_t nSiz1=maHdlList.GetHdlCount();
- for (size_t i=nSiz0; i<nSiz1; ++i)
- {
- SdrHdl* pHdl=maHdlList.GetHdl(i);
- pHdl->SetObj(mpMarkedObj);
- pHdl->SetPos( pHdl->GetPos() + aGridOff );
- pHdl->SetPageView(mpMarkedPV);
- pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0));
- }
}
else
{
@@ -876,6 +865,20 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell)
}
}
}
+
+ const size_t nSiz1(maHdlList.GetHdlCount());
+
+ // moved setting the missing parameters at SdrHdl here from the
+ // single loop above (bSingleTextObjMark), this was missing all
+ // the time. Setting SdrObject is now required to correctly get
+ // the View-Dependent evtl. GridOffset adapted
+ for (size_t i=nSiz0; i<nSiz1; ++i)
+ {
+ SdrHdl* pHdl=maHdlList.GetHdl(i);
+ pHdl->SetObj(mpMarkedObj);
+ pHdl->SetPageView(mpMarkedPV);
+ pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0));
+ }
}
}
else
@@ -888,7 +891,19 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell)
// Default addCropHandles from SdrObject does nothing. When pMarkedObj is SdrGrafObj, previous
// behaviour occurs (code in svx/source/svdraw/svdograf.cxx). When pMarkedObj is SwVirtFlyDrawObj
// writer takes the responsibility of adding handles (code in sw/source/core/draw/dflyobj.cxx)
+ const size_t nSiz0(maHdlList.GetHdlCount());
mpMarkedObj->addCropHandles(maHdlList);
+ const size_t nSiz1(maHdlList.GetHdlCount());
+
+ // Was missing: Set infos at SdrCropHdl
+ for (size_t i=nSiz0; i<nSiz1; ++i)
+ {
+ SdrHdl* pHdl=maHdlList.GetHdl(i);
+ pHdl->SetObj(mpMarkedObj);
+ pHdl->SetPageView(mpMarkedPV);
+ pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0));
+ }
+
bDone = true;
}
@@ -907,7 +922,6 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell)
for (size_t i=nSiz0; i<nSiz1; ++i)
{
SdrHdl* pHdl=maHdlList.GetHdl(i);
- pHdl->SetPos( pHdl->GetPos() + aGridOff );
pHdl->SetObj(pObj);
pHdl->SetPageView(pPV);
pHdl->SetObjHdlNum(sal_uInt16(i-nSiz0));
@@ -1695,6 +1709,83 @@ void SdrMarkView::SetMarkHdlSizePixel(sal_uInt16 nSiz)
}
}
+bool SdrMarkView::getPossibleGridOffsetForSdrObject(
+ basegfx::B2DVector& rOffset,
+ const SdrObject* pObj,
+ const SdrPageView* pPV) const
+{
+ if(nullptr == pObj || nullptr == pPV)
+ {
+ return false;
+ }
+
+ const OutputDevice* pOutputDevice(GetFirstOutputDevice());
+
+ if(nullptr == pOutputDevice)
+ {
+ return false;
+ }
+
+ const SdrPageWindow* pSdrPageWindow(pPV->FindPageWindow(*pOutputDevice));
+
+ if(nullptr == pSdrPageWindow)
+ {
+ return false;
+ }
+
+ const sdr::contact::ObjectContact& rObjectContact(pSdrPageWindow->GetObjectContact());
+
+ if(!rObjectContact.supportsGridOffsets())
+ {
+ return false;
+ }
+
+ basegfx::B2DVector aOffset(0.0, 0.0);
+ const sdr::contact::ViewObjectContact& rVOC(pObj->GetViewContact().GetViewObjectContact(
+ const_cast<sdr::contact::ObjectContact&>(rObjectContact)));
+
+ rObjectContact.calculateGridOffsetForViewOjectContact(rOffset, rVOC);
+
+ return !rOffset.equalZero();
+}
+
+bool SdrMarkView::getPossibleGridOffsetForPosition(
+ basegfx::B2DVector& rOffset,
+ const basegfx::B2DPoint& rPoint,
+ const SdrPageView* pPV) const
+{
+ if(nullptr == pPV)
+ {
+ return false;
+ }
+
+ const OutputDevice* pOutputDevice(GetFirstOutputDevice());
+
+ if(nullptr == pOutputDevice)
+ {
+ return false;
+ }
+
+ const SdrPageWindow* pSdrPageWindow(pPV->FindPageWindow(*pOutputDevice));
+
+ if(nullptr == pSdrPageWindow)
+ {
+ return false;
+ }
+
+ const sdr::contact::ObjectContact& rObjectContact(pSdrPageWindow->GetObjectContact());
+
+ if(!rObjectContact.supportsGridOffsets())
+ {
+ return false;
+ }
+
+ basegfx::B2DVector aOffset(0.0, 0.0);
+ rObjectContact.calculateGridOffsetForB2DRange(rOffset, basegfx::B2DRange(rPoint));
+
+ return !rOffset.equalZero();
+}
+
SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObject* pObj, SdrPageView* pPV, SdrSearchOptions nOptions, const SdrLayerIDSet* pMVisLay) const
{
if(((nOptions & SdrSearchOptions::IMPISMASTER) && pObj->IsNotVisibleAsMaster()) || (!pObj->IsVisible()))
@@ -1708,8 +1799,16 @@ SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nT
const bool bTXT(dynamic_cast<const SdrTextObj*>( pObj) != nullptr && static_cast<SdrTextObj*>(pObj)->IsTextFrame());
SdrObject* pRet=nullptr;
tools::Rectangle aRect(pObj->GetCurrentBoundRect());
- // hack for calc grid sync
- aRect += pObj->GetGridOffset();
+
+ // add possible GridOffset to up-to-now view-independent BountRect data
+ basegfx::B2DVector aGridOffset(0.0, 0.0);
+ if(getPossibleGridOffsetForSdrObject(aGridOffset, pObj, pPV))
+ {
+ aRect += Point(
+ basegfx::fround(aGridOffset.getX()),
+ basegfx::fround(aGridOffset.getY()));
+ }
+
sal_uInt16 nTol2(nTol);
// double tolerance for OLE, text frames and objects in
@@ -2009,6 +2108,7 @@ void SdrMarkView::AdjustMarkHdl(SfxViewShell* pOtherShell)
SetMarkHandles(pOtherShell);
}
+// BoundRect in model coordinates, no GridOffset added
tools::Rectangle SdrMarkView::GetMarkedObjBoundRect() const
{
tools::Rectangle aRect;
@@ -2016,49 +2116,28 @@ tools::Rectangle SdrMarkView::GetMarkedObjBoundRect() const
SdrMark* pM=GetSdrMarkByIndex(nm);
SdrObject* pO=pM->GetMarkedSdrObj();
tools::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 tools::Rectangle& aGroupSyncedRect = GetMarkedObjRect();
- aOffset = aGroupSyncedRect.TopLeft() - maMarkedObjRectNoOffset.TopLeft();
- return aOffset;
-}
-
+// ObjRect in model coordinates, no GridOffset added
const tools::Rectangle& SdrMarkView::GetMarkedObjRect() const
{
if (mbMarkedObjRectDirty) {
const_cast<SdrMarkView*>(this)->mbMarkedObjRectDirty=false;
tools::Rectangle aRect;
- tools::Rectangle aRect2;
for (size_t nm=0; nm<GetMarkedObjectCount(); ++nm) {
SdrMark* pM=GetSdrMarkByIndex(nm);
SdrObject* pO = pM->GetMarkedSdrObj();
if (!pO)
continue;
tools::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);
}
const_cast<SdrMarkView*>(this)->maMarkedObjRect=aRect;
- const_cast<SdrMarkView*>(this)->maMarkedObjRectNoOffset=aRect2;
}
return maMarkedObjRect;
}
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index cb104cba5358..7706cfebd826 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -890,6 +890,8 @@ void SdrObject::RecalcBoundRect()
// central new method which will calculate the BoundRect using primitive geometry
if(aOutRect.IsEmpty())
{
+ // Use view-independent data - we do not want any connections
+ // to e.g. GridOffset in SdrObject-level
const drawinglayer::primitive2d::Primitive2DContainer xPrimitives(GetViewContact().getViewIndependentPrimitive2DContainer());
if(!xPrimitives.empty())
@@ -905,7 +907,6 @@ void SdrObject::RecalcBoundRect()
static_cast<long>(floor(aRange.getMinY())),
static_cast<long>(ceil(aRange.getMaxX())),
static_cast<long>(ceil(aRange.getMaxY())));
- aOutRect -= GetGridOffset(); // don't include grid offset
return;
}
}
@@ -1022,8 +1023,6 @@ SdrObject& SdrObject::operator=(const SdrObject& rObj)
pGrabBagItem.reset();
if (rObj.pGrabBagItem!=nullptr)
pGrabBagItem.reset(static_cast< SfxGrabBagItem* >( rObj.pGrabBagItem->Clone() ));
-
- aGridOffset = rObj.aGridOffset;
return *this;
}
@@ -1706,7 +1705,6 @@ bool SdrObject::HasTextEdit() const
bool SdrObject::Equals(const SdrObject& rOtherObj) const
{
return (aAnchor.X() == rOtherObj.aAnchor.X() && aAnchor.Y() == rOtherObj.aAnchor.Y() &&
- aGridOffset.X() == rOtherObj.aGridOffset.X() && aGridOffset.Y() == rOtherObj.aGridOffset.Y() &&
nOrdNum == rOtherObj.nOrdNum && mnNavigationPosition == rOtherObj.mnNavigationPosition &&
mbSupportTextIndentingOnLineWidthChange == rOtherObj.mbSupportTextIndentingOnLineWidthChange &&
mbLineIsOutsideGeometry == rOtherObj.mbLineIsOutsideGeometry && bMarkProt == rOtherObj.bMarkProt &&
diff --git a/svx/source/svdraw/svdorect.cxx b/svx/source/svdraw/svdorect.cxx
index d9b74ea3aaa9..348ef3738842 100644
--- a/svx/source/svdraw/svdorect.cxx
+++ b/svx/source/svdraw/svdorect.cxx
@@ -316,9 +316,7 @@ void SdrRectObj::AddToHdlList(SdrHdlList& rHdlList) const
if(IsTextFrame())
{
OSL_ENSURE(!IsTextEditActive(), "Do not use a ImpTextframeHdl for highlighting text in active text edit, this will collide with EditEngine paints (!)");
- // hack for calc grid sync to ensure the hatched area
- // for a textbox is displayed at correct position
- std::unique_ptr<SdrHdl> pH(new ImpTextframeHdl(maRect + GetGridOffset()));
+ std::unique_ptr<SdrHdl> pH(new ImpTextframeHdl(maRect));
pH->SetObj(const_cast<SdrRectObj*>(this));
pH->SetRotationAngle(aGeo.nRotationAngle);
rHdlList.AddHdl(std::move(pH));
diff --git a/svx/source/svdraw/svdpagv.cxx b/svx/source/svdraw/svdpagv.cxx
index ed73fadf7acd..c180fe9b459e 100644
--- a/svx/source/svdraw/svdpagv.cxx
+++ b/svx/source/svdraw/svdpagv.cxx
@@ -35,7 +35,7 @@
#include <svx/svdtypes.hxx>
#include <svx/svdoole2.hxx>
-#include <sdr/contact/objectcontactofpageview.hxx>
+#include <svx/sdr/contact/objectcontactofpageview.hxx>
#include <svx/sdr/contact/viewobjectcontactredirector.hxx>
#include <svx/fmview.hxx>
diff --git a/svx/source/svdraw/svdview.cxx b/svx/source/svdraw/svdview.cxx
index c68bbe443a72..0cee85fe96c3 100644
--- a/svx/source/svdraw/svdview.cxx
+++ b/svx/source/svdraw/svdview.cxx
@@ -51,6 +51,7 @@
#include <svx/sdr/contact/viewcontact.hxx>
#include <drawinglayer/processor2d/contourextractor2d.hxx>
#include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx>
+#include <svx/sdr/contact/objectcontactofpageview.hxx>
#include <sal/log.hxx>
@@ -1470,5 +1471,12 @@ void SdrView::SetMasterPagePaintCaching(bool bOn)
}
}
+// Default ObjectContact is ObjectContactOfPageView
+sdr::contact::ObjectContact* SdrView::createViewSpecificObjectContact(
+ SdrPageWindow& rPageWindow,
+ const sal_Char* pDebugName) const
+{
+ return new sdr::contact::ObjectContactOfPageView(rPageWindow, pDebugName);
+}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */