diff options
author | Michael Stahl <mstahl@redhat.com> | 2013-08-28 14:16:38 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@suse.cz> | 2013-08-29 14:40:17 +0000 |
commit | 2ab0e4df9951009d68614583c0db3527e07f7bab (patch) | |
tree | 9e175e7853681bba60bda4e66777db2e2f7c66a6 | |
parent | 43003812ca085a642d262d5cbf1a63f8df043d40 (diff) |
fdo#66215: sw: fix clicking on text above background fly
SwPageFrm::GetCrsrOfst() tries to compare the distance to the closest
text vs. fly but does not do it right because GetCharRect()
returns just a line of width 1 on the left edge of the character;
try to figure out the entire area covered by the character via 2 calls
to GetCrsrOfst(), which gives much better clickability.
(regression from e8fbe97900f13305b17015d9044993bde4adab36)
Change-Id: I825e86daf65692dfb962ad576772c5f543d02d19
(cherry picked from commit edd2db1c783bd571ff796a5298385cacc91877b9)
Reviewed-on: https://gerrit.libreoffice.org/5660
Reviewed-by: Miklos Vajna <vmiklos@suse.cz>
Tested-by: Miklos Vajna <vmiklos@suse.cz>
-rw-r--r-- | sw/inc/crstate.hxx | 2 | ||||
-rw-r--r-- | sw/source/core/layout/trvlfrm.cxx | 45 |
2 files changed, 43 insertions, 4 deletions
diff --git a/sw/inc/crstate.hxx b/sw/inc/crstate.hxx index 6c8c86f6c6a1..7bd3cb4b5c4b 100644 --- a/sw/inc/crstate.hxx +++ b/sw/inc/crstate.hxx @@ -143,7 +143,7 @@ struct SwCrsrMoveState sal_Bool bRealWidth; ///< Calculation of the width required sal_Bool b2Lines; ///< Check 2line portions and fill p2Lines sal_Bool bNoScroll; ///< No scrolling of undersized textframes - sal_Bool bPosMatchesBounds; /**< GetCrsrOfst should not return the next + bool bPosMatchesBounds; /**< GetCrsrOfst should not return the next position if screen position is inside second have of bound rect */ diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx index 0d9fd9c85150..fcaa4af43ff1 100644 --- a/sw/source/core/layout/trvlfrm.cxx +++ b/sw/source/core/layout/trvlfrm.cxx @@ -19,6 +19,7 @@ #include <hintids.hxx> #include <hints.hxx> +#include <comphelper/flagguard.hxx> #include <tools/bigint.hxx> #include <tools/line.hxx> #include <editeng/opaqitem.hxx> @@ -287,10 +288,48 @@ sal_Bool SwPageFrm::GetCrsrOfst( SwPosition *pPos, Point &rPoint, if ( pTextNd ) { SwCntntFrm* pTextFrm = pTextNd->getLayoutFrm( getRootFrm( ) ); - SwRect rTextRect; - pTextFrm->GetCharRect( rTextRect, aTextPos ); - nTextDistance = lcl_getDistance( rTextRect, rPoint ); + // try this again but prefer the "previous" position + SwCrsrMoveState aMoveState; + SwCrsrMoveState *const pState((pCMS) ? pCMS : &aMoveState); + comphelper::FlagRestorationGuard g( + pState->bPosMatchesBounds, true); + SwPosition prevTextPos(*pPos); + SwLayoutFrm::GetCrsrOfst(&prevTextPos, aPoint, pState); + + SwRect aTextRect; + pTextFrm->GetCharRect(aTextRect, prevTextPos); + + if (prevTextPos.nContent < pTextNd->Len()) + { + // aRextRect is just a line on the left edge of the + // previous character; to get a better measure from + // lcl_getDistance, extend that to a rectangle over + // the entire character. + SwPosition const nextTextPos(prevTextPos.nNode, + SwIndex(prevTextPos.nContent, +1)); + SwRect nextTextRect; + pTextFrm->GetCharRect(nextTextRect, nextTextPos); + SWRECTFN(pTextFrm); + if ((aTextRect.*fnRect->fnGetTop)() == + (nextTextRect.*fnRect->fnGetTop)()) // same line? + { + // need to handle mixed RTL/LTR portions somehow + if ((aTextRect.*fnRect->fnGetLeft)() < + (nextTextRect.*fnRect->fnGetLeft)()) + { + (aTextRect.*fnRect->fnSetRight)( + (nextTextRect.*fnRect->fnGetLeft)()); + } + else // RTL + { + (aTextRect.*fnRect->fnSetLeft)( + (nextTextRect.*fnRect->fnGetLeft)()); + } + } + } + + nTextDistance = lcl_getDistance(aTextRect, rPoint); bValidTextDistance = true; // If the text position is a clickable field, then that should have priority. |