diff options
author | Mark Hung <marklh9@gmail.com> | 2022-04-17 12:56:06 +0800 |
---|---|---|
committer | Mark Hung <marklh9@gmail.com> | 2022-04-20 13:07:31 +0200 |
commit | 88aeb649ed33a1a67547419f9b76c2c892dd2ee1 (patch) | |
tree | 10cf49b952aee16a37671db1cb832291db962e8f /editeng/source/items | |
parent | 89948bd544516604af057588676b0f979f21c163 (diff) |
tdf#148630 fix text layout and cursor position for IVS+spacing
in Impress. This involves:
1. SvxFont::QuickGetTextSize() and SvxFont::GetPhysTxtSize():
insert space only when text array value changes. Same value indicates
diffferent characters of the same glyph item (e.x. surrogate pairs,
unicode IVS that is made of a base character and a selector. ).
2. ImpEditEngine::GetChar(): fix a logical mistake that tried
to increase the index by 1 than checking the value of character
position. To advance the index we always need to check the position
first.
Change-Id: I4e3547413ce361ae7801c957e6d589776ebed114
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133102
Tested-by: Jenkins
Reviewed-by: Mark Hung <marklh9@gmail.com>
Diffstat (limited to 'editeng/source/items')
-rw-r--r-- | editeng/source/items/svxfont.cxx | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/editeng/source/items/svxfont.cxx b/editeng/source/items/svxfont.cxx index 4b549d49d711..839240f828df 100644 --- a/editeng/source/items/svxfont.cxx +++ b/editeng/source/items/svxfont.cxx @@ -30,6 +30,15 @@ #include <com/sun/star/i18n/KCharacterType.hpp> #include <editeng/escapementitem.hxx> #include <sal/log.hxx> +#include <limits> + +static tools::Long GetTextArray( const OutputDevice* pOut, const OUString& rStr, std::vector<sal_Int32>* pDXAry, + sal_Int32 nIndex, sal_Int32 nLen ) + +{ + const SalLayoutGlyphs* layoutGlyphs = SalLayoutGlyphsCache::self()->GetLayoutGlyphs(pOut, rStr, nIndex, nLen); + return pOut->GetTextArray( rStr, pDXAry, nIndex, nLen, nullptr, layoutGlyphs); +} SvxFont::SvxFont() { @@ -433,7 +442,21 @@ Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const OUString &rTxt, } if( IsKern() && ( nLen > 1 ) ) - aTxtSize.AdjustWidth( ( nLen-1 ) * tools::Long( nKern ) ); + { + std::vector<sal_Int32> aDXArray(nLen); + GetTextArray(pOut, rTxt, &aDXArray, nIdx, nLen); + tools::Long nOldValue = aDXArray[0]; + sal_Int32 nSpaceCount = 0; + for(sal_Int32 i = 1; i < nLen; ++i) + { + if (aDXArray[i] != nOldValue) + { + nOldValue = aDXArray[i]; + ++nSpaceCount; + } + } + aTxtSize.AdjustWidth( nSpaceCount * tools::Long( nKern ) ); + } return aTxtSize; } @@ -453,13 +476,6 @@ Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut ) return aTxtSize; } -static tools::Long GetTextArray( const OutputDevice* pOut, const OUString& rStr, std::vector<sal_Int32>* pDXAry, - sal_Int32 nIndex, sal_Int32 nLen ) -{ - const SalLayoutGlyphs* layoutGlyphs = SalLayoutGlyphsCache::self()->GetLayoutGlyphs(pOut, rStr, nIndex, nLen); - return pOut->GetTextArray( rStr, pDXAry, nIndex, nLen, nullptr, layoutGlyphs); -} - Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, const OUString &rTxt, const sal_Int32 nIdx, const sal_Int32 nLen, std::vector<sal_Int32>* pDXArray ) const { @@ -467,6 +483,15 @@ Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, const OUString &rTxt, return Size( GetTextArray( pOut, rTxt, pDXArray, nIdx, nLen ), pOut->GetTextHeight() ); + std::vector<sal_Int32> aDXArray; + + // We always need pDXArray to count the number of kern spaces + if (!pDXArray && IsKern() && nLen > 1) + { + pDXArray = &aDXArray; + aDXArray.reserve(nLen); + } + Size aTxtSize; aTxtSize.setHeight( pOut->GetTextHeight() ); if ( !IsCaseMap() ) @@ -477,16 +502,29 @@ Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, const OUString &rTxt, if( IsKern() && ( nLen > 1 ) ) { - aTxtSize.AdjustWidth( ( nLen-1 ) * tools::Long( nKern ) ); + tools::Long nOldValue = (*pDXArray)[0]; + tools::Long nSpaceSum = nKern; + (*pDXArray)[0] += nSpaceSum; - if ( pDXArray ) + for ( sal_Int32 i = 1; i < nLen; i++ ) { - for ( sal_Int32 i = 0; i < nLen; i++ ) - (*pDXArray)[i] += ( (i+1) * tools::Long( nKern ) ); - // The last one is a nKern too big: - (*pDXArray)[nLen-1] -= nKern; + if ( (*pDXArray)[i] != nOldValue ) + { + nOldValue = (*pDXArray)[i]; + nSpaceSum += nKern; + } + (*pDXArray)[i] += nSpaceSum; } + + // The last one is a nKern too big: + nOldValue = (*pDXArray)[nLen - 1]; + tools::Long nNewValue = nOldValue - nKern; + for ( sal_Int32 i = nLen - 1; i >= 0 && (*pDXArray)[i] == nOldValue; --i) + (*pDXArray)[i] = nNewValue; + + aTxtSize.AdjustWidth(nSpaceSum - nKern); } + return aTxtSize; } |