[Libreoffice-commits] core.git: vcl/inc vcl/qt5 vcl/quartz vcl/source vcl/unx vcl/win

Jan-Marek Glogowski glogow at fbihome.de
Mon May 7 21:04:00 UTC 2018


 vcl/inc/CommonSalLayout.hxx                    |    2 
 vcl/inc/PhysicalFontFace.hxx                   |    2 
 vcl/inc/fontinstance.hxx                       |   11 ++-
 vcl/inc/fontselect.hxx                         |    3 -
 vcl/inc/impfontcache.hxx                       |    8 +-
 vcl/inc/qt5/Qt5Font.hxx                        |   12 +---
 vcl/inc/quartz/salgdi.h                        |   14 ++--
 vcl/inc/salwtype.hxx                           |    2 
 vcl/inc/unx/freetype_glyphcache.hxx            |    5 +
 vcl/inc/win/salgdi.h                           |    5 -
 vcl/inc/win/winlayout.hxx                      |    2 
 vcl/qt5/Qt5FontFace.cxx                        |    6 ++
 vcl/qt5/Qt5FontFace.hxx                        |    2 
 vcl/qt5/Qt5Graphics.cxx                        |   20 ++++--
 vcl/qt5/Qt5Graphics.hxx                        |    2 
 vcl/qt5/Qt5Graphics_Text.cxx                   |   17 +++--
 vcl/quartz/ctfonts.cxx                         |   41 +++++++-------
 vcl/quartz/salgdi.cxx                          |   52 +++++++++--------
 vcl/source/font/PhysicalFontFace.cxx           |    2 
 vcl/source/font/fontcache.cxx                  |   73 ++++++++-----------------
 vcl/source/font/fontinstance.cxx               |    9 +--
 vcl/source/font/fontmetric.cxx                 |    8 +-
 vcl/source/font/fontselect.cxx                 |    2 
 vcl/source/gdi/CommonSalLayout.cxx             |   11 ++-
 vcl/source/gdi/pdfwriter_impl.cxx              |   14 ++--
 vcl/source/gdi/print.cxx                       |    2 
 vcl/source/outdev/font.cxx                     |   26 ++++----
 vcl/source/outdev/text.cxx                     |    5 +
 vcl/source/window/window.cxx                   |    2 
 vcl/unx/generic/gdi/cairotextrender.cxx        |    4 -
 vcl/unx/generic/glyphs/freetype_glyphcache.cxx |   20 ++++--
 vcl/unx/generic/glyphs/glyphcache.cxx          |   41 +++++++-------
 vcl/unx/generic/print/genpspgraphics.cxx       |    4 -
 vcl/win/gdi/salfont.cxx                        |   66 ++++++++++++----------
 vcl/win/gdi/salgdi.cxx                         |    1 
 vcl/win/gdi/winlayout.cxx                      |   10 +--
 vcl/win/window/salframe.cxx                    |    4 -
 37 files changed, 263 insertions(+), 247 deletions(-)

New commits:
commit 083b7ca26bbf4b9bad2922520caaf5c0227dac5e
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Tue Dec 26 15:58:21 2017 +0100

    Move PhysicalFontFace member of FontSelectPattern
    
    A FontSelectPattern describes a general font request. It can be
    used to find the best matching LogicalFontInstance. The instance
    will be created based on a PhysicalFontFace, which is really a
    factory since commit 8b700794b2746070814e9ff416ecd7bbb1c902e7.
    Following this workflow, this moves the PhysicalFontFace pointer
    to the instance and makes it constant.
    
    Which leaves some special symbol font handling code in the hash
    and instance lookup code path. It used to query the font face
    directly from the instance.
    I'm not sure of the correct handling. The related commits where
    made to fix #i89002#, which has an attached test document.
    
    1. commit 849f618270da313f9339dda29a9f35938434c91d
    2. commit 8c9823d311fdf8092cc75873e4565325d204a658
    
    The document is as broken as it was before the patch. The symbol
    substitution still works, but the 'Q's are missing when displaying
    a symbol font.
    
    I also don't understand all the reinterpret_casts for fake font
    ids. I guess this was used to prevent the crashes I see, where a
    PhysicalFontFace referenced in a valid LogicalFontInstance is
    freed and a later FontId check in the GlyphCache crashes. So this
    now checks for a valid cache instead.
    
    Change-Id: If8ee5a6288e66cfa4c419289fbdd5b5da128c6ea
    Reviewed-on: https://gerrit.libreoffice.org/47279
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Khaled Hosny <khaledhosny at eglug.org>

diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx
index 3b6e61308248..6ad2627b129b 100644
--- a/vcl/inc/CommonSalLayout.hxx
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -82,7 +82,7 @@ class VCL_DLLPUBLIC CommonSalLayout : public GenericSalLayout
 
 public:
 #if defined(_WIN32)
-    explicit                CommonSalLayout(HDC, WinFontInstance&, const WinFontFace&);
+    explicit                CommonSalLayout(HDC, WinFontInstance&);
     const FontSelectPattern& getFontSelData() const { return mrFontSelData; }
     HFONT                   getHFONT() const { return mhFont; }
     WinFontInstance&        getWinFontInstance() const { return mrWinFontInstance; }
diff --git a/vcl/inc/PhysicalFontFace.hxx b/vcl/inc/PhysicalFontFace.hxx
index ff708b99cfb8..39237ff46f89 100644
--- a/vcl/inc/PhysicalFontFace.hxx
+++ b/vcl/inc/PhysicalFontFace.hxx
@@ -22,9 +22,7 @@
 
 #include <vcl/dllapi.h>
 
-#include "fontinstance.hxx"
 #include "fontattributes.hxx"
-#include "fontselect.hxx"
 
 class LogicalFontInstance;
 struct FontMatchStatus;
diff --git a/vcl/inc/fontinstance.hxx b/vcl/inc/fontinstance.hxx
index cdafb1573a98..c37ada563fb0 100644
--- a/vcl/inc/fontinstance.hxx
+++ b/vcl/inc/fontinstance.hxx
@@ -22,13 +22,13 @@
 
 #include "fontselect.hxx"
 #include "impfontmetricdata.hxx"
-#include "PhysicalFontFace.hxx"
 
 #include <unordered_map>
 #include <memory>
 
 class ConvertChar;
 class ImplFontCache;
+class PhysicalFontFace;
 
 // TODO: allow sharing of metrics for related fonts
 
@@ -42,7 +42,6 @@ class VCL_PLUGIN_PUBLIC LogicalFontInstance
 public: // TODO: make data members private
     virtual ~LogicalFontInstance();
 
-    FontSelectPattern  maFontSelData;       // FontSelectionData
     ImplFontMetricDataRef mxFontMetric;        // Font attributes
     const ConvertChar* mpConversion;        // used e.g. for StarBats->StarSymbol
 
@@ -58,8 +57,12 @@ public: // TODO: make data members private
     void            Acquire();
     void            Release();
 
+    const FontSelectPattern& GetFontSelectPattern() const { return m_aFontSelData; }
+    const PhysicalFontFace* GetFontFace() const { return m_pFontFace; }
+    const ImplFontCache* GetFontCache() const { return mpFontCache; }
+
 protected:
-    explicit LogicalFontInstance(const FontSelectPattern&);
+    explicit LogicalFontInstance(const PhysicalFontFace&, const FontSelectPattern&);
 
 private:
     // cache of Unicode characters and replacement font names
@@ -69,6 +72,8 @@ private:
     std::unique_ptr<UnicodeFallbackList> mpUnicodeFallbackList;
     ImplFontCache * mpFontCache;
     sal_uInt32      mnRefCount;
+    const FontSelectPattern m_aFontSelData;
+    const PhysicalFontFace* m_pFontFace;
 };
 
 #endif // INCLUDED_VCL_INC_FONTINSTANCE_HXX
diff --git a/vcl/inc/fontselect.hxx b/vcl/inc/fontselect.hxx
index dec59905455b..389077270758 100644
--- a/vcl/inc/fontselect.hxx
+++ b/vcl/inc/fontselect.hxx
@@ -28,8 +28,8 @@
 
 namespace vcl { class Font; }
 
-class PhysicalFontFace;
 class LogicalFontInstance;
+class PhysicalFontFace;
 class Size;
 
 class FontSelectPatternAttributes : public FontAttributes
@@ -80,7 +80,6 @@ public:
 #endif
 
 public: // TODO: change to private
-    const PhysicalFontFace* mpFontData;         // a matching PhysicalFontFace object
     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 c5c7a4718d19..a99283fb300e 100644
--- a/vcl/inc/impfontcache.hxx
+++ b/vcl/inc/impfontcache.hxx
@@ -35,9 +35,10 @@ class ImplFontCache
 {
     // For access to Acquire and Release
     friend class LogicalFontInstance;
+
 private:
-    LogicalFontInstance* mpFirstEntry;
-    int                  mnRef0Count;    // number of unreferenced LogicalFontInstances
+    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; };
@@ -53,13 +54,14 @@ private:
     /// 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();
 
     LogicalFontInstance* GetFontInstance( PhysicalFontCollection const *,
                              const vcl::Font&, const Size& rPixelSize, float fExactHeight);
-    LogicalFontInstance* GetFontInstance( PhysicalFontCollection const *, FontSelectPattern& );
     LogicalFontInstance* GetGlyphFallbackFont( PhysicalFontCollection const *, FontSelectPattern&,
                             int nFallbackLevel, OUString& rMissingCodes );
 
diff --git a/vcl/inc/qt5/Qt5Font.hxx b/vcl/inc/qt5/Qt5Font.hxx
index 789c925a104c..1a1940fa7df0 100644
--- a/vcl/inc/qt5/Qt5Font.hxx
+++ b/vcl/inc/qt5/Qt5Font.hxx
@@ -22,25 +22,23 @@
 #include <vcl/dllapi.h>
 #include <QtGui/QFont>
 
-#include <fontselect.hxx>
+#include <fontinstance.hxx>
 #include <hb-ot.h>
 
