diff options
Diffstat (limited to 'editeng/source/items/svxfont.cxx')
-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; } |