summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/vcl/outdev.hxx20
-rw-r--r--sw/source/core/inc/drawfont.hxx16
-rw-r--r--sw/source/core/text/guess.cxx7
-rw-r--r--sw/source/core/text/inftxt.cxx35
-rw-r--r--sw/source/core/text/inftxt.hxx25
-rw-r--r--sw/source/core/text/porfld.cxx4
-rw-r--r--sw/source/core/text/pormulti.cxx3
-rw-r--r--sw/source/core/txtnode/fntcache.cxx7
-rw-r--r--vcl/generic/glyphs/gcach_layout.cxx64
-rw-r--r--vcl/inc/generic/glyphcache.hxx3
-rw-r--r--vcl/inc/sallayout.hxx12
-rw-r--r--vcl/source/gdi/sallayout.cxx10
-rw-r--r--vcl/source/outdev/text.cxx53
13 files changed, 213 insertions, 46 deletions
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 7911b662b285..47c77ad4c47c 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -140,6 +140,7 @@ namespace vcl
class ExtOutDevData;
class ITextLayout;
struct FontCapabilities;
+ class TextLayoutCache;
}
// OutputDevice-Types
@@ -1066,7 +1067,8 @@ public:
See also GetTextBoundRect() for more explanation + code examples.
*/
- long GetTextWidth( const OUString& rStr, sal_Int32 nIndex = 0, sal_Int32 nLen = -1 ) const;
+ long GetTextWidth( const OUString& rStr, sal_Int32 nIndex = 0, sal_Int32 nLen = -1,
+ vcl::TextLayoutCache const* = nullptr) const;
/** Height where any character of the current font fits; in logic coordinates.
@@ -1081,7 +1083,8 @@ public:
sal_Int32 nLen = -1,
int flags = 0);
long GetTextArray( const OUString& rStr, long* pDXAry = NULL,
- sal_Int32 nIndex = 0, sal_Int32 nLen = -1 ) const;
+ sal_Int32 nIndex = 0, sal_Int32 nLen = -1,
+ vcl::TextLayoutCache const* = nullptr) const;
bool GetCaretPositions( const OUString&, long* pCaretXArray,
sal_Int32 nIndex, sal_Int32 nLen,
@@ -1092,11 +1095,14 @@ public:
sal_Int32 nIndex = 0, sal_Int32 nLen = -1);
sal_Int32 GetTextBreak( const OUString& rStr, long nTextWidth,
sal_Int32 nIndex = 0, sal_Int32 nLen = -1,
- long nCharExtra = 0 ) const;
+ long nCharExtra = 0,
+ vcl::TextLayoutCache const* = nullptr) const;
sal_Int32 GetTextBreak( const OUString& rStr, long nTextWidth,
sal_Unicode nExtraChar, sal_Int32& rExtraCharPos,
sal_Int32 nIndex, sal_Int32 nLen,
- long nCharExtra = 0 ) const;
+ long nCharExtra = 0,
+ vcl::TextLayoutCache const* = nullptr) const;
+ std::shared_ptr<vcl::TextLayoutCache> CreateTextLayoutCache(OUString const&) const;
private:
SAL_DLLPRIVATE void ImplInitTextColor();
@@ -1247,9 +1253,11 @@ public:
virtual bool HasMirroredGraphics() const;
SAL_DLLPRIVATE SalLayout* ImplLayout( const OUString&, sal_Int32 nIndex, sal_Int32 nLen,
const Point& rLogicPos = Point(0,0), long nLogicWidth=0,
- const long* pLogicDXArray=NULL, int flags=0 ) const;
+ const long* pLogicDXArray=NULL, int flags=0,
+ vcl::TextLayoutCache const* = nullptr) const;
SAL_DLLPRIVATE ImplLayoutArgs ImplPrepareLayoutArgs( OUString&, const sal_Int32 nIndex, const sal_Int32 nLen,
- DeviceCoordinate nPixelWidth, const DeviceCoordinate* pPixelDXArray, int flags = 0 ) const;
+ DeviceCoordinate nPixelWidth, const DeviceCoordinate* pPixelDXArray, int flags = 0,
+ vcl::TextLayoutCache const* = nullptr) const;
SAL_DLLPRIVATE SalLayout* ImplGlyphFallbackLayout( SalLayout*, ImplLayoutArgs& ) const;
// tells whether this output device is RTL in an LTR UI or LTR in a RTL UI
SAL_DLLPRIVATE SalLayout* getFallbackFont(ImplFontEntry &rFallbackFont,
diff --git a/sw/source/core/inc/drawfont.hxx b/sw/source/core/inc/drawfont.hxx
index 033d4901b263..fee34b12737e 100644
--- a/sw/source/core/inc/drawfont.hxx
+++ b/sw/source/core/inc/drawfont.hxx
@@ -31,7 +31,10 @@ class Point;
class SwWrongList;
class Size;
class SwFont;
-namespace vcl { class Font; }
+namespace vcl {
+ class Font;
+ class TextLayoutCache;
+}
class SwUnderlineFont;
// encapsulates information for drawing text
@@ -42,6 +45,7 @@ class SwDrawTextInfo
SwViewShell const * pSh;
const SwScriptInfo* pScriptInfo;
Point m_aPos;
+ vcl::TextLayoutCache const* m_pCachedVclData;
OUString m_aText;
const SwWrongList* pWrong;
const SwWrongList* pGrammarCheck;
@@ -104,7 +108,9 @@ public:
SwDrawTextInfo( SwViewShell const *pS, OutputDevice &rO, const SwScriptInfo* pSI,
const OUString &rSt, sal_Int32 nI, sal_Int32 nL,
- sal_uInt16 nW = 0, bool bB = false )
+ sal_uInt16 nW = 0, bool bB = false,
+ vcl::TextLayoutCache const*const pCachedVclData = nullptr)
+ : m_pCachedVclData(pCachedVclData)
{
pFrm = NULL;
pSh = pS;
@@ -200,6 +206,11 @@ public:
return pHyphPos;
}
+ vcl::TextLayoutCache const* GetVclCache() const
+ {
+ return m_pCachedVclData;
+ }
+
const OUString &GetText() const
{
return m_aText;
@@ -416,6 +427,7 @@ public:
void SetText( const OUString &rNew )
{
m_aText = rNew;
+ m_pCachedVclData = nullptr; // would any case benefit from save/restore?
}
void SetWrong( const SwWrongList* pNew )
diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx
index 03396469609b..b379308e59b0 100644
--- a/sw/source/core/text/guess.cxx
+++ b/sw/source/core/text/guess.cxx
@@ -152,14 +152,14 @@ bool SwTxtGuess::Guess( const SwTxtPortion& rPor, SwTxtFormatInfo &rInf,
// considering an additional "-" for hyphenation
if( bHyph )
{
- nCutPos = rInf.GetTxtBreak( nLineWidth, nMaxLen, nMaxComp, nHyphPos );
+ nCutPos = rInf.GetTxtBreak( nLineWidth, nMaxLen, nMaxComp, nHyphPos, rInf.GetCachedVclData().get() );
if ( !nHyphPos && rInf.GetIdx() )
nHyphPos = rInf.GetIdx() - 1;
}
else
{
- nCutPos = rInf.GetTxtBreak( nLineWidth, nMaxLen, nMaxComp );
+ nCutPos = rInf.GetTxtBreak( nLineWidth, nMaxLen, nMaxComp, rInf.GetCachedVclData().get() );
#if OSL_DEBUG_LEVEL > 1
if ( COMPLETE_STRING != nCutPos )
@@ -504,7 +504,8 @@ bool SwTxtGuess::Guess( const SwTxtPortion& rPor, SwTxtFormatInfo &rInf,
if( nPorLen )
{
rInf.GetTxtSize( &rSI, rInf.GetIdx(), nPorLen,
- nMaxComp, nBreakWidth, nMaxSizeDiff );
+ nMaxComp, nBreakWidth, nMaxSizeDiff,
+ rInf.GetCachedVclData().get() );
// save maximum width for later use
if ( nMaxSizeDiff )
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index 6a622e44352d..b738d9f5e17f 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -21,6 +21,7 @@
#include <unotools/linguprops.hxx>
#include <unotools/lingucfg.hxx>
#include <hintids.hxx>
+#include <svl/ctloptions.hxx>
#include <sfx2/printer.hxx>
#include <editeng/hyphenzoneitem.hxx>
#include <editeng/escapementitem.hxx>
@@ -360,7 +361,7 @@ SwPosSize SwTxtSizeInfo::GetTxtSize( OutputDevice* pOutDev,
const OUString& rTxt,
const sal_Int32 nIndex,
const sal_Int32 nLength,
- const sal_uInt16 nComp ) const
+ const sal_uInt16 nComp) const
{
SwDrawTextInfo aDrawInf( m_pVsh, *pOutDev, pSI, rTxt, nIndex, nLength );
aDrawInf.SetFrm( m_pFrm );
@@ -393,9 +394,11 @@ SwPosSize SwTxtSizeInfo::GetTxtSize() const
void SwTxtSizeInfo::GetTxtSize( const SwScriptInfo* pSI, const sal_Int32 nIndex,
const sal_Int32 nLength, const sal_uInt16 nComp,
- sal_uInt16& nMinSize, sal_uInt16& nMaxSizeDiff ) const
+ sal_uInt16& nMinSize, sal_uInt16& nMaxSizeDiff,
+ vcl::TextLayoutCache const*const pCache) const
{
- SwDrawTextInfo aDrawInf( m_pVsh, *m_pOut, pSI, *m_pTxt, nIndex, nLength );
+ SwDrawTextInfo aDrawInf( m_pVsh, *m_pOut, pSI, *m_pTxt, nIndex, nLength,
+ 0, false, pCache);
aDrawInf.SetFrm( m_pFrm );
aDrawInf.SetFont( m_pFnt );
aDrawInf.SetSnapToGrid( SnapToGrid() );
@@ -407,14 +410,15 @@ void SwTxtSizeInfo::GetTxtSize( const SwScriptInfo* pSI, const sal_Int32 nIndex,
sal_Int32 SwTxtSizeInfo::GetTxtBreak( const long nLineWidth,
const sal_Int32 nMaxLen,
- const sal_uInt16 nComp ) const
+ const sal_uInt16 nComp,
+ vcl::TextLayoutCache const*const pCache) const
{
const SwScriptInfo& rScriptInfo =
const_cast<SwParaPortion*>(GetParaPortion())->GetScriptInfo();
OSL_ENSURE( m_pRef == m_pOut, "GetTxtBreak is supposed to use the RefDev" );
SwDrawTextInfo aDrawInf( m_pVsh, *m_pOut, &rScriptInfo,
- *m_pTxt, GetIdx(), nMaxLen );
+ *m_pTxt, GetIdx(), nMaxLen, 0, false, pCache );
aDrawInf.SetFrm( m_pFrm );
aDrawInf.SetFont( m_pFnt );
aDrawInf.SetSnapToGrid( SnapToGrid() );
@@ -427,14 +431,15 @@ sal_Int32 SwTxtSizeInfo::GetTxtBreak( const long nLineWidth,
sal_Int32 SwTxtSizeInfo::GetTxtBreak( const long nLineWidth,
const sal_Int32 nMaxLen,
const sal_uInt16 nComp,
- sal_Int32& rExtraCharPos ) const
+ sal_Int32& rExtraCharPos,
+ vcl::TextLayoutCache const*const pCache) const
{
const SwScriptInfo& rScriptInfo =
const_cast<SwParaPortion*>(GetParaPortion())->GetScriptInfo();
OSL_ENSURE( m_pRef == m_pOut, "GetTxtBreak is supposed to use the RefDev" );
SwDrawTextInfo aDrawInf( m_pVsh, *m_pOut, &rScriptInfo,
- *m_pTxt, GetIdx(), nMaxLen );
+ *m_pTxt, GetIdx(), nMaxLen, 0, false, pCache );
aDrawInf.SetFrm( m_pFrm );
aDrawInf.SetFont( m_pFnt );
aDrawInf.SetSnapToGrid( SnapToGrid() );
@@ -1339,6 +1344,19 @@ void SwTxtFormatInfo::CtorInitTxtFormatInfo( SwTxtFrm *pNewFrm, const bool bNewI
nLineHeight = 0;
nLineNetHeight = 0;
SetLineStart(0);
+
+ SvtCTLOptions::TextNumerals const nTextNumerals(
+ SW_MOD()->GetCTLOptions().GetCTLTextNumerals());
+ // cannot cache for NUMERALS_CONTEXT because we need to know the string
+ // for the whole paragraph now
+ if (nTextNumerals != SvtCTLOptions::NUMERALS_CONTEXT)
+ {
+ // set digit mode to what will be used later to get same results
+ SwDigitModeModifier const m(*m_pRef, LANGUAGE_NONE /*dummy*/);
+ assert(m_pRef->GetDigitLanguage() != LANGUAGE_NONE);
+ SetCachedVclData(m_pRef->CreateTextLayoutCache(*m_pTxt));
+ }
+
Init();
}
@@ -1642,9 +1660,11 @@ SwTxtSlot::SwTxtSlot(
nIdx = pInf->GetIdx();
nLen = pInf->GetLen();
pOldTxt = &(pInf->GetTxt());
+ m_pOldCachedVclData = pInf->GetCachedVclData();
pInf->SetTxt( aTxt );
pInf->SetIdx( 0 );
pInf->SetLen( bTxtLen ? pInf->GetTxt().getLength() : pPor->GetLen() );
+ pInf->SetCachedVclData(nullptr);
// ST2
if ( bExgLists )
@@ -1689,6 +1709,7 @@ SwTxtSlot::~SwTxtSlot()
{
if( bOn )
{
+ pInf->SetCachedVclData(m_pOldCachedVclData);
pInf->SetTxt( *pOldTxt );
pInf->SetIdx( nIdx );
pInf->SetLen( nLen );
diff --git a/sw/source/core/text/inftxt.hxx b/sw/source/core/text/inftxt.hxx
index a0b627c2bf48..45680164e43a 100644
--- a/sw/source/core/text/inftxt.hxx
+++ b/sw/source/core/text/inftxt.hxx
@@ -158,6 +158,11 @@ protected:
OutputDevice* m_pOut;
OutputDevice* m_pRef;
+ // performance hack - this is only used by SwTxtFormatInfo but
+ // because it's not even possible to dynamic_cast these things
+ // currently it has to be stored here
+ std::shared_ptr<vcl::TextLayoutCache> m_pCachedVclData;
+
SwFont *m_pFnt;
SwUnderlineFont *m_pUnderFnt; // Font for underlining
SwTxtFrm *m_pFrm;
@@ -295,18 +300,21 @@ public:
SwPosSize GetTxtSize() const;
void GetTxtSize( const SwScriptInfo* pSI, const sal_Int32 nIdx,
const sal_Int32 nLen, const sal_uInt16 nComp,
- sal_uInt16& nMinSize, sal_uInt16& nMaxSizeDiff ) const;
+ sal_uInt16& nMinSize, sal_uInt16& nMaxSizeDiff,
+ vcl::TextLayoutCache const* = nullptr) const;
inline SwPosSize GetTxtSize( const SwScriptInfo* pSI, const sal_Int32 nIdx,
const sal_Int32 nLen, const sal_uInt16 nComp ) const;
inline SwPosSize GetTxtSize( const OUString &rTxt ) const;
sal_Int32 GetTxtBreak( const long nLineWidth,
const sal_Int32 nMaxLen,
- const sal_uInt16 nComp ) const;
+ const sal_uInt16 nComp,
+ vcl::TextLayoutCache const* = nullptr) const;
sal_Int32 GetTxtBreak( const long nLineWidth,
const sal_Int32 nMaxLen,
const sal_uInt16 nComp,
- sal_Int32& rExtraCharPos ) const;
+ sal_Int32& rExtraCharPos,
+ vcl::TextLayoutCache const* = nullptr) const;
sal_uInt16 GetAscent() const;
@@ -371,6 +379,15 @@ public:
{ return ( m_pKanaComp && m_nKanaIdx < m_pKanaComp->size() )
? (*m_pKanaComp)[m_nKanaIdx] : 0; }
+ std::shared_ptr<vcl::TextLayoutCache> GetCachedVclData() const
+ {
+ return m_pCachedVclData;
+ }
+ void SetCachedVclData(std::shared_ptr<vcl::TextLayoutCache> const& pCachedVclData)
+ {
+ m_pCachedVclData = pCachedVclData;
+ }
+
#ifdef DBG_UTIL
bool IsOptDbg() const;
#endif
@@ -725,6 +742,7 @@ public:
inline void SetTabOverflow( bool bOverflow ) { bTabOverflow = bOverflow; }
inline bool IsTabOverflow() { return bTabOverflow; }
+
};
/**
@@ -737,6 +755,7 @@ public:
class SwTxtSlot
{
OUString aTxt;
+ std::shared_ptr<vcl::TextLayoutCache> m_pOldCachedVclData;
const OUString *pOldTxt;
const SwWrongList* pOldSmartTagList;
const SwWrongList* pOldGrammarCheckList;
diff --git a/sw/source/core/text/porfld.cxx b/sw/source/core/text/porfld.cxx
index ae446176bf96..95b1542fe8cc 100644
--- a/sw/source/core/text/porfld.cxx
+++ b/sw/source/core/text/porfld.cxx
@@ -136,6 +136,7 @@ sal_uInt16 SwFldPortion::GetViewWidth( const SwTxtSizeInfo &rInf ) const
*/
class SwFldSlot
{
+ std::shared_ptr<vcl::TextLayoutCache> m_pOldCachedVclData;
const OUString *pOldTxt;
OUString aTxt;
sal_Int32 nIdx;
@@ -162,7 +163,9 @@ SwFldSlot::SwFldSlot( const SwTxtFormatInfo* pNew, const SwFldPortion *pPor )
nIdx = pInf->GetIdx();
nLen = pInf->GetLen();
pOldTxt = &(pInf->GetTxt());
+ m_pOldCachedVclData = pInf->GetCachedVclData();
pInf->SetLen( aTxt.getLength() );
+ pInf->SetCachedVclData(nullptr);
if( pPor->IsFollow() )
{
pInf->SetFakeLineStart( nIdx > pInf->GetLineStart() );
@@ -180,6 +183,7 @@ SwFldSlot::~SwFldSlot()
{
if( bOn )
{
+ pInf->SetCachedVclData(m_pOldCachedVclData);
pInf->SetTxt( *pOldTxt );
pInf->SetIdx( nIdx );
pInf->SetLen( nLen );
diff --git a/sw/source/core/text/pormulti.cxx b/sw/source/core/text/pormulti.cxx
index 9df8de427167..2bb8217403fa 100644
--- a/sw/source/core/text/pormulti.cxx
+++ b/sw/source/core/text/pormulti.cxx
@@ -1735,6 +1735,8 @@ bool SwTxtFormatter::BuildMultiPortion( SwTxtFormatInfo &rInf,
// save some values
const OUString* pOldTxt = &(rInf.GetTxt());
const SwTwips nOldPaintOfst = rInf.GetPaintOfst();
+ std::shared_ptr<vcl::TextLayoutCache> const pOldCachedVclData(rInf.GetCachedVclData());
+ rInf.SetCachedVclData(nullptr);
OUString const aMultiStr( rInf.GetTxt().copy(0, nMultiLen + rInf.GetIdx()) );
rInf.SetTxt( aMultiStr );
@@ -2053,6 +2055,7 @@ bool SwTxtFormatter::BuildMultiPortion( SwTxtFormatInfo &rInf,
rInf.SetRest( pTmp );
}
+ rInf.SetCachedVclData(pOldCachedVclData);
rInf.SetTxt( *pOldTxt );
rInf.SetPaintOfst( nOldPaintOfst );
rInf.SetStop( aInf.IsStop() );
diff --git a/sw/source/core/txtnode/fntcache.cxx b/sw/source/core/txtnode/fntcache.cxx
index 7a837ed5945f..9ba646dcd282 100644
--- a/sw/source/core/txtnode/fntcache.cxx
+++ b/sw/source/core/txtnode/fntcache.cxx
@@ -1973,7 +1973,8 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf )
else
{
aTxtSize.Width() = rInf.GetOut().GetTextWidth( rInf.GetText(),
- rInf.GetIdx(), nLn );
+ rInf.GetIdx(), nLn,
+ rInf.GetVclCache());
rInf.SetKanaDiff( 0 );
}
@@ -2430,12 +2431,12 @@ sal_Int32 SwFont::GetTxtBreak( SwDrawTextInfo& rInf, long nTextWidth )
sal_Int32 nHyphPos = *rInf.GetHyphPos();
nTxtBreak = rInf.GetOut().GetTextBreak( *pTmpText, nTextWidth,
static_cast<sal_Unicode>('-'), nHyphPos,
- nTmpIdx, nTmpLen, nKern );
+ nTmpIdx, nTmpLen, nKern, rInf.GetVclCache());
*rInf.GetHyphPos() = (nHyphPos == -1) ? COMPLETE_STRING : nHyphPos;
}
else
nTxtBreak = rInf.GetOut().GetTextBreak( *pTmpText, nTextWidth,
- nTmpIdx, nTmpLen, nKern );
+ nTmpIdx, nTmpLen, nKern, rInf.GetVclCache());
if ( bTextReplaced && nTxtBreak != -1 )
{
diff --git a/vcl/generic/glyphs/gcach_layout.cxx b/vcl/generic/glyphs/gcach_layout.cxx
index 5010423c03be..8e9deeb4f226 100644
--- a/vcl/generic/glyphs/gcach_layout.cxx
+++ b/vcl/generic/glyphs/gcach_layout.cxx
@@ -349,6 +349,41 @@ struct HbScriptRun
typedef std::vector<HbScriptRun> HbScriptRuns;
+namespace vcl {
+ struct Run
+ {
+ int32_t nStart;
+ int32_t nEnd;
+ UScriptCode nCode;
+ Run(int32_t nStart_, int32_t nEnd_, UScriptCode nCode_)
+ : nStart(nStart_), nEnd(nEnd_), nCode(nCode_)
+ {}
+ };
+
+ class TextLayoutCache
+ {
+ public:
+ std::vector<vcl::Run> runs;
+ TextLayoutCache(OUString const& rString, sal_Int32 const nEnd)
+ {
+ vcl::ScriptRun aScriptRun(
+ reinterpret_cast<const UChar *>(rString.getStr()),
+ nEnd);
+ while (aScriptRun.next())
+ {
+ runs.push_back(Run(aScriptRun.getScriptStart(),
+ aScriptRun.getScriptEnd(), aScriptRun.getScriptCode()));
+ }
+ }
+ };
+}
+
+std::shared_ptr<vcl::TextLayoutCache> ServerFontLayout::CreateTextLayoutCache(
+ OUString const& rString) const
+{
+ return std::make_shared<vcl::TextLayoutCache>(rString, rString.getLength());
+}
+
bool HbLayoutEngine::Layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs)
{
ServerFont& rFont = rLayout.GetServerFont();
@@ -370,7 +405,18 @@ bool HbLayoutEngine::Layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs)
rLayout.Reserve(nGlyphCapacity);
- vcl::ScriptRun aScriptRun(reinterpret_cast<const UChar *>(rArgs.mpStr), rArgs.mnEndCharPos);
+ std::unique_ptr<vcl::TextLayoutCache> pNewScriptRun;
+ vcl::TextLayoutCache const* pTextLayout;
+ if (rArgs.m_pTextLayoutCache)
+ {
+ pTextLayout = rArgs.m_pTextLayoutCache; // use cache!
+ }
+ else
+ {
+ pNewScriptRun.reset(new vcl::TextLayoutCache(
+ reinterpret_cast<const UChar *>(rArgs.mpStr), rArgs.mnEndCharPos));
+ pTextLayout = pNewScriptRun.get();
+ }
Point aCurrPos(0, 0);
while (true)
@@ -383,21 +429,25 @@ bool HbLayoutEngine::Layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs)
// Find script subruns.
int nCurrentPos = nBidiMinRunPos;
HbScriptRuns aScriptSubRuns;
- while (aScriptRun.next())
+ size_t k = 0;
+ for (; k < pTextLayout->runs.size(); ++k)
{
- if (aScriptRun.getScriptStart() <= nCurrentPos && aScriptRun.getScriptEnd() > nCurrentPos)
+ vcl::Run const& rRun(pTextLayout->runs[k]);
+ if (rRun.nStart <= nCurrentPos && nCurrentPos < rRun.nEnd)
+ {
break;
+ }
}
while (nCurrentPos < nBidiEndRunPos)
{
int32_t nMinRunPos = nCurrentPos;
- int32_t nEndRunPos = std::min(aScriptRun.getScriptEnd(), nBidiEndRunPos);
- HbScriptRun aRun(nMinRunPos, nEndRunPos, aScriptRun.getScriptCode());
+ int32_t nEndRunPos = std::min(pTextLayout->runs[k].nEnd, nBidiEndRunPos);
+ HbScriptRun aRun(nMinRunPos, nEndRunPos, pTextLayout->runs[k].nCode);
aScriptSubRuns.push_back(aRun);
nCurrentPos = nEndRunPos;
- aScriptRun.next();
+ ++k;
}
// RTL subruns should be reversed to ensure that final glyph order is
@@ -405,8 +455,6 @@ bool HbLayoutEngine::Layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs)
if (bRightToLeft)
std::reverse(aScriptSubRuns.begin(), aScriptSubRuns.end());
- aScriptRun.reset();
-
for (HbScriptRuns::iterator it = aScriptSubRuns.begin(); it != aScriptSubRuns.end(); ++it)
{
int nMinRunPos = it->mnMin;
diff --git a/vcl/inc/generic/glyphcache.hxx b/vcl/inc/generic/glyphcache.hxx
index c8d3552ba7c9..ae9e30b9c59a 100644
--- a/vcl/inc/generic/glyphcache.hxx
+++ b/vcl/inc/generic/glyphcache.hxx
@@ -299,6 +299,9 @@ public:
ServerFont& GetServerFont() const { return mrServerFont; }
+ virtual std::shared_ptr<vcl::TextLayoutCache>
+ CreateTextLayoutCache(OUString const&) const SAL_OVERRIDE;
+
private:
ServerFont& mrServerFont;
com::sun::star::uno::Reference<com::sun::star::i18n::XBreakIterator> mxBreak;
diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx
index 943f8eb6bf5b..7ad886640d5c 100644
--- a/vcl/inc/sallayout.hxx
+++ b/vcl/inc/sallayout.hxx
@@ -41,6 +41,9 @@ typedef unsigned short LanguageType;
class SalGraphics;
class PhysicalFontFace;
+namespace vcl {
+ class TextLayoutCache;
+}
// used for managing runs e.g. for BiDi, glyph and script fallback
class VCL_PLUGIN_PUBLIC ImplLayoutRuns
@@ -76,6 +79,9 @@ public:
int mnEndCharPos;
const sal_Unicode* mpStr;
+ // performance hack
+ vcl::TextLayoutCache const* m_pTextLayoutCache;
+
// positioning related inputs
const DeviceCoordinate* mpDXArray; // in pixel units
DeviceCoordinate mnLayoutWidth; // in pixel units
@@ -88,7 +94,8 @@ public:
public:
ImplLayoutArgs( const sal_Unicode* pStr, int nLength,
int nMinCharPos, int nEndCharPos, int nFlags,
- const LanguageTag& rLanguageTag );
+ const LanguageTag& rLanguageTag,
+ vcl::TextLayoutCache const* pLayoutCache);
void SetLayoutWidth( DeviceCoordinate nWidth ) { mnLayoutWidth = nWidth; }
void SetDXArray( const DeviceCoordinate* pDXArray ) { mpDXArray = pDXArray; }
@@ -194,6 +201,9 @@ public:
virtual void Simplify( bool bIsBase ) = 0;
virtual void DisableGlyphInjection( bool /*bDisable*/ ) {}
+ virtual std::shared_ptr<vcl::TextLayoutCache>
+ CreateTextLayoutCache(OUString const&) const;
+
protected:
// used by layout engines
SalLayout();
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index 9ba3dcc21d02..c6897f20c76f 100644
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -486,7 +486,8 @@ bool ImplLayoutRuns::GetRun( int* nMinRunPos, int* nEndRunPos, bool* bRightToLef
}
ImplLayoutArgs::ImplLayoutArgs( const sal_Unicode* pStr, int nLen,
- int nMinCharPos, int nEndCharPos, int nFlags, const LanguageTag& rLanguageTag )
+ int nMinCharPos, int nEndCharPos, int nFlags, const LanguageTag& rLanguageTag,
+ vcl::TextLayoutCache const*const pLayoutCache)
:
maLanguageTag( rLanguageTag ),
mnFlags( nFlags ),
@@ -494,6 +495,7 @@ ImplLayoutArgs::ImplLayoutArgs( const sal_Unicode* pStr, int nLen,
mnMinCharPos( nMinCharPos ),
mnEndCharPos( nEndCharPos ),
mpStr( pStr ),
+ m_pTextLayoutCache(pLayoutCache),
mpDXArray( NULL ),
mnLayoutWidth( 0 ),
mnOrientation( 0 )
@@ -2128,4 +2130,10 @@ bool MultiSalLayout::GetOutline( SalGraphics& rGraphics,
return bRet;
}
+std::shared_ptr<vcl::TextLayoutCache> SalLayout::CreateTextLayoutCache(
+ OUString const&) const
+{
+ return 0; // by default, nothing to cache
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx
index 9b97d1de1928..6dfe1098e5c2 100644
--- a/vcl/source/outdev/text.cxx
+++ b/vcl/source/outdev/text.cxx
@@ -925,10 +925,11 @@ void OutputDevice::DrawText( const Point& rStartPt, const OUString& rStr,
mpAlphaVDev->DrawText( rStartPt, rStr, nIndex, nLen, pVector, pDisplayText );
}
-long OutputDevice::GetTextWidth( const OUString& rStr, sal_Int32 nIndex, sal_Int32 nLen ) const
+long OutputDevice::GetTextWidth( const OUString& rStr, sal_Int32 nIndex, sal_Int32 nLen,
+ vcl::TextLayoutCache const*const pLayoutCache) const
{
- long nWidth = GetTextArray( rStr, NULL, nIndex, nLen );
+ long nWidth = GetTextArray( rStr, NULL, nIndex, nLen, pLayoutCache );
return nWidth;
}
@@ -993,7 +994,8 @@ void OutputDevice::DrawTextArray( const Point& rStartPt, const OUString& rStr,
}
long OutputDevice::GetTextArray( const OUString& rStr, long* pDXAry,
- sal_Int32 nIndex, sal_Int32 nLen ) const
+ sal_Int32 nIndex, sal_Int32 nLen,
+ vcl::TextLayoutCache const*const pLayoutCache) const
{
if(nLen == 0x0FFFF)
{
@@ -1009,7 +1011,8 @@ long OutputDevice::GetTextArray( const OUString& rStr, long* pDXAry,
nLen = rStr.getLength() - nIndex;
}
// do layout
- SalLayout* pSalLayout = ImplLayout( rStr, nIndex, nLen );
+ SalLayout *const pSalLayout = ImplLayout(rStr, nIndex, nLen,
+ Point(0,0), 0, nullptr, 0, pLayoutCache);
if( !pSalLayout )
return 0;
#if VCL_FLOAT_DEVICE_PIXEL
@@ -1191,7 +1194,8 @@ void OutputDevice::DrawStretchText( const Point& rStartPt, sal_uLong nWidth,
ImplLayoutArgs OutputDevice::ImplPrepareLayoutArgs( OUString& rStr,
const sal_Int32 nMinIndex, const sal_Int32 nLen,
DeviceCoordinate nPixelWidth, const DeviceCoordinate* pDXArray,
- int nLayoutFlags ) const
+ int nLayoutFlags,
+ vcl::TextLayoutCache const*const pLayoutCache) const
{
assert(nMinIndex >= 0);
assert(nLen >= 0);
@@ -1290,7 +1294,7 @@ ImplLayoutArgs OutputDevice::ImplPrepareLayoutArgs( OUString& rStr,
nLayoutFlags |= SAL_LAYOUT_RIGHT_ALIGN;
// set layout options
- ImplLayoutArgs aLayoutArgs( rStr.getStr(), rStr.getLength(), nMinIndex, nEndIndex, nLayoutFlags, maFont.GetLanguageTag() );
+ ImplLayoutArgs aLayoutArgs( rStr.getStr(), rStr.getLength(), nMinIndex, nEndIndex, nLayoutFlags, maFont.GetLanguageTag(), pLayoutCache );
int nOrientation = mpFontEntry ? mpFontEntry->mnOrientation : 0;
aLayoutArgs.SetOrientation( nOrientation );
@@ -1304,7 +1308,8 @@ ImplLayoutArgs OutputDevice::ImplPrepareLayoutArgs( OUString& rStr,
SalLayout* OutputDevice::ImplLayout(const OUString& rOrigStr,
sal_Int32 nMinIndex, sal_Int32 nLen,
const Point& rLogicalPos, long nLogicalWidth,
- const long* pDXArray, int flags) const
+ const long* pDXArray, int flags,
+ vcl::TextLayoutCache const* pLayoutCache) const
{
// we need a graphics
if( !mpGraphics )
@@ -1333,6 +1338,7 @@ SalLayout* OutputDevice::ImplLayout(const OUString& rOrigStr,
// recode string if needed
if( mpFontEntry->mpConversion ) {
mpFontEntry->mpConversion->RecodeString( aStr, 0, aStr.getLength() );
+ pLayoutCache = nullptr; // don't use cache with modified string!
}
DeviceCoordinate nPixelWidth = (DeviceCoordinate)nLogicalWidth;
DeviceCoordinate* pDXPixelArray = NULL;
@@ -1368,7 +1374,8 @@ SalLayout* OutputDevice::ImplLayout(const OUString& rOrigStr,
}
}
- ImplLayoutArgs aLayoutArgs = ImplPrepareLayoutArgs( aStr, nMinIndex, nLen, nPixelWidth, pDXPixelArray, flags);
+ ImplLayoutArgs aLayoutArgs = ImplPrepareLayoutArgs( aStr, nMinIndex, nLen,
+ nPixelWidth, pDXPixelArray, flags, pLayoutCache);
// get matching layout object for base font
SalLayout* pSalLayout = mpGraphics->GetTextLayout( aLayoutArgs, 0 );
@@ -1407,6 +1414,24 @@ SalLayout* OutputDevice::ImplLayout(const OUString& rOrigStr,
return pSalLayout;
}
+std::shared_ptr<vcl::TextLayoutCache> OutputDevice::CreateTextLayoutCache(
+ OUString const& rString) const
+{
+ if (!mpGraphics) // can happen in e.g Insert Index/Table dialog
+ return nullptr;
+ OUString copyBecausePrepareModifiesIt(rString);
+ ImplLayoutArgs aLayoutArgs = ImplPrepareLayoutArgs(copyBecausePrepareModifiesIt,
+ 0, rString.getLength(), 0, nullptr, 0, nullptr);
+
+ SalLayout *const pSalLayout = mpGraphics->GetTextLayout( aLayoutArgs, 0 );
+ if (!pSalLayout)
+ return nullptr;
+ std::shared_ptr<vcl::TextLayoutCache> const ret(
+ pSalLayout->CreateTextLayoutCache(copyBecausePrepareModifiesIt));
+ pSalLayout->Release();
+ return ret;
+}
+
bool OutputDevice::GetTextIsRTL( const OUString& rString, sal_Int32 nIndex, sal_Int32 nLen ) const
{
OUString aStr( rString );
@@ -1420,9 +1445,11 @@ bool OutputDevice::GetTextIsRTL( const OUString& rString, sal_Int32 nIndex, sal_
sal_Int32 OutputDevice::GetTextBreak( const OUString& rStr, long nTextWidth,
sal_Int32 nIndex, sal_Int32 nLen,
- long nCharExtra ) const
+ long nCharExtra,
+ vcl::TextLayoutCache const*const pLayoutCache) const
{
- SalLayout* pSalLayout = ImplLayout( rStr, nIndex, nLen );
+ SalLayout *const pSalLayout = ImplLayout( rStr, nIndex, nLen,
+ Point(0,0), 0, nullptr, 0, pLayoutCache);
sal_Int32 nRetVal = -1;
if( pSalLayout )
{
@@ -1451,11 +1478,13 @@ sal_Int32 OutputDevice::GetTextBreak( const OUString& rStr, long nTextWidth,
sal_Int32 OutputDevice::GetTextBreak( const OUString& rStr, long nTextWidth,
sal_Unicode nHyphenChar, sal_Int32& rHyphenPos,
sal_Int32 nIndex, sal_Int32 nLen,
- long nCharExtra ) const
+ long nCharExtra,
+ vcl::TextLayoutCache const*const pLayoutCache) const
{
rHyphenPos = -1;
- SalLayout* pSalLayout = ImplLayout( rStr, nIndex, nLen );
+ SalLayout *const pSalLayout = ImplLayout( rStr, nIndex, nLen,
+ Point(0,0), 0, nullptr, 0, pLayoutCache);
sal_Int32 nRetVal = -1;
if( pSalLayout )
{