-class VCL_DLLPUBLIC Qt5Font : public QFont
+class VCL_DLLPUBLIC Qt5Font : public QFont, public LogicalFontInstance
 {
-    const FontSelectPattern m_aFontSelData;
     hb_font_t* m_pHbFont;
 
 public:
-    Qt5Font(const FontSelectPattern& rFSP)
-        : m_aFontSelData(rFSP)
+    Qt5Font(const PhysicalFontFace& rPFF, const FontSelectPattern& rFSP)
+        : LogicalFontInstance(rPFF, rFSP)
         , m_pHbFont(nullptr)
     {
     }
-    virtual ~Qt5Font();
+    virtual ~Qt5Font() override;
 
     hb_font_t* GetHbFont() const { return m_pHbFont; }
     void SetHbFont(hb_font_t* pHbFont) { m_pHbFont = pHbFont; }
-    const FontSelectPattern& GetFontSelData() const { return m_aFontSelData; }
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 1b9782fa652b..4d7fa35a0981 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -69,6 +69,8 @@ public:
     bool                            GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const;
     bool                            HasChar( sal_uInt32 cChar ) const;
 
+    LogicalFontInstance*            CreateFontInstance(const FontSelectPattern&) const override;
+
 protected:
                                     CoreTextFontFace( const CoreTextFontFace& );
 
@@ -79,11 +81,12 @@ private:
     mutable bool                    mbFontCapabilitiesRead;
 };
 
-class CoreTextStyle
+class CoreTextStyle : public LogicalFontInstance
 {
+    friend LogicalFontInstance* CoreTextFontFace::CreateFontInstance(const FontSelectPattern&) const;
+
 public:
-    CoreTextStyle( const FontSelectPattern& );
-    ~CoreTextStyle( void );
+    ~CoreTextStyle();
 
     void       GetFontMetric( ImplFontMetricDataRef const & ) const;
     bool       GetGlyphBoundRect(const GlyphItem&, tools::Rectangle&) const;
@@ -93,14 +96,14 @@ public:
 
     CFMutableDictionaryRef  GetStyleDict( void ) const { return mpStyleDict; }
 
-    const CoreTextFontFace*  mpFontData;
     /// <1.0: font is squeezed, >1.0 font is stretched, else 1.0
     float               mfFontStretch;
     /// text rotation in radian
     float               mfFontRotation;
-    FontSelectPattern   maFontSelData;
 
 private:
+    explicit CoreTextStyle(const PhysicalFontFace&, const FontSelectPattern&);
+
     /// CoreText text style object
     CFMutableDictionaryRef  mpStyleDict;
     mutable hb_font_t*      mpHbFont;
@@ -155,7 +158,6 @@ class AquaSalGraphics : public SalGraphics
     RGBAColor                               maFillColor;
 
     // Device Font settings
-    const CoreTextFontFace*                 mpFontData[MAX_FALLBACK];
     CoreTextStyle*                          mpTextStyle[MAX_FALLBACK];
     RGBAColor                               maTextColor;
     /// allows text to be rendered without antialiasing
diff --git a/vcl/inc/salwtype.hxx b/vcl/inc/salwtype.hxx
index c8cce972b788..1800b976aeb9 100644
--- a/vcl/inc/salwtype.hxx
+++ b/vcl/inc/salwtype.hxx
@@ -239,7 +239,7 @@ struct SalFrameState
 
 struct SalInputContext
 {
-    FontSelectPattern*     mpFont;
+    const FontSelectPattern* mpFont;
     LanguageType           meLanguage;
     InputContextFlags      mnOptions;
 };
diff --git a/vcl/inc/unx/freetype_glyphcache.hxx b/vcl/inc/unx/freetype_glyphcache.hxx
index eb825b7c3f26..fc1852db4f7c 100644
--- a/vcl/inc/unx/freetype_glyphcache.hxx
+++ b/vcl/inc/unx/freetype_glyphcache.hxx
@@ -77,7 +77,7 @@ public:
 
 private:
     FT_FaceRec_*    maFaceFT;
-    FreetypeFontFile*     mpFontFile;
+    FreetypeFontFile* const mpFontFile;
     const int       mnFaceNum;
     int             mnRefCount;
     sal_IntPtr      mnFontId;
@@ -127,12 +127,13 @@ class VCL_DLLPUBLIC FreetypeFontInstance : public LogicalFontInstance
     FreetypeFont* mpFreetypeFont;
 
 protected:
-    explicit FreetypeFontInstance(const FontSelectPattern&);
+    explicit FreetypeFontInstance(const PhysicalFontFace& rPFF, const FontSelectPattern& rFSP);
 
 public:
     virtual ~FreetypeFontInstance() override;
 
     void SetFreetypeFont(FreetypeFont* p);
+    FreetypeFont* GetFreetypeFont() const { return mpFreetypeFont; }
 };
 
 #endif // INCLUDED_VCL_GENERIC_GLYPHS_GCACH_FTYP_HXX
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 23531842dde3..cc30963d21c2 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -164,7 +164,6 @@ private:
     HWND                    mhWnd;              // Window-Handle, when Window-Graphics
 
     HFONT                   mhFonts[ MAX_FALLBACK ];        // Font + Fallbacks
-    const WinFontFace*  mpWinFontData[ MAX_FALLBACK ];  // pointer to the most recent font face
     WinFontInstance*       mpWinFontEntry[ MAX_FALLBACK ]; // pointer to the most recent font instance
     float                   mfFontScale[ MAX_FALLBACK ];        // allows metrics emulation of huge font sizes
     float                   mfCurrentFontScale;
@@ -207,7 +206,7 @@ public:
 
     HWND gethWnd();
 
-    HFONT                   ImplDoSetFont( FontSelectPattern const * i_pFont, float& o_rFontScale, HFONT& o_rOldFont );
+    HFONT                   ImplDoSetFont( FontSelectPattern const * i_pFont, const PhysicalFontFace * i_pFontFace, float& o_rFontScale, HFONT& o_rOldFont );
 
 public:
     explicit WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hWnd,
@@ -400,7 +399,7 @@ public:
 void    ImplUpdateSysColorEntries();
 int     ImplIsSysColorEntry( Color nColor );
 void    ImplGetLogFontFromFontSelect( HDC, const FontSelectPattern*,
-            LOGFONTW&, bool bTestVerticalAvail );
+            const PhysicalFontFace*, LOGFONTW& );
 
 #define MAX_64KSALPOINTS    ((((sal_uInt16)0xFFFF)-8)/sizeof(POINTS))
 
diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx
index 4e1174899d8e..600817d8e2b8 100644
--- a/vcl/inc/win/winlayout.hxx
+++ b/vcl/inc/win/winlayout.hxx
@@ -155,7 +155,7 @@ public:
     GlyphCache& GetGlyphCache() { return maGlyphCache; }
 
 private:
-    explicit WinFontInstance(const FontSelectPattern&);
+    explicit WinFontInstance(const PhysicalFontFace&, const FontSelectPattern&);
 
     // TODO: also add HFONT??? Watch out for issues with too many active fonts...
     GlyphCache maGlyphCache;
diff --git a/vcl/qt5/Qt5FontFace.cxx b/vcl/qt5/Qt5FontFace.cxx
index a73e4528ec05..dd80292922aa 100644
--- a/vcl/qt5/Qt5FontFace.cxx
+++ b/vcl/qt5/Qt5FontFace.cxx
@@ -18,6 +18,7 @@
  */
 
 #include "Qt5FontFace.hxx"
+#include <qt5/Qt5Font.hxx>
 #include "Qt5Tools.hxx"
 
 #include <sft.hxx>
@@ -60,6 +61,11 @@ Qt5FontFace::~Qt5FontFace() {}
 
 sal_IntPtr Qt5FontFace::GetFontId() const { return reinterpret_cast<sal_IntPtr>(&m_aFontId); }
 
+LogicalFontInstance* Qt5FontFace::CreateFontInstance(const FontSelectPattern& rFSD) const
+{
+    return new Qt5Font(*this, rFSD);
+}
+
 const FontCharMapRef Qt5FontFace::GetFontCharMap() const
 {
     if (m_xCharMap.is())
diff --git a/vcl/qt5/Qt5FontFace.hxx b/vcl/qt5/Qt5FontFace.hxx
index bd33893609d8..9468cf15b4e3 100644
--- a/vcl/qt5/Qt5FontFace.hxx
+++ b/vcl/qt5/Qt5FontFace.hxx
@@ -47,6 +47,8 @@ public:
     bool GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities) const;
     bool HasChar(sal_uInt32 cChar) const;
 
+    LogicalFontInstance* CreateFontInstance(const FontSelectPattern& rFSD) const override;
+
 protected:
     Qt5FontFace(const Qt5FontFace&);
     Qt5FontFace(const FontAttributes& rFA, const QString& rFontID);
diff --git a/vcl/qt5/Qt5Graphics.cxx b/vcl/qt5/Qt5Graphics.cxx
index 6ec6c341913a..cf39b916ab42 100644
--- a/vcl/qt5/Qt5Graphics.cxx
+++ b/vcl/qt5/Qt5Graphics.cxx
@@ -19,16 +19,13 @@
 
 #include "Qt5Graphics.hxx"
 
+#include <qt5/Qt5Font.hxx>
 #include "Qt5Frame.hxx"
 #include "Qt5Painter.hxx"
 
-#include <qt5/Qt5Font.hxx>
-
-#include <QtWidgets/QWidget>
-
-#include <QtGui/QPainter>
-
 #include <QtGui/QImage>
+#include <QtGui/QPainter>
+#include <QtWidgets/QWidget>
 
 Qt5Graphics::Qt5Graphics( Qt5Frame *pFrame, QImage *pQImage )
     : m_pFrame( pFrame )
@@ -44,7 +41,16 @@ Qt5Graphics::Qt5Graphics( Qt5Frame *pFrame, QImage *pQImage )
     ResetClipRegion();
 }
 
-Qt5Graphics::~Qt5Graphics() {}
+Qt5Graphics::~Qt5Graphics()
+{
+    // release the text styles
+    for (int i = 0; i < MAX_FALLBACK; ++i)
+    {
+        if (!m_pTextStyle[i])
+            break;
+        m_pTextStyle[i]->Release();
+    }
+}
 
 void Qt5Graphics::ChangeQImage(QImage* pQImage)
 {
diff --git a/vcl/qt5/Qt5Graphics.hxx b/vcl/qt5/Qt5Graphics.hxx
index 0ece5ec5f036..9feff684ec93 100644
--- a/vcl/qt5/Qt5Graphics.hxx
+++ b/vcl/qt5/Qt5Graphics.hxx
@@ -49,7 +49,7 @@ class Qt5Graphics : public SalGraphics
 
     PhysicalFontCollection* m_pFontCollection;
     const Qt5FontFace* m_pFontData[MAX_FALLBACK];
-    std::unique_ptr<Qt5Font> m_pTextStyle[MAX_FALLBACK];
+    Qt5Font* m_pTextStyle[MAX_FALLBACK];
     Color m_aTextColor;
 
     Qt5Graphics(Qt5Frame* pFrame, QImage* pQImage);
diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx
index 2dbeaecfdf2c..4314e6333fe3 100644
--- a/vcl/qt5/Qt5Graphics_Text.cxx
+++ b/vcl/qt5/Qt5Graphics_Text.cxx
@@ -39,17 +39,18 @@ void Qt5Graphics::SetFont(const FontSelectPattern* pReqFont, int nFallbackLevel)
     {
         if (!m_pTextStyle[i])
             break;
-        m_pTextStyle[i].reset();
+        m_pTextStyle[i]->Release();
+        m_pTextStyle[i] = nullptr;
     }
 
     if (!pReqFont)
-        // handle release-font-resources request
-        m_pFontData[nFallbackLevel] = nullptr;
-    else
-    {
-        m_pFontData[nFallbackLevel] = static_cast<const Qt5FontFace*>(pReqFont->mpFontData);
-        m_pTextStyle[nFallbackLevel].reset(new Qt5Font(*pReqFont));
-    }
+        return;
+    assert(pReqFont->mpFontInstance);
+    if (!pReqFont->mpFontInstance)
+        return;
+
+    m_pTextStyle[nFallbackLevel] = static_cast<Qt5Font*>(pReqFont->mpFontInstance);
+    m_pTextStyle[nFallbackLevel]->Acquire();
 }
 
 void Qt5Graphics::GetFontMetric(ImplFontMetricDataRef& rFMD, int nFallbackLevel)
diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx
index 1ac73c59a60f..b35d121a314c 100644
--- a/vcl/quartz/ctfonts.cxx
+++ b/vcl/quartz/ctfonts.cxx
@@ -37,35 +37,32 @@
 #include <quartz/salgdi.h>
 #include <quartz/utils.h>
 #include <sallayout.hxx>
-
+#include <hb-coretext.h>
 
 inline double toRadian(int nDegree)
 {
     return nDegree * (M_PI / 1800.0);
 }
 
-CoreTextStyle::CoreTextStyle( const FontSelectPattern& rFSD )
-    : mpFontData( static_cast<CoreTextFontFace const *>(rFSD.mpFontData) )
+CoreTextStyle::CoreTextStyle(const PhysicalFontFace& rPFF, const FontSelectPattern& rFSP)
+    : LogicalFontInstance(rPFF, rFSP)
     , mfFontStretch( 1.0 )
     , mfFontRotation( 0.0 )
-    , maFontSelData( rFSD )
     , mpStyleDict( nullptr )
     , mpHbFont( nullptr )
 {
-    const FontSelectPattern* const pReqFont = &rFSD;
-
-    double fScaledFontHeight = pReqFont->mfExactHeight;
+    double fScaledFontHeight = rFSP.mfExactHeight;
 
     // convert font rotation to radian
-    mfFontRotation = toRadian(pReqFont->mnOrientation);
+    mfFontRotation = toRadian(rFSP.mnOrientation);
 
     // dummy matrix so we can use CGAffineTransformConcat() below
     CGAffineTransform aMatrix = CGAffineTransformMakeTranslation(0, 0);
 
     // handle font stretching if any
-    if( (pReqFont->mnWidth != 0) && (pReqFont->mnWidth != pReqFont->mnHeight) )
+    if( (rFSP.mnWidth != 0) && (rFSP.mnWidth != rFSP.mnHeight) )
     {
-        mfFontStretch = static_cast<float>(pReqFont->mnWidth) / pReqFont->mnHeight;
+        mfFontStretch = (float)rFSP.mnWidth / rFSP.mnHeight;
         aMatrix = CGAffineTransformConcat(aMatrix, CGAffineTransformMakeScale(mfFontStretch, 1.0F));
     }
 
@@ -75,28 +72,28 @@ CoreTextStyle::CoreTextStyle( const FontSelectPattern& rFSD )
                                              &kCFTypeDictionaryKeyCallBacks,
                                              &kCFTypeDictionaryValueCallBacks );
 
-    CFBooleanRef pCFVertBool = pReqFont->mbVertical ? kCFBooleanTrue : kCFBooleanFalse;
+    CFBooleanRef pCFVertBool = rFSP.mbVertical ? kCFBooleanTrue : kCFBooleanFalse;
     CFDictionarySetValue( mpStyleDict, kCTVerticalFormsAttributeName, pCFVertBool );
 
     // fake bold
-    if ( (pReqFont->GetWeight() >= WEIGHT_BOLD) &&
-         ((mpFontData->GetWeight() < WEIGHT_SEMIBOLD) &&
-          (mpFontData->GetWeight() != WEIGHT_DONTKNOW)) )
+    if ( (rFSP.GetWeight() >= WEIGHT_BOLD) &&
+         ((rPFF.GetWeight() < WEIGHT_SEMIBOLD) &&
+          (rPFF.GetWeight() != WEIGHT_DONTKNOW)) )
     {
-        int nStroke = -lrint((3.5F * pReqFont->GetWeight()) / mpFontData->GetWeight());
+        int nStroke = -lrint((3.5F * rFSP.GetWeight()) / rPFF.GetWeight());
         CFNumberRef rStroke = CFNumberCreate(nullptr, kCFNumberSInt32Type, &nStroke);
         CFDictionarySetValue(mpStyleDict, kCTStrokeWidthAttributeName, rStroke);
     }
 
     // fake italic
-    if (((pReqFont->GetItalic() == ITALIC_NORMAL) ||
-         (pReqFont->GetItalic() == ITALIC_OBLIQUE)) &&
-        (mpFontData->GetItalic() == ITALIC_NONE))
+    if (((rFSP.GetItalic() == ITALIC_NORMAL) ||
+         (rFSP.GetItalic() == ITALIC_OBLIQUE)) &&
+        (rPFF.GetItalic() == ITALIC_NONE))
     {
         aMatrix = CGAffineTransformConcat(aMatrix, CGAffineTransformMake(1, 0, toRadian(120), 1, 0, 0));
     }
 
-    CTFontDescriptorRef pFontDesc = reinterpret_cast<CTFontDescriptorRef>(mpFontData->GetFontId());
+    CTFontDescriptorRef pFontDesc = reinterpret_cast<CTFontDescriptorRef>(rPFF.GetFontId());
     CTFontRef pNewCTFont = CTFontCreateWithFontDescriptor( pFontDesc, fScaledFontHeight, &aMatrix );
     CFDictionarySetValue( mpStyleDict, kCTFontAttributeName, pNewCTFont );
     CFRelease( pNewCTFont);
@@ -115,6 +112,7 @@ void CoreTextStyle::GetFontMetric( ImplFontMetricDataRef const & rxFontMetric )
     // get the matching CoreText font handle
     // TODO: is it worth it to cache the CTFontRef in SetFont() and reuse it here?
     CTFontRef aCTFontRef = static_cast<CTFontRef>(CFDictionaryGetValue( mpStyleDict, kCTFontAttributeName ));
+    const CoreTextFontFace* mpFontData = static_cast<const CoreTextFontFace*>(GetFontFace());
 
     int nBufSize = 0;
 
@@ -268,6 +266,11 @@ PhysicalFontFace* CoreTextFontFace::Clone() const
     return new CoreTextFontFace( *this);
 }
 
