drawinglayer/source/processor2d/hittestprocessor2d.cxx  |   49 ++++++++--------
 include/basegfx/range/Range2D.hxx                       |    7 ++
 include/drawinglayer/processor2d/hittestprocessor2d.hxx |   10 +--
 include/svx/sdrhittesthelper.hxx                        |   12 ++-
 sc/source/ui/drawfunc/fupoor.cxx                        |    5 -
 sc/source/ui/drawfunc/fusel2.cxx                        |    5 -
 sc/source/ui/unoobj/viewuno.cxx                         |    5 -
 sd/source/ui/func/fudraw.cxx                            |   12 +--
 sd/source/ui/func/fusel.cxx                             |   12 +--
 sd/source/ui/view/sdview3.cxx                           |   13 +---
 svx/source/accessibility/GraphCtlAccessibleContext.cxx  |    2 
 svx/source/sdr/overlay/overlayobjectlist.cxx            |    2 
 svx/source/svdraw/sdrhittesthelper.cxx                  |   19 ++----
 svx/source/svdraw/svdetc.cxx                            |    2 
 svx/source/svdraw/svdmrkv.cxx                           |    4 -
 svx/source/svdraw/svdobj.cxx                            |    2 
 svx/source/svdraw/svdocapt.cxx                          |    2 
 svx/source/svdraw/svdoedge.cxx                          |   12 +--
 svx/source/svdraw/svdview.cxx                           |   25 +++++---
 19 files changed, 108 insertions(+), 92 deletions(-)

New commits:
commit 2c8c436c4a8546276e285dd18f3f7ded091a2c4e
Author:     Sarper Akdemir <sarper.akdemir.ext...@allotropia.de>
AuthorDate: Tue Jul 18 16:57:59 2023 +0300
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Fri Jul 21 01:37:18 2023 +0200

    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.tie...@documentfoundation.org>
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>

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()))

Reply via email to