vcl/inc/font/PhysicalFontFace.hxx              |    9 ++
 vcl/inc/fontinstance.hxx                       |   17 ----
 vcl/inc/qt5/QtFont.hxx                         |    2 
 vcl/inc/qt5/QtFontFace.hxx                     |    3 
 vcl/inc/quartz/salgdi.h                        |    4 -
 vcl/inc/unx/freetype_glyphcache.hxx            |    5 +
 vcl/inc/win/salgdi.h                           |    7 +
 vcl/inc/win/winlayout.hxx                      |    2 
 vcl/qt5/QtFont.cxx                             |   21 -----
 vcl/qt5/QtFontFace.cxx                         |   16 ++++
 vcl/quartz/ctfonts.cxx                         |   15 +--
 vcl/source/font/PhysicalFontFace.cxx           |   19 +++++
 vcl/source/font/fontinstance.cxx               |    6 -
 vcl/unx/generic/glyphs/freetype_glyphcache.cxx |   18 ++++
 vcl/unx/generic/glyphs/glyphcache.cxx          |   24 ------
 vcl/win/gdi/salfont.cxx                        |   94 ++++++++++++++++++++++---
 vcl/win/gdi/winlayout.cxx                      |   94 -------------------------
 17 files changed, 177 insertions(+), 179 deletions(-)

New commits:
commit dc92a4d973086ce8a6a5f75ba0f4d4c9ca05537a
Author:     Khaled Hosny <kha...@aliftype.com>
AuthorDate: Sat Sep 3 03:14:08 2022 +0200
Commit:     خالد حسني <kha...@aliftype.com>
CommitDate: Sun Sep 4 02:10:17 2022 +0200

    vcl: Create hb_face_t in PhysicalFontFace
    
    The two map to each other, and we want to access hb_face_t to provide
    some functionality scattered currently in platform-specific
    implementations.
    
    Change-Id: Ib3842752ec240b8254db828dba95a6a0ad65f16a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139275
    Tested-by: Jenkins
    Reviewed-by: خالد حسني <kha...@aliftype.com>

diff --git a/vcl/inc/font/PhysicalFontFace.hxx 
b/vcl/inc/font/PhysicalFontFace.hxx
index bd3093562a06..d4851ba507be 100644
--- a/vcl/inc/font/PhysicalFontFace.hxx
+++ b/vcl/inc/font/PhysicalFontFace.hxx
@@ -29,6 +29,8 @@
 
 #include <fontattributes.hxx>
 
+#include <hb.h>
+
 class LogicalFontInstance;
 struct FontMatchStatus;
 namespace vcl::font
@@ -66,6 +68,8 @@ public:
 class VCL_PLUGIN_PUBLIC PhysicalFontFace : public FontAttributes, public 
salhelper::SimpleReferenceObject
 {
 public:
+    ~PhysicalFontFace();
+
     virtual rtl::Reference<LogicalFontInstance> CreateFontInstance(const 
vcl::font::FontSelectPattern&) const = 0;
 
     virtual sal_IntPtr      GetFontId() const = 0;
@@ -75,7 +79,12 @@ public:
     bool                    IsBetterMatch( const 
vcl::font::FontSelectPattern&, FontMatchStatus& ) const;
     sal_Int32               CompareIgnoreSize( const PhysicalFontFace& ) const;
 
+    virtual hb_face_t*      GetHbFace() const;
+    virtual hb_blob_t*      GetHbTable(hb_tag_t) const { assert(false); return 
nullptr; }
+
 protected:
+    mutable hb_face_t*      mpHbFace;
+
     explicit PhysicalFontFace(const FontAttributes&);
 };
 
diff --git a/vcl/inc/fontinstance.hxx b/vcl/inc/fontinstance.hxx
index 5cb05b1d3804..2b382009e263 100644
--- a/vcl/inc/fontinstance.hxx
+++ b/vcl/inc/fontinstance.hxx
@@ -103,16 +103,14 @@ public: // TODO: make data members private
     int GetKashidaWidth() const;
 
     void GetScale(double* nXScale, double* nYScale) const;