+LogicalFontInstance* CoreTextFontFace::CreateFontInstance(const FontSelectPattern& rFSD) const
+{
+    return new CoreTextStyle(*this, rFSD);
+}
+
 int CoreTextFontFace::GetFontTable( const char pTagName[5], unsigned char* pResultBuf ) const
 {
     SAL_WARN_IF( pTagName[4]!='\0', "vcl", "CoreTextFontFace::GetFontTable with invalid tagname!" );
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index ed0d4b78d9d1..80825e77c84f 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -67,8 +67,8 @@ bool CoreTextGlyphFallbackSubstititution::FindFontSubstitute(FontSelectPattern&
     OUString& rMissingChars) const
 {
     bool bFound = false;
-    CoreTextStyle rStyle(rPattern);
-    CTFontRef pFont = static_cast<CTFontRef>(CFDictionaryGetValue(rStyle.GetStyleDict(), kCTFontAttributeName));
+    CoreTextStyle* pStyle = static_cast<CoreTextStyle*>(rPattern.mpFontInstance);
+    CTFontRef pFont = static_cast<CTFontRef>(CFDictionaryGetValue(pStyle->GetStyleDict(), kCTFontAttributeName));
     CFStringRef pStr = CreateCFString(rMissingChars);
     if (pStr)
     {
@@ -89,7 +89,11 @@ bool CoreTextGlyphFallbackSubstititution::FindFontSubstitute(FontSelectPattern&
 
             SalData* pSalData = GetSalData();
             if (pSalData->mpFontList)
-                rPattern.mpFontData = pSalData->mpFontList->GetFontDataFromId(reinterpret_cast<sal_IntPtr>(pDesc));
+            {
+                const CoreTextFontFace *pFontFace = pSalData->mpFontList->GetFontDataFromId(reinterpret_cast<sal_IntPtr>(pDesc));
+                if (pFontFace)
+                    rPattern.mpFontInstance = pFontFace->CreateFontInstance(rPattern);
+            }
 
             CFRelease(pFallback);
             CFRelease(pDesc);
@@ -223,10 +227,7 @@ AquaSalGraphics::AquaSalGraphics()
     SAL_INFO( "vcl.quartz", "AquaSalGraphics::AquaSalGraphics() this=" << this );
 
     for (int i = 0; i < MAX_FALLBACK; ++i)
-    {
         mpTextStyle[i] = nullptr;
-        mpFontData[i] = nullptr;
-    }
 }
 
 AquaSalGraphics::~AquaSalGraphics()
@@ -240,7 +241,11 @@ AquaSalGraphics::~AquaSalGraphics()
     }
 
     for (int i = 0; i < MAX_FALLBACK; ++i)
-        delete mpTextStyle[i];
+    {
+        if (!mpTextStyle[i])
+            break;
+        mpTextStyle[i]->Release();
+    }
 
     if( mpXorEmulation )
         delete mpXorEmulation;
@@ -405,7 +410,7 @@ bool AquaSalGraphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangl
 void AquaSalGraphics::DrawTextLayout(const CommonSalLayout& rLayout)
 {
     const CoreTextStyle& rStyle = rLayout.getFontData();
-    const FontSelectPattern& rFontSelect = rStyle.maFontSelData;
+    const FontSelectPattern& rFontSelect = rStyle.GetFontSelectPattern();
     if (rFontSelect.mnHeight == 0)
         return;
 
@@ -482,26 +487,27 @@ void AquaSalGraphics::SetFont(const FontSelectPattern* pReqFont, int nFallbackLe
     // release the text style
     for (int i = nFallbackLevel; i < MAX_FALLBACK; ++i)
     {
-        delete mpTextStyle[i];
+        if (!mpTextStyle[i])
+            break;
+        mpTextStyle[i]->Release();
         mpTextStyle[i] = nullptr;
     }
 
-    // handle NULL request meaning: release-font-resources request
-    if( !pReqFont )
-    {
-        mpFontData[nFallbackLevel] = nullptr;
+    if (!pReqFont)
+        return;
+    assert(pReqFont->mpFontInstance);
+    if (!pReqFont->mpFontInstance)
         return;
-    }
 
     // update the text style
-    mpFontData[nFallbackLevel] = static_cast<const CoreTextFontFace*>(pReqFont->mpFontData);
-    mpTextStyle[nFallbackLevel] = new CoreTextStyle(*pReqFont);
+    mpTextStyle[nFallbackLevel] = static_cast<CoreTextStyle*>(pReqFont->mpFontInstance);
+    mpTextStyle[nFallbackLevel]->Acquire();
 
     SAL_INFO("vcl.ct",
             "SetFont"
-               " to "     << mpFontData[nFallbackLevel]->GetFamilyName()
-            << ", "       << mpFontData[nFallbackLevel]->GetStyleName()
-            << " fontid=" << mpFontData[nFallbackLevel]->GetFontId()
+               " to "     << mpTextStyle[nFallbackLevel]->GetFontFace()->GetFamilyName()
+            << ", "       << mpTextStyle[nFallbackLevel]->GetFontFace()->GetStyleName()
+            << " fontid=" << mpTextStyle[nFallbackLevel]->GetFontFace()->GetFontId()
             << " for "    << pReqFont->GetFamilyName()
             << ", "       << pReqFont->GetStyleName()
             << " weight=" << pReqFont->GetWeight()
@@ -522,21 +528,21 @@ std::unique_ptr<SalLayout> AquaSalGraphics::GetTextLayout(ImplLayoutArgs& /*rArg
 
 const FontCharMapRef AquaSalGraphics::GetFontCharMap() const
 {
-    if (!mpFontData[0])
+    if (!mpTextStyle[0])
     {
         FontCharMapRef xFontCharMap( new FontCharMap() );
         return xFontCharMap;
     }
 
-    return mpFontData[0]->GetFontCharMap();
+    return static_cast<const CoreTextFontFace*>(mpTextStyle[0]->GetFontFace())->GetFontCharMap();
 }
 
 bool AquaSalGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
 {
-    if (!mpFontData[0])
+    if (!mpTextStyle[0])
         return false;
 
-    return mpFontData[0]->GetFontCapabilities(rFontCapabilities);
+    return static_cast<const CoreTextFontFace*>(mpTextStyle[0]->GetFontFace())->GetFontCapabilities(rFontCapabilities);
 }
 
 // fake a SFNT font directory entry for a font table
diff --git a/vcl/source/font/PhysicalFontFace.cxx b/vcl/source/font/PhysicalFontFace.cxx
index 04ebff2a8ffb..40948c41e77e 100644
--- a/vcl/source/font/PhysicalFontFace.cxx
+++ b/vcl/source/font/PhysicalFontFace.cxx
@@ -39,7 +39,7 @@ PhysicalFontFace::PhysicalFontFace( const FontAttributes& rDFA )
 
 LogicalFontInstance* PhysicalFontFace::CreateFontInstance(const FontSelectPattern& rFSD) const
 {
-    return new LogicalFontInstance(rFSD);
+    return new LogicalFontInstance(*this, rFSD);
 }
 
 sal_Int32 PhysicalFontFace::CompareIgnoreSize( const PhysicalFontFace& rOther ) const
diff --git a/vcl/source/font/fontcache.cxx b/vcl/source/font/fontcache.cxx
index f52eb6e30e16..1aa5f3e4c700 100644
--- a/vcl/source/font/fontcache.cxx
+++ b/vcl/source/font/fontcache.cxx
@@ -59,10 +59,7 @@ bool ImplFontCache::IFSD_Equal::operator()(const FontSelectPattern& rA, const Fo
 
     // Symbol fonts may recode from one type to another So they are only
     // safely equivalent for equal targets
-    if (
-        (rA.mpFontData && rA.mpFontData->IsSymbolFont()) ||
-        (rB.mpFontData && rB.mpFontData->IsSymbolFont())
-       )
+    if (rA.IsSymbolFont() && rB.IsSymbolFont())
     {
         if (rA.maTargetName != rB.maTargetName)
             return false;
@@ -85,7 +82,7 @@ bool ImplFontCache::IFSD_Equal::operator()(const FontSelectPattern& rA, const Fo
 }
 
 ImplFontCache::ImplFontCache()
-:   mpFirstEntry( nullptr ),
+:   mpLastHitCacheEntry( nullptr ),
     mnRef0Count( 0 )
 {}
 
@@ -94,29 +91,31 @@ ImplFontCache::~ImplFontCache()
     for (auto const& fontInstance : maFontInstanceList)
     {
         LogicalFontInstance* pFontInstance = fontInstance.second;
-        delete pFontInstance;
+        if (pFontInstance->mnRefCount)
+            pFontInstance->mpFontCache = nullptr;
+        else
+            delete pFontInstance;
     }
 }
 
 LogicalFontInstance* ImplFontCache::GetFontInstance( PhysicalFontCollection const * pFontList,
     const vcl::Font& rFont, const Size& rSize, float fExactHeight )
 {
-    const OUString& aSearchName = rFont.GetFamilyName();
-
     // initialize internal font request object
-    FontSelectPattern aFontSelData( rFont, aSearchName, rSize, fExactHeight );
+    FontSelectPattern aFontSelData(rFont, rFont.GetFamilyName(), rSize, fExactHeight);
     return GetFontInstance( pFontList, aFontSelData );
 }
 
 LogicalFontInstance* ImplFontCache::GetFontInstance( PhysicalFontCollection const * pFontList,
     FontSelectPattern& aFontSelData )
 {
-    // check if a directly matching logical font instance is already cached,
-    // the most recently used font usually has a hit rate of >50%
     LogicalFontInstance *pFontInstance = nullptr;
     PhysicalFontFamily* pFontFamily = nullptr;
-    if( mpFirstEntry && IFSD_Equal()( aFontSelData, mpFirstEntry->maFontSelData ) )
-        pFontInstance = mpFirstEntry;
+
+    // check if a directly matching logical font instance is already cached,
+    // the most recently used font usually has a hit rate of >50%
+    if (mpLastHitCacheEntry && IFSD_Equal()(aFontSelData, mpLastHitCacheEntry->GetFontSelectPattern()))
+        pFontInstance = mpLastHitCacheEntry;
     else
     {
         FontInstanceList::iterator it = maFontInstanceList.find( aFontSelData );
@@ -130,34 +129,10 @@ LogicalFontInstance* ImplFontCache::GetFontInstance( PhysicalFontCollection cons
         pFontFamily = pFontList->FindFontFamily( aFontSelData );
         SAL_WARN_IF( (pFontFamily == nullptr), "vcl", "ImplFontCache::Get() No logical font found!" );
         if( pFontFamily )
-            aFontSelData.maSearchName = pFontFamily->GetSearchName();
-
-        // check if an indirectly matching logical font instance is already cached
-        FontInstanceList::iterator it = maFontInstanceList.find( aFontSelData );
-        if( it != maFontInstanceList.end() )
         {
-            // we have an indirect cache hit
-            pFontInstance = (*it).second;
-        }
-    }
-
-    PhysicalFontFace* pFontData = nullptr;
-
-    if (!pFontInstance && pFontFamily)// no cache hit => find the best matching physical font face
-    {
-        bool bOrigWasSymbol = aFontSelData.mpFontData && aFontSelData.mpFontData->IsSymbolFont();
-        pFontData = pFontFamily->FindBestFontFace( aFontSelData );
-        aFontSelData.mpFontData = pFontData;
-        bool bNewIsSymbol = aFontSelData.mpFontData && aFontSelData.mpFontData->IsSymbolFont();
+            aFontSelData.maSearchName = pFontFamily->GetSearchName();
 
-        if (bNewIsSymbol != bOrigWasSymbol)
-        {
-            // it is possible, though generally unlikely, that at this point we
-            // will attempt to use a symbol font as a last-ditch fallback for a
-            // non-symbol font request or vice versa, and by changing
-            // aFontSelData.mpFontData to/from a symbol font we may now find
-            // something in the cache that can be reused which previously
-            // wasn't a candidate
+            // check if an indirectly matching logical font instance is already cached
             FontInstanceList::iterator it = maFontInstanceList.find( aFontSelData );
             if( it != maFontInstanceList.end() )
                 pFontInstance = (*it).second;
@@ -169,9 +144,10 @@ LogicalFontInstance* ImplFontCache::GetFontInstance( PhysicalFontCollection cons
         // increase the font instance's reference count
         pFontInstance->Acquire();
     }
-
-    if (!pFontInstance && pFontData)// still no cache hit => create a new font instance
+    else if (pFontFamily) // still no cache hit => create a new font instance
     {
+        PhysicalFontFace* pFontData = pFontFamily->FindBestFontFace(aFontSelData);
+
         // create a new logical font instance from this physical font face
         pFontInstance = pFontData->CreateFontInstance( aFontSelData );
         pFontInstance->mpFontCache = this;
@@ -197,10 +173,14 @@ LogicalFontInstance* ImplFontCache::GetFontInstance( PhysicalFontCollection cons
 #endif
 
         // add the new entry to the cache
-        maFontInstanceList[ aFontSelData ] = pFontInstance;
+#ifndef NDEBUG
+        auto aResult =
+#endif
+        maFontInstanceList.insert({aFontSelData, pFontInstance});
+        assert(aResult.second);
     }
 
-    mpFirstEntry = pFontInstance;
+    mpLastHitCacheEntry = pFontInstance;
     return pFontInstance;
 }
 
@@ -279,8 +259,8 @@ void ImplFontCache::Release(LogicalFontInstance* pFontInstance)
         --mnRef0Count;
         assert(mnRef0Count>=0 && "ImplFontCache::Release() - refcount0 underflow");
 
-        if( mpFirstEntry == pFontEntry )
-            mpFirstEntry = nullptr;
+        if (mpLastHitCacheEntry == pFontEntry)
+            mpLastHitCacheEntry = nullptr;
     }
 
     assert(mnRef0Count==0 && "ImplFontCache::Release() - refcount0 mismatch");
@@ -327,11 +307,10 @@ void ImplFontCache::Invalidate()
     }
 
     // #112304# make sure the font cache is really clean
-    mpFirstEntry = nullptr;
+    mpLastHitCacheEntry = 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 85383399abff..5f9ac49afcf7 100644
--- a/vcl/source/font/fontinstance.cxx
+++ b/vcl/source/font/fontinstance.cxx
@@ -37,9 +37,8 @@ namespace std
 }
 
 
-LogicalFontInstance::LogicalFontInstance( const FontSelectPattern& rFontSelData )
-    : maFontSelData( rFontSelData )
-    , mxFontMetric( new ImplFontMetricData( rFontSelData ))
+LogicalFontInstance::LogicalFontInstance(const PhysicalFontFace& rFontFace, const FontSelectPattern& rFontSelData )
+    : mxFontMetric( new ImplFontMetricData( rFontSelData ))
     , mpConversion( nullptr )
     , mnLineHeight( 0 )
     , mnOwnOrientation( 0 )
@@ -47,8 +46,10 @@ LogicalFontInstance::LogicalFontInstance( const FontSelectPattern& rFontSelData
     , mbInit( false )
     , mpFontCache( nullptr )
     , mnRefCount( 1 )
+    , m_aFontSelData(rFontSelData)
+    , m_pFontFace(&rFontFace)
 {
-    maFontSelData.mpFontInstance = this;
+    const_cast<FontSelectPattern*>(&m_aFontSelData)->mpFontInstance = this;
 }
 
 LogicalFontInstance::~LogicalFontInstance()
diff --git a/vcl/source/font/fontmetric.cxx b/vcl/source/font/fontmetric.cxx
index 1351b9167d4b..b619219c44ce 100644
--- a/vcl/source/font/fontmetric.cxx
+++ b/vcl/source/font/fontmetric.cxx
@@ -21,6 +21,8 @@
 #include <vcl/fontcharmap.hxx>
 #include <vcl/metric.hxx>
 
+#include <fontinstance.hxx>
+#include <fontselect.hxx>
 #include <impfontmetric.hxx>
 #include <impfontmetricdata.hxx>
 #include <PhysicalFontFace.hxx>
@@ -224,10 +226,10 @@ ImplFontMetricData::ImplFontMetricData( const FontSelectPattern& rFontSelData )
     , mnDStrikeoutOffset2( 0 )
 {
     // initialize the used font name
-    if( rFontSelData.mpFontData )
+    if (rFontSelData.mpFontInstance)
     {
-        SetFamilyName( rFontSelData.mpFontData->GetFamilyName() );
-        SetStyleName( rFontSelData.mpFontData->GetStyleName() );
+        SetFamilyName(rFontSelData.mpFontInstance->GetFontFace()->GetFamilyName());
+        SetStyleName(rFontSelData.mpFontInstance->GetFontFace()->GetStyleName());
     }
     else
     {
diff --git a/vcl/source/font/fontselect.cxx b/vcl/source/font/fontselect.cxx
index 8e62cf080808..fd67335eb1cd 100644
--- a/vcl/source/font/fontselect.cxx
+++ b/vcl/source/font/fontselect.cxx
@@ -30,7 +30,6 @@ const char FontSelectPatternAttributes::FEAT_SEPARATOR = '&';
 FontSelectPattern::FontSelectPattern( const vcl::Font& rFont,
     const OUString& rSearchName, const Size& rSize, float fExactHeight)
     : FontSelectPatternAttributes(rFont, rSearchName, rSize, fExactHeight)
-    , mpFontData( nullptr )
     , mpFontInstance( nullptr )
 {
 }
@@ -90,7 +89,6 @@ FontSelectPatternAttributes::FontSelectPatternAttributes( const PhysicalFontFace
 FontSelectPattern::FontSelectPattern( const PhysicalFontFace& rFontData,
     const Size& rSize, float fExactHeight, int nOrientation, bool bVertical )
     : FontSelectPatternAttributes(rFontData, rSize, fExactHeight, nOrientation, bVertical)
-    , mpFontData( &rFontData )
     , mpFontInstance( nullptr )
 {
 }
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index ddb3986b277d..120993557634 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -187,8 +187,8 @@ void CommonSalLayout::ParseFeatures(const OUString& aName)
 }
 
 #if defined(_WIN32)
-CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance, const WinFontFace& rWinFontFace)
-:   mrFontSelData(rWinFontInstance.maFontSelData)
+CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance)
+:   mrFontSelData(rWinFontInstance.GetFontSelectPattern())
 ,   mhDC(hDC)
 ,   mhFont(static_cast<HFONT>(GetCurrentObject(hDC, OBJ_FONT)))
 ,   mrWinFontInstance(rWinFontInstance)
@@ -196,6 +196,7 @@ CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance, con
 ,   mpVertGlyphs(nullptr)
 ,   mbFuzzing(utl::ConfigManager::IsFuzzing())
 {
+    const WinFontFace& rWinFontFace = *static_cast<const WinFontFace*>(rWinFontInstance.GetFontFace());
     mpHbFont = rWinFontFace.GetHbFont();
     if (!mpHbFont)
     {
@@ -239,7 +240,7 @@ bool CommonSalLayout::hasHScale() const
 
 #elif defined(MACOSX) || defined(IOS)
 CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle)
-:   mrFontSelData(rCoreTextStyle.maFontSelData)
+:   mrFontSelData(rCoreTextStyle.GetFontSelectPattern())
 ,   mrCoreTextStyle(rCoreTextStyle)
 ,   mpVertGlyphs(nullptr)
 ,   mbFuzzing(utl::ConfigManager::IsFuzzing())
@@ -256,7 +257,7 @@ CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle)
         if (pCGFont)
             pHbFace = hb_coretext_face_create(pCGFont);
         else
-            pHbFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr);
+            pHbFace = hb_face_create_for_tables(getFontTable, const_cast<PhysicalFontFace*>(rCoreTextStyle.GetFontFace()), nullptr);
         CGFontRelease(pCGFont);
 
         mpHbFont = createHbFont(pHbFace);
@@ -314,7 +315,7 @@ CommonSalLayout::CommonSalLayout(FreetypeFont& rFreetypeFont)
 }
 
 CommonSalLayout::CommonSalLayout(Qt5Font& rQFont)
-    : CommonSalLayout(rQFont.GetFontSelData(),
+    : CommonSalLayout(rQFont.GetFontSelectPattern(),
                       nullptr, &rQFont, true)
 {
 }
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index c10dbf1cb2f6..5ebdda50bace 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -6219,7 +6219,7 @@ sal_Int32 PDFWriterImpl::getSystemFont( const vcl::Font& i_rFont )
     getReferenceDevice()->SetFont( i_rFont );
     getReferenceDevice()->ImplNewFont();
 
-    const PhysicalFontFace* pDevFont = m_pReferenceDevice->mpFontInstance->maFontSelData.mpFontData;
+    const PhysicalFontFace* pDevFont = m_pReferenceDevice->mpFontInstance->GetFontFace();
     sal_Int32 nFontID = 0;
     FontEmbedData::iterator it = m_aSystemFonts.find( pDevFont );
     if( it != m_aSystemFonts.end() )
@@ -6553,7 +6553,7 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
     int nIndex = 0;
     double fXScale = 1.0;
     double fSkew = 0.0;
-    sal_Int32 nPixelFontHeight = m_pReferenceDevice->mpFontInstance->maFontSelData.mnHeight;
+    sal_Int32 nPixelFontHeight = m_pReferenceDevice->mpFontInstance->GetFontSelectPattern().mnHeight;
     TextAlign eAlign = m_aCurrentPDFState.m_aFont.GetAlignment();
 
     // transform font height back to current units
@@ -6577,8 +6577,8 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
     // perform artificial italics if necessary
     if( ( m_aCurrentPDFState.m_aFont.GetItalic() == ITALIC_NORMAL ||
           m_aCurrentPDFState.m_aFont.GetItalic() == ITALIC_OBLIQUE ) &&
-        !( m_pReferenceDevice->mpFontInstance->maFontSelData.mpFontData->GetItalic() == ITALIC_NORMAL ||
-           m_pReferenceDevice->mpFontInstance->maFontSelData.mpFontData->GetItalic() == ITALIC_OBLIQUE )
+        !( m_pReferenceDevice->mpFontInstance->GetFontFace()->GetItalic() == ITALIC_NORMAL ||
+           m_pReferenceDevice->mpFontInstance->GetFontFace()->GetItalic() == ITALIC_OBLIQUE )
         )
     {
         fSkew = M_PI/12.0;
@@ -6605,8 +6605,8 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
     bool bPop = false;
     bool bABold = false;
     // artificial bold necessary ?
-    if( m_pReferenceDevice->mpFontInstance->maFontSelData.mpFontData->GetWeight() <= WEIGHT_MEDIUM &&
-        m_pReferenceDevice->mpFontInstance->maFontSelData.GetWeight() > WEIGHT_MEDIUM )
+    if( m_pReferenceDevice->mpFontInstance->GetFontFace()->GetWeight() <= WEIGHT_MEDIUM &&
+        m_pReferenceDevice->mpFontInstance->GetFontSelectPattern().GetWeight() > WEIGHT_MEDIUM )
     {
         if( ! bPop )
             aLine.append( "q " );
@@ -6667,7 +6667,7 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
     }
 
     FontMetric aRefDevFontMetric = m_pReferenceDevice->GetFontMetric();
-    const PhysicalFontFace* pDevFont = m_pReferenceDevice->mpFontInstance->maFontSelData.mpFontData;
+    const PhysicalFontFace* pDevFont = m_pReferenceDevice->mpFontInstance->GetFontFace();
 
     // collect the glyphs into a single array
     std::vector< PDFGlyph > aGlyphs;
diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx
index f5780ea2680f..a5fe96a76db0 100644
--- a/vcl/source/gdi/print.cxx
+++ b/vcl/source/gdi/print.cxx
@@ -1719,7 +1719,7 @@ void Printer::InitFont() const
     if ( mbInitFont )
     {
         // select font in the device layers
-        mpGraphics->SetFont( &(mpFontInstance->maFontSelData), 0 );
+        mpGraphics->SetFont(&mpFontInstance->GetFontSelectPattern(), 0);
         mbInitFont = false;
     }
 }
diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx
index 25f3feec001f..c65dd0d5cce9 100644
--- a/vcl/source/outdev/font.cxx
+++ b/vcl/source/outdev/font.cxx
@@ -887,10 +887,8 @@ vcl::Font OutputDevice::GetDefaultFont( DefaultFontType nType, LanguageType eLan
                     LogicalFontInstance* pFontInstance = pOutDev->mpFontCache->GetFontInstance( pOutDev->mpFontCollection, aFont, aSize, fExactHeight );
                     if (pFontInstance)
                     {
-                        if( pFontInstance->maFontSelData.mpFontData )
-                            aFont.SetFamilyName( pFontInstance->maFontSelData.mpFontData->GetFamilyName() );
-                        else
-                            aFont.SetFamilyName( pFontInstance->maFontSelData.maTargetName );
+                        assert(pFontInstance->GetFontFace());
+                        aFont.SetFamilyName(pFontInstance->GetFontFace()->GetFamilyName());
                         pFontInstance->Release();
                     }
                 }
@@ -977,16 +975,17 @@ void OutputDevice::InitFont() const
     {
         // decide if antialiasing is appropriate
         bool bNonAntialiased(GetAntialiasing() & AntialiasingFlags::DisableText);
+        FontSelectPattern aPattern(mpFontInstance->GetFontSelectPattern());
         if (!utl::ConfigManager::IsFuzzing())
         {
             const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
             bNonAntialiased |= bool(rStyleSettings.GetDisplayOptions() & DisplayOptions::AADisable);
-            bNonAntialiased |= (int(rStyleSettings.GetAntialiasingMinPixelHeight()) > mpFontInstance->maFontSelData.mnHeight);
+            bNonAntialiased |= (int(rStyleSettings.GetAntialiasingMinPixelHeight()) > aPattern.mnHeight);
         }
-        mpFontInstance->maFontSelData.mbNonAntialiased = bNonAntialiased;
+        aPattern.mbNonAntialiased = bNonAntialiased;
 
         // select font in the device layers
-        mpGraphics->SetFont( &(mpFontInstance->maFontSelData), 0 );
+        mpGraphics->SetFont(&aPattern, 0);
         mbInitFont = false;
     }
 }
@@ -1063,7 +1062,7 @@ bool OutputDevice::ImplNewFont() const
         {
             pFontInstance->mbInit = true;
 
-            pFontInstance->mxFontMetric->SetOrientation( sal::static_int_cast<short>(pFontInstance->maFontSelData.mnOrientation) );
+            pFontInstance->mxFontMetric->SetOrientation( sal::static_int_cast<short>(mpFontInstance->GetFontSelectPattern().mnOrientation) );
             pGraphics->GetFontMetric( pFontInstance->mxFontMetric, 0 );
 
             pFontInstance->mxFontMetric->ImplInitTextLineSize( this );
@@ -1150,9 +1149,9 @@ bool OutputDevice::ImplNewFont() const
 
 void OutputDevice::SetFontOrientation( LogicalFontInstance* const pFontInstance ) const
 {
-    if( pFontInstance->maFontSelData.mnOrientation && !pFontInstance->mxFontMetric->GetOrientation() )
+    if( pFontInstance->GetFontSelectPattern().mnOrientation && !pFontInstance->mxFontMetric->GetOrientation() )
     {
-        pFontInstance->mnOwnOrientation = sal::static_int_cast<short>(pFontInstance->maFontSelData.mnOrientation);
+        pFontInstance->mnOwnOrientation = sal::static_int_cast<short>(pFontInstance->GetFontSelectPattern().mnOrientation);
         pFontInstance->mnOrientation = pFontInstance->mnOwnOrientation;
     }
     else
@@ -1341,7 +1340,7 @@ std::unique_ptr<SalLayout> OutputDevice::ImplGlyphFallbackLayout( std::unique_pt
     rLayoutArgs.ResetPos();
     OUString aMissingCodes = aMissingCodeBuf.makeStringAndClear();
 
-    FontSelectPattern aFontSelData = mpFontInstance->maFontSelData;
+    FontSelectPattern aFontSelData(mpFontInstance->GetFontSelectPattern());
 
     // try if fallback fonts support the missing code units
     for( int nFallbackLevel = 1; nFallbackLevel < MAX_FALLBACK; ++nFallbackLevel )
@@ -1357,13 +1356,12 @@ std::unique_ptr<SalLayout> OutputDevice::ImplGlyphFallbackLayout( std::unique_pt
             break;
 
         aFontSelData.mpFontInstance = pFallbackFont;
-        aFontSelData.mpFontData = pFallbackFont->maFontSelData.mpFontData;
         if( nFallbackLevel < MAX_FALLBACK-1)
         {
             // ignore fallback font if it is the same as the original font
             // unless we are looking for a substitution for 0x202F, in which
             // case we'll just use a normal space
-            if( mpFontInstance->maFontSelData.mpFontData == aFontSelData.mpFontData &&
+            if( mpFontInstance->GetFontFace() == pFallbackFont->GetFontFace() &&
                 aMissingCodes.indexOf(0x202F) == -1 )
             {
                 pFallbackFont->Release();
@@ -1379,7 +1377,7 @@ std::unique_ptr<SalLayout> OutputDevice::ImplGlyphFallbackLayout( std::unique_pt
             if( !pMultiSalLayout )
                 pMultiSalLayout.reset( new MultiSalLayout( std::move(pSalLayout) ) );
             pMultiSalLayout->AddFallback( std::move(pFallback),
-                rLayoutArgs.maRuns, aFontSelData.mpFontData );
+                rLayoutArgs.maRuns, aFontSelData.mpFontInstance->GetFontFace() );
             if (nFallbackLevel == MAX_FALLBACK-1)
                 pMultiSalLayout->SetIncomplete(true);
         }
diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx
index d794feb5ec42..1d115dc56397 100644
--- a/vcl/source/outdev/text.cxx
+++ b/vcl/source/outdev/text.cxx
@@ -217,9 +217,10 @@ bool OutputDevice::ImplDrawRotateText( SalLayout& rSalLayout )
     if( !pVDev->SetOutputSizePixel( aBoundRect.GetSize() ) )
         return false;
 
+    const FontSelectPattern& rPattern = mpFontInstance->GetFontSelectPattern();
     vcl::Font aFont( GetFont() );
     aFont.SetOrientation( 0 );
-    aFont.SetFontSize( Size( mpFontInstance->maFontSelData.mnWidth, mpFontInstance->maFontSelData.mnHeight ) );
+    aFont.SetFontSize( Size( rPattern.mnWidth, rPattern.mnHeight ) );
     pVDev->SetFont( aFont );
     pVDev->SetTextColor( COL_BLACK );
     pVDev->SetTextFillColor();
@@ -1358,7 +1359,7 @@ std::unique_ptr<SalLayout> OutputDevice::ImplLayout(const OUString& rOrigStr,
 
     // do glyph fallback if needed
     // #105768# avoid fallback for very small font sizes
-    if (aLayoutArgs.NeedFallback() && mpFontInstance->maFontSelData.mnHeight >= 3)
+    if (aLayoutArgs.NeedFallback() && mpFontInstance->GetFontSelectPattern().mnHeight >= 3)
         pSalLayout = ImplGlyphFallbackLayout(std::move(pSalLayout), aLayoutArgs);
 
     // position, justify, etc. the layout
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index c4db4c912977..879834c0da4c 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -1756,7 +1756,7 @@ void Window::ImplNewInputContext()
         pFontInstance = pFocusWin->mpFontCache->GetFontInstance( pFocusWin->mpFontCollection,
                          rFont, aSize, static_cast<float>(aSize.Height()) );
         if ( pFontInstance )
-            aNewContext.mpFont = &pFontInstance->maFontSelData;
+            aNewContext.mpFont = &pFontInstance->GetFontSelectPattern();
     }
     aNewContext.meLanguage  = rFont.GetLanguage();
     aNewContext.mnOptions   = rInputContext.GetOptions();
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
index 10edfd0e5001..bde9ff6827ac 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -99,10 +99,6 @@ void CairoTextRender::setFont( const FontSelectPattern *pEntry, int nFallbackLev
     if( !pEntry )
         return;
 
-    // return early if this is not a valid font for this graphics
-    if( !pEntry->mpFontData )
-        return;
-
     // handle the request for a non-native X11-font => use the GlyphCache
     FreetypeFont* pFreetypeFont = GlyphCache::GetInstance().CacheFont( *pEntry );
     if( pFreetypeFont != nullptr )
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index 65a9e4f14a0b..795284493f12 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -63,6 +63,7 @@
 #include <sys/mman.h>
 #include <unx/fontmanager.hxx>
 #include <impfontcharmap.hxx>
+#include <impfontcache.hxx>
 
 static FT_Library aLibFT = nullptr;
 
@@ -335,8 +336,11 @@ FreetypeFont* FreetypeManager::CreateFont( const FontSelectPattern& rFSD )
     FreetypeFontInfo* pFontInfo = nullptr;
 
     // find a FontInfo matching to the font id
-    sal_IntPtr nFontId = reinterpret_cast<sal_IntPtr>( rFSD.mpFontData );
-    FontList::iterator it = maFontList.find( nFontId );
+    sal_IntPtr nFontId = 0;
+    if (rFSD.mpFontInstance && rFSD.mpFontInstance->GetFontFace())
+        nFontId = rFSD.mpFontInstance->GetFontFace()->GetFontId();
+
+    FontList::iterator it = maFontList.find(nFontId);
     if( it != maFontList.end() )
         pFontInfo = it->second;
 
@@ -356,7 +360,7 @@ FreetypeFontFace::FreetypeFontFace( FreetypeFontInfo* pFI, const FontAttributes&
 
 LogicalFontInstance* FreetypeFontFace::CreateFontInstance(const FontSelectPattern& rFSD) const
 {
-    return new FreetypeFontInstance(rFSD);
+    return new FreetypeFontInstance(*this, rFSD);
 }
 
 // FreetypeFont
@@ -384,6 +388,7 @@ FreetypeFont::FreetypeFont( const FontSelectPattern& rFSD, FreetypeFontInfo* pFI
     // TODO: move update of mpFontInstance into FontEntry class when
     // it becomes responsible for the FreetypeFont instantiation
     static_cast<FreetypeFontInstance*>(rFSD.mpFontInstance)->SetFreetypeFont( this );
+    maFontSelData.mpFontInstance->Acquire();
 
     maFaceFT = pFI->GetFaceFT();
 
@@ -485,15 +490,16 @@ FreetypeFont::~FreetypeFont()
     if( mpHbFont )
         hb_font_destroy( mpHbFont );
 
+    maFontSelData.mpFontInstance->Release();
+
     ReleaseFromGarbageCollect();
 }
 
-
 void FreetypeFont::GetFontMetric(ImplFontMetricDataRef const & rxTo) const
 {
     rxTo->FontAttributes::operator =(mpFontInfo->GetFontAttributes());
 
-    rxTo->SetOrientation( GetFontSelData().mnOrientation );
+    rxTo->SetOrientation( maFontSelData.mnOrientation );
 
     //Always consider [star]symbol as symbol fonts
     if ( IsStarSymbol( rxTo->GetFamilyName() ) )
@@ -563,7 +569,7 @@ void FreetypeFont::GetFontMetric(ImplFontMetricDataRef const & rxTo) const
 void FreetypeFont::ApplyGlyphTransform(bool bVertical, FT_Glyph pGlyphFT ) const
 {
     // shortcut most common case
-    if (!GetFontSelData().mnOrientation && !bVertical)
+    if (!maFontSelData.mnOrientation && !bVertical)
         return;
 
     const FT_Size_Metrics& rMetrics = maFaceFT->size->metrics;
@@ -644,7 +650,7 @@ void FreetypeFont::InitGlyphData(const GlyphItem& rGlyph, GlyphData& rGD ) const
 bool FreetypeFont::GetAntialiasAdvice() const
 {
     // TODO: also use GASP info
-    return !GetFontSelData().mbNonAntialiased && (mnPrioAntiAlias > 0);
+    return !maFontSelData.mbNonAntialiased && (mnPrioAntiAlias > 0);
 }
 
 // determine unicode ranges in font
diff --git a/vcl/unx/generic/glyphs/glyphcache.cxx b/vcl/unx/generic/glyphs/glyphcache.cxx
index 4029d4bdf7bc..ac2f8cf83218 100644
--- a/vcl/unx/generic/glyphs/glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/glyphcache.cxx
@@ -71,11 +71,18 @@ void GlyphCache::ClearFontOptions()
     }
 }
 
+static inline sal_IntPtr GetFontId(const FontSelectPattern& rFSP)
+{
+    if (rFSP.mpFontInstance && rFSP.mpFontInstance->GetFontFace())
+        return rFSP.mpFontInstance->GetFontFace()->GetFontId();
+    return 0;
+}
+
 inline
 size_t GlyphCache::IFSD_Hash::operator()( const FontSelectPattern& rFontSelData ) const
 {
     // TODO: is it worth to improve this hash function?
-    sal_uIntPtr nFontId = reinterpret_cast<sal_uIntPtr>(rFontSelData.mpFontData);
+    sal_IntPtr nFontId = GetFontId(rFontSelData);
 
     if (rFontSelData.maTargetName.indexOf(FontSelectPatternAttributes::FEAT_PREFIX)
         != -1)
@@ -97,10 +104,11 @@ size_t GlyphCache::IFSD_Hash::operator()( const FontSelectPattern& rFontSelData
 
 bool GlyphCache::IFSD_Equal::operator()( const FontSelectPattern& rA, const FontSelectPattern& rB) const
 {
+    if (!rA.mpFontInstance->GetFontCache() || !rB.mpFontInstance->GetFontCache())
+        return false;
+
     // check font ids
-    sal_IntPtr nFontIdA = reinterpret_cast<sal_IntPtr>( rA.mpFontData );
-    sal_IntPtr nFontIdB = reinterpret_cast<sal_IntPtr>( rB.mpFontData );
-    if( nFontIdA != nFontIdB )
+    if (GetFontId(rA) != GetFontId(rB))
         return false;
 
     // compare with the requested metrics
@@ -167,34 +175,27 @@ void GlyphCache::ClearFontCache()
 
 FreetypeFont* GlyphCache::CacheFont( const FontSelectPattern& rFontSelData )
 {
-    // a serverfont request has pFontData
-    if( rFontSelData.mpFontData == nullptr )
-        return nullptr;
     // a serverfont request has a fontid > 0
-    sal_IntPtr nFontId = rFontSelData.mpFontData->GetFontId();
-    if( nFontId <= 0 )
+    if (GetFontId(rFontSelData) <= 0)
         return nullptr;
 
-    // the FontList's key mpFontData member is reinterpreted as font id
-    FontSelectPattern aFontSelData = rFontSelData;
-    aFontSelData.mpFontData = reinterpret_cast<PhysicalFontFace*>( nFontId );
-    FontList::iterator it = maFontList.find( aFontSelData );
+    FontList::iterator it = maFontList.find(rFontSelData);
     if( it != maFontList.end() )
     {
         FreetypeFont* pFound = it->second;
-        if( pFound )
-            pFound->AddRef();
+        assert(pFound);
+        pFound->AddRef();
         return pFound;
     }
 
     // font not cached yet => create new font item
     FreetypeFont* pNew = nullptr;
     if( mpFtManager )
-        pNew = mpFtManager->CreateFont( aFontSelData );
+        pNew = mpFtManager->CreateFont( rFontSelData );
 
     if( pNew )
     {
-        maFontList[ aFontSelData ] = pNew;
+        maFontList[ rFontSelData ] = pNew;
         mnBytesUsed += pNew->GetByteCount();
 
         // enable garbage collection for new font
@@ -347,9 +348,9 @@ void FreetypeFont::GarbageCollect( long nMinLruIndex )
     }
 }
 
-FreetypeFontInstance::FreetypeFontInstance( FontSelectPattern const & rFSD )
-:   LogicalFontInstance( rFSD )
-,   mpFreetypeFont( nullptr )
+FreetypeFontInstance::FreetypeFontInstance(const PhysicalFontFace& rPFF, const FontSelectPattern& rFSP)
+    : LogicalFontInstance(rPFF, rFSP)
+    , mpFreetypeFont(nullptr)
 {}
 
 void FreetypeFontInstance::SetFreetypeFont(FreetypeFont* p)
diff --git a/vcl/unx/generic/print/genpspgraphics.cxx b/vcl/unx/generic/print/genpspgraphics.cxx
index 402ac5788f08..d651da2812c6 100644
--- a/vcl/unx/generic/print/genpspgraphics.cxx
+++ b/vcl/unx/generic/print/genpspgraphics.cxx
@@ -610,7 +610,7 @@ void GenPspGraphics::SetFont( const FontSelectPattern *pEntry, int nFallbackLeve
     if( !pEntry )
         return;
 
-    sal_IntPtr nID = pEntry->mpFontData ? pEntry->mpFontData->GetFontId() : 0;
+    sal_IntPtr nID = pEntry->mpFontInstance ? pEntry->mpFontInstance->GetFontFace()->GetFontId() : 0;
 
     // determine which font attributes need to be emulated
     bool bArtItalic = false;
@@ -629,7 +629,7 @@ void GenPspGraphics::SetFont( const FontSelectPattern *pEntry, int nFallbackLeve
     }
 
     // also set the serverside font for layouting
-    if( pEntry->mpFontData )
+    if( pEntry->mpFontInstance )
     {
         // requesting a font provided by builtin rasterizer
         FreetypeFont* pFreetypeFont = GlyphCache::GetInstance().CacheFont( *pEntry );
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 11cc5e2d9115..2c96edc91fbe 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -52,6 +52,7 @@
 #include <sft.hxx>
 #include <win/saldata.hxx>
 #include <win/salgdi.h>
+#include <win/winlayout.hxx>
 #include <impfontcharmap.hxx>
 #include <impfontmetricdata.hxx>
 
@@ -182,7 +183,7 @@ bool WinGlyphFallbackSubstititution::HasMissingChars(PhysicalFontFace* pFace, OU
         const FontSelectPattern aFSD( *pFace, aSize, static_cast<float>(aSize.Height()), 0, false );
         // construct log font
         LOGFONTW aLogFont;
-        ImplGetLogFontFromFontSelect( mhDC, &aFSD, aLogFont, true );
+        ImplGetLogFontFromFontSelect( mhDC, &aFSD, pFace, aLogFont );
 
         // create HFONT from log font
         HFONT hNewFont = ::CreateFontIndirectW( &aLogFont );
@@ -757,12 +758,15 @@ int CALLBACK SalEnumQueryFontProcExW( const LOGFONTW*,
 
 void ImplGetLogFontFromFontSelect( HDC hDC,
                                    const FontSelectPattern* pFont,
-                                   LOGFONTW& rLogFont,
-                                   bool /*bTestVerticalAvail*/ )
+                                   const PhysicalFontFace* pFontFace,
+                                   LOGFONTW& rLogFont )
 {
-    OUString   aName;
-    if ( pFont->mpFontData )
-        aName = pFont->mpFontData->GetFamilyName();
+    OUString aName;
+    if (!pFontFace && pFont->mpFontInstance)
+        pFontFace = pFont->mpFontInstance->GetFontFace();
+
+    if (pFontFace)
+        aName = pFontFace->GetFamilyName();
     else
         aName = pFont->GetFamilyName().getToken( 0, ';' );
 
@@ -772,17 +776,17 @@ void ImplGetLogFontFromFontSelect( HDC hDC,
     memcpy( rLogFont.lfFaceName, aName.getStr(), nNameLen*sizeof( wchar_t ) );
     rLogFont.lfFaceName[nNameLen] = 0;
 
-    if( !pFont->mpFontData )
+    if  (pFontFace)
     {
-        rLogFont.lfCharSet = pFont->IsSymbolFont() ? SYMBOL_CHARSET : DEFAULT_CHARSET;
-        rLogFont.lfPitchAndFamily = ImplPitchToWin( pFont->GetPitch() )
-                                  | ImplFamilyToWin( pFont->GetFamilyType() );
+        const WinFontFace* pWinFontData = static_cast<const WinFontFace*>(pFontFace);
+        rLogFont.lfCharSet = pWinFontData->GetCharSet();
+        rLogFont.lfPitchAndFamily = pWinFontData->GetPitchAndFamily();
     }
     else
     {
-        const WinFontFace* pWinFontData = static_cast<const WinFontFace*>( pFont->mpFontData );
-        rLogFont.lfCharSet        = pWinFontData->GetCharSet();
-        rLogFont.lfPitchAndFamily = pWinFontData->GetPitchAndFamily();
+        rLogFont.lfCharSet = pFont->IsSymbolFont() ? SYMBOL_CHARSET : DEFAULT_CHARSET;
+        rLogFont.lfPitchAndFamily = ImplPitchToWin( pFont->GetPitch() )
+                                  | ImplFamilyToWin( pFont->GetFamilyType() );
     }
 
     static BYTE nDefaultQuality = NONANTIALIASED_QUALITY;
@@ -838,7 +842,10 @@ void ImplGetLogFontFromFontSelect( HDC hDC,
     }
 }
 
-HFONT WinSalGraphics::ImplDoSetFont(FontSelectPattern const * i_pFont, float& o_rFontScale, HFONT& o_rOldFont)
+HFONT WinSalGraphics::ImplDoSetFont(FontSelectPattern const * i_pFont,
+                                    const PhysicalFontFace * i_pFontFace,
+                                    float& o_rFontScale,
+                                    HFONT& o_rOldFont)
 {
     // clear the cache on font change
     g_BoundRectCache.clear();
@@ -850,7 +857,7 @@ HFONT WinSalGraphics::ImplDoSetFont(FontSelectPattern const * i_pFont, float& o_
         hdcScreen = GetDC(nullptr);
 
     LOGFONTW aLogFont;
-    ImplGetLogFontFromFontSelect( getHDC(), i_pFont, aLogFont, true );
+    ImplGetLogFontFromFontSelect( getHDC(), i_pFont, i_pFontFace, aLogFont );
 
     // #i47675# limit font requests to MAXFONTHEIGHT
     // TODO: share MAXFONTHEIGHT font instance
@@ -917,17 +924,13 @@ void WinSalGraphics::SetFont( const FontSelectPattern* pFont, int nFallbackLevel
                 ::DeleteFont( mhFonts[i] );
             mhFonts[ i ] = nullptr;
             if (mpWinFontEntry[i])
-            {
                 GetWinFontEntry(i)->Release();
-            }
             mpWinFontEntry[i] = nullptr;
-            mpWinFontData[i] = nullptr;
         }
         mhDefFont = nullptr;
         return;
     }
 
-    assert(pFont->mpFontData);
     if (mpWinFontEntry[nFallbackLevel])
     {
         GetWinFontEntry(nFallbackLevel)->Release();
@@ -939,10 +942,9 @@ void WinSalGraphics::SetFont( const FontSelectPattern* pFont, int nFallbackLevel
         pFont->mpFontInstance->Acquire();
     }
     mpWinFontEntry[ nFallbackLevel ] = reinterpret_cast<WinFontInstance*>( pFont->mpFontInstance );
-    mpWinFontData[ nFallbackLevel ] = static_cast<const WinFontFace*>( pFont->mpFontData );
 
     HFONT hOldFont = nullptr;
-    HFONT hNewFont = ImplDoSetFont(pFont, mfFontScale[ nFallbackLevel ], hOldFont);
+    HFONT hNewFont = ImplDoSetFont(pFont, nullptr, mfFontScale[ nFallbackLevel ], hOldFont);
     mfCurrentFontScale = mfFontScale[nFallbackLevel];
 
     if( !mhDefFont )
@@ -966,9 +968,13 @@ void WinSalGraphics::SetFont( const FontSelectPattern* pFont, int nFallbackLevel
 
     // store new font in correct layer
     mhFonts[ nFallbackLevel ] = hNewFont;
+
     // now the font is live => update font face
-    if( mpWinFontData[ nFallbackLevel ] )
-        mpWinFontData[ nFallbackLevel ]->UpdateFromHDC( getHDC() );
+    if (mpWinFontEntry[nFallbackLevel])
+    {
+        const WinFontFace* pFontFace = static_cast<const WinFontFace*>(mpWinFontEntry[nFallbackLevel]->GetFontFace());
+        pFontFace->UpdateFromHDC(getHDC());
+    }
 }
 
 void WinSalGraphics::GetFontMetric( ImplFontMetricDataRef& rxFontMetric, int nFallbackLevel )
@@ -1023,19 +1029,19 @@ void WinSalGraphics::GetFontMetric( ImplFontMetricDataRef& rxFontMetric, int nFa
 
 const FontCharMapRef WinSalGraphics::GetFontCharMap() const
 {
-    if( !mpWinFontData[0] )
+    if (!mpWinFontEntry[0])
     {
         FontCharMapRef xDefFontCharMap( new FontCharMap() );
         return xDefFontCharMap;
     }
-    return mpWinFontData[0]->GetFontCharMap();
+    return static_cast<const WinFontFace*>(mpWinFontEntry[0]->GetFontFace())->GetFontCharMap();
 }
 
 bool WinSalGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
 {
-    if( !mpWinFontData[0] )
+    if (!mpWinFontEntry[0])
         return false;
-    return mpWinFontData[0]->GetFontCapabilities(rFontCapabilities);
+    return static_cast<const WinFontFace*>(mpWinFontEntry[0]->GetFontFace())->GetFontCapabilities(rFontCapabilities);
 }
 
 int CALLBACK SalEnumFontsProcExW( const LOGFONTW* lpelfe,
@@ -1644,9 +1650,9 @@ bool WinSalGraphics::CreateFontSubset( const OUString& rToFile,
     ScopedFont aOldFont(*this);
     float fScale = 1.0;
     HFONT hOldFont = nullptr;
-    ImplDoSetFont(&aIFSD, fScale, hOldFont);
+    ImplDoSetFont(&aIFSD, pFont, fScale, hOldFont);
 
-    WinFontFace const * pWinFontData = static_cast<WinFontFace const *>(aIFSD.mpFontData);
+    WinFontFace const * pWinFontData = static_cast<WinFontFace const *>(pFont);
 
 #if OSL_DEBUG_LEVEL > 1
     // get font metrics
@@ -1793,7 +1799,7 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
 
     float fScale = 0.0;
     HFONT hOldFont = nullptr;
-    ImplDoSetFont(&aIFSD, fScale, hOldFont);
+    ImplDoSetFont(&aIFSD, pFont, fScale, hOldFont);
 
     // get raw font file data
     const RawFontData xRawFontData( getHDC() );
diff --git a/vcl/win/gdi/salgdi.cxx b/vcl/win/gdi/salgdi.cxx
index 8aa601a461b2..d38337b6d546 100644
--- a/vcl/win/gdi/salgdi.cxx
+++ b/vcl/win/gdi/salgdi.cxx
@@ -624,7 +624,6 @@ WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hW
     for( int i = 0; i < MAX_FALLBACK; ++i )
     {
         mhFonts[ i ] = nullptr;
-        mpWinFontData[ i ]  = nullptr;
         mpWinFontEntry[ i ] = nullptr;
         mfFontScale[ i ] = 1.0;
     }
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 94eb47dddebb..cc37b866848d 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -305,9 +305,9 @@ std::unique_ptr<SalLayout> WinSalGraphics::GetTextLayout(ImplLayoutArgs& /*rArgs
     if (!mpWinFontEntry[nFallbackLevel])
         return nullptr;
 
-    assert(mpWinFontData[nFallbackLevel]);
+    assert(mpWinFontEntry[nFallbackLevel]->GetFontFace());
 
-    return std::unique_ptr<SalLayout>(new CommonSalLayout(getHDC(), *mpWinFontEntry[nFallbackLevel], *mpWinFontData[nFallbackLevel]));
+    return std::unique_ptr<SalLayout>(new CommonSalLayout(getHDC(), *mpWinFontEntry[nFallbackLevel]));
 }
 
 LogicalFontInstance * WinSalGraphics::GetWinFontEntry(int const nFallbackLevel)
@@ -315,8 +315,8 @@ LogicalFontInstance * WinSalGraphics::GetWinFontEntry(int const nFallbackLevel)
     return mpWinFontEntry[nFallbackLevel];
 }
 
-WinFontInstance::WinFontInstance( FontSelectPattern const & rFSD )
-:   LogicalFontInstance( rFSD )
+WinFontInstance::WinFontInstance(const PhysicalFontFace& rPFF, const FontSelectPattern& rFSP)
+    : LogicalFontInstance(rPFF, rFSP)
 {
 }
 
@@ -335,7 +335,7 @@ PhysicalFontFace* WinFontFace::Clone() const
 
 LogicalFontInstance* WinFontFace::CreateFontInstance(const FontSelectPattern& rFSD) const
 {
-    return new WinFontInstance(rFSD);
+    return new WinFontInstance(*this, rFSD);
 }
 
 bool WinSalGraphics::CacheGlyphs(const CommonSalLayout& rLayout)
diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx
index 864c0dd45f03..ed65a8698d70 100644
--- a/vcl/win/window/salframe.cxx
+++ b/vcl/win/window/salframe.cxx
@@ -2184,8 +2184,8 @@ static void ImplSalFrameSetInputContext( HWND hWnd, const SalInputContext* pCont
                 // specified by this font name; but it seems to decide whether
                 // to use that font's horizontal or vertical variant based on a
                 // '@' in front of this font name.
-                ImplGetLogFontFromFontSelect( hDC, pContext->mpFont, aLogFont,
-                                              false );
+                ImplGetLogFontFromFontSelect(hDC, pContext->mpFont,
+                                             nullptr, aLogFont);
                 ReleaseDC( pFrame->mhWnd, hDC );
                 ImmSetCompositionFontW( hIMC, &aLogFont );
                 ImmReleaseContext( pFrame->mhWnd, hIMC );


More information about the Libreoffice-commits mailing list