summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSarper Akdemir <sarper.akdemir.extern@allotropia.de>2023-07-18 16:57:59 +0300
committerThorsten Behrens <thorsten.behrens@allotropia.de>2023-07-21 01:37:18 +0200
commit2c8c436c4a8546276e285dd18f3f7ded091a2c4e (patch)
tree42c2c380b57a5037bef21591ee685cb17ac0fc4d
parent3d4f9e3818cde6efcf88a8bfa39eb42c0fa949f8 (diff)
tdf#152992: for Impress/Draw add horizontal hit tolerance for quick text edit
Implements horizontal hit tolerance for quick text edit in Impress & Draw making it more forgiving. Previously it was required to click exactly on the glyph to get a direct text cursor. Refactors hittestprocessor2d so that it now supports pseudo per axis hit tolerance. i.e. underlying isInEpsilonRange hit check is still the same utilizing the larger tolerance of the two per axis tolerance, but the preliminary check that uses aPolygonRange.grow() and later aPolygonRange.isInside() now filters hit misses out with respect to the per axis hit tolerance. Utilizes hittestprocessor2d's new per axis tolerance to introduce hit tolerance for quick text edit, making it similar to TextEdit mode hit tolerance which only has horizontal tolerance. Fixes wrong use of BoundRect hit to determine text frame border hits. Which previously only made sense for TextFrame borders, and was mostly useless for shapes with text inside. Change-Id: I749e63752da05b01270bfcab2632c41879a848ec Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154640 Reviewed-by: Heiko Tietze <heiko.tietze@documentfoundation.org> Tested-by: Jenkins Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de>
-rw-r--r--drawinglayer/source/processor2d/hittestprocessor2d.cxx49
-rw-r--r--include/basegfx/range/Range2D.hxx7
-rw-r--r--include/drawinglayer/processor2d/hittestprocessor2d.hxx10
-rw-r--r--include/svx/sdrhittesthelper.hxx12
-rw-r--r--sc/source/ui/drawfunc/fupoor.cxx5
-rw-r--r--sc/source/ui/drawfunc/fusel2.cxx5
-rw-r--r--sc/source/ui/unoobj/viewuno.cxx5
-rw-r--r--sd/source/ui/func/fudraw.cxx12
-rw-r--r--sd/source/ui/func/fusel.cxx12
-rw-r--r--sd/source/ui/view/sdview3.cxx13
-rw-r--r--svx/source/accessibility/GraphCtlAccessibleContext.cxx2
-rw-r--r--svx/source/sdr/overlay/overlayobjectlist.cxx2
-rw-r--r--svx/source/svdraw/sdrhittesthelper.cxx19
-rw-r--r--svx/source/svdraw/svdetc.cxx2
-rw-r--r--svx/source/svdraw/svdmrkv.cxx4
-rw-r--r--svx/source/svdraw/svdobj.cxx2
-rw-r--r--svx/source/svdraw/svdocapt.cxx2
-rw-r--r--svx/source/svdraw/svdoedge.cxx12
-rw-r--r--svx/source/svdraw/svdview.cxx25
19 files changed, 108 insertions, 92 deletions
diff --git a/drawinglayer/source/processor2d/hittestprocessor2d.cxx b/drawinglayer/source/processor2d/hittestprocessor2d.cxx
index 9af3504a5113..6e624fa4ef97 100644
--- a/drawinglayer/source/processor2d/hittestprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/hittestprocessor2d.cxx
@@ -41,27 +41,25 @@ namespace drawinglayer::processor2d
{
HitTestProcessor2D::HitTestProcessor2D(const geometry::ViewInformation2D& rViewInformation,
const basegfx::B2DPoint& rLogicHitPosition,
- double fLogicHitTolerance,
+ const basegfx::B2DVector& rLogicHitTolerance,
bool bHitTextOnly)
: BaseProcessor2D(rViewInformation),
- mfDiscreteHitTolerance(0.0),
+ maDiscreteHitTolerance(rLogicHitTolerance),
mbCollectHitStack(false),
mbHit(false),
mbHitTextOnly(bHitTextOnly)
{
- // init hit tolerance
- mfDiscreteHitTolerance = fLogicHitTolerance;
+ // ensure input parameters for hit tolerance is >= 0.0
+ if (maDiscreteHitTolerance.getX() < 0.0)
+ maDiscreteHitTolerance.setX(0.0);
+ if (maDiscreteHitTolerance.getY() < 0.0)
+ maDiscreteHitTolerance.setY(0.0);
- if(basegfx::fTools::less(mfDiscreteHitTolerance, 0.0))
- {
- // ensure input parameter for hit tolerance is >= 0.0
- mfDiscreteHitTolerance = 0.0;
- }
- else if(basegfx::fTools::more(mfDiscreteHitTolerance, 0.0))
+ if (!maDiscreteHitTolerance.equalZero())
{
// generate discrete hit tolerance
- mfDiscreteHitTolerance = (getViewInformation2D().getObjectToViewTransformation()
- * basegfx::B2DVector(mfDiscreteHitTolerance, 0.0)).getLength();
+ maDiscreteHitTolerance
+ = getViewInformation2D().getObjectToViewTransformation() * rLogicHitTolerance;
}
// generate discrete hit position
@@ -74,7 +72,7 @@ namespace drawinglayer::processor2d
bool HitTestProcessor2D::checkHairlineHitWithTolerance(
const basegfx::B2DPolygon& rPolygon,
- double fDiscreteHitTolerance) const
+ const basegfx::B2DVector& rDiscreteHitTolerance) const
{
basegfx::B2DPolygon aLocalPolygon(rPolygon);
aLocalPolygon.transform(getViewInformation2D().getObjectToViewTransformation());
@@ -82,9 +80,9 @@ namespace drawinglayer::processor2d
// get discrete range
basegfx::B2DRange aPolygonRange(aLocalPolygon.getB2DRange());
- if(basegfx::fTools::more(fDiscreteHitTolerance, 0.0))
+ if(rDiscreteHitTolerance.getX() > 0 || rDiscreteHitTolerance.getY() > 0)
{
- aPolygonRange.grow(fDiscreteHitTolerance);
+ aPolygonRange.grow(rDiscreteHitTolerance);
}
// do rough range test first
@@ -94,7 +92,7 @@ namespace drawinglayer::processor2d
return basegfx::utils::isInEpsilonRange(
aLocalPolygon,
getDiscreteHitPosition(),
- fDiscreteHitTolerance);
+ std::max(rDiscreteHitTolerance.getX(), rDiscreteHitTolerance.getY()));
}
return false;
@@ -102,7 +100,7 @@ namespace drawinglayer::processor2d
bool HitTestProcessor2D::checkFillHitWithTolerance(
const basegfx::B2DPolyPolygon& rPolyPolygon,
- double fDiscreteHitTolerance) const
+ const basegfx::B2DVector& rDiscreteHitTolerance) const
{
bool bRetval(false);
basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolyPolygon);
@@ -110,11 +108,13 @@ namespace drawinglayer::processor2d
// get discrete range
basegfx::B2DRange aPolygonRange(aLocalPolyPolygon.getB2DRange());
- const bool bDiscreteHitToleranceUsed(basegfx::fTools::more(fDiscreteHitTolerance, 0.0));
- if(bDiscreteHitToleranceUsed)
+ const bool bDiscreteHitToleranceUsed(rDiscreteHitTolerance.getX() > 0
+ || rDiscreteHitTolerance.getY() > 0);
+
+ if (bDiscreteHitToleranceUsed)
{
- aPolygonRange.grow(fDiscreteHitTolerance);
+ aPolygonRange.grow(rDiscreteHitTolerance);
}
// do rough range test first
@@ -125,7 +125,7 @@ namespace drawinglayer::processor2d
basegfx::utils::isInEpsilonRange(
aLocalPolyPolygon,
getDiscreteHitPosition(),
- fDiscreteHitTolerance))
+ std::max(rDiscreteHitTolerance.getX(), rDiscreteHitTolerance.getY())))
{
bRetval = true;
}
@@ -294,7 +294,7 @@ namespace drawinglayer::processor2d
* basegfx::B2DVector(rLineAttribute.getWidth() * 0.5, 0.0));
mbHit = checkHairlineHitWithTolerance(
rPolygonCandidate.getB2DPolygon(),
- getDiscreteHitTolerance() + aDiscreteHalfLineVector.getLength());
+ getDiscreteHitTolerance() + aDiscreteHalfLineVector);
}
}
else
@@ -332,7 +332,7 @@ namespace drawinglayer::processor2d
mbHit = checkHairlineHitWithTolerance(
rPolygonCandidate.getB2DPolygon(),
- getDiscreteHitTolerance() + aDiscreteHalfLineVector.getLength());
+ getDiscreteHitTolerance() + aDiscreteHalfLineVector);
}
break;
@@ -516,7 +516,8 @@ namespace drawinglayer::processor2d
const basegfx::B2DPoint aPosition(getViewInformation2D().getObjectToViewTransformation() * rPositions[a]);
const basegfx::B2DVector aDistance(aPosition - getDiscreteHitPosition());
- if(aDistance.getLength() <= getDiscreteHitTolerance())
+ if (aDistance.getLength() <= std::max(getDiscreteHitTolerance().getX(),
+ getDiscreteHitTolerance().getY()))
{
mbHit = true;
}
diff --git a/include/basegfx/range/Range2D.hxx b/include/basegfx/range/Range2D.hxx
index 664887529d35..c93ca1664151 100644
--- a/include/basegfx/range/Range2D.hxx
+++ b/include/basegfx/range/Range2D.hxx
@@ -166,6 +166,13 @@ public:
maRangeY.grow(fValue);
}
+ /// grow set by axis aware values from rTuple
+ void grow(const Tuple2D<TYPE>& rTuple)
+ {
+ maRangeX.grow(rTuple.getX());
+ maRangeY.grow(rTuple.getY());
+ }
+
/// clamp value on range
Tuple2D<TYPE> clamp(const Tuple2D<TYPE>& rTuple) const
{
diff --git a/include/drawinglayer/processor2d/hittestprocessor2d.hxx b/include/drawinglayer/processor2d/hittestprocessor2d.hxx
index 5638f688964e..5755cf77f5e0 100644
--- a/include/drawinglayer/processor2d/hittestprocessor2d.hxx
+++ b/include/drawinglayer/processor2d/hittestprocessor2d.hxx
@@ -42,7 +42,7 @@ namespace drawinglayer::processor2d
basegfx::B2DPoint maDiscreteHitPosition;
/// discrete HitTolerance
- double mfDiscreteHitTolerance;
+ basegfx::B2DVector maDiscreteHitTolerance;
/// stack of HitPrimitives, taken care of during HitTest run
primitive2d::Primitive2DContainer maHitStack;
@@ -60,17 +60,17 @@ namespace drawinglayer::processor2d
void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) override;
bool checkHairlineHitWithTolerance(
const basegfx::B2DPolygon& rPolygon,
- double fDiscreteHitTolerance) const;
+ const basegfx::B2DVector& rDiscreteHitTolerance) const;
bool checkFillHitWithTolerance(
const basegfx::B2DPolyPolygon& rPolyPolygon,
- double fDiscreteHitTolerance) const;
+ const basegfx::B2DVector& rDiscreteHitTolerance) const;
void check3DHit(const primitive2d::ScenePrimitive2D& rCandidate);
public:
HitTestProcessor2D(
const geometry::ViewInformation2D& rViewInformation,
const basegfx::B2DPoint& rLogicHitPosition,
- double fLogicHitTolerance,
+ const basegfx::B2DVector& rLogicHitTolerance,
bool bHitTextOnly);
virtual ~HitTestProcessor2D() override;
@@ -83,7 +83,7 @@ namespace drawinglayer::processor2d
/// data read access
const basegfx::B2DPoint& getDiscreteHitPosition() const { return maDiscreteHitPosition; }
- double getDiscreteHitTolerance() const { return mfDiscreteHitTolerance; }
+ const basegfx::B2DVector& getDiscreteHitTolerance() const { return maDiscreteHitTolerance; }
bool getCollectHitStack() const { return mbCollectHitStack; }
bool getHit() const { return mbHit; }
bool getHitTextOnly() const { return mbHitTextOnly; }
diff --git a/include/svx/sdrhittesthelper.hxx b/include/svx/sdrhittesthelper.hxx
index 87cf1afbea10..5df35c7df28a 100644
--- a/include/svx/sdrhittesthelper.hxx
+++ b/include/svx/sdrhittesthelper.hxx
@@ -32,7 +32,11 @@ class SdrPageView;
class SdrLayerIDSet;
class SdrObjList;
namespace sdr::contact { class ViewObjectContact; }
-namespace basegfx { class B2DPoint; }
+namespace basegfx
+{
+class B2DPoint;
+class B2DVector;
+}
namespace drawinglayer::primitive2d { class Primitive2DContainer; }
@@ -41,7 +45,7 @@ namespace drawinglayer::primitive2d { class Primitive2DContainer; }
SVXCORE_DLLPUBLIC SdrObject* SdrObjectPrimitiveHit(
const SdrObject& rObject,
const Point& rPnt,
- sal_uInt16 nTol,
+ const basegfx::B2DVector& rHitTolerance,
const SdrPageView& rSdrPageView,
const SdrLayerIDSet* pVisiLayer,
bool bTextOnly,
@@ -51,7 +55,7 @@ SVXCORE_DLLPUBLIC SdrObject* SdrObjectPrimitiveHit(
SVXCORE_DLLPUBLIC SdrObject* SdrObjListPrimitiveHit(
const SdrObjList& rList,
const Point& rPnt,
- sal_uInt16 nTol,
+ const basegfx::B2DVector& rHitTolerance,
const SdrPageView& rSdrPageView,
const SdrLayerIDSet* pVisiLayer,
bool bTextOnly);
@@ -62,7 +66,7 @@ SVXCORE_DLLPUBLIC SdrObject* SdrObjListPrimitiveHit(
bool ViewObjectContactPrimitiveHit(
const sdr::contact::ViewObjectContact& rVOC,
const basegfx::B2DPoint& rHitPosition,
- double fLogicHitTolerance,
+ const basegfx::B2DVector& rLogicHitTolerance,
bool bTextOnly,
/// allow to get back the stack of primitives that lead to the hit
drawinglayer::primitive2d::Primitive2DContainer* pHitContainer);
diff --git a/sc/source/ui/drawfunc/fupoor.cxx b/sc/source/ui/drawfunc/fupoor.cxx
index a10aa185b54f..4299e02512d8 100644
--- a/sc/source/ui/drawfunc/fupoor.cxx
+++ b/sc/source/ui/drawfunc/fupoor.cxx
@@ -196,9 +196,8 @@ bool FuPoor::IsDetectiveHit( const Point& rLogicPos )
{
if (ScDetectiveFunc::IsNonAlienArrow( pObject ))
{
- sal_uInt16 nHitLog = static_cast<sal_uInt16>(pWindow->PixelToLogic(
- Size(pView->GetHitTolerancePixel(),0)).Width());
- if(SdrObjectPrimitiveHit(*pObject, rLogicPos, nHitLog, *pPV, nullptr, false))
+ double fHitLog = pWindow->PixelToLogic(Size(pView->GetHitTolerancePixel(),0)).Width();
+ if(SdrObjectPrimitiveHit(*pObject, rLogicPos, {fHitLog, fHitLog}, *pPV, nullptr, false))
{
bFound = true;
}
diff --git a/sc/source/ui/drawfunc/fusel2.cxx b/sc/source/ui/drawfunc/fusel2.cxx
index 4ce7c2be290d..cc9a1478ceb4 100644
--- a/sc/source/ui/drawfunc/fusel2.cxx
+++ b/sc/source/ui/drawfunc/fusel2.cxx
@@ -53,9 +53,8 @@ bool FuSelection::TestDetective( const SdrPageView* pPV, const Point& rPos )
{
if (ScDetectiveFunc::IsNonAlienArrow( pObject ))
{
- sal_uInt16 nHitLog = static_cast<sal_uInt16>(pWindow->PixelToLogic(
- Size(pView->GetHitTolerancePixel(),0)).Width());
- if (SdrObjectPrimitiveHit(*pObject, rPos, nHitLog, *pPV, nullptr, false))
+ double fHitLog = pWindow->PixelToLogic(Size(pView->GetHitTolerancePixel(),0)).Width();
+ if (SdrObjectPrimitiveHit(*pObject, rPos, {fHitLog, fHitLog}, *pPV, nullptr, false))
{
ScViewData& rViewData = rViewShell.GetViewData();
ScSplitPos ePos = rViewShell.FindWindow( pWindow );
diff --git a/sc/source/ui/unoobj/viewuno.cxx b/sc/source/ui/unoobj/viewuno.cxx
index e92c45deec39..80b1e4afdac7 100644
--- a/sc/source/ui/unoobj/viewuno.cxx
+++ b/sc/source/ui/unoobj/viewuno.cxx
@@ -1110,15 +1110,14 @@ uno::Reference< uno::XInterface > ScTabViewObj::GetClickedObject(const Point& rP
vcl::Window* pActiveWin = rData.GetActiveWin();
Point aPos = pActiveWin->PixelToLogic(rPoint);
- sal_uInt16 nHitLog = static_cast<sal_uInt16>(pActiveWin->PixelToLogic(
- Size(pDrawView->GetHitTolerancePixel(),0)).Width());
+ double fHitLog = pActiveWin->PixelToLogic(Size(pDrawView->GetHitTolerancePixel(),0)).Width();
const size_t nCount(pDrawPage->GetObjCount());
bool bFound(false);
for (size_t i = 0; i < nCount && !bFound; ++i)
{
SdrObject* pObj = pDrawPage->GetObj(i);
- if (pObj && SdrObjectPrimitiveHit(*pObj, aPos, nHitLog, *pDrawView->GetSdrPageView(), nullptr, false))
+ if (pObj && SdrObjectPrimitiveHit(*pObj, aPos, {fHitLog, fHitLog}, *pDrawView->GetSdrPageView(), nullptr, false))
{
xTarget.set(pObj->getUnoShape(), uno::UNO_QUERY);
bFound = true;
diff --git a/sd/source/ui/func/fudraw.cxx b/sd/source/ui/func/fudraw.cxx
index ed4478747e8c..fca4f65fa54e 100644
--- a/sd/source/ui/func/fudraw.cxx
+++ b/sd/source/ui/func/fudraw.cxx
@@ -588,8 +588,8 @@ bool FuDraw::SetPointer(const SdrObject* pObj, const Point& rPos)
return false;
const SdrLayerIDSet* pVisiLayer = &mpView->GetSdrPageView()->GetVisibleLayers();
- sal_uInt16 nHitLog(sal_uInt16(mpWindow->PixelToLogic(Size(HITPIX, 0)).Width()));
- ::tools::Long n2HitLog(nHitLog * 2);
+ double fHitLog(mpWindow->PixelToLogic(Size(HITPIX, 0)).Width());
+ ::tools::Long n2HitLog(fHitLog * 2);
Point aHitPosR(rPos);
Point aHitPosL(rPos);
Point aHitPosT(rPos);
@@ -601,13 +601,13 @@ bool FuDraw::SetPointer(const SdrObject* pObj, const Point& rPos)
aHitPosB.AdjustY(-n2HitLog);
if (!pObj->IsClosedObj()
- || (SdrObjectPrimitiveHit(*pObj, aHitPosR, nHitLog, *mpView->GetSdrPageView(), pVisiLayer,
+ || (SdrObjectPrimitiveHit(*pObj, aHitPosR, {fHitLog, fHitLog}, *mpView->GetSdrPageView(), pVisiLayer,
false)
- && SdrObjectPrimitiveHit(*pObj, aHitPosL, nHitLog, *mpView->GetSdrPageView(),
+ && SdrObjectPrimitiveHit(*pObj, aHitPosL, {fHitLog, fHitLog}, *mpView->GetSdrPageView(),
pVisiLayer, false)
- && SdrObjectPrimitiveHit(*pObj, aHitPosT, nHitLog, *mpView->GetSdrPageView(),
+ && SdrObjectPrimitiveHit(*pObj, aHitPosT, {fHitLog, fHitLog}, *mpView->GetSdrPageView(),
pVisiLayer, false)
- && SdrObjectPrimitiveHit(*pObj, aHitPosB, nHitLog, *mpView->GetSdrPageView(),
+ && SdrObjectPrimitiveHit(*pObj, aHitPosB, {fHitLog, fHitLog}, *mpView->GetSdrPageView(),
pVisiLayer, false)))
{
// hit inside the object (without margin) or open object
diff --git a/sd/source/ui/func/fusel.cxx b/sd/source/ui/func/fusel.cxx
index 4a897e7df7f2..4d7fec5f8d43 100644
--- a/sd/source/ui/func/fusel.cxx
+++ b/sd/source/ui/func/fusel.cxx
@@ -1237,8 +1237,8 @@ bool FuSelection::HandleImageMapClick(const SdrObject* pObj, const Point& rPos)
}
const SdrLayerIDSet* pVisiLayer = &mpView->GetSdrPageView()->GetVisibleLayers();
- sal_uInt16 nHitLog = sal_uInt16(mpWindow->PixelToLogic(Size(HITPIX, 0)).Width());
- const ::tools::Long n2HitLog = nHitLog * 2;
+ double fHitLog = mpWindow->PixelToLogic(Size(HITPIX, 0)).Width();
+ const ::tools::Long n2HitLog = fHitLog * 2;
Point aHitPosR(rPos);
Point aHitPosL(rPos);
Point aHitPosT(rPos);
@@ -1250,13 +1250,13 @@ bool FuSelection::HandleImageMapClick(const SdrObject* pObj, const Point& rPos)
aHitPosB.AdjustY(-n2HitLog);
if (!bClosed || !bFilled
- || (SdrObjectPrimitiveHit(*pObj, aHitPosR, nHitLog, *mpView->GetSdrPageView(), pVisiLayer,
+ || (SdrObjectPrimitiveHit(*pObj, aHitPosR, {fHitLog, fHitLog}, *mpView->GetSdrPageView(), pVisiLayer,
false)
- && SdrObjectPrimitiveHit(*pObj, aHitPosL, nHitLog, *mpView->GetSdrPageView(),
+ && SdrObjectPrimitiveHit(*pObj, aHitPosL, {fHitLog, fHitLog}, *mpView->GetSdrPageView(),
pVisiLayer, false)
- && SdrObjectPrimitiveHit(*pObj, aHitPosT, nHitLog, *mpView->GetSdrPageView(),
+ && SdrObjectPrimitiveHit(*pObj, aHitPosT, {fHitLog, fHitLog}, *mpView->GetSdrPageView(),
pVisiLayer, false)
- && SdrObjectPrimitiveHit(*pObj, aHitPosB, nHitLog, *mpView->GetSdrPageView(),
+ && SdrObjectPrimitiveHit(*pObj, aHitPosB, {fHitLog, fHitLog}, *mpView->GetSdrPageView(),
pVisiLayer, false)))
{
if (SvxIMapInfo::GetIMapInfo(pObj))
diff --git a/sd/source/ui/view/sdview3.cxx b/sd/source/ui/view/sdview3.cxx
index 06f07048455e..7065c677246b 100644
--- a/sd/source/ui/view/sdview3.cxx
+++ b/sd/source/ui/view/sdview3.cxx
@@ -1378,9 +1378,8 @@ bool View::InsertData( const TransferableDataHelper& rDataHelper,
SfxItemSet aSet( mrDoc.GetPool() );
bool bClosed = pPickObj->IsClosedObj();
::sd::Window* pWin = mpViewSh->GetActiveWindow();
- sal_uInt16 nHitLog = static_cast<sal_uInt16>(pWin->PixelToLogic(
- Size(FuPoor::HITPIX, 0 ) ).Width());
- const ::tools::Long n2HitLog = nHitLog << 1;
+ double fHitLog = pWin->PixelToLogic(Size(FuPoor::HITPIX, 0 ) ).Width();
+ const ::tools::Long n2HitLog = fHitLog * 2;
Point aHitPosR( rPos );
Point aHitPosL( rPos );
Point aHitPosT( rPos );
@@ -1393,10 +1392,10 @@ bool View::InsertData( const TransferableDataHelper& rDataHelper,
aHitPosB.AdjustY( -n2HitLog );
if( bClosed &&
- SdrObjectPrimitiveHit(*pPickObj, aHitPosR, nHitLog, *GetSdrPageView(), pVisiLayer, false) &&
- SdrObjectPrimitiveHit(*pPickObj, aHitPosL, nHitLog, *GetSdrPageView(), pVisiLayer, false) &&
- SdrObjectPrimitiveHit(*pPickObj, aHitPosT, nHitLog, *GetSdrPageView(), pVisiLayer, false) &&
- SdrObjectPrimitiveHit(*pPickObj, aHitPosB, nHitLog, *GetSdrPageView(), pVisiLayer, false) )
+ SdrObjectPrimitiveHit(*pPickObj, aHitPosR, {fHitLog, fHitLog}, *GetSdrPageView(), pVisiLayer, false) &&
+ SdrObjectPrimitiveHit(*pPickObj, aHitPosL, {fHitLog, fHitLog}, *GetSdrPageView(), pVisiLayer, false) &&
+ SdrObjectPrimitiveHit(*pPickObj, aHitPosT, {fHitLog, fHitLog}, *GetSdrPageView(), pVisiLayer, false) &&
+ SdrObjectPrimitiveHit(*pPickObj, aHitPosB, {fHitLog, fHitLog}, *GetSdrPageView(), pVisiLayer, false) )
{
// area fill
if(eFill == drawing::FillStyle_SOLID )
diff --git a/svx/source/accessibility/GraphCtlAccessibleContext.cxx b/svx/source/accessibility/GraphCtlAccessibleContext.cxx
index c30756804b49..1287f7e9ea2f 100644
--- a/svx/source/accessibility/GraphCtlAccessibleContext.cxx
+++ b/svx/source/accessibility/GraphCtlAccessibleContext.cxx
@@ -181,7 +181,7 @@ Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleAt
if(mpView && mpView->GetSdrPageView())
{
- pObj = SdrObjListPrimitiveHit(*mpPage, aPnt, 1, *mpView->GetSdrPageView(), nullptr, false);
+ pObj = SdrObjListPrimitiveHit(*mpPage, aPnt, {1, 1}, *mpView->GetSdrPageView(), nullptr, false);
}
if( pObj )
diff --git a/svx/source/sdr/overlay/overlayobjectlist.cxx b/svx/source/sdr/overlay/overlayobjectlist.cxx
index d71f6c2783b9..32e785d4011a 100644
--- a/svx/source/sdr/overlay/overlayobjectlist.cxx
+++ b/svx/source/sdr/overlay/overlayobjectlist.cxx
@@ -80,7 +80,7 @@ namespace sdr::overlay
drawinglayer::processor2d::HitTestProcessor2D aHitTestProcessor2D(
aViewInformation2D,
rLogicPosition,
- fLogicTolerance,
+ {fLogicTolerance, fLogicTolerance},
false);
for(auto & pCandidate : maVector)
diff --git a/svx/source/svdraw/sdrhittesthelper.cxx b/svx/source/svdraw/sdrhittesthelper.cxx
index 62ebde956c73..9dc3b9118f07 100644
--- a/svx/source/svdraw/sdrhittesthelper.cxx
+++ b/svx/source/svdraw/sdrhittesthelper.cxx
@@ -36,7 +36,7 @@
SdrObject* SdrObjectPrimitiveHit(
const SdrObject& rObject,
const Point& rPnt,
- sal_uInt16 nTol,
+ const basegfx::B2DVector& rHitTolerance,
const SdrPageView& rSdrPageView,
const SdrLayerIDSet* pVisiLayer,
bool bTextOnly,
@@ -48,7 +48,7 @@ SdrObject* SdrObjectPrimitiveHit(
{
// group or scene with content. Single 3D objects also have a
// true == rObject.GetSubList(), but no content
- pResult = SdrObjListPrimitiveHit(*rObject.GetSubList(), rPnt, nTol, rSdrPageView, pVisiLayer, bTextOnly);
+ pResult = SdrObjListPrimitiveHit(*rObject.GetSubList(), rPnt, rHitTolerance, rSdrPageView, pVisiLayer, bTextOnly);
}
else
{
@@ -73,12 +73,11 @@ SdrObject* SdrObjectPrimitiveHit(
// with split views uses multiple PageWindows nowadays)
if(rSdrPageView.PageWindowCount())
{
- const double fLogicTolerance(nTol);
const basegfx::B2DPoint aHitPosition(rPnt.X(), rPnt.Y());
const sdr::contact::ViewObjectContact& rVOC = rObject.GetViewContact().GetViewObjectContact(
rSdrPageView.GetPageWindow(0)->GetObjectContact());
- if(ViewObjectContactPrimitiveHit(rVOC, aHitPosition, fLogicTolerance, bTextOnly, pHitContainer))
+ if(ViewObjectContactPrimitiveHit(rVOC, aHitPosition, rHitTolerance, bTextOnly, pHitContainer))
{
pResult = const_cast< SdrObject* >(&rObject);
}
@@ -94,7 +93,7 @@ SdrObject* SdrObjectPrimitiveHit(
SdrObject* SdrObjListPrimitiveHit(
const SdrObjList& rList,
const Point& rPnt,
- sal_uInt16 nTol,
+ const basegfx::B2DVector& rHitTolerance,
const SdrPageView& rSdrPageView,
const SdrLayerIDSet* pVisiLayer,
bool bTextOnly)
@@ -107,7 +106,7 @@ SdrObject* SdrObjListPrimitiveHit(
nObjNum--;
SdrObject* pObj = rList.GetObj(nObjNum);
- pRetval = SdrObjectPrimitiveHit(*pObj, rPnt, nTol, rSdrPageView, pVisiLayer, bTextOnly);
+ pRetval = SdrObjectPrimitiveHit(*pObj, rPnt, rHitTolerance, rSdrPageView, pVisiLayer, bTextOnly);
}
return pRetval;
@@ -117,7 +116,7 @@ SdrObject* SdrObjListPrimitiveHit(
bool ViewObjectContactPrimitiveHit(
const sdr::contact::ViewObjectContact& rVOC,
const basegfx::B2DPoint& rHitPosition,
- double fLogicHitTolerance,
+ const basegfx::B2DVector& rLogicHitTolerance,
bool bTextOnly,
drawinglayer::primitive2d::Primitive2DContainer* pHitContainer)
{
@@ -127,9 +126,9 @@ bool ViewObjectContactPrimitiveHit(
{
// first do a rough B2DRange based HitTest; do not forget to
// include the HitTolerance if given
- if(basegfx::fTools::more(fLogicHitTolerance, 0.0))
+ if(rLogicHitTolerance.getX() > 0 || rLogicHitTolerance.getY() > 0)
{
- aObjectRange.grow(fLogicHitTolerance);
+ aObjectRange.grow(rLogicHitTolerance);
}
if(aObjectRange.isInside(rHitPosition))
@@ -146,7 +145,7 @@ bool ViewObjectContactPrimitiveHit(
drawinglayer::processor2d::HitTestProcessor2D aHitTestProcessor2D(
rViewInformation2D,
rHitPosition,
- fLogicHitTolerance,
+ rLogicHitTolerance,
bTextOnly);
// ask for HitStack
diff --git a/svx/source/svdraw/svdetc.cxx b/svx/source/svdraw/svdetc.cxx
index acd15f7cc265..feb879f27c5d 100644
--- a/svx/source/svdraw/svdetc.cxx
+++ b/svx/source/svdraw/svdetc.cxx
@@ -504,7 +504,7 @@ namespace
&& (!bMaster || (!pObj->IsNotVisibleAsMaster() && 0 != no))
&& pObj->GetCurrentBoundRect().Contains(rPnt)
&& !pText->IsHideContour()
- && SdrObjectPrimitiveHit(*pObj, rPnt, 0, rTextEditPV, &rVisLayers, false))
+ && SdrObjectPrimitiveHit(*pObj, rPnt, {0, 0}, rTextEditPV, &rVisLayers, false))
{
bRet = GetDraftFillColor(pObj->GetMergedItemSet(), rCol);
}
diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx
index 7a623dca9c92..5b8a86a9526d 100644
--- a/svx/source/svdraw/svdmrkv.cxx
+++ b/svx/source/svdraw/svdmrkv.cxx
@@ -2323,7 +2323,7 @@ SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nT
basegfx::fround(aGridOffset.getY()));
}
- sal_uInt16 nTol2(nTol);
+ double nTol2(nTol);
// double tolerance for OLE, text frames and objects in
// active text edit
@@ -2361,7 +2361,7 @@ SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nT
{
if(!pMVisLay || pMVisLay->IsSet(pObj->GetLayer()))
{
- pRet = SdrObjectPrimitiveHit(*pObj, rPnt, nTol2, *pPV, &pPV->GetVisibleLayers(), false);
+ pRet = SdrObjectPrimitiveHit(*pObj, rPnt, {nTol2, nTol2}, *pPV, &pPV->GetVisibleLayers(), false);
}
}
}
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index 77a78035cdda..5c7789ee7ed0 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -1853,7 +1853,7 @@ SdrObject* SdrObject::CheckMacroHit(const SdrObjMacroHitRec& rRec) const
{
if(rRec.pPageView)
{
- return SdrObjectPrimitiveHit(*this, rRec.aPos, rRec.nTol, *rRec.pPageView, rRec.pVisiLayer, false);
+ return SdrObjectPrimitiveHit(*this, rRec.aPos, {static_cast<double>(rRec.nTol), static_cast<double>(rRec.nTol)}, *rRec.pPageView, rRec.pVisiLayer, false);
}
return nullptr;
diff --git a/svx/source/svdraw/svdocapt.cxx b/svx/source/svdraw/svdocapt.cxx
index 14e7678499c7..98c86664c28a 100644
--- a/svx/source/svdraw/svdocapt.cxx
+++ b/svx/source/svdraw/svdocapt.cxx
@@ -312,7 +312,7 @@ bool SdrCaptionObj::beginSpecialDrag(SdrDragStat& rDrag) const
Point aHit(rDrag.GetStart());
- if(rDrag.GetPageView() && SdrObjectPrimitiveHit(*this, aHit, 0, *rDrag.GetPageView(), nullptr, false))
+ if(rDrag.GetPageView() && SdrObjectPrimitiveHit(*this, aHit, {0, 0}, *rDrag.GetPageView(), nullptr, false))
{
return true;
}
diff --git a/svx/source/svdraw/svdoedge.cxx b/svx/source/svdraw/svdoedge.cxx
index d63c837f6e90..be203714bddd 100644
--- a/svx/source/svdraw/svdoedge.cxx
+++ b/svx/source/svdraw/svdoedge.cxx
@@ -2155,7 +2155,7 @@ bool SdrEdgeObj::ImpFindConnector(const Point& rPt, const SdrPageView& rPV, SdrO
aMouseRect.AdjustTop( -(aHalfConSiz.Height()) );
aMouseRect.AdjustRight(aHalfConSiz.Width() );
aMouseRect.AdjustBottom(aHalfConSiz.Height() );
- sal_uInt16 nBoundHitTol=static_cast<sal_uInt16>(aHalfConSiz.Width())/2; if (nBoundHitTol==0) nBoundHitTol=1;
+ double fBoundHitTol=static_cast<double>(aHalfConSiz.Width())/2; if (fBoundHitTol==0.0) fBoundHitTol=1.0;
size_t no=pOL->GetObjCount();
bool bFnd = false;
SdrObjConnection aTestCon;
@@ -2249,7 +2249,7 @@ bool SdrEdgeObj::ImpFindConnector(const Point& rPt, const SdrPageView& rPV, SdrO
// if no connector is hit, try HitTest again, for BestConnector (=bCenter)
if(!bFnd &&
!bEdge &&
- SdrObjectPrimitiveHit(*pObj, rPt, nBoundHitTol, rPV, &rVisLayer, false))
+ SdrObjectPrimitiveHit(*pObj, rPt, {fBoundHitTol, fBoundHitTol}, rPV, &rVisLayer, false))
{
// Suppress default connect at object inside bound
if(!pThis || !pThis->GetSuppressDefaultConnect())
@@ -2260,10 +2260,10 @@ bool SdrEdgeObj::ImpFindConnector(const Point& rPt, const SdrPageView& rPV, SdrO
}
}
if (bFnd) {
- aMouseRect.AdjustLeft( -nBoundHitTol );
- aMouseRect.AdjustTop( -nBoundHitTol );
- aMouseRect.AdjustRight(nBoundHitTol );
- aMouseRect.AdjustBottom(nBoundHitTol );
+ aMouseRect.AdjustLeft( -fBoundHitTol );
+ aMouseRect.AdjustTop( -fBoundHitTol );
+ aMouseRect.AdjustRight(fBoundHitTol );
+ aMouseRect.AdjustBottom(fBoundHitTol );
}
}
diff --git a/svx/source/svdraw/svdview.cxx b/svx/source/svdraw/svdview.cxx
index 06680bd5eecc..d6a203ae3ccb 100644
--- a/svx/source/svdraw/svdview.cxx
+++ b/svx/source/svdraw/svdview.cxx
@@ -449,7 +449,7 @@ SdrHitKind SdrView::PickAnything(const Point& rLogicPos, SdrViewEvent& rVEvt) co
// includes grouping primitives (like TextHierarchyPrimitives we deed here)
// but also all decomposed ones which lead to the creation of that primitive
drawinglayer::primitive2d::Primitive2DContainer aHitContainer;
- const bool bTEHit(pPV && SdrObjectPrimitiveHit(*pTextObj, aLocalLogicPosition, 0, *pPV, &pPV->GetVisibleLayers(), true, &aHitContainer));
+ const bool bTEHit(pPV && SdrObjectPrimitiveHit(*pTextObj, aLocalLogicPosition, {0, 0}, *pPV, &pPV->GetVisibleLayers(), true, &aHitContainer));
if (bTEHit && !aHitContainer.empty())
{
@@ -514,13 +514,21 @@ SdrHitKind SdrView::PickAnything(const Point& rLogicPos, SdrViewEvent& rVEvt) co
(eHit==SdrHitKind::MarkedObject || eHit==SdrHitKind::UnmarkedObject) &&
(IsTextTool() || (IsEditMode() && IsQuickTextEditMode())) && pHitObj->HasTextEdit())
{
+ auto pTextObj = DynCastSdrTextObj(pHitObj);
+
// Around the TextEditArea there's a border to select without going into text edit mode.
- tools::Rectangle aBoundRect(pHitObj->GetCurrentBoundRect());
+ tools::Rectangle aBoundRect;
+ const GeoStat& rGeo = pTextObj->GetGeoStat();
+ if (pTextObj && !rGeo.m_nRotationAngle && !rGeo.m_nShearAngle)
+ {
+ pTextObj->TakeTextEditArea(nullptr, nullptr, &aBoundRect, nullptr);
+ }
+ else
+ aBoundRect = pHitObj->GetCurrentBoundRect();
// Force to SnapRect when Fontwork
- if( auto pTextObj = DynCastSdrTextObj(pHitObj) )
- if( pTextObj->IsFontwork() )
- aBoundRect = pHitObj->GetSnapRect();
+ if( pTextObj && pTextObj->IsFontwork() )
+ aBoundRect = pHitObj->GetSnapRect();
sal_Int32 nTolerance(mnHitTolLog);
bool bBoundRectHit(false);
@@ -538,10 +546,11 @@ SdrHitKind SdrView::PickAnything(const Point& rLogicPos, SdrViewEvent& rVEvt) co
bBoundRectHit = true;
}
- if(!bBoundRectHit)
+ if(!bBoundRectHit && aBoundRect.Contains(aLocalLogicPosition))
{
- bool bTEHit(pPV &&
- SdrObjectPrimitiveHit(*pHitObj, aLocalLogicPosition, 0, *pPV, &pPV->GetVisibleLayers(), true));
+ bool bTEHit(pPV
+ && SdrObjectPrimitiveHit(*pHitObj, aLocalLogicPosition, { 2000.0, 0.0 },
+ *pPV, &pPV->GetVisibleLayers(), true));
// TextEdit attached to an object in a locked layer
if (bTEHit && pPV->GetLockedLayers().IsSet(pHitObj->GetLayer()))