-    static inline void DecodeOpenTypeTag(const uint32_t nTableTag, char* 
pTagName);
 
 protected:
     explicit LogicalFontInstance(const vcl::font::PhysicalFontFace&, const 
vcl::font::FontSelectPattern&);
 
     virtual bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) 
const = 0;
 
-    // Takes ownership of pHbFace.
-    static hb_font_t* InitHbFont(hb_face_t* pHbFace);
-    virtual hb_font_t* ImplInitHbFont() { assert(false); return 
hb_font_get_empty(); }
+    hb_font_t* InitHbFont();
+    virtual void ImplInitHbFont(hb_font_t*) { }
 
 private:
     struct MapEntry
@@ -142,17 +140,8 @@ private:
 inline hb_font_t* LogicalFontInstance::GetHbFont()
 {
     if (!m_pHbFont)
-        m_pHbFont = ImplInitHbFont();
+        m_pHbFont = InitHbFont();
     return m_pHbFont;
 }
 
-inline void LogicalFontInstance::DecodeOpenTypeTag(const uint32_t nTableTag, 
char* pTagName)
-{
-    pTagName[0] = static_cast<char>(nTableTag >> 24);
-    pTagName[1] = static_cast<char>(nTableTag >> 16);
-    pTagName[2] = static_cast<char>(nTableTag >> 8);
-    pTagName[3] = static_cast<char>(nTableTag);
-    pTagName[4] = 0;
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/qt5/QtFont.hxx b/vcl/inc/qt5/QtFont.hxx
index 237523e2d10a..2ba6f49e557f 100644
--- a/vcl/inc/qt5/QtFont.hxx
+++ b/vcl/inc/qt5/QtFont.hxx
@@ -35,8 +35,6 @@ class QtFont final : public QFont, public LogicalFontInstance
     bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const 
override;
     bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const 
override;
 
-    virtual hb_font_t* ImplInitHbFont() override;
-
     explicit QtFont(const vcl::font::PhysicalFontFace&, const 
vcl::font::FontSelectPattern&);
 };
 
diff --git a/vcl/inc/qt5/QtFontFace.hxx b/vcl/inc/qt5/QtFontFace.hxx
index 2df5ab7eb009..eb4846ef772d 100644
--- a/vcl/inc/qt5/QtFontFace.hxx
+++ b/vcl/inc/qt5/QtFontFace.hxx
@@ -51,7 +51,6 @@ public:
     sal_IntPtr GetFontId() const override;
 
     QFont CreateFont() const;
-    int GetFontTable(const char pTagName[5], unsigned char*) const;
 
     FontCharMapRef GetFontCharMap() const override;
     bool GetFontCapabilities(vcl::FontCapabilities&) const override;
@@ -60,6 +59,8 @@ public:
     rtl::Reference<LogicalFontInstance>
     CreateFontInstance(const vcl::font::FontSelectPattern& rFSD) const 
override;
 
+    hb_blob_t* GetHbTable(hb_tag_t nTag) const override;
+
 private:
     typedef enum { Font, FontDB } FontIdType;
 
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 29739adf33eb..9fc3e6b2d74c 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -75,6 +75,8 @@ public:
 
     rtl::Reference<LogicalFontInstance> CreateFontInstance(const 
vcl::font::FontSelectPattern&) const override;
 
+    virtual hb_blob_t*              GetHbTable(hb_tag_t nTag) const override;
+
 private:
     const sal_IntPtr                mnFontId;
     mutable FontCharMapRef          mxCharMap;
@@ -104,7 +106,7 @@ public:
 private:
     explicit CoreTextStyle(const vcl::font::PhysicalFontFace&, const 
vcl::font::FontSelectPattern&);
 
-    hb_font_t* ImplInitHbFont() override;
+    virtual void ImplInitHbFont(hb_font_t*) override;
     bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const 
override;
 
     void SetFontVariationsOnHBFont(hb_font_t*) const;
diff --git a/vcl/inc/unx/freetype_glyphcache.hxx 
b/vcl/inc/unx/freetype_glyphcache.hxx
index 525bd35dc6f2..c3ca90591f59 100644
--- a/vcl/inc/unx/freetype_glyphcache.hxx
+++ b/vcl/inc/unx/freetype_glyphcache.hxx
@@ -106,6 +106,9 @@ public:
 
     FontCharMapRef GetFontCharMap() const override { return 
mpFreetypeFontInfo->GetFontCharMap(); }
     inline bool GetFontCapabilities(vcl::FontCapabilities&) const override;
+
+    virtual hb_face_t* GetHbFace() const override;
+    virtual hb_blob_t* GetHbTable(hb_tag_t nTag) const override;
 };
 
 bool FreetypeFontFace::GetFontCapabilities(vcl::FontCapabilities& 
rFontCapabilities) const
@@ -119,7 +122,7 @@ class SAL_DLLPUBLIC_RTTI FreetypeFontInstance final : 
public LogicalFontInstance
 
     std::unique_ptr<FreetypeFont> mxFreetypeFont;
 
-    virtual hb_font_t* ImplInitHbFont() override;
+    virtual void ImplInitHbFont(hb_font_t*) override;
     virtual bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) 
const override;
 
     explicit FreetypeFontInstance(const vcl::font::PhysicalFontFace& rPFF, 
const vcl::font::FontSelectPattern& rFSP);
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 7833f988bd18..cddd59774b43 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -79,6 +79,8 @@ public:
     FontCharMapRef GetFontCharMap() const override;
     bool GetFontCapabilities(vcl::FontCapabilities&) const override;
 
+    virtual hb_blob_t*      GetHbTable(hb_tag_t nTag) const override;
+
 private:
     sal_IntPtr              mnId;
 
@@ -91,9 +93,10 @@ private:
     BYTE                    mnPitchAndFamily;
     bool                    mbAliasSymbolsHigh;
     bool                    mbAliasSymbolsLow;
+    mutable HDC             mhDC;
 
