diff options
Diffstat (limited to 'sw')
-rw-r--r-- | sw/qa/core/txtnode/justify.cxx | 14 | ||||
-rw-r--r-- | sw/source/core/inc/scriptinfo.hxx | 8 | ||||
-rw-r--r-- | sw/source/core/text/porlay.cxx | 36 | ||||
-rw-r--r-- | sw/source/core/txtnode/fntcache.cxx | 100 | ||||
-rw-r--r-- | sw/source/core/txtnode/justify.cxx | 45 | ||||
-rw-r--r-- | sw/source/core/txtnode/justify.hxx | 10 |
6 files changed, 125 insertions, 88 deletions
diff --git a/sw/qa/core/txtnode/justify.cxx b/sw/qa/core/txtnode/justify.cxx index 1565703f1f9e..6a8afd2b52ef 100644 --- a/sw/qa/core/txtnode/justify.cxx +++ b/sw/qa/core/txtnode/justify.cxx @@ -23,11 +23,11 @@ class SwCoreJustifyTest : public SwModelTestBase class CharWidthArray { public: - std::vector<sal_Int32> maArray; - template <typename... Args> - CharWidthArray(Args&&... args) - : maArray{ std::forward<Args>(args)... } + KernArray maArray; + template <typename... Args> CharWidthArray(Args&&... args) { + for (auto arg : { args... }) + maArray.push_back(arg); } template <typename Function> void InvokeWithKernArray(Function f); void ConvertToKernArray(); @@ -41,7 +41,7 @@ inline bool operator==(const CharWidthArray& lhs, const CharWidthArray& rhs) std::ostream& operator<<(std::ostream& rStrm, const CharWidthArray& rCharWidthArray) { - const std::vector<sal_Int32>& rArray(rCharWidthArray.maArray); + const KernArray& rArray(rCharWidthArray.maArray); sal_Int32 nLen = rArray.size(); rStrm << "{ "; for (sal_Int32 i = 0; i < nLen; ++i) @@ -56,13 +56,13 @@ std::ostream& operator<<(std::ostream& rStrm, const CharWidthArray& rCharWidthAr void CharWidthArray::ConvertToKernArray() { for (std::size_t i = 1; i < maArray.size(); ++i) - maArray[i] += maArray[i - 1]; + maArray.adjust(i, maArray[i - 1]); } void CharWidthArray::ConvertToCharWidths() { for (sal_Int32 i = maArray.size() - 1; i > 0; --i) - maArray[i] -= maArray[i - 1]; + maArray.adjust(i, -maArray[i - 1]); } /// Convert maArray to kern array values, then invoke the function, and convert it back. diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx index 9fdaa9073eb8..21c3c2240cc4 100644 --- a/sw/source/core/inc/scriptinfo.hxx +++ b/sw/source/core/inc/scriptinfo.hxx @@ -272,7 +272,7 @@ public: // HIDDEN TEXT STUFF END // modifies the kerning array according to a given compress value - tools::Long Compress( sal_Int32* pKernArray, TextFrameIndex nIdx, TextFrameIndex nLen, + tools::Long Compress( KernArray& rKernArray, TextFrameIndex nIdx, TextFrameIndex nLen, const sal_uInt16 nCompress, const sal_uInt16 nFontHeight, const bool bCentered, Point* pPoint = nullptr ) const; @@ -291,7 +291,7 @@ public: The value which has to be added to a kashida opportunity. @return The number of kashida opportunities in the given range */ - sal_Int32 KashidaJustify( sal_Int32* pKernArray, sal_Bool* pKashidaArray, + sal_Int32 KashidaJustify( KernArray* pKernArray, sal_Bool* pKashidaArray, TextFrameIndex nStt, TextFrameIndex nLen, tools::Long nSpaceAdd = 0) const; /** Clears array of kashidas marked as invalid @@ -362,7 +362,7 @@ public: The value which has to be added to the cells. @return The number of extra spaces in the given range */ - static TextFrameIndex ThaiJustify( std::u16string_view aText, sal_Int32* pKernArray, + static TextFrameIndex ThaiJustify( std::u16string_view aText, KernArray* pKernArray, TextFrameIndex nIdx, TextFrameIndex nLen, TextFrameIndex nNumberOfBlanks = TextFrameIndex(0), @@ -371,7 +371,7 @@ public: static TextFrameIndex CountCJKCharacters(const OUString &rText, TextFrameIndex nPos, TextFrameIndex nEnd, LanguageType aLang); - static void CJKJustify( const OUString& rText, sal_Int32* pKernArray, + static void CJKJustify( const OUString& rText, KernArray& rKernArray, TextFrameIndex nStt, TextFrameIndex nLen, LanguageType aLang, tools::Long nSpaceAdd, bool bIsSpaceStop ); diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx index 29080e7e785a..8705ac6ecbd1 100644 --- a/sw/source/core/text/porlay.cxx +++ b/sw/source/core/text/porlay.cxx @@ -65,6 +65,7 @@ #include <docsh.hxx> #include <unobookmark.hxx> #include <unocrsrhelper.hxx> +#include <vcl/kernarray.hxx> #include <com/sun/star/rdf/Statement.hpp> #include <com/sun/star/rdf/URI.hpp> #include <com/sun/star/rdf/URIs.hpp> @@ -2195,7 +2196,7 @@ size_t SwScriptInfo::HasKana(TextFrameIndex const nStart, TextFrameIndex const n return SAL_MAX_SIZE; } -tools::Long SwScriptInfo::Compress(sal_Int32* pKernArray, TextFrameIndex nIdx, TextFrameIndex nLen, +tools::Long SwScriptInfo::Compress(KernArray& rKernArray, TextFrameIndex nIdx, TextFrameIndex nLen, const sal_uInt16 nCompress, const sal_uInt16 nFontHeight, bool bCenter, Point* pPoint ) const @@ -2231,7 +2232,7 @@ tools::Long SwScriptInfo::Compress(sal_Int32* pKernArray, TextFrameIndex nIdx, T return 0; tools::Long nSub = 0; - tools::Long nLast = nI ? pKernArray[ nI - 1 ] : 0; + tools::Long nLast = nI ? rKernArray[ nI - 1 ] : 0; do { const CompType nType = GetCompType( nCompIdx ); @@ -2243,7 +2244,7 @@ tools::Long SwScriptInfo::Compress(sal_Int32* pKernArray, TextFrameIndex nIdx, T nCompLen = nLen; // are we allowed to compress the character? - if ( pKernArray[ nI ] - nLast < nMinWidth ) + if ( rKernArray[ nI ] - nLast < nMinWidth ) { nIdx++; nI++; } @@ -2254,7 +2255,7 @@ tools::Long SwScriptInfo::Compress(sal_Int32* pKernArray, TextFrameIndex nIdx, T SAL_WARN_IF( SwScriptInfo::NONE == nType, "sw.core", "None compression?!" ); // nLast is width of current character - nLast -= pKernArray[ nI ]; + nLast -= rKernArray[ nI ]; nLast *= nCompress; tools::Long nMove = 0; @@ -2277,10 +2278,11 @@ tools::Long SwScriptInfo::Compress(sal_Int32* pKernArray, TextFrameIndex nIdx, T else nLast /= 100000; nSub -= nLast; - nLast = pKernArray[ nI ]; + nLast = rKernArray[ nI ]; if( nI && nMove ) - pKernArray[ nI - 1 ] += nMove; - pKernArray[ nI++ ] -= nSub; + rKernArray.adjust(nI - 1, nMove); + rKernArray.adjust(nI, -nSub); + ++nI; ++nIdx; } } @@ -2299,8 +2301,9 @@ tools::Long SwScriptInfo::Compress(sal_Int32* pKernArray, TextFrameIndex nIdx, T while( nIdx < nTmpChg ) { - nLast = pKernArray[ nI ]; - pKernArray[ nI++ ] -= nSub; + nLast = rKernArray[ nI ]; + rKernArray.adjust(nI, -nSub); + ++nI; ++nIdx; } } while( nIdx < nLen ); @@ -2312,7 +2315,7 @@ tools::Long SwScriptInfo::Compress(sal_Int32* pKernArray, TextFrameIndex nIdx, T // total number of kashida positions, or the number of kashida positions after some positions // have been dropped, depending on the state of the m_KashidaInvalid set. -sal_Int32 SwScriptInfo::KashidaJustify( sal_Int32* pKernArray, +sal_Int32 SwScriptInfo::KashidaJustify( KernArray* pKernArray, sal_Bool* pKashidaArray, TextFrameIndex const nStt, TextFrameIndex const nLen, @@ -2387,7 +2390,7 @@ sal_Int32 SwScriptInfo::KashidaJustify( sal_Int32* pKernArray, while ( nArrayPos < nArrayEnd ) { - pKernArray[ sal_Int32(nArrayPos) ] += nKashAdd; + pKernArray->adjust(sal_Int32(nArrayPos), nKashAdd); ++nArrayPos; } nKashAdd += nSpaceAdd; @@ -2574,7 +2577,7 @@ void SwScriptInfo::MarkKashidasInvalid(sal_Int32 const nCnt, } } -TextFrameIndex SwScriptInfo::ThaiJustify( std::u16string_view aText, sal_Int32* pKernArray, +TextFrameIndex SwScriptInfo::ThaiJustify( std::u16string_view aText, KernArray* pKernArray, TextFrameIndex const nStt, TextFrameIndex const nLen, TextFrameIndex nNumberOfBlanks, @@ -2606,7 +2609,8 @@ TextFrameIndex SwScriptInfo::ThaiJustify( std::u16string_view aText, sal_Int32* ++nCnt; } - if ( pKernArray ) pKernArray[ nI ] += nSpaceSum; + if (pKernArray) + pKernArray->adjust(nI, nSpaceSum); } return nCnt; @@ -2901,12 +2905,12 @@ TextFrameIndex SwScriptInfo::CountCJKCharacters(const OUString &rText, return nCount; } -void SwScriptInfo::CJKJustify( const OUString& rText, sal_Int32* pKernArray, +void SwScriptInfo::CJKJustify( const OUString& rText, KernArray& rKernArray, TextFrameIndex const nStt, TextFrameIndex const nLen, LanguageType aLang, tools::Long nSpaceAdd, bool bIsSpaceStop ) { - assert( pKernArray != nullptr && sal_Int32(nStt) >= 0 ); + assert( sal_Int32(nStt) >= 0 ); if (sal_Int32(nLen) <= 0) return; @@ -2924,7 +2928,7 @@ void SwScriptInfo::CJKJustify( const OUString& rText, sal_Int32* pKernArray, if (nNext < sal_Int32(nStt + nLen) || !bIsSpaceStop) nSpaceSum += nSpaceAdd; } - pKernArray[ nI ] += nSpaceSum; + rKernArray.adjust(nI, nSpaceSum); } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/txtnode/fntcache.cxx b/sw/source/core/txtnode/fntcache.cxx index 5b26029b36dd..20ed476398d8 100644 --- a/sw/source/core/txtnode/fntcache.cxx +++ b/sw/source/core/txtnode/fntcache.cxx @@ -22,6 +22,7 @@ #include <i18nlangtag/mslangid.hxx> #include <officecfg/Office/Common.hxx> #include <vcl/outdev.hxx> +#include <vcl/kernarray.hxx> #include <vcl/lineinfo.hxx> #include <vcl/metric.hxx> #include <vcl/svapp.hxx> @@ -169,12 +170,12 @@ struct CalcLinePosData const bool bSwitchH2VLRBT; const bool bSwitchL2R; tools::Long nHalfSpace; - sal_Int32* pKernArray; + KernArray& rKernArray; const bool bBidiPor; CalcLinePosData( SwDrawTextInfo& _rInf, vcl::Font& _rFont, TextFrameIndex const _nCnt, const bool _bSwitchH2V, const bool _bSwitchH2VLRBT, const bool _bSwitchL2R, - tools::Long _nHalfSpace, sal_Int32* _pKernArray, const bool _bBidiPor) : + tools::Long _nHalfSpace, KernArray& _rKernArray, const bool _bBidiPor) : rInf( _rInf ), rFont( _rFont ), nCnt( _nCnt ), @@ -182,7 +183,7 @@ struct CalcLinePosData bSwitchH2VLRBT( _bSwitchH2VLRBT ), bSwitchL2R( _bSwitchL2R ), nHalfSpace( _nHalfSpace ), - pKernArray( _pKernArray ), + rKernArray( _rKernArray ), bBidiPor( _bBidiPor ) { } @@ -209,8 +210,8 @@ static void lcl_calcLinePos( const CalcLinePosData &rData, } // determine start, end and length of wave line - sal_Int32 nKernStart = nStart ? rData.pKernArray[sal_Int32(nStart) - 1] : 0; - sal_Int32 nKernEnd = rData.pKernArray[sal_Int32(nEnd) - 1]; + sal_Int32 nKernStart = nStart ? rData.rKernArray[sal_Int32(nStart) - 1] : 0; + sal_Int32 nKernEnd = rData.rKernArray[sal_Int32(nEnd) - 1]; const Degree10 nDir = rData.bBidiPor ? 1800_deg10 : UnMapDirection(rData.rFont.GetOrientation(), @@ -731,7 +732,7 @@ static void lcl_DrawLineForWrongListData( rInf.GetOut().Pop(); } -static void GetTextArray(const OutputDevice& rDevice, const OUString& rStr, std::vector<sal_Int32>& rDXAry, +static void GetTextArray(const OutputDevice& rDevice, const OUString& rStr, KernArray& rDXAry, sal_Int32 nIndex, sal_Int32 nLen, bool bCaret = false, const vcl::text::TextLayoutCache* layoutCache = nullptr) { @@ -740,14 +741,14 @@ static void GetTextArray(const OutputDevice& rDevice, const OUString& rStr, std: rDevice.GetTextArray(rStr, &rDXAry, nIndex, nLen, bCaret, layoutCache, pLayoutCache); } -static void GetTextArray(const OutputDevice& rOutputDevice, const SwDrawTextInfo& rInf, std::vector<sal_Int32>& rDXAry, +static void GetTextArray(const OutputDevice& rOutputDevice, const SwDrawTextInfo& rInf, KernArray& rDXAry, bool bCaret = false) { return GetTextArray(rOutputDevice, rInf.GetText(), rDXAry, rInf.GetIdx().get(), rInf.GetLen().get(), bCaret, rInf.GetVclCache()); } -static void GetTextArray(const OutputDevice& rOutputDevice, const SwDrawTextInfo& rInf, std::vector<sal_Int32>& rDXAry, +static void GetTextArray(const OutputDevice& rOutputDevice, const SwDrawTextInfo& rInf, KernArray& rDXAry, sal_Int32 nLen, bool bCaret = false) { // Substring is fine. @@ -928,7 +929,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) tools::Long nSpaceAdd = rInf.GetSpace() / SPACING_PRECISION_FACTOR; // kerning array - gives the absolute position of end of each character - std::vector<sal_Int32> aKernArray; + KernArray aKernArray; if ( m_pPrinter ) GetTextArray(*m_pPrinter, rInf, aKernArray); @@ -982,7 +983,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) // Simple kerning is handled by DrawStretchText if( rInf.GetSpace() || rInf.GetKanaComp() ) { - std::vector<sal_Int32> aKernArray; + KernArray aKernArray; GetTextArray(rInf.GetOut(), rInf, aKernArray); std::vector<sal_Bool> aKashidaArray; @@ -1007,7 +1008,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) tools::Long nSum = nDiff; for( sal_Int32 i = 0; i < nZwi; ) { - aKernArray[ i ] += nSum; + aKernArray.adjust(i, nSum); if( ++i == nRest ) nDiff += nAdd; nSum += nDiff; @@ -1029,7 +1030,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) pSI && pSI->CountCompChg() && lcl_IsMonoSpaceFont( rInf.GetOut() ) ) { - pSI->Compress( aKernArray.data(), rInf.GetIdx(), rInf.GetLen(), + pSI->Compress( aKernArray, rInf.GetIdx(), rInf.GetLen(), rInf.GetKanaComp(), o3tl::narrowing<sal_uInt16>(m_aFont.GetFontSize().Height()), lcl_IsFullstopCentered( rInf.GetOut() ), &aTextOriginPos ); bSpecialJust = true; @@ -1042,7 +1043,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) if (!MsLangId::isKorean(aLang)) { - SwScriptInfo::CJKJustify( rInf.GetText(), aKernArray.data(), + SwScriptInfo::CJKJustify( rInf.GetText(), aKernArray, rInf.GetIdx(), rInf.GetLen(), aLang, nSpaceAdd, rInf.IsSpaceStop() ); bSpecialJust = true; @@ -1057,7 +1058,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) { aKashidaArray.resize(aKernArray.size(), false); if ( pSI && pSI->CountKashida() && - pSI->KashidaJustify( aKernArray.data(), aKashidaArray.data(), rInf.GetIdx(), + pSI->KashidaJustify( &aKernArray, aKashidaArray.data(), rInf.GetIdx(), rInf.GetLen(), nSpaceAdd ) != -1 ) { bSpecialJust = true; @@ -1077,7 +1078,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) { // Use rInf.GetSpace() because it has more precision than // nSpaceAdd: - SwScriptInfo::ThaiJustify( rInf.GetText(), aKernArray.data(), + SwScriptInfo::ThaiJustify( rInf.GetText(), &aKernArray, rInf.GetIdx(), rInf.GetLen(), rInf.GetNumberOfBlanks(), rInf.GetSpace() ); @@ -1098,7 +1099,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) { if (CH_BLANK == rInf.GetText()[sal_Int32(rInf.GetIdx()) + i]) nKernSum += nSpaceAdd; - aKernArray[i] += nKernSum; + aKernArray.adjust(i, nKernSum); } // In case of underlined/strike-through justified text @@ -1109,14 +1110,15 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) // If it is a single underlined space, output 2 spaces: if (TextFrameIndex(1) == rInf.GetLen()) { - aKernArray[0] = rInf.GetWidth() + nSpaceAdd; + aKernArray.set(0, rInf.GetWidth() + nSpaceAdd); rInf.GetOut().DrawTextArray( aTextOriginPos, rInf.GetText(), aKernArray, aKashidaArray, sal_Int32(rInf.GetIdx()), 1 ); } else { - aKernArray[ sal_Int32(rInf.GetLen()) - 2 ] += nSpaceAdd; + sal_Int32 nIndex(sal_Int32(rInf.GetLen()) - 2); + aKernArray.adjust(nIndex, nSpaceAdd); rInf.GetOut().DrawTextArray( aTextOriginPos, rInf.GetText(), aKernArray, aKashidaArray, sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen())); } @@ -1190,9 +1192,10 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) bool bBullet = rInf.GetBullet(); if( m_bSymbol ) bBullet = false; - std::vector<sal_Int32> aKernArray; CreateScrFont( *rInf.GetShell(), rInf.GetOut() ); + VclPtr<OutputDevice> xFormattingDevice; + // OLE: no printer available // OSL_ENSURE( pPrinter, "DrawText needs pPrinter" ) if ( m_pPrinter ) @@ -1203,12 +1206,27 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) if( !m_pPrtFont->IsSameInstance( m_pPrinter->GetFont() ) ) m_pPrinter->SetFont( *m_pPrtFont ); } - GetTextArray(*m_pPrinter, rInf, aKernArray); + xFormattingDevice = m_pPrinter; } else { - GetTextArray(rInf.GetOut(), rInf, aKernArray); + xFormattingDevice = &rInf.GetOut(); + } + + //tdf#152094 see if we can retain a subpixel factor + int nSubPixels = 1; + MapMode aMapMode(xFormattingDevice->GetMapMode()); + if (aMapMode.IsSimple() && aMapMode.GetMapUnit() == MapUnit::MapTwip) + { + if (xFormattingDevice->GetDPIX() == xFormattingDevice->GetDPIY()) + { + int nRatio = xFormattingDevice->GetDPIX() / 1440; + if (nRatio * 1440 == xFormattingDevice->GetDPIX()) + nSubPixels = nRatio; + } } + KernArray aKernArray(nSubPixels); + GetTextArray(*xFormattingDevice, rInf, aKernArray); std::vector<sal_Bool> aKashidaArray; @@ -1227,7 +1245,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) pSI && pSI->CountCompChg() && lcl_IsMonoSpaceFont( rInf.GetOut() ) ) { - pSI->Compress( aKernArray.data(), rInf.GetIdx(), rInf.GetLen(), + pSI->Compress( aKernArray, rInf.GetIdx(), rInf.GetLen(), rInf.GetKanaComp(), o3tl::narrowing<sal_uInt16>(m_aFont.GetFontSize().Height()), lcl_IsFullstopCentered( rInf.GetOut() ), &aTextOriginPos ); } @@ -1239,7 +1257,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) if (!MsLangId::isKorean(aLang)) { - SwScriptInfo::CJKJustify( rInf.GetText(), aKernArray.data(), + SwScriptInfo::CJKJustify( rInf.GetText(), aKernArray, rInf.GetIdx(), rInf.GetLen(), aLang, nSpaceAdd, rInf.IsSpaceStop() ); nSpaceAdd = 0; @@ -1253,7 +1271,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) { aKashidaArray.resize(aKernArray.size(), false); if ( pSI && pSI->CountKashida() && - pSI->KashidaJustify( aKernArray.data(), aKashidaArray.data(), rInf.GetIdx(), + pSI->KashidaJustify( &aKernArray, aKashidaArray.data(), rInf.GetIdx(), rInf.GetLen(), nSpaceAdd ) != -1 ) nSpaceAdd = 0; else @@ -1271,7 +1289,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) if ( LANGUAGE_THAI == aLang ) { - SwScriptInfo::ThaiJustify( rInf.GetText(), aKernArray.data(), + SwScriptInfo::ThaiJustify( rInf.GetText(), &aKernArray, rInf.GetIdx(), rInf.GetLen(), rInf.GetNumberOfBlanks(), @@ -1326,9 +1344,9 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) // have to output 2 spaces: if ((nCnt == TextFrameIndex(1)) && rInf.GetSpace() && (cChPrev == CH_BLANK)) { - aKernArray[0] = rInf.GetWidth() + + aKernArray.set(0, rInf.GetWidth() + rInf.GetKern() + - ( rInf.GetSpace() / SPACING_PRECISION_FACTOR ); + (rInf.GetSpace() / SPACING_PRECISION_FACTOR)); if ( bSwitchL2R ) rInf.GetFrame()->SwitchLTRtoRTL( aTextOriginPos ); @@ -1427,7 +1445,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) const tools::Long nHalfSpace = bNoHalfSpace ? 0 : nSpaceAdd / 2; CalcLinePosData aCalcLinePosData(rInf, GetFont(), nCnt, bSwitchH2V, bSwitchH2VLRBT, bSwitchL2R, nHalfSpace, - aKernArray.data(), bBidiPor); + aKernArray, bBidiPor); SwForbidden aForbidden; // draw line for smart tag data @@ -1488,9 +1506,9 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf ) for( sal_Int32 i = 1 ; i < nLen ; ++i ) { if ( aBulletOverlay[ i ] == CH_BULLET ) - aKernArray [ i - 1 ] += nShift ; + aKernArray.adjust(i - 1, nShift); if ( nAdd ) - aKernArray [ i - 1 ] -= nAdd; + aKernArray.adjust(i - 1, -nAdd); } } rInf.GetOut().DrawTextArray( aTextOriginPos, aBulletOverlay, aKernArray, @@ -1559,7 +1577,7 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf ) aTextSize.setHeight( pOutDev->GetTextHeight() + GetFontLeading( rInf.GetShell(), rInf.GetOut() ) ); - std::vector<sal_Int32> aKernArray; + KernArray aKernArray; GetTextArray(*pOutDev, rInf, aKernArray, sal_Int32(nLn), bCaret); if (pGrid->IsSnapToChars()) { @@ -1591,7 +1609,7 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf ) // This is the part used e.g., for cursor travelling // See condition for DrawText or DrawTextArray (bDirectPrint) - std::vector<sal_Int32> aKernArray; + KernArray aKernArray; if ( m_pPrinter && m_pPrinter.get() != rInf.GetpOut() ) { if( !m_pPrtFont->IsSameInstance( m_pPrinter->GetFont() ) ) @@ -1616,7 +1634,7 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf ) if (bCompress) { - rInf.SetKanaDiff(rInf.GetScriptInfo()->Compress(aKernArray.data(), rInf.GetIdx(), nLn, rInf.GetKanaComp(), + rInf.SetKanaDiff(rInf.GetScriptInfo()->Compress(aKernArray, rInf.GetIdx(), nLn, rInf.GetKanaComp(), o3tl::narrowing<sal_uInt16>(m_aFont.GetFontSize().Height()), lcl_IsFullstopCentered(rInf.GetOut()))); } else @@ -1660,7 +1678,7 @@ TextFrameIndex SwFntObj::GetModelPositionForViewPoint(SwDrawTextInfo &rInf) if( 0 != nCharacterSpacing ) nKern -= nCharacterSpacing; - std::vector<sal_Int32> aKernArray; + KernArray aKernArray; // be sure to have the correct layout mode at the printer if ( m_pPrinter ) @@ -1709,7 +1727,7 @@ TextFrameIndex SwFntObj::GetModelPositionForViewPoint(SwDrawTextInfo &rInf) pSI && pSI->CountCompChg() && lcl_IsMonoSpaceFont( rInf.GetOut() ) ) { - pSI->Compress( aKernArray.data(), rInf.GetIdx(), rInf.GetLen(), + pSI->Compress( aKernArray, rInf.GetIdx(), rInf.GetLen(), rInf.GetKanaComp(), o3tl::narrowing<sal_uInt16>(m_aFont.GetFontSize().Height()), lcl_IsFullstopCentered( rInf.GetOut() ) ); @@ -1722,7 +1740,7 @@ TextFrameIndex SwFntObj::GetModelPositionForViewPoint(SwDrawTextInfo &rInf) if (!MsLangId::isKorean(aLang)) { - SwScriptInfo::CJKJustify( rInf.GetText(), aKernArray.data(), + SwScriptInfo::CJKJustify( rInf.GetText(), aKernArray, rInf.GetIdx(), rInf.GetLen(), aLang, nSpaceAdd, rInf.IsSpaceStop() ); nSpaceAdd = 0; @@ -1736,7 +1754,7 @@ TextFrameIndex SwFntObj::GetModelPositionForViewPoint(SwDrawTextInfo &rInf) if ( SwScriptInfo::IsArabicText( rInf.GetText(), rInf.GetIdx(), rInf.GetLen() ) ) { if ( pSI && pSI->CountKashida() && - pSI->KashidaJustify( aKernArray.data(), nullptr, rInf.GetIdx(), rInf.GetLen(), + pSI->KashidaJustify( &aKernArray, nullptr, rInf.GetIdx(), rInf.GetLen(), nSpaceAdd ) != -1 ) nSpaceAdd = 0; } @@ -1749,7 +1767,7 @@ TextFrameIndex SwFntObj::GetModelPositionForViewPoint(SwDrawTextInfo &rInf) if ( LANGUAGE_THAI == aLang ) { - SwScriptInfo::ThaiJustify( rInf.GetText(), aKernArray.data(), + SwScriptInfo::ThaiJustify( rInf.GetText(), &aKernArray, rInf.GetIdx(), rInf.GetLen(), rInf.GetNumberOfBlanks(), rInf.GetSpace() ); @@ -1956,7 +1974,7 @@ TextFrameIndex SwFont::GetTextBreak(SwDrawTextInfo const & rInf, tools::Long nTe const SwDoc* pDoc = rInf.GetShell()->GetDoc(); const sal_uInt16 nGridWidth = GetGridWidth(*pGrid, *pDoc); - std::vector<sal_Int32> aKernArray; + KernArray aKernArray; GetTextArray( rInf.GetOut(), rInf.GetText(), aKernArray, sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen())); @@ -2084,10 +2102,10 @@ TextFrameIndex SwFont::GetTextBreak(SwDrawTextInfo const & rInf, tools::Long nTe nLn = TextFrameIndex(1); else if (nLn > nTextBreak2 + nTextBreak2) nLn = nTextBreak2 + nTextBreak2; - std::vector<sal_Int32> aKernArray; + KernArray aKernArray; GetTextArray( rInf.GetOut(), rInf.GetText(), aKernArray, sal_Int32(rInf.GetIdx()), sal_Int32(nLn)); - if( rInf.GetScriptInfo()->Compress( aKernArray.data(), rInf.GetIdx(), nLn, + if( rInf.GetScriptInfo()->Compress( aKernArray, rInf.GetIdx(), nLn, rInf.GetKanaComp(), o3tl::narrowing<sal_uInt16>(GetHeight( m_nActual )), lcl_IsFullstopCentered( rInf.GetOut() ) ) ) { diff --git a/sw/source/core/txtnode/justify.cxx b/sw/source/core/txtnode/justify.cxx index b59c5d8787b9..40ded5663f17 100644 --- a/sw/source/core/txtnode/justify.cxx +++ b/sw/source/core/txtnode/justify.cxx @@ -9,6 +9,7 @@ #include <vector> #include <sal/types.h> +#include <vcl/kernarray.hxx> #include <swfont.hxx> #include "justify.hxx" @@ -73,7 +74,7 @@ tools::Long lcl_OffsetFromGridEdge(tools::Long nMinWidth, tools::Long nCharWidth namespace sw::Justify { -sal_Int32 GetModelPosition(const std::vector<sal_Int32>& rKernArray, sal_Int32 nLen, tools::Long nX) +sal_Int32 GetModelPosition(const KernArray& rKernArray, sal_Int32 nLen, tools::Long nX) { tools::Long nLeft = 0, nRight = 0; sal_Int32 nLast = 0, nIdx = 0; @@ -97,9 +98,8 @@ sal_Int32 GetModelPosition(const std::vector<sal_Int32>& rKernArray, sal_Int32 n return nIdx; } -void SpaceDistribution(std::vector<sal_Int32>& rKernArray, std::u16string_view aText, - sal_Int32 nStt, sal_Int32 nLen, tools::Long nSpaceAdd, tools::Long nKern, - bool bNoHalfSpace) +void SpaceDistribution(KernArray& rKernArray, std::u16string_view aText, sal_Int32 nStt, + sal_Int32 nLen, tools::Long nSpaceAdd, tools::Long nKern, bool bNoHalfSpace) { assert(nStt + nLen <= sal_Int32(aText.size())); assert(nLen <= sal_Int32(rKernArray.size())); @@ -152,26 +152,29 @@ void SpaceDistribution(std::vector<sal_Int32>& rKernArray, std::u16string_view a } cChPrev = nCh; - rKernArray[nPrevIdx] += nKernSum + nSpaceSum; + rKernArray.adjust(nPrevIdx, nKernSum + nSpaceSum); // In word line mode and for Arabic, we disabled the half space trick. If a portion // ends with a blank, the full nSpaceAdd value has been added to the character in // front of the blank. This leads to painting artifacts, therefore we remove the // nSpaceAdd value again: if (bNoHalfSpace && i + 1 == nLen && nCh == CH_BLANK) - rKernArray[nPrevIdx] = rKernArray[nPrevIdx] - nSpaceAdd; + rKernArray.adjust(nPrevIdx, -nSpaceAdd); // Advance nPrevIdx and assign kern values to previous cluster. for (tools::Long nValue = rKernArray[nPrevIdx++]; nPrevIdx < i; ++nPrevIdx) - rKernArray[nPrevIdx] = nValue; + rKernArray.set(nPrevIdx, nValue); } // the layout engine requires the total width of the output while (nPrevIdx < nLen) - rKernArray[nPrevIdx++] += nKernSum + nSpaceSum; + { + rKernArray.adjust(nPrevIdx, nKernSum + nSpaceSum); + ++nPrevIdx; + } } -tools::Long SnapToGrid(std::vector<sal_Int32>& rKernArray, std::u16string_view aText, - sal_Int32 nStt, sal_Int32 nLen, tools::Long nGridWidth, bool bForceLeft) +tools::Long SnapToGrid(KernArray& rKernArray, std::u16string_view aText, sal_Int32 nStt, + sal_Int32 nLen, tools::Long nGridWidth, bool bForceLeft) { assert(nStt + nLen <= sal_Int32(aText.size())); assert(nLen <= sal_Int32(rKernArray.size())); @@ -195,16 +198,22 @@ tools::Long SnapToGrid(std::vector<sal_Int32>& rKernArray, std::u16string_view a nEdge += nMinWidth; while (nLast < i) - rKernArray[nLast++] = nX; + { + rKernArray.set(nLast, nX); + ++nLast; + } } while (nLast < nLen) - rKernArray[nLast++] = nEdge; + { + rKernArray.set(nLast, nEdge); + ++nLast; + } return nDelta; } -void SnapToGridEdge(std::vector<sal_Int32>& rKernArray, sal_Int32 nLen, tools::Long nGridWidth, +void SnapToGridEdge(KernArray& rKernArray, sal_Int32 nLen, tools::Long nGridWidth, tools::Long nSpace, tools::Long nKern) { assert(nLen <= sal_Int32(rKernArray.size())); @@ -222,13 +231,19 @@ void SnapToGridEdge(std::vector<sal_Int32>& rKernArray, sal_Int32 nLen, tools::L nCharWidth = rKernArray[i] - rKernArray[nLast]; tools::Long nMinWidth = lcl_MinGridWidth(nGridWidth, nCharWidth + nKern); while (nLast < i) - rKernArray[nLast++] = nEdge; + { + rKernArray.set(nLast, nEdge); + ++nLast; + } nEdge += nMinWidth + nSpace; } while (nLast < nLen) - rKernArray[nLast++] = nEdge; + { + rKernArray.set(nLast, nEdge); + ++nLast; + } } } diff --git a/sw/source/core/txtnode/justify.hxx b/sw/source/core/txtnode/justify.hxx index 9a7ff5f126ab..454b6c259001 100644 --- a/sw/source/core/txtnode/justify.hxx +++ b/sw/source/core/txtnode/justify.hxx @@ -16,7 +16,7 @@ namespace sw::Justify /// @param rKernArray text positions from OutDev::GetTextArray(). /// @param nLen number of elements to process in rKernArray. /// @param nX the visual position -SW_DLLPUBLIC sal_Int32 GetModelPosition(const std::vector<sal_Int32>& rKernArray, sal_Int32 nLen, +SW_DLLPUBLIC sal_Int32 GetModelPosition(const KernArray& rKernArray, sal_Int32 nLen, tools::Long nX); /// Distribute space between words and letters. /// @param[in,out] rKernArray text positions from OutDev::GetTextArray(). @@ -28,7 +28,7 @@ SW_DLLPUBLIC sal_Int32 GetModelPosition(const std::vector<sal_Int32>& rKernArray /// @param bNoHalfSpace whether to split the space into two halves. /// Split spaces are inserted before and after CH_BLANK. /// Set to true in word line mode and for Arabic text to avoid splitting. -SW_DLLPUBLIC void SpaceDistribution(std::vector<sal_Int32>& rKernArray, std::u16string_view aText, +SW_DLLPUBLIC void SpaceDistribution(KernArray& rKernArray, std::u16string_view aText, sal_Int32 nStt, sal_Int32 nLen, tools::Long nSpaceAdd, tools::Long nKern, bool bNoHalfSpace); @@ -47,7 +47,7 @@ SW_DLLPUBLIC void SpaceDistribution(std::vector<sal_Int32>& rKernArray, std::u16 /// @param bForceLeft for align to the left edge of the grid disregard of the punctuation type. /// This is useful for calculate text width, line break, and conversion model position. /// @return the delta offset of first glyph so text origin can be updated accordingly. -SW_DLLPUBLIC tools::Long SnapToGrid(std::vector<sal_Int32>& rKernArray, std::u16string_view aText, +SW_DLLPUBLIC tools::Long SnapToGrid(KernArray& rKernArray, std::u16string_view aText, sal_Int32 nStt, sal_Int32 nLen, tools::Long nGridWidth, bool bForceLeft); @@ -58,8 +58,8 @@ SW_DLLPUBLIC tools::Long SnapToGrid(std::vector<sal_Int32>& rKernArray, std::u16 /// @param nGridWidth width of a text grid /// @param nSpace amount of space distributed under justify text alignment mode. /// @param nKern letter spacing. -SW_DLLPUBLIC void SnapToGridEdge(std::vector<sal_Int32>& rKernArray, sal_Int32 nLen, - tools::Long nGridWidth, tools::Long nSpace, tools::Long nKern); +SW_DLLPUBLIC void SnapToGridEdge(KernArray& rKernArray, sal_Int32 nLen, tools::Long nGridWidth, + tools::Long nSpace, tools::Long nKern); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |