summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorKhaled Hosny <khaled@aliftype.com>2022-09-03 03:14:08 +0200
committerخالد حسني <khaled@aliftype.com>2022-09-04 02:10:17 +0200
commitdc92a4d973086ce8a6a5f75ba0f4d4c9ca05537a (patch)
tree9380a4db2bb8ee1ea131b62c6cfab2957ccd5fef /vcl
parentb87f4dfd33b48bb2f6cec9732ace51f2a272308d (diff)
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: خالد حسني <khaled@aliftype.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/font/PhysicalFontFace.hxx9
-rw-r--r--vcl/inc/fontinstance.hxx17
-rw-r--r--vcl/inc/qt5/QtFont.hxx2
-rw-r--r--vcl/inc/qt5/QtFontFace.hxx3
-rw-r--r--vcl/inc/quartz/salgdi.h4
-rw-r--r--vcl/inc/unx/freetype_glyphcache.hxx5
-rw-r--r--vcl/inc/win/salgdi.h7
-rw-r--r--vcl/inc/win/winlayout.hxx2
-rw-r--r--vcl/qt5/QtFont.cxx21
-rw-r--r--vcl/qt5/QtFontFace.cxx16
-rw-r--r--vcl/quartz/ctfonts.cxx15
-rw-r--r--vcl/source/font/PhysicalFontFace.cxx19
-rw-r--r--vcl/source/font/fontinstance.cxx6
-rw-r--r--vcl/unx/generic/glyphs/freetype_glyphcache.cxx18
-rw-r--r--vcl/unx/generic/glyphs/glyphcache.cxx24
-rw-r--r--vcl/win/gdi/salfont.cxx94
-rw-r--r--vcl/win/gdi/winlayout.cxx94
17 files changed, 177 insertions, 179 deletions
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)