[Libreoffice-commits] core.git: 2 commits - include/vcl sw/source vcl/inc vcl/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Thu Aug 16 21:39:34 UTC 2018
include/vcl/outdev.hxx | 8 ++--
include/vcl/vcllayout.hxx | 2 -
sw/source/core/txtnode/fntcache.cxx | 40 +++++++++++++++++++-
vcl/inc/sallayout.hxx | 2 -
vcl/source/gdi/CommonSalLayout.cxx | 4 +-
vcl/source/gdi/sallayout.cxx | 4 +-
vcl/source/outdev/text.cxx | 72 ++++++++++--------------------------
vcl/source/window/status.cxx | 10 +++--
8 files changed, 75 insertions(+), 67 deletions(-)
New commits:
commit 436b829f5b904d76039db0818cff5dedf1ae89f1
Author: Miklos Vajna <vmiklos at collabora.co.uk>
AuthorDate: Thu Aug 16 17:35:17 2018 +0200
Commit: Miklos Vajna <vmiklos at collabora.co.uk>
CommitDate: Thu Aug 16 23:39:15 2018 +0200
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 at collabora.co.uk>
Tested-by: Jenkins
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();
commit c5dc042219e9872937f9fe1cb68f2f03423f398e
Author: Miklos Vajna <vmiklos at collabora.co.uk>
AuthorDate: Thu Aug 16 17:34:49 2018 +0200
Commit: Miklos Vajna <vmiklos at collabora.co.uk>
CommitDate: Thu Aug 16 23:39:04 2018 +0200
vcl: use SalLayoutGlyphs, not SalLayout for pre-computed layout
This means that the pre-computed glyph ids and positions are usable with
multiple dx array or draw base.
So the amount of cached data is smaller, but it can be used in more
situations, most importantly Writer's SwFntObj::DrawText() use-case
(which does GetTextArray() followed by a DrawTextArray(), with different
dx array arguments).
Change-Id: I3bcd1b7a015c2cf9921efa0f3f355f2c627fb652
Reviewed-on: https://gerrit.libreoffice.org/59207
Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
Tested-by: Jenkins
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 6a91fd2527e8..553baf20e591 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -976,7 +976,7 @@ public:
void DrawText( const Point& rStartPt, const OUString& rStr,
sal_Int32 nIndex = 0, sal_Int32 nLen = -1,
MetricVector* pVector = nullptr, OUString* pDisplayText = nullptr,
- SalLayout* pLayoutCache = nullptr );
+ const SalLayoutGlyphs* pLayoutCache = nullptr );
void DrawText( const tools::Rectangle& rRect,
const OUString& rStr, DrawTextFlags nStyle = DrawTextFlags::NONE,
@@ -1138,7 +1138,7 @@ public:
*/
long GetTextWidth( const OUString& rStr, sal_Int32 nIndex = 0, sal_Int32 nLen = -1,
vcl::TextLayoutCache const* = nullptr,
- SalLayout const*const pLayoutCache = nullptr) const;
+ SalLayoutGlyphs const*const pLayoutCache = nullptr) const;
/** Height where any character of the current font fits; in logic coordinates.
@@ -1154,11 +1154,11 @@ public:
sal_Int32 nLen = -1,
SalLayoutFlags flags = SalLayoutFlags::NONE,
vcl::TextLayoutCache const* = nullptr,
- SalLayout* pLayoutCache = nullptr);
+ const SalLayoutGlyphs* pLayoutCache = nullptr);
long GetTextArray( const OUString& rStr, long* pDXAry,
sal_Int32 nIndex = 0, sal_Int32 nLen = -1,
vcl::TextLayoutCache const* = nullptr,
- SalLayout const*const pLayoutCache = nullptr) const;
+ SalLayoutGlyphs const*const pLayoutCache = nullptr) const;
void GetCaretPositions( const OUString&, long* pCaretXArray,
sal_Int32 nIndex, sal_Int32 nLen ) const;
diff --git a/include/vcl/vcllayout.hxx b/include/vcl/vcllayout.hxx
index 735dc4cf748f..fad06ef4646c 100644
--- a/include/vcl/vcllayout.hxx
+++ b/include/vcl/vcllayout.hxx
@@ -159,7 +159,7 @@ public:
virtual std::shared_ptr<vcl::TextLayoutCache>
CreateTextLayoutCache(OUString const&) const;
- virtual SalLayoutGlyphs GetGlyphs() const;
+ virtual const SalLayoutGlyphs* GetGlyphs() const;
protected:
// used by layout engines
diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx
index a8b9e233f450..a6505eb92d35 100644
--- a/vcl/inc/sallayout.hxx
+++ b/vcl/inc/sallayout.hxx
@@ -175,7 +175,7 @@ public:
bool LayoutText(ImplLayoutArgs&, const SalLayoutGlyphs*) final override;
void DrawText(SalGraphics&) const final override;
std::shared_ptr<vcl::TextLayoutCache> CreateTextLayoutCache(OUString const&) const final override;
- SalLayoutGlyphs GetGlyphs() const final override;
+ const SalLayoutGlyphs* GetGlyphs() const final override;
bool IsKashidaPosValid(int nCharPos) const final override;
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index fc38b33437e1..e4312847d72b 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -169,9 +169,9 @@ std::shared_ptr<vcl::TextLayoutCache> GenericSalLayout::CreateTextLayoutCache(OU
return std::make_shared<vcl::TextLayoutCache>(rString.getStr(), rString.getLength());
}
-SalLayoutGlyphs GenericSalLayout::GetGlyphs() const
+const SalLayoutGlyphs* GenericSalLayout::GetGlyphs() const
{
- return m_GlyphItems;
+ return &m_GlyphItems;
}
void GenericSalLayout::SetNeedFallback(ImplLayoutArgs& rArgs, sal_Int32 nCharPos, bool bRightToLeft)
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index 09cf35d8fdfe..b9cc988fdbbb 100644
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -1579,10 +1579,10 @@ std::shared_ptr<vcl::TextLayoutCache> SalLayout::CreateTextLayoutCache(
return nullptr; // by default, nothing to cache
}
-SalLayoutGlyphs SalLayout::GetGlyphs() const
+const SalLayoutGlyphs* SalLayout::GetGlyphs() const
{
// No access to the glyphs by default.
- return SalLayoutGlyphs();
+ return nullptr;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx
index f1747895e947..9568b3b50eb2 100644
--- a/vcl/source/outdev/text.cxx
+++ b/vcl/source/outdev/text.cxx
@@ -788,7 +788,7 @@ void OutputDevice::SetTextAlign( TextAlign eAlign )
void OutputDevice::DrawText( const Point& rStartPt, const OUString& rStr,
sal_Int32 nIndex, sal_Int32 nLen,
MetricVector* pVector, OUString* pDisplayText,
- SalLayout* pLayoutCache
+ const SalLayoutGlyphs* pLayoutCache
)
{
assert(!is_double_buffered_window());
@@ -873,27 +873,10 @@ void OutputDevice::DrawText( const Point& rStartPt, const OUString& rStr,
pLayoutCache = nullptr;
#endif
- // without cache
- if(!pLayoutCache)
+ std::unique_ptr<SalLayout> pSalLayout = ImplLayout(rStr, nIndex, nLen, rStartPt, 0, nullptr, SalLayoutFlags::NONE, nullptr, pLayoutCache);
+ if(pSalLayout)
{
- std::unique_ptr<SalLayout> pSalLayout = ImplLayout(rStr, nIndex, nLen, rStartPt);
- if(pSalLayout)
- {
- ImplDrawText( *pSalLayout );
- }
- }
- else
- {
- // initialize font if needed
- if( mbNewFont )
- if( !ImplNewFont() )
- return;
- if( mbInitFont )
- InitFont();
-
- pLayoutCache->DrawBase() = ImplLogicToDevicePixel( rStartPt );
-
- ImplDrawText( *pLayoutCache );
+ ImplDrawText( *pSalLayout );
}
if( mpAlphaVDev )
@@ -902,7 +885,7 @@ void OutputDevice::DrawText( const Point& rStartPt, const OUString& rStr,
long OutputDevice::GetTextWidth( const OUString& rStr, sal_Int32 nIndex, sal_Int32 nLen,
vcl::TextLayoutCache const*const pLayoutCache,
- SalLayout const*const pSalLayoutCache) const
+ SalLayoutGlyphs const*const pSalLayoutCache) const
{
long nWidth = GetTextArray( rStr, nullptr, nIndex,
@@ -946,7 +929,7 @@ void OutputDevice::DrawTextArray( const Point& rStartPt, const OUString& rStr,
const long* pDXAry,
sal_Int32 nIndex, sal_Int32 nLen, SalLayoutFlags flags,
vcl::TextLayoutCache const*const pLayoutCache,
- SalLayout* pSalLayoutCache )
+ const SalLayoutGlyphs* pSalLayoutCache )
{
assert(!is_double_buffered_window());
@@ -966,13 +949,7 @@ void OutputDevice::DrawTextArray( const Point& rStartPt, const OUString& rStr,
if( mbOutputClipped )
return;
- SalLayout* pSalLayout = pSalLayoutCache;
- std::unique_ptr<SalLayout> pLayout;
- if (!pSalLayout)
- {
- pLayout = ImplLayout(rStr, nIndex, nLen, rStartPt, 0, pDXAry, flags, pLayoutCache);
- pSalLayout = pLayout.get();
- }
+ std::unique_ptr<SalLayout> pSalLayout = ImplLayout(rStr, nIndex, nLen, rStartPt, 0, pDXAry, flags, pLayoutCache, pSalLayoutCache);
if( pSalLayout )
{
ImplDrawText( *pSalLayout );
@@ -985,7 +962,7 @@ void OutputDevice::DrawTextArray( const Point& rStartPt, const OUString& rStr,
long OutputDevice::GetTextArray( const OUString& rStr, long* pDXAry,
sal_Int32 nIndex, sal_Int32 nLen,
vcl::TextLayoutCache const*const pLayoutCache,
- SalLayout const*const pSalLayoutCache) const
+ SalLayoutGlyphs const*const pSalLayoutCache) const
{
if( nIndex >= rStr.getLength() )
return 0; // TODO: this looks like a buggy caller?
@@ -995,29 +972,22 @@ long OutputDevice::GetTextArray( const OUString& rStr, long* pDXAry,
nLen = rStr.getLength() - nIndex;
}
- std::unique_ptr<SalLayout> xSalLayout;
- const SalLayout* pSalLayout = pSalLayoutCache;
-
- if(!pSalLayoutCache)
+ // do layout
+ std::unique_ptr<SalLayout> pSalLayout = ImplLayout(rStr, nIndex, nLen,
+ Point(0,0), 0, nullptr, SalLayoutFlags::NONE, pLayoutCache, pSalLayoutCache);
+ if( !pSalLayout )
{
- // do layout
- xSalLayout = ImplLayout(rStr, nIndex, nLen,
- Point(0,0), 0, nullptr, SalLayoutFlags::NONE, pLayoutCache);
- pSalLayout = xSalLayout.get();
- if( !pSalLayout )
+ // The caller expects this to init the elements of pDXAry.
+ // Adapting all the callers to check that GetTextArray succeeded seems
+ // too much work.
+ // Init here to 0 only in the (rare) error case, so that any missing
+ // element init in the happy case will still be found by tools,
+ // and hope that is sufficient.
+ if (pDXAry)
{
- // The caller expects this to init the elements of pDXAry.
- // Adapting all the callers to check that GetTextArray succeeded seems
- // too much work.
- // Init here to 0 only in the (rare) error case, so that any missing
- // element init in the happy case will still be found by tools,
- // and hope that is sufficient.
- if (pDXAry)
- {
- memset(pDXAry, 0, nLen * sizeof(*pDXAry));
- }
- return 0;
+ memset(pDXAry, 0, nLen * sizeof(*pDXAry));
}
+ return 0;
}
#if VCL_FLOAT_DEVICE_PIXEL
diff --git a/vcl/source/window/status.cxx b/vcl/source/window/status.cxx
index 4a9d24bd4f7e..666824613b34 100644
--- a/vcl/source/window/status.cxx
+++ b/vcl/source/window/status.cxx
@@ -408,7 +408,8 @@ void StatusBar::ImplDrawItem(vcl::RenderContext& rRenderContext, bool bOffScreen
pLayoutCache = pItem->mxLayoutCache.get();
}
- Size aTextSize(rRenderContext.GetTextWidth(pItem->maText,0,-1,nullptr,pLayoutCache), rRenderContext.GetTextHeight());
+ const SalLayoutGlyphs* pGlyphs = pLayoutCache ? pLayoutCache->GetGlyphs() : nullptr;
+ Size aTextSize(rRenderContext.GetTextWidth(pItem->maText,0,-1,nullptr,pGlyphs), rRenderContext.GetTextHeight());
Point aTextPos = ImplGetItemTextPos(aTextRectSize, aTextSize, pItem->mnBits);
@@ -418,7 +419,7 @@ void StatusBar::ImplDrawItem(vcl::RenderContext& rRenderContext, bool bOffScreen
aTextPos,
pItem->maText,
0, -1, nullptr, nullptr,
- pLayoutCache );
+ pGlyphs );
}
else
{
@@ -428,7 +429,7 @@ void StatusBar::ImplDrawItem(vcl::RenderContext& rRenderContext, bool bOffScreen
aTextPos,
pItem->maText,
0, -1, nullptr, nullptr,
- pLayoutCache );
+ pGlyphs );
}
// call DrawItem if necessary
@@ -1192,7 +1193,8 @@ void StatusBar::SetItemText( sal_uInt16 nItemId, const OUString& rText )
long nFudge = GetTextHeight()/4;
std::unique_ptr<SalLayout> pSalLayout = ImplLayout(pItem->maText,0,-1);
- long nWidth = GetTextWidth( pItem->maText,0,-1,nullptr,pSalLayout.get() ) + nFudge;
+ const SalLayoutGlyphs* pGlyphs = pSalLayout ? pSalLayout->GetGlyphs() : nullptr;
+ long nWidth = GetTextWidth( pItem->maText,0,-1,nullptr,pGlyphs ) + nFudge;
// Store the calculated layout.
pItem->mxLayoutCache = std::move(pSalLayout);
More information about the Libreoffice-commits
mailing list