include/vcl/outdev.hxx | 2 vcl/inc/PhysicalFontFace.hxx | 2 vcl/inc/fontinstance.hxx | 9 + vcl/inc/fontselect.hxx | 3 vcl/inc/impfontcache.hxx | 20 ++- vcl/inc/qt5/Qt5Font.hxx | 3 vcl/inc/qt5/Qt5FontFace.hxx | 3 vcl/inc/qt5/Qt5Graphics.hxx | 2 vcl/inc/quartz/salgdi.h | 6 - vcl/inc/sallayout.hxx | 2 vcl/inc/salwtype.hxx | 3 vcl/inc/unx/freetype_glyphcache.hxx | 4 vcl/inc/unx/glyphcache.hxx | 5 vcl/inc/win/salgdi.h | 7 - vcl/inc/win/winlayout.hxx | 2 vcl/qt5/Qt5FontFace.cxx | 3 vcl/qt5/Qt5Graphics.cxx | 2 vcl/qt5/Qt5Graphics_Text.cxx | 8 - vcl/quartz/ctfonts.cxx | 2 vcl/quartz/salgdi.cxx | 10 + vcl/source/font/PhysicalFontFace.cxx | 2 vcl/source/font/fontcache.cxx | 148 +++++++++++++++++++------ vcl/source/font/fontinstance.cxx | 22 +++ vcl/source/font/fontselect.cxx | 1 vcl/source/gdi/CommonSalLayout.cxx | 2 vcl/source/gdi/pdfwriter_impl.cxx | 12 +- vcl/source/gdi/print.cxx | 25 +++- vcl/source/gdi/virdev.cxx | 6 - vcl/source/outdev/font.cxx | 26 ++-- vcl/source/outdev/outdev.cxx | 3 vcl/source/outdev/outdevstate.cxx | 7 + vcl/source/outdev/textline.cxx | 8 - vcl/source/window/window.cxx | 5 vcl/unx/generic/glyphs/freetype_glyphcache.cxx | 9 - vcl/win/gdi/salfont.cxx | 29 +++- vcl/win/gdi/salgdi.cxx | 1 vcl/win/gdi/winlayout.cxx | 5 37 files changed, 293 insertions(+), 116 deletions(-)
New commits: commit cb63178ec92253c502710fce044700d2a6b86851 Author: Katarina Behrens <katarina.behr...@cib.de> AuthorDate: Wed Oct 2 11:32:06 2019 +0200 Commit: Thorsten Behrens <thorsten.behr...@cib.de> CommitDate: Mon Oct 7 04:13:36 2019 +0200 Revert series of LogicalFontInstance refactorings that cripple MM on Windows. They were backported in anticipation of backporting kde5 vclplug to 6.1 but otherwise add ~no value. Those are the reverted changes: e1266add9454 qt5: hold LogicalFontInstance with rtl::Reference ef759d03610b fixup 3eb3f0d9bc7fa94510 dbc1d2fe423b hold LogicalFontInstance with rtl::Reference Change-Id: Ieb0790797630c59ba233145c2ec075cf99725f8c Reviewed-on: https://gerrit.libreoffice.org/80247 Reviewed-by: Thorsten Behrens <thorsten.behr...@cib.de> Tested-by: Thorsten Behrens <thorsten.behr...@cib.de> diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index d0231e78a18e..59780f9f5e2f 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -332,7 +332,7 @@ private: mutable VclPtr<OutputDevice> mpPrevGraphics; ///< Previous output device in list mutable VclPtr<OutputDevice> mpNextGraphics; ///< Next output device in list GDIMetaFile* mpMetaFile; - mutable rtl::Reference<LogicalFontInstance> mpFontInstance; + mutable LogicalFontInstance* mpFontInstance; mutable ImplFontCache* mpFontCache; mutable PhysicalFontCollection* mpFontCollection; mutable std::unique_ptr<ImplDeviceFontList> mpDeviceFontList; diff --git a/vcl/inc/PhysicalFontFace.hxx b/vcl/inc/PhysicalFontFace.hxx index e289345716ca..2406b6cf41da 100644 --- a/vcl/inc/PhysicalFontFace.hxx +++ b/vcl/inc/PhysicalFontFace.hxx @@ -54,7 +54,7 @@ public: class VCL_PLUGIN_PUBLIC PhysicalFontFace : public FontAttributes, public salhelper::SimpleReferenceObject { public: - virtual rtl::Reference<LogicalFontInstance> CreateFontInstance(const FontSelectPattern&) const; + virtual LogicalFontInstance* CreateFontInstance(const FontSelectPattern&) const; virtual rtl::Reference<PhysicalFontFace> Clone() const = 0; int GetHeight() const { return mnHeight; } diff --git a/vcl/inc/fontinstance.hxx b/vcl/inc/fontinstance.hxx index 149bb553c3eb..317b7181198d 100644 --- a/vcl/inc/fontinstance.hxx +++ b/vcl/inc/fontinstance.hxx @@ -24,7 +24,6 @@ #include "impfontmetricdata.hxx" #include <rtl/ref.hxx> -#include <salhelper/simplereferenceobject.hxx> #include <unordered_map> #include <memory> @@ -36,7 +35,7 @@ class PhysicalFontFace; // TODO: allow sharing of metrics for related fonts -class VCL_PLUGIN_PUBLIC LogicalFontInstance : public salhelper::SimpleReferenceObject +class VCL_PLUGIN_PUBLIC LogicalFontInstance { // just declaring the factory function doesn't work AKA // friend LogicalFontInstance* PhysicalFontFace::CreateFontInstance(const FontSelectPattern&) const; @@ -44,7 +43,7 @@ class VCL_PLUGIN_PUBLIC LogicalFontInstance : public salhelper::SimpleReferenceO friend class ImplFontCache; public: // TODO: make data members private - virtual ~LogicalFontInstance() override; + virtual ~LogicalFontInstance(); ImplFontMetricDataRef mxFontMetric; // Font attributes const ConvertChar* mpConversion; // used e.g. for StarBats->StarSymbol @@ -58,6 +57,9 @@ public: // TODO: make data members private bool GetFallbackForUnicode( sal_UCS4, FontWeight eWeight, OUString* pFontName ) const; void IgnoreFallbackForUnicode( sal_UCS4, FontWeight eWeight, const OUString& rFontName ); + void Acquire(); + void Release(); + inline hb_font_t* GetHbFont(); void SetAverageWidthFactor(double nFactor) { m_nAveWidthFactor = nFactor; } double GetAverageWidthFactor() const { return m_nAveWidthFactor; } @@ -86,6 +88,7 @@ private: typedef ::std::unordered_map< ::std::pair<sal_UCS4,FontWeight>, OUString > UnicodeFallbackList; std::unique_ptr<UnicodeFallbackList> mpUnicodeFallbackList; ImplFontCache * mpFontCache; + sal_uInt32 mnRefCount; const FontSelectPattern m_aFontSelData; hb_font_t* m_pHbFont; double m_nAveWidthFactor; diff --git a/vcl/inc/fontselect.hxx b/vcl/inc/fontselect.hxx index efb88ad74ae1..389077270758 100644 --- a/vcl/inc/fontselect.hxx +++ b/vcl/inc/fontselect.hxx @@ -21,7 +21,6 @@ #define INCLUDED_VCL_INC_FONTSELECT_HXX #include <i18nlangtag/lang.h> -#include <rtl/ref.hxx> #include "fontattributes.hxx" @@ -81,7 +80,7 @@ public: #endif public: // TODO: change to private - rtl::Reference<LogicalFontInstance> mpFontInstance; // pointer to the resulting FontCache entry + LogicalFontInstance* mpFontInstance; // pointer to the resulting FontCache entry void copyAttributes(const FontSelectPatternAttributes &rAttributes); }; diff --git a/vcl/inc/impfontcache.hxx b/vcl/inc/impfontcache.hxx index 6cb05b39d9b3..a99283fb300e 100644 --- a/vcl/inc/impfontcache.hxx +++ b/vcl/inc/impfontcache.hxx @@ -33,24 +33,36 @@ class PhysicalFontCollection; class ImplFontCache { + // For access to Acquire and Release + friend class LogicalFontInstance; + private: LogicalFontInstance* mpLastHitCacheEntry; ///< keeps the last hit cache entry + int mnRef0Count; ///< number of unreferenced LogicalFontInstances // cache of recently used font instances struct IFSD_Equal { bool operator()( const FontSelectPattern&, const FontSelectPattern& ) const; }; struct IFSD_Hash { size_t operator()( const FontSelectPattern& ) const; }; - typedef std::unordered_map<FontSelectPattern, rtl::Reference<LogicalFontInstance>, IFSD_Hash, IFSD_Equal> FontInstanceList; + typedef std::unordered_map<FontSelectPattern,LogicalFontInstance*,IFSD_Hash,IFSD_Equal > FontInstanceList; FontInstanceList maFontInstanceList; - rtl::Reference<LogicalFontInstance> GetFontInstance(PhysicalFontCollection const*, FontSelectPattern&); + int CountUnreferencedEntries() const; + bool IsFontInList(const LogicalFontInstance* pFont) const; + + /// Increase the refcount of the given LogicalFontInstance. + void Acquire(LogicalFontInstance*); + /// Decrease the refcount and potentially cleanup the entries with zero refcount from the cache. + void Release(LogicalFontInstance*); + + LogicalFontInstance* GetFontInstance(PhysicalFontCollection const*, FontSelectPattern&); public: ImplFontCache(); ~ImplFontCache(); - rtl::Reference<LogicalFontInstance> GetFontInstance( PhysicalFontCollection const *, + LogicalFontInstance* GetFontInstance( PhysicalFontCollection const *, const vcl::Font&, const Size& rPixelSize, float fExactHeight); - rtl::Reference<LogicalFontInstance> GetGlyphFallbackFont( PhysicalFontCollection const *, FontSelectPattern&, + LogicalFontInstance* GetGlyphFallbackFont( PhysicalFontCollection const *, FontSelectPattern&, int nFallbackLevel, OUString& rMissingCodes ); void Invalidate(); diff --git a/vcl/inc/qt5/Qt5Font.hxx b/vcl/inc/qt5/Qt5Font.hxx index de5cd16039f1..0505a688b331 100644 --- a/vcl/inc/qt5/Qt5Font.hxx +++ b/vcl/inc/qt5/Qt5Font.hxx @@ -27,8 +27,7 @@ class Qt5Font final : public QFont, public LogicalFontInstance { - friend rtl::Reference<LogicalFontInstance> - Qt5FontFace::CreateFontInstance(const FontSelectPattern&) const; + friend LogicalFontInstance* Qt5FontFace::CreateFontInstance(const FontSelectPattern&) const; virtual hb_font_t* ImplInitHbFont() override; diff --git a/vcl/inc/qt5/Qt5FontFace.hxx b/vcl/inc/qt5/Qt5FontFace.hxx index ed954a0a832e..463ee8fb59f3 100644 --- a/vcl/inc/qt5/Qt5FontFace.hxx +++ b/vcl/inc/qt5/Qt5FontFace.hxx @@ -46,8 +46,7 @@ public: bool GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities) const; bool HasChar(sal_uInt32 cChar) const; - rtl::Reference<LogicalFontInstance> - CreateFontInstance(const FontSelectPattern& rFSD) const override; + LogicalFontInstance* CreateFontInstance(const FontSelectPattern& rFSD) const override; protected: Qt5FontFace(const Qt5FontFace&); diff --git a/vcl/inc/qt5/Qt5Graphics.hxx b/vcl/inc/qt5/Qt5Graphics.hxx index 9bffe7a51555..f08b944c95b1 100644 --- a/vcl/inc/qt5/Qt5Graphics.hxx +++ b/vcl/inc/qt5/Qt5Graphics.hxx @@ -54,7 +54,7 @@ class Qt5Graphics : public SalGraphics QPainter::CompositionMode m_eCompositionMode; PhysicalFontCollection* m_pFontCollection; - rtl::Reference<Qt5Font> m_pTextStyle[MAX_FALLBACK]; + Qt5Font* m_pTextStyle[MAX_FALLBACK]; Color m_aTextColor; std::unique_ptr<QPushButton> m_focusedButton; std::unique_ptr<QImage> m_image; diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index d9e1806d89ce..50b29eedf554 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -71,7 +71,7 @@ public: bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const; bool HasChar( sal_uInt32 cChar ) const; - rtl::Reference<LogicalFontInstance> CreateFontInstance(const FontSelectPattern&) const override; + LogicalFontInstance* CreateFontInstance(const FontSelectPattern&) const override; protected: CoreTextFontFace( const CoreTextFontFace& ); @@ -85,7 +85,7 @@ private: class CoreTextStyle : public LogicalFontInstance { - friend rtl::Reference<LogicalFontInstance> CoreTextFontFace::CreateFontInstance(const FontSelectPattern&) const; + friend LogicalFontInstance* CoreTextFontFace::CreateFontInstance(const FontSelectPattern&) const; public: ~CoreTextStyle(); @@ -159,7 +159,7 @@ class AquaSalGraphics : public SalGraphics RGBAColor maFillColor; // Device Font settings - rtl::Reference<CoreTextStyle> mpTextStyle[MAX_FALLBACK]; + CoreTextStyle* mpTextStyle[MAX_FALLBACK]; RGBAColor maTextColor; /// allows text to be rendered without antialiasing bool mbNonAntialiasedText; diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx index 8daed9a01d09..62cda5832906 100644 --- a/vcl/inc/sallayout.hxx +++ b/vcl/inc/sallayout.hxx @@ -352,7 +352,7 @@ private: void ParseFeatures(const OUString& name); - rtl::Reference<LogicalFontInstance> const mpFont; + LogicalFontInstance* const mpFont; css::uno::Reference<css::i18n::XBreakIterator> mxBreak; std::vector<GlyphItem> m_GlyphItems; diff --git a/vcl/inc/salwtype.hxx b/vcl/inc/salwtype.hxx index 29cbaf00c3a6..34ca43664a25 100644 --- a/vcl/inc/salwtype.hxx +++ b/vcl/inc/salwtype.hxx @@ -21,7 +21,6 @@ #define INCLUDED_VCL_INC_SALWTYPE_HXX #include <i18nlangtag/lang.h> -#include <rtl/ref.hxx> #include <rtl/ustring.hxx> #include <tools/solar.h> @@ -239,7 +238,7 @@ struct SalFrameState struct SalInputContext { - rtl::Reference<LogicalFontInstance> mpFont; + LogicalFontInstance* mpFont; LanguageType meLanguage; InputContextFlags mnOptions; }; diff --git a/vcl/inc/unx/freetype_glyphcache.hxx b/vcl/inc/unx/freetype_glyphcache.hxx index bf00935b15a1..d6b87b7ab7a9 100644 --- a/vcl/inc/unx/freetype_glyphcache.hxx +++ b/vcl/inc/unx/freetype_glyphcache.hxx @@ -114,7 +114,7 @@ private: public: FreetypeFontFace( FreetypeFontInfo*, const FontAttributes& ); - virtual rtl::Reference<LogicalFontInstance> CreateFontInstance( const FontSelectPattern& ) const override; + virtual LogicalFontInstance* CreateFontInstance( const FontSelectPattern& ) const override; virtual rtl::Reference<PhysicalFontFace> Clone() const override { return new FreetypeFontFace( *this ); } virtual sal_IntPtr GetFontId() const override { return mpFreetypeFontInfo->GetFontId(); } }; @@ -122,7 +122,7 @@ public: // a class for cache entries for physical font instances that are based on serverfonts class VCL_DLLPUBLIC FreetypeFontInstance : public LogicalFontInstance { - friend rtl::Reference<LogicalFontInstance> FreetypeFontFace::CreateFontInstance(const FontSelectPattern&) const; + friend LogicalFontInstance* FreetypeFontFace::CreateFontInstance(const FontSelectPattern&) const; FreetypeFont* mpFreetypeFont; diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx index 50d1f071d44f..5e515db564b5 100644 --- a/vcl/inc/unx/glyphcache.hxx +++ b/vcl/inc/unx/glyphcache.hxx @@ -39,7 +39,6 @@ #include <unordered_map> class FreetypeManager; -class FreetypeFontInstance; class FreetypeFontInfo; class GlyphData; class FontConfigFontOptions; @@ -140,7 +139,7 @@ public: bool GetGlyphOutline(const GlyphItem& rGlyph, basegfx::B2DPolyPolygon&) const; bool GetAntialiasAdvice() const; - FreetypeFontInstance* GetFontInstance() const { return mpFontInstance.get(); } + LogicalFontInstance* GetFontInstance() const { return mpFontInstance; } private: friend class GlyphCache; @@ -162,7 +161,7 @@ private: typedef std::unordered_map<int,GlyphData> GlyphList; mutable GlyphList maGlyphList; - rtl::Reference<FreetypeFontInstance> mpFontInstance; + LogicalFontInstance* const mpFontInstance; // used by GlyphCache for cache LRU algorithm mutable long mnRefCount; diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 0538eca4a019..2edc8a9507b8 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -64,7 +64,7 @@ public: virtual ~WinFontFace() override; virtual rtl::Reference<PhysicalFontFace> Clone() const override; - virtual rtl::Reference<LogicalFontInstance> CreateFontInstance( const FontSelectPattern& ) const override; + virtual LogicalFontInstance* CreateFontInstance( const FontSelectPattern& ) const override; virtual sal_IntPtr GetFontId() const override; void SetFontId( sal_IntPtr nId ) { mnId = nId; } void UpdateFromHDC( HDC ) const; @@ -170,8 +170,7 @@ private: **/ HFONT mhFonts[ MAX_FALLBACK ]; // Font + Fallbacks - rtl::Reference<WinFontInstance> - mpWinFontEntry[ MAX_FALLBACK ]; // pointer to the most recent font instance + WinFontInstance* mpWinFontEntry[ MAX_FALLBACK ]; // pointer to the most recent font instance float mfFontScale[ MAX_FALLBACK ]; // allows metrics emulation of huge font sizes HRGN mhRegion; // vcl::Region Handle HPEN mhDefPen; // DefaultPen @@ -183,6 +182,8 @@ private: RGNDATA* mpStdClipRgnData; // Cache Standard-ClipRegion-Data int mnPenWidth; // line width + LogicalFontInstance* GetWinFontEntry(int nFallbackLevel); + bool CacheGlyphs(const GenericSalLayout& rLayout); bool DrawCachedGlyphs(const GenericSalLayout& rLayout); HFONT ImplDoSetFont(FontSelectPattern const * i_pFont, const PhysicalFontFace * i_pFontFace, float& o_rFontScale, HFONT& o_rOldFont); diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx index 07ae1a7d03c1..0c447153c800 100644 --- a/vcl/inc/win/winlayout.hxx +++ b/vcl/inc/win/winlayout.hxx @@ -145,7 +145,7 @@ public: // win32 specific physical font instance class WinFontInstance : public LogicalFontInstance { - friend rtl::Reference<LogicalFontInstance> WinFontFace::CreateFontInstance(const FontSelectPattern&) const; + friend LogicalFontInstance* WinFontFace::CreateFontInstance(const FontSelectPattern&) const; public: virtual ~WinFontInstance() override; diff --git a/vcl/qt5/Qt5FontFace.cxx b/vcl/qt5/Qt5FontFace.cxx index 171902c63925..669bd403c8a1 100644 --- a/vcl/qt5/Qt5FontFace.cxx +++ b/vcl/qt5/Qt5FontFace.cxx @@ -114,8 +114,7 @@ Qt5FontFace::Qt5FontFace(const FontAttributes& rFA, const QString& rFontID) sal_IntPtr Qt5FontFace::GetFontId() const { return reinterpret_cast<sal_IntPtr>(&m_aFontId); } -rtl::Reference<LogicalFontInstance> -Qt5FontFace::CreateFontInstance(const FontSelectPattern& rFSD) const +LogicalFontInstance* Qt5FontFace::CreateFontInstance(const FontSelectPattern& rFSD) const { return new Qt5Font(*this, rFSD); } diff --git a/vcl/qt5/Qt5Graphics.cxx b/vcl/qt5/Qt5Graphics.cxx index fbf7ae05bf6b..15cb06e8c9a3 100644 --- a/vcl/qt5/Qt5Graphics.cxx +++ b/vcl/qt5/Qt5Graphics.cxx @@ -48,7 +48,7 @@ Qt5Graphics::~Qt5Graphics() { if (!m_pTextStyle[i]) break; - m_pTextStyle[i].clear(); + m_pTextStyle[i]->Release(); } } diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx index f63756c768f7..e024baafac56 100644 --- a/vcl/qt5/Qt5Graphics_Text.cxx +++ b/vcl/qt5/Qt5Graphics_Text.cxx @@ -43,7 +43,8 @@ void Qt5Graphics::SetFont(const FontSelectPattern* pReqFont, int nFallbackLevel) { if (!m_pTextStyle[i]) break; - m_pTextStyle[i].clear(); + m_pTextStyle[i]->Release(); + m_pTextStyle[i] = nullptr; } if (!pReqFont) @@ -52,7 +53,8 @@ void Qt5Graphics::SetFont(const FontSelectPattern* pReqFont, int nFallbackLevel) if (!pReqFont->mpFontInstance) return; - m_pTextStyle[nFallbackLevel] = static_cast<Qt5Font*>(pReqFont->mpFontInstance.get()); + m_pTextStyle[nFallbackLevel] = static_cast<Qt5Font*>(pReqFont->mpFontInstance); + m_pTextStyle[nFallbackLevel]->Acquire(); } void Qt5Graphics::GetFontMetric(ImplFontMetricDataRef& rFMD, int nFallbackLevel) @@ -166,7 +168,7 @@ bool Qt5Graphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle& r if (nLevel >= MAX_FALLBACK) return false; - Qt5Font* pFont = m_pTextStyle[nLevel].get(); + Qt5Font* pFont = m_pTextStyle[nLevel]; if (!pFont) return false; diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx index dc372325e9e8..1d72f601eafa 100644 --- a/vcl/quartz/ctfonts.cxx +++ b/vcl/quartz/ctfonts.cxx @@ -288,7 +288,7 @@ rtl::Reference<PhysicalFontFace> CoreTextFontFace::Clone() const return new CoreTextFontFace( *this); } -rtl::Reference<LogicalFontInstance> CoreTextFontFace::CreateFontInstance(const FontSelectPattern& rFSD) const +LogicalFontInstance* CoreTextFontFace::CreateFontInstance(const FontSelectPattern& rFSD) const { return new CoreTextStyle(*this, rFSD); } diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx index 48e40f3d0895..7154bd672e0f 100644 --- a/vcl/quartz/salgdi.cxx +++ b/vcl/quartz/salgdi.cxx @@ -66,7 +66,7 @@ bool CoreTextGlyphFallbackSubstititution::FindFontSubstitute(FontSelectPattern& OUString& rMissingChars) const { bool bFound = false; - CoreTextStyle* pStyle = static_cast<CoreTextStyle*>(rPattern.mpFontInstance.get()); + CoreTextStyle* pStyle = static_cast<CoreTextStyle*>(rPattern.mpFontInstance); CTFontRef pFont = static_cast<CTFontRef>(CFDictionaryGetValue(pStyle->GetStyleDict(), kCTFontAttributeName)); CFStringRef pStr = CreateCFString(rMissingChars); if (pStr) @@ -243,7 +243,7 @@ AquaSalGraphics::~AquaSalGraphics() { if (!mpTextStyle[i]) break; - mpTextStyle[i].clear(); + mpTextStyle[i]->Release(); } if( mpXorEmulation ) @@ -488,7 +488,8 @@ void AquaSalGraphics::SetFont(const FontSelectPattern* pReqFont, int nFallbackLe { if (!mpTextStyle[i]) break; - mpTextStyle[i].clear(); + mpTextStyle[i]->Release(); + mpTextStyle[i] = nullptr; } if (!pReqFont) @@ -498,7 +499,8 @@ void AquaSalGraphics::SetFont(const FontSelectPattern* pReqFont, int nFallbackLe return; // update the text style - mpTextStyle[nFallbackLevel] = static_cast<CoreTextStyle*>(pReqFont->mpFontInstance.get()); + mpTextStyle[nFallbackLevel] = static_cast<CoreTextStyle*>(pReqFont->mpFontInstance); + mpTextStyle[nFallbackLevel]->Acquire(); SAL_INFO("vcl.ct", "SetFont" diff --git a/vcl/source/font/PhysicalFontFace.cxx b/vcl/source/font/PhysicalFontFace.cxx index d356438e43a1..690fd1fdc401 100644 --- a/vcl/source/font/PhysicalFontFace.cxx +++ b/vcl/source/font/PhysicalFontFace.cxx @@ -45,7 +45,7 @@ PhysicalFontFace::PhysicalFontFace( const PhysicalFontFace& other ) { } -rtl::Reference<LogicalFontInstance> PhysicalFontFace::CreateFontInstance(const FontSelectPattern& rFSD) const +LogicalFontInstance* PhysicalFontFace::CreateFontInstance(const FontSelectPattern& rFSD) const { return new LogicalFontInstance(*this, rFSD); } diff --git a/vcl/source/font/fontcache.cxx b/vcl/source/font/fontcache.cxx index a58d9b6931f2..205b49ada4e0 100644 --- a/vcl/source/font/fontcache.cxx +++ b/vcl/source/font/fontcache.cxx @@ -83,14 +83,23 @@ bool ImplFontCache::IFSD_Equal::operator()(const FontSelectPattern& rA, const Fo } ImplFontCache::ImplFontCache() -: mpLastHitCacheEntry( nullptr ) +: mpLastHitCacheEntry( nullptr ), + mnRef0Count( 0 ) {} ImplFontCache::~ImplFontCache() { + for (auto const& fontInstance : maFontInstanceList) + { + LogicalFontInstance* pFontInstance = fontInstance.second; + if (pFontInstance->mnRefCount) + pFontInstance->mpFontCache = nullptr; + else + delete pFontInstance; + } } -rtl::Reference<LogicalFontInstance> ImplFontCache::GetFontInstance( PhysicalFontCollection const * pFontList, +LogicalFontInstance* ImplFontCache::GetFontInstance( PhysicalFontCollection const * pFontList, const vcl::Font& rFont, const Size& rSize, float fExactHeight ) { // initialize internal font request object @@ -98,10 +107,10 @@ rtl::Reference<LogicalFontInstance> ImplFontCache::GetFontInstance( PhysicalFont return GetFontInstance( pFontList, aFontSelData ); } -rtl::Reference<LogicalFontInstance> ImplFontCache::GetFontInstance( PhysicalFontCollection const * pFontList, +LogicalFontInstance* ImplFontCache::GetFontInstance( PhysicalFontCollection const * pFontList, FontSelectPattern& aFontSelData ) { - rtl::Reference<LogicalFontInstance> pFontInstance; + LogicalFontInstance *pFontInstance = nullptr; PhysicalFontFamily* pFontFamily = nullptr; // check if a directly matching logical font instance is already cached, @@ -131,7 +140,12 @@ rtl::Reference<LogicalFontInstance> ImplFontCache::GetFontInstance( PhysicalFont } } - if( !pFontInstance && pFontFamily) // still no cache hit => create a new font instance + if( pFontInstance ) // cache hit => use existing font instance + { + // increase the font instance's reference count + pFontInstance->Acquire(); + } + else if (pFontFamily) // still no cache hit => create a new font instance { PhysicalFontFace* pFontData = pFontFamily->FindBestFontFace(aFontSelData); @@ -159,38 +173,19 @@ rtl::Reference<LogicalFontInstance> ImplFontCache::GetFontInstance( PhysicalFont } #endif - static const size_t FONTCACHE_MAX = getenv("LO_TESTNAME") ? 1 : 50; - - if (maFontInstanceList.size() >= FONTCACHE_MAX) - { - // remove entries from font instance cache that are only referenced by the cache - FontInstanceList::iterator it_next = maFontInstanceList.begin(); - while( it_next != maFontInstanceList.end() ) - { - LogicalFontInstance* pFontEntry = (*it_next).second.get(); - if( pFontEntry->m_nCount > 1 ) - { - ++it_next; - continue; - } - maFontInstanceList.erase(it_next); - if (mpLastHitCacheEntry == pFontEntry) - mpLastHitCacheEntry = nullptr; - // just remove one entry, which will bring us back under FONTCACHE_MAX size again - break; - } - } - - assert(pFontInstance); // add the new entry to the cache - maFontInstanceList.insert({aFontSelData, pFontInstance.get()}); +#ifndef NDEBUG + auto aResult = +#endif + maFontInstanceList.insert({aFontSelData, pFontInstance}); + assert(aResult.second); } - mpLastHitCacheEntry = pFontInstance.get(); + mpLastHitCacheEntry = pFontInstance; return pFontInstance; } -rtl::Reference<LogicalFontInstance> ImplFontCache::GetGlyphFallbackFont( PhysicalFontCollection const * pFontCollection, +LogicalFontInstance* ImplFontCache::GetGlyphFallbackFont( PhysicalFontCollection const * pFontCollection, FontSelectPattern& rFontSelData, int nFallbackLevel, OUString& rMissingCodes ) { // get a candidate font for glyph fallback @@ -221,17 +216,102 @@ rtl::Reference<LogicalFontInstance> ImplFontCache::GetGlyphFallbackFont( Physica rFontSelData.maSearchName.clear(); } - rtl::Reference<LogicalFontInstance> pFallbackFont = GetFontInstance( pFontCollection, rFontSelData ); + LogicalFontInstance* pFallbackFont = GetFontInstance( pFontCollection, rFontSelData ); return pFallbackFont; } +void ImplFontCache::Acquire(LogicalFontInstance* pFontInstance) +{ + assert(pFontInstance->mpFontCache == this); + assert(IsFontInList(pFontInstance) && "ImplFontCache::Acquire() - font absent in the cache"); + + if (0 == pFontInstance->mnRefCount++) + --mnRef0Count; +} + +void ImplFontCache::Release(LogicalFontInstance* pFontInstance) +{ + static const int FONTCACHE_MAX = getenv("LO_TESTNAME") ? 1 : 50; + + assert(pFontInstance->mpFontCache == this); + assert(IsFontInList(pFontInstance) && "ImplFontCache::Release() - font absent in the cache"); + assert(pFontInstance->mnRefCount > 0 && "ImplFontCache::Release() - font refcount underflow"); + if( --pFontInstance->mnRefCount > 0 ) + return; + + if (++mnRef0Count < FONTCACHE_MAX) + return; + + assert(CountUnreferencedEntries() == mnRef0Count); + + // remove unused entries from font instance cache + FontInstanceList::iterator it_next = maFontInstanceList.begin(); + while( it_next != maFontInstanceList.end() ) + { + LogicalFontInstance* pFontEntry = (*it_next).second; + if( pFontEntry->mnRefCount > 0 ) + { + ++it_next; + continue; + } + + it_next = maFontInstanceList.erase(it_next); + delete pFontEntry; + --mnRef0Count; + assert(mnRef0Count>=0 && "ImplFontCache::Release() - refcount0 underflow"); + + if (mpLastHitCacheEntry == pFontEntry) + mpLastHitCacheEntry = nullptr; + } + + assert(mnRef0Count==0 && "ImplFontCache::Release() - refcount0 mismatch"); +} + +bool ImplFontCache::IsFontInList(const LogicalFontInstance* pFont) const +{ + auto Pred = [pFont](const FontInstanceList::value_type& el) -> bool { return el.second == pFont; }; + return std::find_if(maFontInstanceList.begin(), maFontInstanceList.end(), Pred) != maFontInstanceList.end(); +} + +int ImplFontCache::CountUnreferencedEntries() const +{ + size_t nCount = 0; + // count unreferenced entries + for (auto const& fontInstance : maFontInstanceList) + { + const LogicalFontInstance* pFontEntry = fontInstance.second; + if (pFontEntry->mnRefCount > 0) + continue; + ++nCount; + } + return nCount; +} + void ImplFontCache::Invalidate() { + assert(CountUnreferencedEntries() == mnRef0Count); + + // delete unreferenced entries + for (auto const& fontInstance : maFontInstanceList) + { + LogicalFontInstance* pFontEntry = fontInstance.second; + if( pFontEntry->mnRefCount > 0 ) + { + // These fonts will become orphans after clearing the list below; + // allow them to control their life from now on and wish good luck :) + pFontEntry->mpFontCache = nullptr; + continue; + } + + delete pFontEntry; + --mnRef0Count; + } + // #112304# make sure the font cache is really clean mpLastHitCacheEntry = nullptr; - for (auto const & pair : maFontInstanceList) - pair.second->mpFontCache = nullptr; maFontInstanceList.clear(); + + assert(mnRef0Count==0 && "ImplFontCache::Invalidate() - mnRef0Count non-zero"); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/font/fontinstance.cxx b/vcl/source/font/fontinstance.cxx index e5fac6c6a67b..fca20fd03ca3 100644 --- a/vcl/source/font/fontinstance.cxx +++ b/vcl/source/font/fontinstance.cxx @@ -48,6 +48,7 @@ LogicalFontInstance::LogicalFontInstance(const PhysicalFontFace& rFontFace, cons , mnOrientation( 0 ) , mbInit( false ) , mpFontCache( nullptr ) + , mnRefCount( 1 ) , m_aFontSelData(rFontSelData) , m_pHbFont(nullptr) , m_nAveWidthFactor(1.0f) @@ -114,6 +115,27 @@ void LogicalFontInstance::GetScale(double* nXScale, double* nYScale) *nXScale = nWidth / nUPEM; } +void LogicalFontInstance::Acquire() +{ + assert(mnRefCount < std::numeric_limits<decltype(mnRefCount)>::max() + && "LogicalFontInstance::Release() - refcount overflow"); + if (mpFontCache) + mpFontCache->Acquire(this); + else + ++mnRefCount; +} + +void LogicalFontInstance::Release() +{ + assert(mnRefCount > 0 && "LogicalFontInstance::Release() - refcount underflow"); + + if (mpFontCache) + mpFontCache->Release(this); + else + if (--mnRefCount == 0) + delete this; +} + void LogicalFontInstance::AddFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const OUString& rFontName ) { if( !mpUnicodeFallbackList ) diff --git a/vcl/source/font/fontselect.cxx b/vcl/source/font/fontselect.cxx index 563c6ebcbc54..80b9ba78ce6b 100644 --- a/vcl/source/font/fontselect.cxx +++ b/vcl/source/font/fontselect.cxx @@ -21,7 +21,6 @@ #include <o3tl/safeint.hxx> #include <fontselect.hxx> -#include <fontinstance.hxx> #include <PhysicalFontFace.hxx> #include <svdata.hxx> diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 22b5ea460d8e..8dcdc06a1ce8 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -58,10 +58,12 @@ GenericSalLayout::GenericSalLayout(LogicalFontInstance &rFont) , mpVertGlyphs(nullptr) , mbFuzzing(utl::ConfigManager::IsFuzzing()) { + mpFont->Acquire(); } GenericSalLayout::~GenericSalLayout() { + mpFont->Release(); } void GenericSalLayout::ParseFeatures(const OUString& aName) diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 181d2003f3e4..d9411779fb34 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -6779,7 +6779,7 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool // This includes ascent / descent. aRectangle.setHeight(aRefDevFontMetric.GetLineHeight()); - LogicalFontInstance* pFontInstance = m_pReferenceDevice->mpFontInstance.get(); + LogicalFontInstance* pFontInstance = m_pReferenceDevice->mpFontInstance; if (pFontInstance->mnOrientation) { // Adapt rectangle for rotated text. @@ -7269,7 +7269,7 @@ void PDFWriterImpl::drawLine( const Point& rStart, const Point& rStop, const Lin void PDFWriterImpl::drawWaveTextLine( OStringBuffer& aLine, long nWidth, FontLineStyle eTextLine, Color aColor, bool bIsAbove ) { // note: units in pFontInstance are ref device pixel - LogicalFontInstance* pFontInstance = m_pReferenceDevice->mpFontInstance.get(); + LogicalFontInstance* pFontInstance = m_pReferenceDevice->mpFontInstance; long nLineHeight = 0; long nLinePos = 0; @@ -7339,7 +7339,7 @@ void PDFWriterImpl::drawWaveTextLine( OStringBuffer& aLine, long nWidth, FontLin void PDFWriterImpl::drawStraightTextLine( OStringBuffer& aLine, long nWidth, FontLineStyle eTextLine, Color aColor, bool bIsAbove ) { // note: units in pFontInstance are ref device pixel - LogicalFontInstance* pFontInstance = m_pReferenceDevice->mpFontInstance.get(); + LogicalFontInstance* pFontInstance = m_pReferenceDevice->mpFontInstance; long nLineHeight = 0; long nLinePos = 0; long nLinePos2 = 0; @@ -7510,7 +7510,7 @@ void PDFWriterImpl::drawStraightTextLine( OStringBuffer& aLine, long nWidth, Fon void PDFWriterImpl::drawStrikeoutLine( OStringBuffer& aLine, long nWidth, FontStrikeout eStrikeout, Color aColor ) { // note: units in pFontInstance are ref device pixel - LogicalFontInstance* pFontInstance = m_pReferenceDevice->mpFontInstance.get(); + LogicalFontInstance* pFontInstance = m_pReferenceDevice->mpFontInstance; long nLineHeight = 0; long nLinePos = 0; long nLinePos2 = 0; @@ -7607,7 +7607,7 @@ void PDFWriterImpl::drawStrikeoutChar( const Point& rPos, long nWidth, FontStrik aRect.SetBottom( rPos.Y()+aRefDevFontMetric.GetDescent() ); aRect.SetTop( rPos.Y()-aRefDevFontMetric.GetAscent() ); - LogicalFontInstance* pFontInstance = m_pReferenceDevice->mpFontInstance.get(); + LogicalFontInstance* pFontInstance = m_pReferenceDevice->mpFontInstance; if (pFontInstance->mnOrientation) { tools::Polygon aPoly( aRect ); @@ -7642,7 +7642,7 @@ void PDFWriterImpl::drawTextLine( const Point& rPos, long nWidth, FontStrikeout updateGraphicsState(); // note: units in pFontInstance are ref device pixel - LogicalFontInstance* pFontInstance = m_pReferenceDevice->mpFontInstance.get(); + LogicalFontInstance* pFontInstance = m_pReferenceDevice->mpFontInstance; Color aUnderlineColor = m_aCurrentPDFState.m_aTextLineColor; Color aOverlineColor = m_aCurrentPDFState.m_aOverlineColor; Color aStrikeoutColor = m_aCurrentPDFState.m_aFont.GetColor(); diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx index 61fa23ec48f5..9de4ca74bfa2 100644 --- a/vcl/source/gdi/print.cxx +++ b/vcl/source/gdi/print.cxx @@ -571,7 +571,12 @@ void Printer::ImplReleaseFonts() mbNewFont = true; mbInitFont = true; - mpFontInstance.clear(); + if ( mpFontInstance ) + { + mpFontInstance->Release(); + mpFontInstance = nullptr; + } + mpDeviceFontList.reset(); mpDeviceFontSizeList.reset(); } @@ -932,7 +937,11 @@ void Printer::dispose() // OutputDevice Dtor is trying the same thing; that why we need to set // the FontEntry to NULL here // TODO: consolidate duplicate cleanup by Printer and OutputDevice - mpFontInstance.clear(); + if ( mpFontInstance ) + { + mpFontInstance->Release(); + mpFontInstance = nullptr; + } mpDeviceFontList.reset(); mpDeviceFontSizeList.reset(); delete mpFontCache; @@ -1069,7 +1078,11 @@ bool Printer::SetPrinterProps( const Printer* pPrinter ) { ReleaseGraphics(); pSVData->mpDefInst->DestroyInfoPrinter( mpInfoPrinter ); - mpFontInstance.clear(); + if ( mpFontInstance ) + { + mpFontInstance->Release(); + mpFontInstance = nullptr; + } mpDeviceFontList.reset(); mpDeviceFontSizeList.reset(); // clean up font list @@ -1100,7 +1113,11 @@ bool Printer::SetPrinterProps( const Printer* pPrinter ) { pSVData->mpDefInst->DestroyInfoPrinter( mpInfoPrinter ); - mpFontInstance.clear(); + if ( mpFontInstance ) + { + mpFontInstance->Release(); + mpFontInstance = nullptr; + } mpDeviceFontList.reset(); mpDeviceFontSizeList.reset(); delete mpFontCache; diff --git a/vcl/source/gdi/virdev.cxx b/vcl/source/gdi/virdev.cxx index dad14458705c..8972d83c23c8 100644 --- a/vcl/source/gdi/virdev.cxx +++ b/vcl/source/gdi/virdev.cxx @@ -487,7 +487,11 @@ void VirtualDevice::ImplSetReferenceDevice( RefDevMode i_eRefDevMode, sal_Int32 // the reference device should have only scalable fonts // => clean up the original font lists before getting new ones - mpFontInstance.clear(); + if ( mpFontInstance ) + { + mpFontInstance->Release(); + mpFontInstance = nullptr; + } mpDeviceFontList.reset(); mpDeviceFontSizeList.reset(); diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx index 439a3df75c5b..c65dd0d5cce9 100644 --- a/vcl/source/outdev/font.cxx +++ b/vcl/source/outdev/font.cxx @@ -168,7 +168,7 @@ FontMetric OutputDevice::GetFontMetric() const if( mbNewFont && !ImplNewFont() ) return aMetric; - LogicalFontInstance* pFontInstance = mpFontInstance.get(); + LogicalFontInstance* pFontInstance = mpFontInstance; ImplFontMetricDataRef xFontMetric = pFontInstance->mxFontMetric; // prepare metric @@ -475,7 +475,11 @@ long OutputDevice::GetFontExtLeading() const void OutputDevice::ImplClearFontData( const bool bNewFontLists ) { // the currently selected logical font is no longer needed - mpFontInstance.clear(); + if ( mpFontInstance ) + { + mpFontInstance->Release(); + mpFontInstance = nullptr; + } mbInitFont = true; mbNewFont = true; @@ -880,11 +884,12 @@ vcl::Font OutputDevice::GetDefaultFont( DefaultFontType nType, LanguageType eLan // get the name of the first available font float fExactHeight = static_cast<float>(aSize.Height()); - rtl::Reference<LogicalFontInstance> pFontInstance = pOutDev->mpFontCache->GetFontInstance( pOutDev->mpFontCollection, aFont, aSize, fExactHeight ); + LogicalFontInstance* pFontInstance = pOutDev->mpFontCache->GetFontInstance( pOutDev->mpFontCollection, aFont, aSize, fExactHeight ); if (pFontInstance) { assert(pFontInstance->GetFontFace()); aFont.SetFamilyName(pFontInstance->GetFontFace()->GetFamilyName()); + pFontInstance->Release(); } } } @@ -1029,12 +1034,12 @@ bool OutputDevice::ImplNewFont() const aSize.setWidth( 1 ); // get font entry - rtl::Reference<LogicalFontInstance> pOldFontInstance = mpFontInstance; + LogicalFontInstance* pOldFontInstance = mpFontInstance; mpFontInstance = mpFontCache->GetFontInstance( mpFontCollection, maFont, aSize, fExactHeight ); - bool bNewFontInstance = pOldFontInstance.get() != mpFontInstance.get(); - pOldFontInstance.clear(); + if( pOldFontInstance ) + pOldFontInstance->Release(); - LogicalFontInstance* pFontInstance = mpFontInstance.get(); + LogicalFontInstance* pFontInstance = mpFontInstance; if (!pFontInstance) { @@ -1044,7 +1049,7 @@ bool OutputDevice::ImplNewFont() const // mark when lower layers need to get involved mbNewFont = false; - if( bNewFontInstance ) + if( pFontInstance != pOldFontInstance ) mbInitFont = true; // select font when it has not been initialized yet @@ -1345,7 +1350,7 @@ std::unique_ptr<SalLayout> OutputDevice::ImplGlyphFallbackLayout( std::unique_pt // if the system-specific glyph fallback is active aFontSelData.mpFontInstance = mpFontInstance; // reset the fontinstance to base-level - rtl::Reference<LogicalFontInstance> pFallbackFont = mpFontCache->GetGlyphFallbackFont( mpFontCollection, + LogicalFontInstance* pFallbackFont = mpFontCache->GetGlyphFallbackFont( mpFontCollection, aFontSelData, nFallbackLevel, aMissingCodes ); if( !pFallbackFont ) break; @@ -1359,6 +1364,7 @@ std::unique_ptr<SalLayout> OutputDevice::ImplGlyphFallbackLayout( std::unique_pt if( mpFontInstance->GetFontFace() == pFallbackFont->GetFontFace() && aMissingCodes.indexOf(0x202F) == -1 ) { + pFallbackFont->Release(); continue; } } @@ -1376,6 +1382,8 @@ std::unique_ptr<SalLayout> OutputDevice::ImplGlyphFallbackLayout( std::unique_pt pMultiSalLayout->SetIncomplete(true); } + pFallbackFont->Release(); + // break when this fallback was sufficient if( !rLayoutArgs.PrepareFallback() ) break; diff --git a/vcl/source/outdev/outdev.cxx b/vcl/source/outdev/outdev.cxx index 1ecdcca86411..82833c72d819 100644 --- a/vcl/source/outdev/outdev.cxx +++ b/vcl/source/outdev/outdev.cxx @@ -172,7 +172,8 @@ void OutputDevice::dispose() mpOutDevStateStack.reset(); // release the active font instance - mpFontInstance.clear(); + if( mpFontInstance ) + mpFontInstance->Release(); // remove cached results of GetDevFontList/GetDevSizeList mpDeviceFontList.reset(); diff --git a/vcl/source/outdev/outdevstate.cxx b/vcl/source/outdev/outdevstate.cxx index 24e0b75e3c3e..6713f6481369 100644 --- a/vcl/source/outdev/outdevstate.cxx +++ b/vcl/source/outdev/outdevstate.cxx @@ -615,7 +615,12 @@ void OutputDevice::ImplReleaseFonts() mbNewFont = true; mbInitFont = true; - mpFontInstance.clear(); + if ( mpFontInstance ) + { + mpFontInstance->Release(); + mpFontInstance = nullptr; + } + mpDeviceFontList.reset(); mpDeviceFontSizeList.reset(); } diff --git a/vcl/source/outdev/textline.cxx b/vcl/source/outdev/textline.cxx index 2034a54beb8a..22e7db6230a1 100644 --- a/vcl/source/outdev/textline.cxx +++ b/vcl/source/outdev/textline.cxx @@ -211,7 +211,7 @@ void OutputDevice::ImplDrawWaveTextLine( long nBaseX, long nBaseY, Color aColor, bool bIsAbove ) { - LogicalFontInstance* pFontInstance = mpFontInstance.get(); + LogicalFontInstance* pFontInstance = mpFontInstance; long nLineHeight; long nLinePos; @@ -279,7 +279,7 @@ void OutputDevice::ImplDrawStraightTextLine( long nBaseX, long nBaseY, Color aColor, bool bIsAbove ) { - LogicalFontInstance* pFontInstance = mpFontInstance.get(); + LogicalFontInstance* pFontInstance = mpFontInstance; long nLineHeight = 0; long nLinePos = 0; long nLinePos2 = 0; @@ -521,7 +521,7 @@ void OutputDevice::ImplDrawStrikeoutLine( long nBaseX, long nBaseY, FontStrikeout eStrikeout, Color aColor ) { - LogicalFontInstance* pFontInstance = mpFontInstance.get(); + LogicalFontInstance* pFontInstance = mpFontInstance; long nLineHeight = 0; long nLinePos = 0; long nLinePos2 = 0; @@ -1030,7 +1030,7 @@ void OutputDevice::DrawWaveLine( const Point& rStartPos, const Point& rEndPos ) } // #109280# make sure the waveline does not exceed the descent to avoid paint problems - LogicalFontInstance* pFontInstance = mpFontInstance.get(); + LogicalFontInstance* pFontInstance = mpFontInstance; if( nWaveHeight > pFontInstance->mxFontMetric->GetWavelineUnderlineSize() ) { nWaveHeight = pFontInstance->mxFontMetric->GetWavelineUnderlineSize(); diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index d15181288cf2..af40d96882e7 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -1735,7 +1735,7 @@ void Window::ImplNewInputContext() SalInputContext aNewContext; const vcl::Font& rFont = rInputContext.GetFont(); const OUString& rFontName = rFont.GetFamilyName(); - rtl::Reference<LogicalFontInstance> pFontInstance; + LogicalFontInstance* pFontInstance = nullptr; aNewContext.mpFont = nullptr; if (!rFontName.isEmpty()) { @@ -1758,6 +1758,9 @@ void Window::ImplNewInputContext() aNewContext.meLanguage = rFont.GetLanguage(); aNewContext.mnOptions = rInputContext.GetOptions(); pFocusWin->ImplGetFrame()->SetInputContext( &aNewContext ); + + if ( pFontInstance ) + pFontInstance->Release(); } void Window::SetModalHierarchyHdl(const Link<bool, void>& rLink) diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx index d17f02db69ff..5d7b9ff064ac 100644 --- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx +++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx @@ -357,7 +357,7 @@ FreetypeFontFace::FreetypeFontFace( FreetypeFontInfo* pFI, const FontAttributes& { } -rtl::Reference<LogicalFontInstance> FreetypeFontFace::CreateFontInstance(const FontSelectPattern& rFSD) const +LogicalFontInstance* FreetypeFontFace::CreateFontInstance(const FontSelectPattern& rFSD) const { return new FreetypeFontInstance(*this, rFSD); } @@ -366,7 +366,7 @@ rtl::Reference<LogicalFontInstance> FreetypeFontFace::CreateFontInstance(const F FreetypeFont::FreetypeFont( const FontSelectPattern& rFSD, FreetypeFontInfo* pFI ) : maGlyphList( 0), - mpFontInstance(static_cast<FreetypeFontInstance*>(rFSD.mpFontInstance.get())), + mpFontInstance(rFSD.mpFontInstance), mnRefCount(1), mnBytesUsed( sizeof(FreetypeFont) ), mpPrevGCFont( nullptr ), @@ -385,7 +385,8 @@ FreetypeFont::FreetypeFont( const FontSelectPattern& rFSD, FreetypeFontInfo* pFI int nPrioEmbedded = nDefaultPrioEmbedded; // TODO: move update of mpFontInstance into FontEntry class when // it becomes responsible for the FreetypeFont instantiation - mpFontInstance->SetFreetypeFont( this ); + static_cast<FreetypeFontInstance*>(mpFontInstance)->SetFreetypeFont( this ); + mpFontInstance->Acquire(); maFaceFT = pFI->GetFaceFT(); @@ -484,7 +485,7 @@ FreetypeFont::~FreetypeFont() mpFontInfo->ReleaseFaceFT(); - mpFontInstance.clear(); + mpFontInstance->Release(); ReleaseFromGarbageCollect(); } diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index 1e060e780321..11957c7043dc 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -658,7 +658,7 @@ rtl::Reference<PhysicalFontFace> WinFontFace::Clone() const return new WinFontFace(*this); } -rtl::Reference<LogicalFontInstance> WinFontFace::CreateFontInstance(const FontSelectPattern& rFSD) const +LogicalFontInstance* WinFontFace::CreateFontInstance(const FontSelectPattern& rFSD) const { return new WinFontInstance(*this, rFSD); } @@ -926,15 +926,28 @@ void WinSalGraphics::SetFont( const FontSelectPattern* pFont, int nFallbackLevel ::DeleteFont( mhFonts[i] ); mhFonts[ i ] = nullptr; } - mpWinFontEntry[i] = nullptr; + if (mpWinFontEntry[i]) + { + GetWinFontEntry(i)->Release(); + mpWinFontEntry[i] = nullptr; + } mfFontScale[i] = 1.0; } return; } + if (mpWinFontEntry[nFallbackLevel]) + { + GetWinFontEntry(nFallbackLevel)->Release(); + } // WinSalGraphics::GetEmbedFontData does not set mpFontInstance // since it is interested in font file data only. - WinFontInstance *pFontInstance = static_cast<WinFontInstance*>(pFont->mpFontInstance.get()); + if (pFont->mpFontInstance) + { + pFont->mpFontInstance->Acquire(); + } + + WinFontInstance *pFontInstance = static_cast<WinFontInstance*>(pFont->mpFontInstance); mpWinFontEntry[ nFallbackLevel ] = pFontInstance; HFONT hOldFont = nullptr; @@ -972,7 +985,11 @@ void WinSalGraphics::SetFont( const FontSelectPattern* pFont, int nFallbackLevel ::DeleteFont( mhFonts[i] ); mhFonts[i] = nullptr; } - mpWinFontEntry[i] = nullptr; + if (mpWinFontEntry[i]) + { + GetWinFontEntry(i)->Release(); + mpWinFontEntry[i] = nullptr; + } mfFontScale[i] = 1.0; } } @@ -1363,7 +1380,7 @@ void WinSalGraphics::ClearDevFontCache() bool WinSalGraphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle& rRect) { - WinFontInstance* pFont = mpWinFontEntry[rGlyph.mnFallbackLevel].get(); + WinFontInstance* pFont = mpWinFontEntry[rGlyph.mnFallbackLevel]; HFONT hNewFont = pFont ? pFont->GetHFONT() : mhFonts[rGlyph.mnFallbackLevel]; float fFontScale = pFont ? pFont->GetScale() : mfFontScale[rGlyph.mnFallbackLevel]; @@ -1572,7 +1589,7 @@ bool WinSalGraphics::GetGlyphOutline(const GlyphItem& rGlyph, // rescaling needed for the tools::PolyPolygon conversion if( rB2DPolyPoly.count() ) { - WinFontInstance *pFont = mpWinFontEntry[rGlyph.mnFallbackLevel].get(); + WinFontInstance *pFont = mpWinFontEntry[rGlyph.mnFallbackLevel]; float fFontScale = pFont ? pFont->GetScale() : mfFontScale[rGlyph.mnFallbackLevel]; const double fFactor(fFontScale/256); rB2DPolyPoly.transform(basegfx::utils::createScaleB2DHomMatrix(fFactor, fFactor)); diff --git a/vcl/win/gdi/salgdi.cxx b/vcl/win/gdi/salgdi.cxx index 57dd4ed37efd..aba0d6e6589e 100644 --- a/vcl/win/gdi/salgdi.cxx +++ b/vcl/win/gdi/salgdi.cxx @@ -29,7 +29,6 @@ #include <win/salgdi.h> #include <win/salframe.h> #include <win/salvd.h> -#include <win/winlayout.hxx> #include <basegfx/matrix/b2dhommatrixtools.hxx> #include <salgdiimpl.hxx> diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index fa0c2b683387..392a6abef02a 100644 --- a/vcl/win/gdi/winlayout.cxx +++ b/vcl/win/gdi/winlayout.cxx @@ -310,6 +310,11 @@ std::unique_ptr<SalLayout> WinSalGraphics::GetTextLayout(ImplLayoutArgs& /*rArgs return std::unique_ptr<SalLayout>(aLayout); } +LogicalFontInstance * WinSalGraphics::GetWinFontEntry(int const nFallbackLevel) +{ + return mpWinFontEntry[nFallbackLevel]; +} + WinFontInstance::WinFontInstance(const PhysicalFontFace& rPFF, const FontSelectPattern& rFSP) : LogicalFontInstance(rPFF, rFSP) , m_hFont(nullptr) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits