summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2018-08-16 17:35:17 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2018-08-16 23:39:15 +0200
commit436b829f5b904d76039db0818cff5dedf1ae89f1 (patch)
tree1da08431fa6a277d781362dbb53f832d6f7f1645
parentc5dc042219e9872937f9fe1cb68f2f03423f398e (diff)
sw: save one vcl layout call in SwFntObj::DrawText()
Pressing a key in Writer used to lay out the relevant string 4 times (counting GenericSalLayout::LayoutText() invocations), save one of them by pre-calculating the layout and sharing it between GetTextArray() and DrawTextArray(). Change-Id: Ic2194bdcbe94a546d57745463ae81e6b0cadcd92 Reviewed-on: https://gerrit.libreoffice.org/59208 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Jenkins
-rw-r--r--sw/source/core/txtnode/fntcache.cxx40
1 files changed, 38 insertions, 2 deletions
diff --git a/sw/source/core/txtnode/fntcache.cxx b/sw/source/core/txtnode/fntcache.cxx
index 4d0f59fcc56d..985ffab1c87b 100644
--- a/sw/source/core/txtnode/fntcache.cxx
+++ b/sw/source/core/txtnode/fntcache.cxx
@@ -54,6 +54,7 @@
#include <svx/sdr/attribute/sdrallfillattributeshelper.hxx>
#include <doc.hxx>
#include <editeng/fhgtitem.hxx>
+#include <vcl/vcllayout.hxx>
#include <docsh.hxx>
#include <strings.hrc>
#include <fntcap.hxx>
@@ -96,6 +97,36 @@ long EvalGridWidthAdd( const SwTextGridItem *const pGrid, const SwDrawTextInfo &
return nGridWidthAdd;
}
+/**
+ * Pre-calculates glyph items for the rendered subset of rInf's text, assuming
+ * outdev state does not change between the outdev calls.
+ */
+SalLayoutGlyphs* lcl_CreateLayout(SwDrawTextInfo& rInf, const OUString& rText, sal_Int32 nIdx,
+ sal_Int32 nLen, SalLayoutGlyphs& rTextGlyphs)
+{
+ // Not the string we want to pre-calculate.
+ if (rText != rInf.GetText() || nIdx != rInf.GetIdx() || nLen != rInf.GetLen())
+ return nullptr;
+
+ // Use pre-calculated result.
+ if (!rTextGlyphs.empty())
+ return &rTextGlyphs;
+
+ // Calculate glyph items.
+ std::unique_ptr<SalLayout> pLayout = rInf.GetOut().ImplLayout(
+ rText, nIdx, nLen, 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;
+}
}
void SwFntCache::Flush( )
@@ -779,6 +810,8 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
vcl::Font* pTmpFont = bUseScrFont ? m_pScrFont : m_pPrtFont;
+ SalLayoutGlyphs aTextGlyphs;
+
// bDirectPrint and bUseScrFont should have these values:
// Outdev / RefDef | Printer | VirtPrinter | Window
@@ -1393,8 +1426,10 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
// get screen array
std::unique_ptr<long[]> pScrArray(new long[sal_Int32(rInf.GetLen())]);
+ SalLayoutGlyphs* pGlyphs = lcl_CreateLayout(rInf, rInf.GetText(), sal_Int32(rInf.GetIdx()),
+ sal_Int32(rInf.GetLen()), aTextGlyphs);
rInf.GetOut().GetTextArray( rInf.GetText(), pScrArray.get(),
- sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()));
+ sal_Int32(rInf.GetIdx()), sal_Int32(rInf.GetLen()), nullptr, pGlyphs);
// OLE: no printer available
// OSL_ENSURE( pPrinter, "DrawText needs pPrinter" )
@@ -1743,8 +1778,9 @@ void SwFntObj::DrawText( SwDrawTextInfo &rInf )
sal_Int32 nTmpIdx = bBullet
? (rInf.GetIdx() ? 1 : 0)
: sal_Int32(rInf.GetIdx());
+ pGlyphs = lcl_CreateLayout(rInf, *pStr, nTmpIdx, nLen, aTextGlyphs);
rInf.GetOut().DrawTextArray( aTextOriginPos, *pStr, pKernArray.get(),
- nTmpIdx , nLen );
+ nTmpIdx , nLen, SalLayoutFlags::NONE, nullptr, pGlyphs );
if (bBullet)
{
rInf.GetOut().Push();