include/vcl/glyphitemcache.hxx | 6 +++++- vcl/inc/pdf/pdfwriter_impl.hxx | 3 +++ vcl/source/gdi/impglyphitem.cxx | 35 +++++++++++++++++++++++++---------- vcl/source/gdi/pdfwriter_impl.cxx | 12 ++++++------ 4 files changed, 39 insertions(+), 17 deletions(-)
New commits: commit 9ed2912d4ecfd9573b3ca9d2390a0f1b0e3060a2 Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Thu Apr 7 12:07:02 2022 +0200 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Fri Apr 8 21:28:44 2022 +0200 check better for unchanged OutputDevice in SalLayoutGlyphsCache Some things like font could change, so it needs to be saved and compared. If would be even better to avoid comparing OutputDevice pointers and instead compare only what actually matters, in order to reuse the same glyphs used for different output devices, but I can't find all the relevant data in OutputDevice. Change-Id: Ib8634165b5b312d1db2c9fc28f8d7fdf7b552d25 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132671 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lu...@collabora.com> diff --git a/include/vcl/glyphitemcache.hxx b/include/vcl/glyphitemcache.hxx index 83c77309a632..64a1a64186ee 100644 --- a/include/vcl/glyphitemcache.hxx +++ b/include/vcl/glyphitemcache.hxx @@ -61,12 +61,16 @@ public: private: struct CachedGlyphsKey { - VclPtr<const OutputDevice> outputDevice; OUString text; sal_Int32 index; sal_Int32 len; Point logicPos; tools::Long logicWidth; + VclPtr<const OutputDevice> outputDevice; + vcl::Font font; + bool rtl; + vcl::text::ComplexTextLayoutFlags layoutMode; + LanguageType digitLanguage; size_t hashValue; CachedGlyphsKey(const VclPtr<const OutputDevice>& dev, const OUString& t, sal_Int32 i, sal_Int32 l, const Point& p, tools::Long w); diff --git a/vcl/source/gdi/impglyphitem.cxx b/vcl/source/gdi/impglyphitem.cxx index d320d27dad88..ea3c490b0ba2 100644 --- a/vcl/source/gdi/impglyphitem.cxx +++ b/vcl/source/gdi/impglyphitem.cxx @@ -135,32 +135,47 @@ SalLayoutGlyphsCache::GetLayoutGlyphs(VclPtr<const OutputDevice> outputDevice, c SalLayoutGlyphsCache::CachedGlyphsKey::CachedGlyphsKey(const VclPtr<const OutputDevice>& d, const OUString& t, sal_Int32 i, sal_Int32 l, const Point& p, tools::Long w) - : outputDevice(d) - , text(t) + : text(t) , index(i) , len(l) , logicPos(p) , logicWidth(w) + , outputDevice(d) + // we also need to save things used in OutputDevice::ImplPrepareLayoutArgs(), in case they + // change in the output device + // TODO there is still something missing, otherwise it wouldn't be necessary to compare + // also the OutputDevice pointers + , font(outputDevice->GetFont()) + , rtl(outputDevice->IsRTLEnabled()) + , layoutMode(outputDevice->GetLayoutMode()) + , digitLanguage(outputDevice->GetDigitLanguage()) { hashValue = 0; - o3tl::hash_combine(hashValue, outputDevice.get()); - SvMemoryStream stream; - WriteFont(stream, outputDevice->GetFont()); - o3tl::hash_combine(hashValue, static_cast<const char*>(stream.GetData()), stream.GetSize()); o3tl::hash_combine(hashValue, vcl::text::FirstCharsStringHash()(text)); o3tl::hash_combine(hashValue, index); o3tl::hash_combine(hashValue, len); o3tl::hash_combine(hashValue, logicPos.X()); o3tl::hash_combine(hashValue, logicPos.Y()); o3tl::hash_combine(hashValue, logicWidth); + + o3tl::hash_combine(hashValue, outputDevice.get()); + SvMemoryStream stream; + WriteFont(stream, font); + o3tl::hash_combine(hashValue, static_cast<const char*>(stream.GetData()), stream.GetSize()); + o3tl::hash_combine(hashValue, rtl); + o3tl::hash_combine(hashValue, layoutMode); + o3tl::hash_combine(hashValue, digitLanguage.get()); } inline bool SalLayoutGlyphsCache::CachedGlyphsKey::operator==(const CachedGlyphsKey& other) const { - return hashValue == other.hashValue && outputDevice == other.outputDevice - && index == other.index && len == other.len && logicPos == other.logicPos - && logicWidth == other.logicWidth - && vcl::text::FastStringCompareEqual()(text, other.text); + return hashValue == other.hashValue && index == other.index && len == other.len + && logicPos == other.logicPos && logicWidth == other.logicWidth + && outputDevice == other.outputDevice && rtl == other.rtl + && layoutMode == other.layoutMode + && digitLanguage == other.digitLanguage + // slower things here + && font == other.font && vcl::text::FastStringCompareEqual()(text, other.text); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 376a9792c32a51c91079a54a0cf190acd58485af Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Wed Apr 6 19:29:06 2022 +0200 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Fri Apr 8 21:28:29 2022 +0200 use SalLayoutGlyphsCache in PDFWriterImpl It's unlikely to repeatedly lay out the same strings often, so it probably won't gain much, but still. If SalLayoutGlyphsCache would work even on different OutputDevice pointers (that would provide the same glyphs) then presumably this would be able to reuse caching even from e.g. Writer. Change-Id: Ib52d9ee92e950e69229497122df1789f5fc6b07e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132670 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lu...@collabora.com> diff --git a/vcl/inc/pdf/pdfwriter_impl.hxx b/vcl/inc/pdf/pdfwriter_impl.hxx index b8bdc3825eee..69570fa84afb 100644 --- a/vcl/inc/pdf/pdfwriter_impl.hxx +++ b/vcl/inc/pdf/pdfwriter_impl.hxx @@ -53,6 +53,7 @@ #include <comphelper/hash.hxx> #include <tools/stream.hxx> #include <vcl/BinaryDataContainer.hxx> +#include <vcl/glyphitemcache.hxx> #include <vcl/filter/pdfobjectcontainer.hxx> #include <pdf/ExternalPDFStreams.hxx> @@ -764,6 +765,8 @@ private: ::comphelper::Hash m_DocDigest; + SalLayoutGlyphsCache m_layoutGlyphsCache; + /* variables for PDF security i12626 diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 40eab868a80a..65a0827ad68d 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -6499,9 +6499,9 @@ void PDFWriterImpl::drawText( const Point& rPos, const OUString& rText, sal_Int3 // get a layout from the OutputDevice's SalGraphics // this also enforces font substitution and sets the font on SalGraphics - std::shared_ptr<const vcl::text::TextLayoutCache> layoutCache = CreateTextLayoutCache(rText); + const SalLayoutGlyphs* layoutGlyphs = m_layoutGlyphsCache.GetLayoutGlyphs( this, rText, nIndex, nLen, rPos ); std::unique_ptr<SalLayout> pLayout = ImplLayout( rText, nIndex, nLen, rPos, - 0, {}, SalLayoutFlags::NONE, layoutCache.get() ); + 0, {}, SalLayoutFlags::NONE, nullptr, layoutGlyphs ); if( pLayout ) { drawLayout( *pLayout, rText, bTextLines ); @@ -6516,9 +6516,9 @@ void PDFWriterImpl::drawTextArray( const Point& rPos, const OUString& rText, o3t // get a layout from the OutputDevice's SalGraphics // this also enforces font substitution and sets the font on SalGraphics - std::shared_ptr<const vcl::text::TextLayoutCache> layoutCache = CreateTextLayoutCache(rText); + const SalLayoutGlyphs* layoutGlyphs = m_layoutGlyphsCache.GetLayoutGlyphs( this, rText, nIndex, nLen, rPos, 0 ); std::unique_ptr<SalLayout> pLayout = ImplLayout( rText, nIndex, nLen, rPos, 0, pDXArray, - SalLayoutFlags::NONE, layoutCache.get() ); + SalLayoutFlags::NONE, nullptr, layoutGlyphs ); if( pLayout ) { drawLayout( *pLayout, rText, true ); @@ -6533,9 +6533,9 @@ void PDFWriterImpl::drawStretchText( const Point& rPos, sal_uLong nWidth, const // get a layout from the OutputDevice's SalGraphics // this also enforces font substitution and sets the font on SalGraphics - std::shared_ptr<const vcl::text::TextLayoutCache> layoutCache = CreateTextLayoutCache(rText); + const SalLayoutGlyphs* layoutGlyphs = m_layoutGlyphsCache.GetLayoutGlyphs( this, rText, nIndex, nLen, rPos, nWidth ); std::unique_ptr<SalLayout> pLayout = ImplLayout( rText, nIndex, nLen, rPos, nWidth, - {}, SalLayoutFlags::NONE, layoutCache.get() ); + {}, SalLayoutFlags::NONE, nullptr, layoutGlyphs ); if( pLayout ) { drawLayout( *pLayout, rText, true );