-    void                    ReadCmapTable( HDC ) const;
-    void                    GetFontCapabilities( HDC hDC ) const;
+    void                    ReadCmapTable() const;
+    void                    GetFontCapabilities() const;
 };
 
 /** Class that creates (and destroys) a compatible Device Context.
diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx
index 5f56fe6b0c5e..702bf7bf0b2a 100644
--- a/vcl/inc/win/winlayout.hxx
+++ b/vcl/inc/win/winlayout.hxx
@@ -57,7 +57,7 @@ public:
 private:
     explicit WinFontInstance(const WinFontFace&, const 
vcl::font::FontSelectPattern&);
 
-    hb_font_t* ImplInitHbFont() override;
+    virtual void ImplInitHbFont(hb_font_t*) override;
     bool ImplGetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const 
override;
 
     WinSalGraphics *m_pGraphics;
diff --git a/vcl/qt5/QtFont.cxx b/vcl/qt5/QtFont.cxx
index 07bf9f541f0b..384f56774ffd 100644
--- a/vcl/qt5/QtFont.cxx
+++ b/vcl/qt5/QtFont.cxx
@@ -131,27 +131,6 @@ QtFont::QtFont(const vcl::font::PhysicalFontFace& rPFF, 
const vcl::font::FontSel
     applyStyle(*this, rFSP.GetItalic());
 }
 
-static hb_blob_t* getFontTable(hb_face_t*, hb_tag_t nTableTag, void* pUserData)
-{
-    char pTagName[5];
-    LogicalFontInstance::DecodeOpenTypeTag(nTableTag, pTagName);
-
-    QtFont* pFont = static_cast<QtFont*>(pUserData);
-    QRawFont aRawFont(QRawFont::fromFont(*pFont));
-    QByteArray aTable = aRawFont.fontTable(pTagName);
-    const sal_uInt32 nLength = aTable.size();
-
-    hb_blob_t* pBlob = nullptr;
-    if (nLength > 0)
-        pBlob = hb_blob_create(aTable.data(), nLength, 
HB_MEMORY_MODE_DUPLICATE, nullptr, nullptr);
-    return pBlob;
-}
-
-hb_font_t* QtFont::ImplInitHbFont()
-{
-    return InitHbFont(hb_face_create_for_tables(getFontTable, this, nullptr));
-}
-
 bool QtFont::GetGlyphOutline(sal_GlyphId nId, basegfx::B2DPolyPolygon& 
rB2DPolyPoly, bool) const
 {
     rB2DPolyPoly.clear();
diff --git a/vcl/qt5/QtFontFace.cxx b/vcl/qt5/QtFontFace.cxx
index e97bee11d078..60e42422d454 100644
--- a/vcl/qt5/QtFontFace.cxx
+++ b/vcl/qt5/QtFontFace.cxx
@@ -253,4 +253,20 @@ bool 
QtFontFace::GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities) c
     return rFontCapabilities.oUnicodeRange || rFontCapabilities.oCodePageRange;
 }
 
+hb_blob_t* QtFontFace::GetHbTable(hb_tag_t nTag) const
+{
+    char pTagName[5] = { '\0' };
+    hb_tag_to_string(nTag, pTagName);
+
+    QFont aFont = CreateFont();
+    QRawFont aRawFont(QRawFont::fromFont(aFont));
+    QByteArray aTable = aRawFont.fontTable(pTagName);
+    const sal_uInt32 nLength = aTable.size();
+
+    hb_blob_t* pBlob = nullptr;
+    if (nLength > 0)
+        pBlob = hb_blob_create(aTable.data(), nLength, 
HB_MEMORY_MODE_DUPLICATE, nullptr, nullptr);
+    return pBlob;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx
index e5db219c3f8d..5e3e014c3cd4 100644
--- a/vcl/quartz/ctfonts.cxx
+++ b/vcl/quartz/ctfonts.cxx
@@ -232,16 +232,15 @@ bool CoreTextStyle::GetGlyphOutline(sal_GlyphId nId, 
basegfx::B2DPolyPolygon& rR
     return true;
 }
 
-static hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* 
pUserData)
+hb_blob_t* CoreTextFontFace::GetHbTable(hb_tag_t nTag) const
 {
     sal_uLong nLength = 0;
     unsigned char* pBuffer = nullptr;
-    CoreTextFontFace* pFont = static_cast<CoreTextFontFace*>(pUserData);
-    nLength = pFont->GetFontTable(nTableTag, nullptr);
+    nLength = GetFontTable(nTag, nullptr);
     if (nLength > 0)
     {
         pBuffer = new unsigned char[nLength];
-        pFont->GetFontTable(nTableTag, pBuffer);
+        GetFontTable(nTag, pBuffer);
     }
 
     hb_blob_t* pBlob = nullptr;
@@ -293,13 +292,9 @@ void CoreTextStyle::SetFontVariationsOnHBFont(hb_font_t* 
pHbFont) const
         hb_font_set_variations(pHbFont, aHBVariations.data(), 
aHBVariations.size());
 }
 
-hb_font_t* CoreTextStyle::ImplInitHbFont()
+void CoreTextStyle::ImplInitHbFont(hb_font_t* pHbFont)
 {
-    hb_face_t* pHbFace = hb_face_create_for_tables(getFontTable, 
GetFontFace(), nullptr);
-    hb_font_t* pHBFont = InitHbFont(pHbFace);
-    SetFontVariationsOnHBFont(pHBFont);
-
-    return pHBFont;
+    SetFontVariationsOnHBFont(pHbFont);
 }
 
 rtl::Reference<LogicalFontInstance> CoreTextFontFace::CreateFontInstance(const 
vcl::font::FontSelectPattern& rFSD) const
diff --git a/vcl/source/font/PhysicalFontFace.cxx 
b/vcl/source/font/PhysicalFontFace.cxx
index aef9054fdcc1..9969304e512a 100644
--- a/vcl/source/font/PhysicalFontFace.cxx
+++ b/vcl/source/font/PhysicalFontFace.cxx
@@ -36,6 +36,7 @@ namespace vcl::font
 
 PhysicalFontFace::PhysicalFontFace( const FontAttributes& rDFA )
     : FontAttributes( rDFA )
+    , mpHbFace(nullptr)
 {
     // StarSymbol is a unicode font, but it still deserves the symbol flag
     if( !IsSymbolFont() )
@@ -43,6 +44,12 @@ PhysicalFontFace::PhysicalFontFace( const FontAttributes& 
rDFA )
             SetSymbolFlag( true );
 }
 
+PhysicalFontFace::~PhysicalFontFace()
+{
+    if (mpHbFace)
+        hb_face_destroy(mpHbFace);
+}
+
 sal_Int32 PhysicalFontFace::CompareIgnoreSize( const PhysicalFontFace& rOther 
) const
 {
     // compare their width, weight, italic, style name and family name
@@ -201,6 +208,18 @@ bool PhysicalFontFace::IsBetterMatch( const 
FontSelectPattern& rFSP, FontMatchSt
 
     return true;
 }
+
+static hb_blob_t* getTable(hb_face_t*, hb_tag_t nTag, void* pUserData)
+{
+    return static_cast<const PhysicalFontFace*>(pUserData)->GetHbTable(nTag);
+}
+
+hb_face_t* PhysicalFontFace::GetHbFace() const
+{
+    if (mpHbFace == nullptr)
+        mpHbFace = hb_face_create_for_tables(getTable, 
const_cast<PhysicalFontFace*>(this), nullptr);
+    return mpHbFace;
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/vcl/source/font/fontinstance.cxx b/vcl/source/font/fontinstance.cxx
index 44c2c8cc757d..6b9f9b16ed26 100644
--- a/vcl/source/font/fontinstance.cxx
+++ b/vcl/source/font/fontinstance.cxx
@@ -51,15 +51,15 @@ LogicalFontInstance::~LogicalFontInstance()
         hb_font_destroy(m_pHbFont);
 }
 
-hb_font_t* LogicalFontInstance::InitHbFont(hb_face_t* pHbFace)
+hb_font_t* LogicalFontInstance::InitHbFont()
 {
+    hb_face_t* pHbFace = GetFontFace()->GetHbFace();
     assert(pHbFace);
     hb_font_t* pHbFont = hb_font_create(pHbFace);
     unsigned int nUPEM = hb_face_get_upem(pHbFace);
     hb_font_set_scale(pHbFont, nUPEM, nUPEM);
     hb_ot_font_set_funcs(pHbFont);
-    // hb_font_t keeps a reference to hb_face_t, so destroy this one.
-    hb_face_destroy(pHbFace);
+    ImplInitHbFont(pHbFont);
     return pHbFont;
 }
 
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx 
b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index 3b45eadd9658..5945a4813326 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -374,6 +374,24 @@ rtl::Reference<LogicalFontInstance> 
FreetypeFontFace::CreateFontInstance(const v
     return new FreetypeFontInstance(*this, rFSD);
 }
 
+hb_face_t* FreetypeFontFace::GetHbFace() const
+{
+    if (!mpHbFace)
+    {
+        auto* pFileName = mpFreetypeFontInfo->GetFontFileName().getStr();
+        auto nIndex = mpFreetypeFontInfo->GetFontFaceIndex();
+        hb_blob_t* pHbBlob = hb_blob_create_from_file(pFileName);
+        mpHbFace = hb_face_create(pHbBlob, nIndex);
+        hb_blob_destroy(pHbBlob);
+    }
+    return mpHbFace;
+}
+
+hb_blob_t* FreetypeFontFace::GetHbTable(hb_tag_t nTag) const
+{
+    return hb_face_reference_table(mpHbFace, nTag);
+}
+
 // FreetypeFont
 
 FreetypeFont::FreetypeFont(FreetypeFontInstance& rFontInstance, 
std::shared_ptr<FreetypeFontInfo> xFI)
diff --git a/vcl/unx/generic/glyphs/glyphcache.cxx 
b/vcl/unx/generic/glyphs/glyphcache.cxx
index 896585a87a27..b285bcc04c63 100644
--- a/vcl/unx/generic/glyphs/glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/glyphcache.cxx
@@ -75,30 +75,10 @@ FreetypeFontInstance::~FreetypeFontInstance()
 {
 }
 
-static hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* 
pUserData)
+void FreetypeFontInstance::ImplInitHbFont(hb_font_t* pHbFont)
 {
-    char pTagName[5];
-    LogicalFontInstance::DecodeOpenTypeTag( nTableTag, pTagName );
-
-    sal_uLong nLength = 0;
-    FreetypeFontInstance* pFontInstance = static_cast<FreetypeFontInstance*>( 
pUserData );
-    FreetypeFont& rFont = pFontInstance->GetFreetypeFont();
-    const char* pBuffer = reinterpret_cast<const char*>(
-        rFont.GetTable(pTagName, &nLength) );
-
-    hb_blob_t* pBlob = nullptr;
-    if (pBuffer != nullptr)
-        pBlob = hb_blob_create(pBuffer, nLength, HB_MEMORY_MODE_READONLY, 
nullptr, nullptr);
-
-    return pBlob;
-}
-
-hb_font_t* FreetypeFontInstance::ImplInitHbFont()
-{
-    hb_font_t* pRet = InitHbFont(hb_face_create_for_tables(getFontTable, this, 
nullptr));
     assert(mxFreetypeFont);
-    mxFreetypeFont->SetFontVariationsOnHBFont(pRet);
-    return pRet;
+    mxFreetypeFont->SetFontVariationsOnHBFont(pHbFont);
 }
 
 bool FreetypeFontInstance::ImplGetGlyphBoundRect(sal_GlyphId nId, 
tools::Rectangle& rRect, bool bVertical) const
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 3a2eb226114a..2135c7a02860 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -634,7 +634,8 @@ WinFontFace::WinFontFace( const FontAttributes& rDFS,
     meWinCharSet( eWinCharSet ),
     mnPitchAndFamily( nPitchAndFamily ),
     mbAliasSymbolsHigh( false ),
-    mbAliasSymbolsLow( false )
+    mbAliasSymbolsLow( false ),
+    mhDC( nullptr )
 {
     if( eWinCharSet == SYMBOL_CHARSET )
     {
@@ -677,16 +678,93 @@ rtl::Reference<LogicalFontInstance> 
WinFontFace::CreateFontInstance(const vcl::f
     return new WinFontInstance(*this, rFSD);
 }
 
+namespace
+{
+struct BlobReference
+{
+    hb_blob_t* mpBlob;
+    BlobReference(hb_blob_t* pBlob)
+        : mpBlob(pBlob)
+    {
+        hb_blob_reference(mpBlob);
+    }
+    BlobReference(BlobReference&& other) noexcept
+        : mpBlob(other.mpBlob)
+    {
+        other.mpBlob = nullptr;
+    }
+    BlobReference& operator=(BlobReference&& other)
+    {
+        std::swap(mpBlob, other.mpBlob);
+        return *this;
+    }
+    BlobReference(const BlobReference& other) = delete;
+    BlobReference& operator=(BlobReference& other) = delete;
+    ~BlobReference() { hb_blob_destroy(mpBlob); }
+};
+}
+
+using BlobCacheKey = std::pair<sal_IntPtr, hb_tag_t>;
+
+namespace
+{
+struct BlobCacheKeyHash
+{
+    std::size_t operator()(BlobCacheKey const& rKey) const
+    {
+        std::size_t seed = 0;
+        o3tl::hash_combine(seed, rKey.first);
+        o3tl::hash_combine(seed, rKey.second);
+        return seed;
+    }
+};
+}
+
+hb_blob_t* WinFontFace::GetHbTable(hb_tag_t nTag) const
+{
+    static o3tl::lru_map<BlobCacheKey, BlobReference, BlobCacheKeyHash> 
gCache(50);
+    BlobCacheKey aCacheKey{ GetFontId(), nTag };
+    auto it = gCache.find(aCacheKey);
+    if (it != gCache.end())
+    {
+        hb_blob_reference(it->second.mpBlob);
+        return it->second.mpBlob;
+    }
+
+    assert(mhDC);
+
+    sal_uLong nLength = 0;
+    unsigned char* pBuffer = nullptr;
+
+    nLength = ::GetFontData(mhDC, OSL_NETDWORD(nTag), 0, nullptr, 0);
+    if (nLength > 0 && nLength != GDI_ERROR)
+    {
+        pBuffer = new unsigned char[nLength];
+        ::GetFontData(mhDC, OSL_NETDWORD(nTag), 0, pBuffer, nLength);
+    }
+
+    hb_blob_t* pBlob = nullptr;
+
+    if (pBuffer)
+        pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), 
nLength, HB_MEMORY_MODE_READONLY,
+                               pBuffer, [](void* data) { delete[] 
static_cast<unsigned char*>(data); });
+
+    gCache.insert({ aCacheKey, BlobReference(pBlob) });
+    return pBlob;
+}
+
 static DWORD CalcTag( const char p[5]) { return 
(p[0]+(p[1]<<8)+(p[2]<<16)+(p[3]<<24)); }
 
 void WinFontFace::UpdateFromHDC( HDC hDC ) const
 {
+    mhDC = hDC;
+
     // short circuit if already initialized
     if( mxUnicodeMap.is() )
         return;
 
-    ReadCmapTable( hDC );
-    GetFontCapabilities( hDC );
+    ReadCmapTable();
+    GetFontCapabilities();
 }
 
 FontCharMapRef WinFontFace::GetFontCharMap() const
@@ -700,7 +778,7 @@ bool WinFontFace::GetFontCapabilities(vcl::FontCapabilities 
&rFontCapabilities)
     return rFontCapabilities.oUnicodeRange || rFontCapabilities.oCodePageRange;
 }
 
-void WinFontFace::ReadCmapTable( HDC hDC ) const
+void WinFontFace::ReadCmapTable() const
 {
     if( mxUnicodeMap.is() )
         return;
@@ -708,7 +786,7 @@ void WinFontFace::ReadCmapTable( HDC hDC ) const
     bool bIsSymbolFont = (meWinCharSet == SYMBOL_CHARSET);
     // get the CMAP table from the font which is selected into the DC
     const DWORD nCmapTag = CalcTag( "cmap" );
-    const RawFontData aRawFontData( hDC, nCmapTag );
+    const RawFontData aRawFontData( mhDC, nCmapTag );
     // parse the CMAP table if available
     if( aRawFontData.get() ) {
         CmapResult aResult;
@@ -727,7 +805,7 @@ void WinFontFace::ReadCmapTable( HDC hDC ) const
     }
 }
 
-void WinFontFace::GetFontCapabilities( HDC hDC ) const
+void WinFontFace::GetFontCapabilities() const
 {
     // read this only once per font
     if( mbFontCapabilitiesRead )
@@ -737,12 +815,12 @@ void WinFontFace::GetFontCapabilities( HDC hDC ) const
 
     // OS/2 table
     const DWORD OS2Tag = CalcTag( "OS/2" );
-    DWORD nLength = ::GetFontData( hDC, OS2Tag, 0, nullptr, 0 );
+    DWORD nLength = ::GetFontData( mhDC, OS2Tag, 0, nullptr, 0 );
     if( (nLength != GDI_ERROR) && nLength )
     {
         std::vector<unsigned char> aTable( nLength );
         unsigned char* pTable = aTable.data();
-        ::GetFontData( hDC, OS2Tag, 0, pTable, nLength );
+        ::GetFontData( mhDC, OS2Tag, 0, pTable, nLength );
         vcl::getTTCoverage(maFontCapabilities.oUnicodeRange, 
maFontCapabilities.oCodePageRange, pTable, nLength);
     }
 }
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 66e9ac3e3597..b9134312bac1 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -46,7 +46,6 @@
 
 #include <rtl/character.hxx>
 
-#include <o3tl/hash_combine.hxx>
 #include <algorithm>
 
 #include <shlwapi.h>
@@ -167,98 +166,9 @@ float WinFontInstance::getHScale() const
     return nWidth / nHeight;
 }
 
-namespace
-{
-struct BlobReference
-{
-    hb_blob_t* mpBlob;
-    BlobReference(hb_blob_t* pBlob)
-        : mpBlob(pBlob)
-    {
-        hb_blob_reference(mpBlob);
-    }
-    BlobReference(BlobReference&& other) noexcept
-        : mpBlob(other.mpBlob)
-    {
-        other.mpBlob = nullptr;
-    }
-    BlobReference& operator=(BlobReference&& other)
-    {
-        std::swap(mpBlob, other.mpBlob);
-        return *this;
-    }
-    BlobReference(const BlobReference& other) = delete;
-    BlobReference& operator=(BlobReference& other) = delete;
-    ~BlobReference() { hb_blob_destroy(mpBlob); }
-};
-}
-
-using BlobCacheKey = std::pair<rtl::Reference<vcl::font::PhysicalFontFace>, 
hb_tag_t>;
-
-namespace
-{
-struct BlobCacheKeyHash
-{
-    std::size_t operator()(BlobCacheKey const& rKey) const
-    {
-        std::size_t seed = 0;
-        o3tl::hash_combine(seed, rKey.first.get());
-        o3tl::hash_combine(seed, rKey.second);
-        return seed;
-    }
-};
-}
-
-static hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* 
pUserData)
-{
-    static o3tl::lru_map<BlobCacheKey, BlobReference, BlobCacheKeyHash> 
gCache(50);
-
-    WinFontInstance* pFont = static_cast<WinFontInstance*>(pUserData);
-
-    BlobCacheKey cacheKey{ 
rtl::Reference<vcl::font::PhysicalFontFace>(pFont->GetFontFace()),
-                           nTableTag };
-    auto it = gCache.find(cacheKey);
-    if (it != gCache.end())
-    {
-        hb_blob_reference(it->second.mpBlob);
-        return it->second.mpBlob;
-    }
-
-    HDC hDC = pFont->GetGraphics()->getHDC();
-    HFONT hFont = pFont->GetHFONT();
-    assert(hDC);
-    assert(hFont);
-
-    sal_uLong nLength = 0;
-    unsigned char* pBuffer = nullptr;
-
-    HGDIOBJ hOrigFont = SelectObject(hDC, hFont);
-    nLength = ::GetFontData(hDC, OSL_NETDWORD(nTableTag), 0, nullptr, 0);
-    if (nLength > 0 && nLength != GDI_ERROR)
-    {
-        pBuffer = new unsigned char[nLength];
-        ::GetFontData(hDC, OSL_NETDWORD(nTableTag), 0, pBuffer, nLength);
-    }
-    SelectObject(hDC, hOrigFont);
-
-    if (!pBuffer)
-    { // Cache also failures.
-        gCache.insert({ cacheKey, BlobReference(nullptr) });
-        return nullptr;
-    }
-
-    hb_blob_t* pBlob
-        = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, 
HB_MEMORY_MODE_READONLY,
-                         pBuffer, [](void* data) { delete[] 
static_cast<unsigned char*>(data); });
-    gCache.insert({ cacheKey, BlobReference(pBlob) });
-    return pBlob;
-}
-
-hb_font_t* WinFontInstance::ImplInitHbFont()
+void WinFontInstance::ImplInitHbFont(hb_font_t* pHbFont)
 {
     assert(m_pGraphics);
-    hb_font_t* pHbFont = InitHbFont(hb_face_create_for_tables(getFontTable, 
this, nullptr));
-
     // Calculate the AverageWidthFactor, see LogicalFontInstance::GetScale().
     if (GetFontSelectPattern().mnWidth)
     {
@@ -282,8 +192,6 @@ hb_font_t* WinFontInstance::ImplInitHbFont()
 
         SetAverageWidthFactor(nUPEM / aFontMetric.tmAveCharWidth);
     }
-
-    return pHbFont;
 }
 
 void WinFontInstance::SetGraphics(WinSalGraphics* pGraphics)

Reply via email to