summaryrefslogtreecommitdiff
path: root/vcl/source/outdev/text.cxx
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/outdev/text.cxx
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/outdev/text.cxx')
-rw-r--r--vcl/source/outdev/text.cxx46
1 files changed, 30 insertions, 16 deletions
diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx
index aaa165b8f208..435110ab5bdd 100644
--- a/vcl/source/outdev/text.cxx
+++ b/vcl/source/outdev/text.cxx
@@ -1035,7 +1035,7 @@ tools::Long OutputDevice::GetTextArray( const OUString& rStr, KernArray* pKernAr
return basegfx::fround(nWidth);
}
-void OutputDevice::GetCaretPositions( const OUString& rStr, sal_Int32* pCaretXArray,
+void OutputDevice::GetCaretPositions( const OUString& rStr, KernArray& rCaretXArray,
sal_Int32 nIndex, sal_Int32 nLen,
const SalLayoutGlyphs* pGlyphs ) const
{
@@ -1045,45 +1045,59 @@ void OutputDevice::GetCaretPositions( const OUString& rStr, sal_Int32* pCaretXAr
if( nIndex+nLen >= rStr.getLength() )
nLen = rStr.getLength() - nIndex;
- // layout complex text
+ sal_Int32 nCaretPos = nLen * 2;
+ std::vector<sal_Int32>& rCaretPos = rCaretXArray.get_subunit_array();
+ rCaretPos.resize(nCaretPos);
+
+ // do layout
std::unique_ptr<SalLayout> pSalLayout = ImplLayout(rStr, nIndex, nLen, Point(0, 0), 0, {}, {},
eDefaultLayout, nullptr, pGlyphs);
if( !pSalLayout )
{
- std::fill(pCaretXArray, pCaretXArray + nLen * 2, -1);
+ std::fill(rCaretPos.begin(), rCaretPos.end(), -1);
return;
}
- pSalLayout->GetCaretPositions( 2*nLen, pCaretXArray );
- double nWidth = pSalLayout->GetTextWidth();
+ std::vector<double> aCaretPixelPos;
+ pSalLayout->GetCaretPositions(aCaretPixelPos, rStr);
// fixup unknown caret positions
int i;
- for( i = 0; i < 2 * nLen; ++i )
- if( pCaretXArray[ i ] >= 0 )
+ for (i = 0; i < nCaretPos; ++i)
+ if (aCaretPixelPos[i] >= 0)
break;
- tools::Long nXPos = (i < 2 * nLen) ? pCaretXArray[i] : -1;
- for( i = 0; i < 2 * nLen; ++i )
+ tools::Long nXPos = (i < nCaretPos) ? aCaretPixelPos[i] : -1;
+ for (i = 0; i < nCaretPos; ++i)
{
- if( pCaretXArray[ i ] >= 0 )
- nXPos = pCaretXArray[ i ];
+ if (aCaretPixelPos[i] >= 0)
+ nXPos = aCaretPixelPos[i];
else
- pCaretXArray[ i ] = nXPos;
+ aCaretPixelPos[i] = nXPos;
}
// handle window mirroring
if( IsRTLEnabled() )
{
- for( i = 0; i < 2 * nLen; ++i )
- pCaretXArray[i] = nWidth - pCaretXArray[i] - 1;
+ double nWidth = pSalLayout->GetTextWidth();
+ for (i = 0; i < nCaretPos; ++i)
+ aCaretPixelPos[i] = nWidth - aCaretPixelPos[i] - 1;
}
+ int nSubPixelFactor = rCaretXArray.get_factor();
// convert from font units to logical units
if( mbMap )
{
- for( i = 0; i < 2*nLen; ++i )
- pCaretXArray[i] = ImplDevicePixelToLogicWidth( pCaretXArray[i] );
+ for (i = 0; i < nCaretPos; ++i)
+ aCaretPixelPos[i] = ImplDevicePixelToLogicWidth(aCaretPixelPos[i] * nSubPixelFactor);
}
+ else if (nSubPixelFactor)
+ {
+ for (i = 0; i < nCaretPos; ++i)
+ aCaretPixelPos[i] *= nSubPixelFactor;
+ }
+
+ for (i = 0; i < nCaretPos; ++i)
+ rCaretPos[i] = basegfx::fround(aCaretPixelPos[i]);
}
void OutputDevice::DrawStretchText( const Point& rStartPt, sal_Int32 nWidth,