[Libreoffice-commits] core.git: Branch 'distro/collabora/dcm-6.2' - 5 commits - configure.ac sw/inc sw/source
LuboÅ¡ LuÅák (via logerrit)
logerrit at kemper.freedesktop.org
Tue Mar 23 15:04:45 UTC 2021
configure.ac | 11 +-
sw/inc/swtable.hxx | 2
sw/source/core/inc/fntcache.hxx | 23 +----
sw/source/core/table/swtable.cxx | 48 +++++-----
sw/source/core/txtnode/fntcache.cxx | 164 +++++++++++++++++++++++-------------
sw/source/filter/xml/xmltbli.cxx | 2
6 files changed, 150 insertions(+), 100 deletions(-)
New commits:
commit e5c88ce0b91d105d3dc6ba1366de101c0e04e09a
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Mar 23 15:52:31 2021 +0100
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Tue Mar 23 15:57:13 2021 +0100
use --enable-ooenv only if --enable-debug/dbgutil
I'm not sure what the original purpose of the ooenv script was,
but now it contains only debugging settings such as malloc debugging,
which has a noticeable overhead (8.2s->10.1s in my random case).
At least openSUSE appears to not actually package the script, but
it still doesn't make sense to use this script in non-debug builds.
Change-Id: I4518bb1680a543ed520399c11c83dd6dc5539f71
diff --git a/configure.ac b/configure.ac
index 1182bc1c839c..ea6bee87afe4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1184,8 +1184,8 @@ if test "$enable_compiler_plugins" = debug; then
fi
libo_FUZZ_ARG_ENABLE(ooenv,
- AS_HELP_STRING([--disable-ooenv],
- [Disable ooenv for the instdir installation.]))
+ AS_HELP_STRING([--enable-ooenv],
+ [Enable ooenv for the instdir installation.]))
libo_FUZZ_ARG_ENABLE(libnumbertext,
AS_HELP_STRING([--disable-libnumbertext],
@@ -4652,6 +4652,13 @@ AC_SUBST(ASSERT_ALWAYS_ABORT)
# ===================================================================
if test $_os != "WINNT" -a $_os != "Darwin"; then
AC_MSG_CHECKING([whether to use ooenv for the instdir installation])
+ if test -z "$enable_ooenv"; then
+ if test -n "$ENABLE_DEBUG$ENABLE_DBGUTIL"; then
+ enable_ooenv=yes
+ else
+ enable_ooenv=no
+ fi
+ fi
if test "$enable_ooenv" = "no"; then
AC_MSG_RESULT([no])
else
commit b3c890ad303f16e514ea30a96ec86dacb82b6e41
Author: Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Thu Mar 28 13:13:22 2019 +0200
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Tue Mar 23 15:57:13 2021 +0100
tdf#84635 quadratic slowdown on loading large tables
skip the re-registration scan in SwTableBox::ChgFrameFormat, which we
don't need since we are creating this table for the first time
On my machine,
loading the 69 page file goes from 40.9s to 30.4s
loading the 128 page file goes from 79.1s to 45.1s
Change-Id: Id9e48256556e19eca34a892b29beff7eab9f51f1
Reviewed-on: https://gerrit.libreoffice.org/69885
Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>
Tested-by: Noel Grandin <noel.grandin at collabora.co.uk>
diff --git a/sw/inc/swtable.hxx b/sw/inc/swtable.hxx
index 21348a36662b..844ab31497e0 100644
--- a/sw/inc/swtable.hxx
+++ b/sw/inc/swtable.hxx
@@ -433,7 +433,7 @@ public:
// Creates its own FrameFormat if more boxes depend on it.
SwFrameFormat* ClaimFrameFormat();
- void ChgFrameFormat( SwTableBoxFormat *pNewFormat );
+ void ChgFrameFormat( SwTableBoxFormat *pNewFormat, bool bNeedToReregister = true );
void RemoveFromTable();
const SwStartNode *GetSttNd() const { return m_pStartNode; }
diff --git a/sw/source/core/table/swtable.cxx b/sw/source/core/table/swtable.cxx
index 93f53065a7ca..82e3259e435e 100644
--- a/sw/source/core/table/swtable.cxx
+++ b/sw/source/core/table/swtable.cxx
@@ -1734,36 +1734,40 @@ SwFrameFormat* SwTableBox::ClaimFrameFormat()
return pRet;
}
-void SwTableBox::ChgFrameFormat( SwTableBoxFormat* pNewFormat )
+void SwTableBox::ChgFrameFormat( SwTableBoxFormat* pNewFormat, bool bNeedToReregister )
{
SwFrameFormat *pOld = GetFrameFormat();
SwIterator<SwCellFrame,SwFormat> aIter( *pOld );
+ // tdf#84635 We set bNeedToReregister=false to avoid a quadratic slowdown on loading large tables,
+ // and since we are creating the table for the first time, no re-registration is necessary.
+
// First, re-register the Frames.
- for( SwCellFrame* pCell = aIter.First(); pCell; pCell = aIter.Next() )
- {
- if( pCell->GetTabBox() == this )
- {
- pCell->RegisterToFormat( *pNewFormat );
- pCell->InvalidateSize();
- pCell->InvalidatePrt_();
- pCell->SetCompletePaint();
- pCell->SetDerivedVert( false );
- pCell->CheckDirChange();
-
- // #i47489#
- // make sure that the row will be formatted, in order
- // to have the correct Get(Top|Bottom)MarginForLowers values
- // set at the row.
- const SwTabFrame* pTab = pCell->FindTabFrame();
- if ( pTab && pTab->IsCollapsingBorders() )
+ if (bNeedToReregister)
+ for( SwCellFrame* pCell = aIter.First(); pCell; pCell = aIter.Next() )
+ {
+ if( pCell->GetTabBox() == this )
{
- SwFrame* pRow = pCell->GetUpper();
- pRow->InvalidateSize_();
- pRow->InvalidatePrt_();
+ pCell->RegisterToFormat( *pNewFormat );
+ pCell->InvalidateSize();
+ pCell->InvalidatePrt_();
+ pCell->SetCompletePaint();
+ pCell->SetDerivedVert( false );
+ pCell->CheckDirChange();
+
+ // #i47489#
+ // make sure that the row will be formatted, in order
+ // to have the correct Get(Top|Bottom)MarginForLowers values
+ // set at the row.
+ const SwTabFrame* pTab = pCell->FindTabFrame();
+ if ( pTab && pTab->IsCollapsingBorders() )
+ {
+ SwFrame* pRow = pCell->GetUpper();
+ pRow->InvalidateSize_();
+ pRow->InvalidatePrt_();
+ }
}
}
- }
// Now, re-register self.
pNewFormat->Add( this );
diff --git a/sw/source/filter/xml/xmltbli.cxx b/sw/source/filter/xml/xmltbli.cxx
index ed73304a7e5d..6ee095903afc 100644
--- a/sw/source/filter/xml/xmltbli.cxx
+++ b/sw/source/filter/xml/xmltbli.cxx
@@ -1921,7 +1921,7 @@ SwTableBoxFormat* SwXMLTableContext::GetSharedBoxFormat(
{
// set the shared format
pBoxFormat2 = aIter->second;
- pBox->ChgFrameFormat( pBoxFormat2 );
+ pBox->ChgFrameFormat( pBoxFormat2, /*bNeedToReregister*/false );
bNew = false; // copied from an existing format
// claim it, if we are not allowed to share
commit c72de55d0b7a26bb06c4e550b2e4c402ea8676bc
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Mar 12 14:08:11 2021 +0100
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Tue Mar 23 15:57:13 2021 +0100
do not disable Writer font caching on zoom mismatch
This code disables font caching for some cases, e.g. when exporting
to PDF if the zoom is set to anything else than 100%, or also when
loading a document.
It unfortunately comes from the OOo initial import, so it's
impossible to find out why it should be needed. SwFntObj instances
are created only using SwFntAccess ctor, which checks any SwFntObj
it tries to reuse, so if this some additional factor to consider
when reusing SwFntObj, then it can be checked there. But when I
remove the code, I cannot see any breakage. Tests pass, normal
rendering is fine, document thumbnail is fine, printing is fine,
PDF export is fine, embedding in a spreadsheet is fine.
We had a look at this with Miklos and concluded that it is not
needed (until proven otherwise, in which case it'll be also known
why it would be needed).
Change-Id: I59d375229a265a4353c1da6dd067d892dd4ecfb6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112589
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak at collabora.com>
diff --git a/sw/source/core/txtnode/fntcache.cxx b/sw/source/core/txtnode/fntcache.cxx
index 206e95340a0f..7cc9cf35714b 100644
--- a/sw/source/core/txtnode/fntcache.cxx
+++ b/sw/source/core/txtnode/fntcache.cxx
@@ -589,24 +589,6 @@ void SwFntObj::CreateScrFont( const SwViewShell& rSh, const OutputDevice& rOut )
m_pScrFont = m_pPrtFont;
}
- // check zoom factor, e.g. because of PrtOle2 during export
- {
- // In case the zoom factor of the output device differs from the
- // one in the ViewOptions, this Font must not be cached,
- // hence set zoom factor to an invalid value
- long nTmp;
- if( pOut->GetMapMode().GetScaleX().IsValid() &&
- pOut->GetMapMode().GetScaleY().IsValid() &&
- pOut->GetMapMode().GetScaleX() == pOut->GetMapMode().GetScaleY() )
- {
- nTmp = long(100 * pOut->GetMapMode().GetScaleX());
- }
- else
- nTmp = 0;
- if( nTmp != m_nZoom )
- m_nZoom = USHRT_MAX - 1;
- }
-
m_nScrAscent = static_cast<sal_uInt16>(pOut->GetFontMetric().GetAscent());
if ( USHRT_MAX == m_nScrHeight )
m_nScrHeight = static_cast<sal_uInt16>(pOut->GetTextHeight());
commit 5ab9cfe16550ab8d439828d766d36a9a8b611c2b
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Thu Mar 11 15:34:41 2021 +0100
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Tue Mar 23 15:57:13 2021 +0100
improve font caching in SwFntObj
The code previously cached only SalGlyphItems, but such caching
fails if SalLayout::GetGlyphs() does not return valid glyphs,
which is the case with MultiSalLayout. Worse, it not only fails,
but layout is once computed for caching, that fails, and is computed
a second time for actual use.
This improved cache caches the result of GetTextWidth(), which
itself improves the performance a bit, but it also allows caching
the value for GetGlyph() not returning valid glyphs. Moreover this
also caches failures to get valid glyphs from GetGlyphs().
There are quite some calls to GetTextArray(), I didn't cache those,
but it might be added if needed.
Change-Id: Ia2589fb1b778f4f154c88f65d9906584284239da
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112588
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak at collabora.com>
diff --git a/sw/source/core/inc/fntcache.hxx b/sw/source/core/inc/fntcache.hxx
index 04cfc4abc219..d8e11701445b 100644
--- a/sw/source/core/inc/fntcache.hxx
+++ b/sw/source/core/inc/fntcache.hxx
@@ -60,19 +60,9 @@ extern SwFntCache *pFntCache;
extern SwFntObj *pLastFont;
extern sal_uInt8* mnFontCacheIdCounter;
-/**
- * Defines a substring on a given output device, to be used as an std::map<>
- * key.
- */
-struct SwTextGlyphsKey
-{
- VclPtr<OutputDevice> m_pOutputDevice;
- OUString m_aText;
- sal_Int32 m_nIndex;
- sal_Int32 m_nLength;
-
-};
+struct SwTextGlyphsKey;
bool operator<(const SwTextGlyphsKey& l, const SwTextGlyphsKey& r);
+struct SwTextGlyphsData;
class SwFntObj : public SwCacheObj
{
@@ -95,8 +85,8 @@ class SwFntObj : public SwCacheObj
bool m_bSymbol : 1;
bool m_bPaintBlank : 1;
- /// Cache of already calculated layout glyphs.
- std::map<SwTextGlyphsKey, SalLayoutGlyphs> m_aTextGlyphs;
+ /// Cache of already calculated layout glyphs and text widths.
+ std::map<SwTextGlyphsKey, SwTextGlyphsData> m_aTextGlyphs;
static long nPixWidth;
static MapMode *pPixMap;
@@ -125,7 +115,10 @@ public:
sal_uInt16 GetZoom() const { return m_nZoom; }
sal_uInt16 GetPropWidth() const { return m_nPropWidth; }
bool IsSymbol() const { return m_bSymbol; }
- std::map<SwTextGlyphsKey, SalLayoutGlyphs>& GetTextGlyphs() { return m_aTextGlyphs; }
+
+ long GetCachedTextWidth(const SwTextGlyphsKey& key, const vcl::TextLayoutCache* vclCache);
+ SalLayoutGlyphs* GetCachedSalLayoutGlyphs(const SwTextGlyphsKey& key);
+ void ClearCachedTextGlyphs();
void DrawText( SwDrawTextInfo &rInf );
/// determine the TextSize (of the printer)
diff --git a/sw/source/core/txtnode/fntcache.cxx b/sw/source/core/txtnode/fntcache.cxx
index 500190bf064c..206e95340a0f 100644
--- a/sw/source/core/txtnode/fntcache.cxx
+++ b/sw/source/core/txtnode/fntcache.cxx
@@ -76,6 +76,28 @@ long SwFntObj::nPixWidth;
MapMode* SwFntObj::pPixMap = nullptr;
static vcl::DeleteOnDeinit< VclPtr<OutputDevice> > s_pFntObjPixOut( new VclPtr<OutputDevice> );
+/**
+ * Defines a substring on a given output device, to be used as an std::map<>
+ * key.
+ */
+struct SwTextGlyphsKey
+{
+ VclPtr<OutputDevice> m_pOutputDevice;
+ OUString m_aText;
+ sal_Int32 m_nIndex;
+ sal_Int32 m_nLength;
+
+};
+
+/**
+ * Glyphs and text width for the given SwTextGlyphsKey.
+ */
+struct SwTextGlyphsData
+{
+ SalLayoutGlyphs m_aTextGlyphs;
+ long m_nTextWidth = -1; // -1 = not computed yet
+};
+
namespace
{
@@ -98,36 +120,6 @@ long EvalGridWidthAdd( const SwTextGridItem *const pGrid, const SwDrawTextInfo &
return nGridWidthAdd;
}
-/**
- * Pre-calculates glyph items for the rendered subset of rKey's text, assuming
- * outdev state does not change between the outdev calls.
- */
-SalLayoutGlyphs* lcl_CreateLayout(SwTextGlyphsKey& rKey, SalLayoutGlyphs& rTextGlyphs)
-{
- // Use pre-calculated result.
- if (rTextGlyphs.IsValid())
- return &rTextGlyphs;
-
- if (rKey.m_nIndex >= rKey.m_aText.getLength())
- // Same as in OutputDevice::GetTextArray().
- return nullptr;
-
- // Calculate glyph items.
- std::unique_ptr<SalLayout> pLayout
- = rKey.m_pOutputDevice->ImplLayout(rKey.m_aText, rKey.m_nIndex, rKey.m_nLength, Point(0, 0), 0,
- nullptr, SalLayoutFlags::GlyphItemsOnly);
- if (!pLayout)
- return nullptr;
-
- const SalLayoutGlyphs* pGlyphs = pLayout->GetGlyphs();
- if (!pGlyphs)
- return nullptr;
-
- // Remember the calculation result.
- rTextGlyphs = *pGlyphs;
-
- return &rTextGlyphs;
-}
}
bool operator<(const SwTextGlyphsKey& l, const SwTextGlyphsKey& r)
@@ -228,6 +220,72 @@ void SwFntObj::CreatePrtFont( const OutputDevice& rPrt )
}
+/**
+ * Pre-calculates glyph items for the rendered subset of rKey's text, assuming
+ * outdev state does not change between the outdev calls.
+ */
+static SalLayoutGlyphs* lcl_CreateLayout(const SwTextGlyphsKey& rKey, std::map<SwTextGlyphsKey, SwTextGlyphsData>::iterator it)
+{
+ assert (!it->second.m_aTextGlyphs.IsValid());
+
+ if (rKey.m_nIndex >= rKey.m_aText.getLength())
+ // Same as in OutputDevice::GetTextArray().
+ return nullptr;
+
+ // Calculate glyph items.
+ std::unique_ptr<SalLayout> pLayout
+ = rKey.m_pOutputDevice->ImplLayout(rKey.m_aText, rKey.m_nIndex, rKey.m_nLength, Point(0, 0), 0,
+ nullptr, SalLayoutFlags::GlyphItemsOnly);
+ if (!pLayout)
+ return nullptr;
+
+ const SalLayoutGlyphs* pGlyphs = pLayout->GetGlyphs();
+ if (!pGlyphs)
+ return nullptr;
+
+ // Remember the calculation result.
+ it->second.m_aTextGlyphs = *pGlyphs;
+
+ return &it->second.m_aTextGlyphs;
+}
+
+SalLayoutGlyphs* SwFntObj::GetCachedSalLayoutGlyphs(const SwTextGlyphsKey& key)
+{
+ std::map<SwTextGlyphsKey, SwTextGlyphsData>::iterator it = m_aTextGlyphs.find(key);
+ if(it != m_aTextGlyphs.end())
+ {
+ if( it->second.m_aTextGlyphs.IsValid())
+ return &it->second.m_aTextGlyphs;
+ // Do not try to create the layout here. If a cache item exists, it's already
+ // been attempted and the layout was invalid (this happens with MultiSalLayout).
+ // So in that case this is a cached failure.
+ return nullptr;
+ }
+ it = m_aTextGlyphs.emplace( key, SwTextGlyphsData()).first;
+ return lcl_CreateLayout(key, it);
+}
+
+long SwFntObj::GetCachedTextWidth(const SwTextGlyphsKey& key, const vcl::TextLayoutCache* vclCache)
+{
+ std::map<SwTextGlyphsKey, SwTextGlyphsData>::iterator it = m_aTextGlyphs.find(key);
+ if(it != m_aTextGlyphs.end() && it->second.m_nTextWidth >= 0)
+ return it->second.m_nTextWidth;
+ if(it == m_aTextGlyphs.end())
+ {
+ it = m_aTextGlyphs.emplace( key, SwTextGlyphsData()).first;
+ lcl_CreateLayout(key, it);
+ }
+ it->second.m_nTextWidth = key.m_pOutputDevice->GetTextWidth(key.m_aText, key.m_nIndex, key.m_nLength, vclCache,
+ it->second.m_aTextGlyphs.IsValid() ? &it->second.m_aTextGlyphs : nullptr );
+ assert(it->second.m_nTextWidth >= 0);
+ return it->second.m_nTextWidth;
+}
+
+void SwFntObj::ClearCachedTextGlyphs()
+{
+ m_aTextGlyphs.clear();
+}
+
/*
* returns whether we have to adjust the output font to resemble
* the formatting font
@@ -1458,7 +1516,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
// get screen array
std::unique_ptr<long[]> pScrArray(new long[sal_Int32(rInf.GetLen())]);
SwTextGlyphsKey aGlyphsKey{ &rInf.GetOut(), rInf.GetText(), sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()) };
- SalLayoutGlyphs* pGlyphs = lcl_CreateLayout(aGlyphsKey, m_aTextGlyphs[aGlyphsKey]);
+ SalLayoutGlyphs* pGlyphs = GetCachedSalLayoutGlyphs(aGlyphsKey);
rInf.GetOut().GetTextArray( rInf.GetText(), pScrArray.get(),
sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), nullptr, pGlyphs);
@@ -1473,7 +1531,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
m_pPrinter->SetFont( *m_pPrtFont );
}
aGlyphsKey = SwTextGlyphsKey{ m_pPrinter, rInf.GetText(), sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()) };
- pGlyphs = lcl_CreateLayout(aGlyphsKey, m_aTextGlyphs[aGlyphsKey]);
+ pGlyphs = GetCachedSalLayoutGlyphs(aGlyphsKey);
m_pPrinter->GetTextArray(rInf.GetText(), pKernArray.get(),
sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), nullptr, pGlyphs);
}
@@ -1818,7 +1876,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
: sal_Int32(rInf.GetIdx());
aGlyphsKey = SwTextGlyphsKey{ &rInf.GetOut(), *pStr, nTmpIdx, nLen };
if (bCacheLayout)
- pGlyphs = lcl_CreateLayout(aGlyphsKey, m_aTextGlyphs[aGlyphsKey]);
+ pGlyphs = GetCachedSalLayoutGlyphs(aGlyphsKey);
else
pGlyphs = nullptr;
rInf.GetOut().DrawTextArray( aTextOriginPos, *pStr, pKernArray.get(),
@@ -2055,10 +2113,7 @@ Size SwFntObj::GetTextSize( SwDrawTextInfo& rInf )
else
{
SwTextGlyphsKey aGlyphsKey{ &rInf.GetOut(), rInf.GetText(), sal_Int32(rInf.GetIdx()), sal_Int32(nLn) };
- SalLayoutGlyphs* pGlyphs = lcl_CreateLayout(aGlyphsKey, m_aTextGlyphs[aGlyphsKey]);
- aTextSize.setWidth( rInf.GetOut().GetTextWidth( rInf.GetText(),
- sal_Int32(rInf.GetIdx()), sal_Int32(nLn),
- rInf.GetVclCache(), pGlyphs) );
+ aTextSize.setWidth( GetCachedTextWidth(aGlyphsKey, rInf.GetVclCache()));
rInf.SetKanaDiff( 0 );
}
@@ -2092,7 +2147,7 @@ TextFrameIndex SwFntObj::GetCursorOfst(SwDrawTextInfo &rInf)
m_pPrinter->SetLayoutMode( rInf.GetOut().GetLayoutMode() );
m_pPrinter->SetDigitLanguage( rInf.GetOut().GetDigitLanguage() );
SwTextGlyphsKey aGlyphsKey{ m_pPrinter, rInf.GetText(), sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()) };
- SalLayoutGlyphs* pGlyphs = lcl_CreateLayout(aGlyphsKey, m_aTextGlyphs[aGlyphsKey]);
+ SalLayoutGlyphs* pGlyphs = GetCachedSalLayoutGlyphs(aGlyphsKey);
m_pPrinter->GetTextArray( rInf.GetText(), pKernArray.get(),
sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), nullptr, pGlyphs);
}
@@ -2506,8 +2561,7 @@ TextFrameIndex SwFont::GetTextBreak(SwDrawTextInfo const & rInf, long nTextWidth
SwFntAccess aFntAccess(m_aSub[m_nActual].m_nFontCacheId, m_aSub[m_nActual].m_nFontIndex,
&m_aSub[m_nActual], rInf.GetShell());
SwTextGlyphsKey aGlyphsKey{ &rInf.GetOut(), *pTmpText, sal_Int32(nTmpIdx), sal_Int32(nTmpLen) };
- SalLayoutGlyphs* pGlyphs
- = lcl_CreateLayout(aGlyphsKey, aFntAccess.Get()->GetTextGlyphs()[aGlyphsKey]);
+ SalLayoutGlyphs* pGlyphs = aFntAccess.Get()->GetCachedSalLayoutGlyphs(aGlyphsKey);
nTextBreak = TextFrameIndex(rInf.GetOut().GetTextBreak(
*pTmpText, nTextWidth,
sal_Int32(nTmpIdx), sal_Int32(nTmpLen),
@@ -2699,7 +2753,7 @@ bool SwDrawTextInfo::ApplyAutoColor( vcl::Font* pFont )
void SwClearFntCacheTextGlyphs()
{
for (SwFntObj* pFntObj = pFntCache->First(); pFntObj; pFntObj = SwFntCache::Next(pFntObj))
- pFntObj->GetTextGlyphs().clear();
+ pFntObj->ClearCachedTextGlyphs();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 7645b367e51832473f1ed4e19b96dd9b15fb3e1b
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Mar 22 13:51:39 2019 +0100
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Mon Mar 22 21:00:57 2021 +0100
Related: tdf#124109 sw: save one vcl layout call in SwFntObj::DrawText()
Commit 436b829f5b904d76039db0818cff5dedf1ae89f1 (sw: save one vcl layout
call in SwFntObj::DrawText(), 2018-08-16) did this unconditionally,
which broke kashida justification. Re-introduce the same mechanism, but
this time opt out in the kashida case to keep that working.
This means that for Latin scripts we are back to 2 layout calls (instead
of 3) for each keypress in Writer.
Change-Id: I890f0ab04d1f5dce561f1536d7c8a6d67a639813
Reviewed-on: https://gerrit.libreoffice.org/69557
Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
Tested-by: Jenkins
diff --git a/sw/source/core/txtnode/fntcache.cxx b/sw/source/core/txtnode/fntcache.cxx
index 175821ab90ef..500190bf064c 100644
--- a/sw/source/core/txtnode/fntcache.cxx
+++ b/sw/source/core/txtnode/fntcache.cxx
@@ -1487,6 +1487,7 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
long nSpaceAdd = rInf.GetSpace() / SPACING_PRECISION_FACTOR;
bool bNoHalfSpace = false;
+ bool bCacheLayout = true;
if ( rInf.GetFont() && rInf.GetLen() )
{
@@ -1529,7 +1530,12 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
if ( pSI && pSI->CountKashida() &&
pSI->KashidaJustify( pKernArray.get(), pScrArray.get(), rInf.GetIdx(),
rInf.GetLen(), nSpaceAdd ) != -1 )
+ {
nSpaceAdd = 0;
+ // Layout can't be reused in this case, it would lead to missing gaps in
+ // place of kashida.
+ bCacheLayout = false;
+ }
else
bNoHalfSpace = true;
}
@@ -1811,8 +1817,12 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
? (rInf.GetIdx() ? 1 : 0)
: sal_Int32(rInf.GetIdx());
aGlyphsKey = SwTextGlyphsKey{ &rInf.GetOut(), *pStr, nTmpIdx, nLen };
+ if (bCacheLayout)
+ pGlyphs = lcl_CreateLayout(aGlyphsKey, m_aTextGlyphs[aGlyphsKey]);
+ else
+ pGlyphs = nullptr;
rInf.GetOut().DrawTextArray( aTextOriginPos, *pStr, pKernArray.get(),
- nTmpIdx , nLen );
+ nTmpIdx , nLen, SalLayoutFlags::NONE, pGlyphs );
if (bBullet)
{
rInf.GetOut().Push();
More information about the Libreoffice-commits
mailing list