summaryrefslogtreecommitdiff
path: root/vcl/source/control
diff options
context:
space:
mode:
authorKhaled Hosny <khaled@libreoffice.org>2023-07-19 19:07:34 +0300
committerخالد حسني <khaled@libreoffice.org>2023-07-23 06:05:02 +0200
commit21013c4662a9ab32d293de263c54ebeceb66828c (patch)
tree58997e69220f3c4d1a452dbf68f03dd1a02d77c8 /vcl/source/control
parent620fdb3a93e07eb87884ce3de8e436d840dc79e1 (diff)
tdf#156377: Improve cursor traversal in UI widgets
Re-implement GetCaretPositions() on top of GetCharWidths() so it can benefit from our code that handles cursor insertion in middle of ligatures. Change-Id: I2b76b3b0125f2454f78cb6779d88617dc29386fe Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154660 Tested-by: Jenkins Reviewed-by: خالد حسني <khaled@libreoffice.org>
Diffstat (limited to 'vcl/source/control')
-rw-r--r--vcl/source/control/edit.cxx74
1 files changed, 24 insertions, 50 deletions
diff --git a/vcl/source/control/edit.cxx b/vcl/source/control/edit.cxx
index 10c68412a627..0db27e8a315a 100644
--- a/vcl/source/control/edit.cxx
+++ b/vcl/source/control/edit.cxx
@@ -473,20 +473,9 @@ void Edit::ImplRepaint(vcl::RenderContext& rRenderContext, const tools::Rectangl
const OUString aText = ImplGetText();
const sal_Int32 nLen = aText.getLength();
- sal_Int32 nDXBuffer[256];
- std::unique_ptr<sal_Int32[]> pDXBuffer;
- sal_Int32* pDX = nDXBuffer;
-
+ KernArray aDX;
if (nLen)
- {
- if (o3tl::make_unsigned(2 * nLen) > SAL_N_ELEMENTS(nDXBuffer))
- {
- pDXBuffer.reset(new sal_Int32[2 * (nLen + 1)]);
- pDX = pDXBuffer.get();
- }
-
- GetOutDev()->GetCaretPositions(aText, pDX, 0, nLen);
- }
+ GetOutDev()->GetCaretPositions(aText, aDX, 0, nLen);
tools::Long nTH = GetTextHeight();
Point aPos(mnXOffset, ImplGetTextYPosition());
@@ -548,8 +537,8 @@ void Edit::ImplRepaint(vcl::RenderContext& rRenderContext, const tools::Rectangl
for(sal_Int32 i = 0; i < nLen; ++i)
{
tools::Rectangle aRect(aPos, Size(10, nTH));
- aRect.SetLeft( pDX[2 * i] + mnXOffset + ImplGetExtraXOffset() );
- aRect.SetRight( pDX[2 * i + 1] + mnXOffset + ImplGetExtraXOffset() );
+ aRect.SetLeft( aDX[2 * i] + mnXOffset + ImplGetExtraXOffset() );
+ aRect.SetRight( aDX[2 * i + 1] + mnXOffset + ImplGetExtraXOffset() );
aRect.Normalize();
bool bHighlight = false;
if (i >= aTmpSel.Min() && i < aTmpSel.Max())
@@ -626,8 +615,8 @@ void Edit::ImplRepaint(vcl::RenderContext& rRenderContext, const tools::Rectangl
while (nIndex < mpIMEInfos->nLen && mpIMEInfos->pAttribs[nIndex] == nAttr) // #112631# check nIndex before using it
{
tools::Rectangle aRect( aPos, Size( 10, nTH ) );
- aRect.SetLeft( pDX[2 * (nIndex + mpIMEInfos->nPos)] + mnXOffset + ImplGetExtraXOffset() );
- aRect.SetRight( pDX[2 * (nIndex + mpIMEInfos->nPos) + 1] + mnXOffset + ImplGetExtraXOffset() );
+ aRect.SetLeft( aDX[2 * (nIndex + mpIMEInfos->nPos)] + mnXOffset + ImplGetExtraXOffset() );
+ aRect.SetRight( aDX[2 * (nIndex + mpIMEInfos->nPos) + 1] + mnXOffset + ImplGetExtraXOffset() );
aRect.Normalize();
aClip.Union(aRect);
nIndex++;
@@ -1072,24 +1061,15 @@ void Edit::ImplShowCursor( bool bOnlyIfVisible )
tools::Long nTextPos = 0;
- sal_Int32 nDXBuffer[256];
- std::unique_ptr<sal_Int32[]> pDXBuffer;
- sal_Int32* pDX = nDXBuffer;
-
if( !aText.isEmpty() )
{
- if( o3tl::make_unsigned(2*aText.getLength()) > SAL_N_ELEMENTS(nDXBuffer) )
- {
- pDXBuffer.reset(new sal_Int32[2*(aText.getLength()+1)]);
- pDX = pDXBuffer.get();
- }
-
- GetOutDev()->GetCaretPositions( aText, pDX, 0, aText.getLength() );
+ KernArray aDX;
+ GetOutDev()->GetCaretPositions(aText, aDX, 0, aText.getLength());
if( maSelection.Max() < aText.getLength() )
- nTextPos = pDX[ 2*maSelection.Max() ];
+ nTextPos = aDX[ 2*maSelection.Max() ];
else
- nTextPos = pDX[ 2*aText.getLength()-1 ];
+ nTextPos = aDX[ 2*aText.getLength()-1 ];
}
tools::Long nCursorWidth = 0;
@@ -1196,31 +1176,26 @@ sal_Int32 Edit::ImplGetCharPos( const Point& rWindowPos ) const
sal_Int32 nIndex = EDIT_NOLIMIT;
OUString aText = ImplGetText();
- sal_Int32 nDXBuffer[256];
- std::unique_ptr<sal_Int32[]> pDXBuffer;
- sal_Int32* pDX = nDXBuffer;
- if( o3tl::make_unsigned(2*aText.getLength()) > SAL_N_ELEMENTS(nDXBuffer) )
- {
- pDXBuffer.reset(new sal_Int32[2*(aText.getLength()+1)]);
- pDX = pDXBuffer.get();
- }
+ if (aText.isEmpty())
+ return nIndex;
- GetOutDev()->GetCaretPositions( aText, pDX, 0, aText.getLength() );
+ KernArray aDX;
+ GetOutDev()->GetCaretPositions(aText, aDX, 0, aText.getLength());
tools::Long nX = rWindowPos.X() - mnXOffset - ImplGetExtraXOffset();
for (sal_Int32 i = 0; i < aText.getLength(); aText.iterateCodePoints(&i))
{
- if( (pDX[2*i] >= nX && pDX[2*i+1] <= nX) ||
- (pDX[2*i+1] >= nX && pDX[2*i] <= nX))
+ if( (aDX[2*i] >= nX && aDX[2*i+1] <= nX) ||
+ (aDX[2*i+1] >= nX && aDX[2*i] <= nX))
{
nIndex = i;
- if( pDX[2*i] < pDX[2*i+1] )
+ if( aDX[2*i] < aDX[2*i+1] )
{
- if( nX > (pDX[2*i]+pDX[2*i+1])/2 )
+ if( nX > (aDX[2*i]+aDX[2*i+1])/2 )
aText.iterateCodePoints(&nIndex);
}
else
{
- if( nX < (pDX[2*i]+pDX[2*i+1])/2 )
+ if( nX < (aDX[2*i]+aDX[2*i+1])/2 )
aText.iterateCodePoints(&nIndex);
}
break;
@@ -1230,7 +1205,7 @@ sal_Int32 Edit::ImplGetCharPos( const Point& rWindowPos ) const
{
nIndex = 0;
sal_Int32 nFinalIndex = 0;
- tools::Long nDiff = std::abs( pDX[0]-nX );
+ tools::Long nDiff = std::abs( aDX[0]-nX );
sal_Int32 i = 0;
if (!aText.isEmpty())
{
@@ -1238,7 +1213,7 @@ sal_Int32 Edit::ImplGetCharPos( const Point& rWindowPos ) const
}
while (i < aText.getLength())
{
- tools::Long nNewDiff = std::abs( pDX[2*i]-nX );
+ tools::Long nNewDiff = std::abs( aDX[2*i]-nX );
if( nNewDiff < nDiff )
{
@@ -1250,7 +1225,7 @@ sal_Int32 Edit::ImplGetCharPos( const Point& rWindowPos ) const
aText.iterateCodePoints(&i);
}
- if (nIndex == nFinalIndex && std::abs( pDX[2*nIndex+1] - nX ) < nDiff)
+ if (nIndex == nFinalIndex && std::abs( aDX[2*nIndex+1] - nX ) < nDiff)
nIndex = EDIT_NOLIMIT;
}
@@ -2162,9 +2137,8 @@ void Edit::Command( const CommandEvent& rCEvt )
if (mpIMEInfos && mpIMEInfos->nLen > 0)
{
OUString aText = ImplGetText();
- std::vector<sal_Int32> aDX(2*(aText.getLength()+1));
-
- GetOutDev()->GetCaretPositions( aText, aDX.data(), 0, aText.getLength() );
+ KernArray aDX;
+ GetOutDev()->GetCaretPositions(aText, aDX, 0, aText.getLength());
tools::Long nTH = GetTextHeight();
Point aPos( mnXOffset, ImplGetTextYPosition() );