Rebased ref, commits from common ancestor: commit ac9d7d4157813fcf43dd41043981c4bb27d2cc33 Author: Khaled Hosny <khaledho...@eglug.org> AuthorDate: Tue Sep 3 14:40:42 2019 +0200 Commit: Khaled Hosny <khaledho...@eglug.org> CommitDate: Wed Sep 11 12:40:33 2019 +0200
Consolidate GetFontCapabilities() All implementations were basically doing the same thing. Move to PhysicalFontFace and use HarfBuzz API to get the raw OpeenType table data. Change-Id: Ia5ac0d1ba6299f86e90e1b0dac34ba7672855ec0 diff --git a/vcl/inc/PhysicalFontFace.hxx b/vcl/inc/PhysicalFontFace.hxx index 3992bb91bf41..679420a05fd1 100644 --- a/vcl/inc/PhysicalFontFace.hxx +++ b/vcl/inc/PhysicalFontFace.hxx @@ -22,6 +22,7 @@ #include <hb.h> +#include <vcl/fontcapabilities.hxx> #include <salhelper/simplereferenceobject.hxx> #include <rtl/ref.hxx> #include <vcl/dllapi.h> @@ -70,6 +71,7 @@ public: sal_Int32 CompareIgnoreSize( const PhysicalFontFace& ) const; const FontCharMapRef& GetCharMap() const; + bool GetCapabilities(vcl::FontCapabilities &rCapabilities) const; hb_face_t* GetHbFace() const; virtual hb_blob_t* GetHbTable(hb_tag_t nTag) const = 0; @@ -84,6 +86,8 @@ protected: mutable hb_face_t* mpHbFace; mutable FontCharMapRef mxCharMap; + mutable bool mbCapabilitiesRead; + mutable vcl::FontCapabilities maCapabilities; }; #endif // INCLUDED_VCL_INC_PHYSICALFONTFACE_HXX diff --git a/vcl/inc/qt5/Qt5FontFace.hxx b/vcl/inc/qt5/Qt5FontFace.hxx index a179438cf2a5..03884fc31df9 100644 --- a/vcl/inc/qt5/Qt5FontFace.hxx +++ b/vcl/inc/qt5/Qt5FontFace.hxx @@ -42,8 +42,6 @@ public: int GetFontTable(const char pTagName[5], unsigned char*) const; - bool GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities) const; - rtl::Reference<LogicalFontInstance> CreateFontInstance(const FontSelectPattern& rFSD) const override; @@ -55,8 +53,6 @@ protected: private: const QString m_aFontId; - mutable vcl::FontCapabilities m_aFontCapabilities; - mutable bool m_bFontCapabilitiesRead; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index 3be470f0caf6..540d695a3a11 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -67,16 +67,12 @@ public: int GetFontTable( uint32_t nTagCode, unsigned char* ) const; int GetFontTable( const char pTagName[5], unsigned char* ) const; - bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const; - rtl::Reference<LogicalFontInstance> CreateFontInstance(const FontSelectPattern&) const override; hb_blob_t* GetHbTable(hb_tag_t nTag) const override; private: const sal_IntPtr mnFontId; - mutable vcl::FontCapabilities maFontCapabilities; - mutable bool mbFontCapabilitiesRead; }; class CoreTextStyle final : public LogicalFontInstance diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx index c072752db6a7..12800ae0458c 100644 --- a/vcl/inc/unx/glyphcache.hxx +++ b/vcl/inc/unx/glyphcache.hxx @@ -107,7 +107,6 @@ public: void GetFontMetric(ImplFontMetricDataRef const &) const; const unsigned char* GetTable( const char* pName, sal_uLong* pLength ) const; - bool GetFontCapabilities(vcl::FontCapabilities &) const; bool GetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const; bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const; diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 0cc2fd05ba2d..5eeb0747c253 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -71,24 +71,16 @@ public: BYTE GetCharSet() const { return meWinCharSet; } BYTE GetPitchAndFamily() const { return mnPitchAndFamily; } - bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const; - hb_blob_t* GetHbTable(hb_tag_t nTag) const override; private: sal_IntPtr mnId; - // some members that are initialized lazily when the font gets selected into a HDC - mutable bool mbFontCapabilitiesRead; - mutable vcl::FontCapabilities maFontCapabilities; - BYTE meWinCharSet; BYTE mnPitchAndFamily; bool mbAliasSymbolsHigh; bool mbAliasSymbolsLow; - void GetFontCapabilities( HDC hDC ) const; - mutable HDC mhDC; }; diff --git a/vcl/qt5/Qt5FontFace.cxx b/vcl/qt5/Qt5FontFace.cxx index 4c4bbb7ef6de..dcf7cbf6611c 100644 --- a/vcl/qt5/Qt5FontFace.cxx +++ b/vcl/qt5/Qt5FontFace.cxx @@ -128,7 +128,6 @@ Qt5FontFace* Qt5FontFace::fromQFontDatabase(const QString& aFamily, const QStrin Qt5FontFace::Qt5FontFace(const FontAttributes& rFA, const QString& rFontID) : PhysicalFontFace(rFA) , m_aFontId(rFontID) - , m_bFontCapabilitiesRead(false) { } @@ -140,31 +139,6 @@ Qt5FontFace::CreateFontInstance(const FontSelectPattern& rFSD) const return new Qt5Font(*this, rFSD); } -bool Qt5FontFace::GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities) const -{ - // read this only once per font - if (m_bFontCapabilitiesRead) - { - rFontCapabilities = m_aFontCapabilities; - return rFontCapabilities.oUnicodeRange || rFontCapabilities.oCodePageRange; - } - m_bFontCapabilitiesRead = true; - - QFont aFont; - aFont.fromString(m_aFontId); - QRawFont aRawFont(QRawFont::fromFont(aFont)); - QByteArray aOS2Table = aRawFont.fontTable("OS/2"); - if (!aOS2Table.isEmpty()) - { - vcl::getTTCoverage(m_aFontCapabilities.oUnicodeRange, m_aFontCapabilities.oCodePageRange, - reinterpret_cast<const unsigned char*>(aOS2Table.data()), - aOS2Table.size()); - } - - rFontCapabilities = m_aFontCapabilities; - return rFontCapabilities.oUnicodeRange || rFontCapabilities.oCodePageRange; -} - hb_blob_t* Qt5FontFace::GetHbTable(hb_tag_t nTag) const { char pName[5]; diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx index 63072b1ed740..13a559214218 100644 --- a/vcl/qt5/Qt5Graphics_Text.cxx +++ b/vcl/qt5/Qt5Graphics_Text.cxx @@ -78,8 +78,7 @@ bool Qt5Graphics::GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities) { if (!m_pTextStyle[0]) return false; - return static_cast<const Qt5FontFace*>(m_pTextStyle[0]->GetFontFace()) - ->GetFontCapabilities(rFontCapabilities); + return m_pTextStyle[0]->GetFontFace()->GetCapabilities(rFontCapabilities); } void Qt5Graphics::GetDevFontList(PhysicalFontCollection* pPFC) diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx index 2bc08551c1cc..de35edf51341 100644 --- a/vcl/quartz/salgdi.cxx +++ b/vcl/quartz/salgdi.cxx @@ -99,7 +99,6 @@ bool CoreTextGlyphFallbackSubstititution::FindFontSubstitute(FontSelectPattern& CoreTextFontFace::CoreTextFontFace( const FontAttributes& rDFA, sal_IntPtr nFontId ) : PhysicalFontFace( rDFA ) , mnFontId( nFontId ) - , mbFontCapabilitiesRead( false ) { } @@ -112,35 +111,6 @@ sal_IntPtr CoreTextFontFace::GetFontId() const return mnFontId; } -bool CoreTextFontFace::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const -{ - // read this only once per font - if( mbFontCapabilitiesRead ) - { - rFontCapabilities = maFontCapabilities; - return rFontCapabilities.oUnicodeRange || rFontCapabilities.oCodePageRange; - } - mbFontCapabilitiesRead = true; - - int nBufSize = GetFontTable( "OS/2", nullptr ); - if( nBufSize > 0 ) - { - // allocate a buffer for the OS/2 raw data - std::vector<unsigned char> aBuffer( nBufSize ); - // get the OS/2 raw data - const int nRawLength = GetFontTable( "OS/2", aBuffer.data() ); - if( nRawLength > 0 ) - { - const unsigned char* pOS2Table = aBuffer.data(); - vcl::getTTCoverage( maFontCapabilities.oUnicodeRange, - maFontCapabilities.oCodePageRange, - pOS2Table, nRawLength); - } - } - rFontCapabilities = maFontCapabilities; - return rFontCapabilities.oUnicodeRange || rFontCapabilities.oCodePageRange; -} - AquaSalGraphics::AquaSalGraphics() : mpXorEmulation( nullptr ) , mnXorMode( 0 ) @@ -483,7 +453,7 @@ bool AquaSalGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabiliti if (!mpTextStyle[0]) return false; - return static_cast<const CoreTextFontFace*>(mpTextStyle[0]->GetFontFace())->GetFontCapabilities(rFontCapabilities); + return mpTextStyle[0]->GetFontFace()->GetCapabilities(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 997b1c155160..305a06a4edcf 100644 --- a/vcl/source/font/PhysicalFontFace.cxx +++ b/vcl/source/font/PhysicalFontFace.cxx @@ -27,6 +27,7 @@ #include <fontselect.hxx> #include <impfontcharmap.hxx> +#include <sft.hxx> #include <PhysicalFontFace.hxx> PhysicalFontFace::PhysicalFontFace( const FontAttributes& rDFA ) @@ -34,6 +35,7 @@ PhysicalFontFace::PhysicalFontFace( const FontAttributes& rDFA ) , mnWidth(0) , mnHeight(0) , mpHbFace(nullptr) + , mbCapabilitiesRead(false) { // StarSymbol is a unicode font, but it still deserves the symbol flag if( !IsSymbolFont() ) @@ -248,4 +250,30 @@ const FontCharMapRef& PhysicalFontFace::GetCharMap() const return mxCharMap; } +bool PhysicalFontFace::GetCapabilities(vcl::FontCapabilities &rCapabilities) const +{ + // Read this only once. + if (mbCapabilitiesRead) + { + rCapabilities = maCapabilities; + return rCapabilities.oUnicodeRange || rCapabilities.oCodePageRange; + } + + mbCapabilitiesRead = true; + + hb_blob_t* pBlob = hb_face_reference_table(mpHbFace, HB_TAG('O', 'S', '/', '2')); + const unsigned char* pData = reinterpret_cast<const unsigned char*>(hb_blob_get_data(pBlob, nullptr)); + size_t nSize = hb_blob_get_length(pBlob); + if (nSize > 0) + { + vcl::getTTCoverage(maCapabilities.oUnicodeRange, + maCapabilities.oCodePageRange, + pData, nSize); + } + hb_blob_destroy(pBlob); + + rCapabilities = maCapabilities; + return rCapabilities.oUnicodeRange || rCapabilities.oCodePageRange; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx index cc63b05ad394..410ff9366cdc 100644 --- a/vcl/unx/generic/gdi/cairotextrender.cxx +++ b/vcl/unx/generic/gdi/cairotextrender.cxx @@ -378,7 +378,7 @@ bool CairoTextRender::GetFontCapabilities(vcl::FontCapabilities &rGetImplFontCap { if (!mpFreetypeFont[0]) return false; - return mpFreetypeFont[0]->GetFontCapabilities(rGetImplFontCapabilities); + return mpFreetypeFont[0]->GetFontInstance()->GetFontFace()->GetCapabilities(rGetImplFontCapabilities); } // SalGraphics diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx index d52da62da4c0..fda97f4a0c87 100644 --- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx +++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx @@ -706,25 +706,6 @@ bool FreetypeFont::GetAntialiasAdvice() const return !mpFontInstance->GetFontSelectPattern().mbNonAntialiased && (mnPrioAntiAlias > 0); } -bool FreetypeFont::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const -{ - bool bRet = false; - - sal_uLong nLength = 0; - - // load OS/2 table - const FT_Byte* pOS2 = mpFontInfo->GetTable("OS/2", &nLength); - if (pOS2) - { - bRet = vcl::getTTCoverage( - rFontCapabilities.oUnicodeRange, - rFontCapabilities.oCodePageRange, - pOS2, nLength); - } - - return bRet; -} - // outline stuff class PolyArgs diff --git a/vcl/unx/generic/print/genpspgraphics.cxx b/vcl/unx/generic/print/genpspgraphics.cxx index a8a08f263ab3..e7e3cce5c17a 100644 --- a/vcl/unx/generic/print/genpspgraphics.cxx +++ b/vcl/unx/generic/print/genpspgraphics.cxx @@ -614,7 +614,7 @@ bool GenPspGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilitie { if (!m_pFreetypeFont[0]) return false; - return m_pFreetypeFont[0]->GetFontCapabilities(rFontCapabilities); + return m_pFreetypeFont[0]->GetFontInstance()->GetFontFace()->GetCapabilities(rFontCapabilities); } void GenPspGraphics::SetFont(LogicalFontInstance *pFontInstance, int nFallbackLevel) diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index f9b7646bdd7f..ddd4599c3b82 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -585,7 +585,6 @@ WinFontFace::WinFontFace( const FontAttributes& rDFS, BYTE eWinCharSet, BYTE nPitchAndFamily ) : PhysicalFontFace( rDFS ), mnId( 0 ), - mbFontCapabilitiesRead( false ), meWinCharSet( eWinCharSet ), mnPitchAndFamily( nPitchAndFamily ), mbAliasSymbolsHigh( false ), @@ -656,33 +655,6 @@ void WinFontFace::UpdateFromHDC( HDC hDC ) const return; mhDC = hDC; - GetFontCapabilities( hDC ); -} - -bool WinFontFace::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const -{ - rFontCapabilities = maFontCapabilities; - return rFontCapabilities.oUnicodeRange || rFontCapabilities.oCodePageRange; -} - -void WinFontFace::GetFontCapabilities( HDC hDC ) const -{ - // read this only once per font - if( mbFontCapabilitiesRead ) - return; - - mbFontCapabilitiesRead = true; - - // OS/2 table - const DWORD OS2Tag = CalcTag( "OS/2" ); - DWORD nLength = ::GetFontData( hDC, OS2Tag, 0, nullptr, 0 ); - if( (nLength != GDI_ERROR) && nLength ) - { - std::vector<unsigned char> aTable( nLength ); - unsigned char* pTable = &aTable[0]; - ::GetFontData( hDC, OS2Tag, 0, pTable, nLength ); - vcl::getTTCoverage(maFontCapabilities.oUnicodeRange, maFontCapabilities.oCodePageRange, pTable, nLength); - } } void WinSalGraphics::SetTextColor( Color nColor ) @@ -949,7 +921,7 @@ bool WinSalGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilitie { if (!mpWinFontEntry[0]) return false; - return mpWinFontEntry[0]->GetFontFace()->GetFontCapabilities(rFontCapabilities); + return mpWinFontEntry[0]->GetFontFace()->GetCapabilities(rFontCapabilities); } static int CALLBACK SalEnumFontsProcExW( const LOGFONTW* lpelfe, commit befc8853fac9fd1265ebd4898bf63b26e62ac9e7 Author: Khaled Hosny <khaledho...@eglug.org> AuthorDate: Tue Sep 3 13:21:50 2019 +0200 Commit: Khaled Hosny <khaledho...@eglug.org> CommitDate: Wed Sep 11 12:38:18 2019 +0200 Drop SalGraphics::GetGlyphWidths() It was used only on two places. One use is replaced with a new LogicalFontInstance::GetGlyphWidth() (backed by HarfBuzz font) and the other is replaced by getting glyph widths while subsetting the font. PDFFontCache is now unused, so dropped as well. Change-Id: I9741f17c0a5626faa952dd0d417cc786cbc877cd diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index c8e4aa75dccb..71d3c9d8fe64 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -295,7 +295,6 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/gdi/oldprintadaptor \ vcl/source/gdi/pdfbuildin_fonts \ vcl/source/gdi/pdfextoutdevdata \ - vcl/source/gdi/pdffontcache \ vcl/source/gdi/pdfwriter \ vcl/source/gdi/pdfwriter_impl2 \ vcl/source/gdi/pdfwriter_impl \ diff --git a/vcl/headless/svptext.cxx b/vcl/headless/svptext.cxx index e4b625b365cb..36e515b18518 100644 --- a/vcl/headless/svptext.cxx +++ b/vcl/headless/svptext.cxx @@ -84,14 +84,6 @@ void SvpSalGraphics::FreeEmbedFontData( const void* pData, long nLen ) m_aTextRenderImpl.FreeEmbedFontData(pData, nLen); } -void SvpSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - Ucs2UIntMap& rUnicodeEnc ) -{ - m_aTextRenderImpl.GetGlyphWidths(pFont, bVertical, rWidths, rUnicodeEnc); -} - std::unique_ptr<GenericSalLayout> SvpSalGraphics::GetTextLayout(int nFallbackLevel) { if (utl::ConfigManager::IsFuzzing()) diff --git a/vcl/inc/fontinstance.hxx b/vcl/inc/fontinstance.hxx index 5e234df72e0c..423dbe9fb7d0 100644 --- a/vcl/inc/fontinstance.hxx +++ b/vcl/inc/fontinstance.hxx @@ -71,6 +71,7 @@ public: // TODO: make data members private const PhysicalFontFace* GetFontFace() const { return m_pFontFace.get(); } const ImplFontCache* GetFontCache() const { return mpFontCache; } + double GetGlyphWidth(sal_GlyphId, bool, bool); bool GetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool); virtual bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const = 0; diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index b0e4aac4adad..a132c17a26e8 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -188,10 +188,6 @@ public: ) override; virtual const void* GetEmbedFontData(const PhysicalFontFace*, long* pDataLen) override; virtual void FreeEmbedFontData( const void* pData, long nDataLen ) override; - virtual void GetGlyphWidths( const PhysicalFontFace*, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - Ucs2UIntMap& rUnicodeEnc ) override; virtual std::unique_ptr<GenericSalLayout> GetTextLayout(int nFallbackLevel) override; virtual void DrawTextLayout( const GenericSalLayout& ) override; diff --git a/vcl/inc/impglyphitem.hxx b/vcl/inc/impglyphitem.hxx index b379674548d5..d84bff77e662 100644 --- a/vcl/inc/impglyphitem.hxx +++ b/vcl/inc/impglyphitem.hxx @@ -90,6 +90,7 @@ public: inline bool GetGlyphBoundRect(tools::Rectangle&) const; inline bool GetGlyphOutline(basegfx::B2DPolyPolygon&) const; inline void dropGlyph(); + inline double nativeWidth(bool bPS) const; // Unshaped width from the font. sal_GlyphId glyphId() const { return m_aGlyphId; } int charCount() const { return m_nCharCount; } @@ -114,6 +115,11 @@ void GlyphItem::dropGlyph() m_nFlags |= GlyphItemFlags::IS_DROPPED; } +double GlyphItem::nativeWidth(bool bPS) const +{ + return m_pFontInstance->GetGlyphWidth(m_aGlyphId, IsVertical(), bPS); +} + class SalLayoutGlyphsImpl : public std::vector<GlyphItem> { friend class GenericSalLayout; diff --git a/vcl/inc/qt5/Qt5Graphics.hxx b/vcl/inc/qt5/Qt5Graphics.hxx index a7c7aaa727ac..7d6cb63a4a77 100644 --- a/vcl/inc/qt5/Qt5Graphics.hxx +++ b/vcl/inc/qt5/Qt5Graphics.hxx @@ -192,9 +192,6 @@ public: virtual const void* GetEmbedFontData(const PhysicalFontFace*, long* pDataLen) override; virtual void FreeEmbedFontData(const void* pData, long nDataLen) override; - virtual void GetGlyphWidths(const PhysicalFontFace*, bool bVertical, - std::vector<sal_Int32>& rWidths, Ucs2UIntMap& rUnicodeEnc) override; - virtual std::unique_ptr<GenericSalLayout> GetTextLayout(int nFallbackLevel) override; virtual void DrawTextLayout(const GenericSalLayout&) override; }; diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index 68c9aff47757..3be470f0caf6 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -377,11 +377,6 @@ public: // frees the font data again virtual void FreeEmbedFontData( const void* pData, long nDataLen ) override; - virtual void GetGlyphWidths( const PhysicalFontFace*, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - Ucs2UIntMap& rUnicodeEnc ) override; - virtual std::unique_ptr<GenericSalLayout> GetTextLayout(int nFallbackLevel) override; virtual void DrawTextLayout( const GenericSalLayout& ) override; diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx index a504fb9fa071..8e7a3d3c153f 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -30,7 +30,6 @@ #include <config_cairo_canvas.h> -#include <map> #include <vector> class PhysicalFontCollection; @@ -58,7 +57,6 @@ namespace basegfx { } typedef sal_Unicode sal_Ucs; // TODO: use sal_UCS4 instead of sal_Unicode -typedef std::map< sal_Ucs, sal_uInt32 > Ucs2UIntMap; // note: if you add any new methods to class SalGraphics using coordinates // make sure they have a corresponding protected pure virtual method @@ -179,16 +177,6 @@ public: // free the font data again virtual void FreeEmbedFontData( const void* pData, long nDataLen ) = 0; - // get the same widths as in CreateFontSubset - // in case of an embeddable font also fill the mapping - // between unicode and glyph id - // leave widths vector and mapping untouched in case of failure - virtual void GetGlyphWidths( - const PhysicalFontFace* pFont, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - Ucs2UIntMap& rUnicodeEnc ) = 0; - virtual std::unique_ptr<GenericSalLayout> GetTextLayout(int nFallbackLevel) = 0; virtual void DrawTextLayout( const GenericSalLayout& ) = 0; diff --git a/vcl/inc/textrender.hxx b/vcl/inc/textrender.hxx index 742d8445299b..7484a92c48a8 100644 --- a/vcl/inc/textrender.hxx +++ b/vcl/inc/textrender.hxx @@ -53,11 +53,6 @@ public: virtual const void* GetEmbedFontData(const PhysicalFontFace*, long* pDataLen) = 0; virtual void FreeEmbedFontData( const void* pData, long nDataLen ) = 0; - virtual void GetGlyphWidths( - const PhysicalFontFace*, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - Ucs2UIntMap& rUnicodeEnc ) = 0; virtual std::unique_ptr<GenericSalLayout> GetTextLayout(int nFallbackLevel) = 0; diff --git a/vcl/inc/unx/cairotextrender.hxx b/vcl/inc/unx/cairotextrender.hxx index 33b1a622945e..030f10b65de7 100644 --- a/vcl/inc/unx/cairotextrender.hxx +++ b/vcl/inc/unx/cairotextrender.hxx @@ -65,11 +65,6 @@ public: virtual const void* GetEmbedFontData(const PhysicalFontFace*, long* pDataLen) override; virtual void FreeEmbedFontData( const void* pData, long nDataLen ) override; - virtual void GetGlyphWidths( - const PhysicalFontFace*, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - Ucs2UIntMap& rUnicodeEnc ) override; virtual std::unique_ptr<GenericSalLayout> GetTextLayout(int nFallbackLevel) override; diff --git a/vcl/inc/unx/fontmanager.hxx b/vcl/inc/unx/fontmanager.hxx index 8d388013144a..c20864d6c954 100644 --- a/vcl/inc/unx/fontmanager.hxx +++ b/vcl/inc/unx/fontmanager.hxx @@ -42,7 +42,6 @@ class FontSubsetInfo; class FontConfigFontOptions; class FontSelectPattern; class GenericUnixSalData; -class PhysicalFontFace; namespace psp { class PPDParser; @@ -272,10 +271,6 @@ public: sal_Int32* pWidths, int nGlyphs ); - void getGlyphWidths( const PhysicalFontFace* pFace, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc ); // font administration functions diff --git a/vcl/inc/unx/genpspgraphics.h b/vcl/inc/unx/genpspgraphics.h index 44ca12ebc458..8f64eea4e076 100644 --- a/vcl/inc/unx/genpspgraphics.h +++ b/vcl/inc/unx/genpspgraphics.h @@ -55,10 +55,6 @@ public: static void DoFreeEmbedFontData( const void* pData, long nLen ); // helper methods for sharing with X11SalGraphics - static void DoGetGlyphWidths( const PhysicalFontFace*, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - Ucs2UIntMap& rUnicodeEnc ); static FontAttributes Info2FontAttributes( const psp::FastPrintFontInfo& ); static void AnnounceFonts( PhysicalFontCollection*, @@ -106,10 +102,6 @@ public: FontSubsetInfo& rInfo ) override; virtual const void* GetEmbedFontData(const PhysicalFontFace*, long* pDataLen) override; virtual void FreeEmbedFontData( const void* pData, long nDataLen ) override; - virtual void GetGlyphWidths( const PhysicalFontFace*, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - Ucs2UIntMap& rUnicodeEnc ) override; virtual std::unique_ptr<GenericSalLayout> GetTextLayout(int nFallbackLevel) override; virtual void DrawTextLayout( const GenericSalLayout& ) override; diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index c9a9a5120a82..55bcdb7a8a55 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -135,12 +135,6 @@ public: virtual const void* GetEmbedFontData(const PhysicalFontFace*, long* pDataLen) override; virtual void FreeEmbedFontData( const void* pData, long nDataLen ) override; - virtual void GetGlyphWidths( - const PhysicalFontFace*, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - Ucs2UIntMap& rUnicodeEnc ) override; - virtual std::unique_ptr<GenericSalLayout> GetTextLayout(int nFallbackLevel) override; virtual void DrawTextLayout( const GenericSalLayout& ) override; diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 9ccd62085a47..0cc2fd05ba2d 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -370,10 +370,6 @@ public: virtual const void* GetEmbedFontData(const PhysicalFontFace*, long* pDataLen) override; // frees the font data again virtual void FreeEmbedFontData( const void* pData, long nDataLen ) override; - virtual void GetGlyphWidths( const PhysicalFontFace*, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - Ucs2UIntMap& rUnicodeEnc ) override; virtual std::unique_ptr<GenericSalLayout> GetTextLayout(int nFallbackLevel) override; diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx index 73dd374493e7..63072b1ed740 100644 --- a/vcl/qt5/Qt5Graphics_Text.cxx +++ b/vcl/qt5/Qt5Graphics_Text.cxx @@ -144,11 +144,6 @@ const void* Qt5Graphics::GetEmbedFontData(const PhysicalFontFace*, long* /*pData void Qt5Graphics::FreeEmbedFontData(const void* /*pData*/, long /*nDataLen*/) {} -void Qt5Graphics::GetGlyphWidths(const PhysicalFontFace* /*pPFF*/, bool /*bVertical*/, - std::vector<sal_Int32>& /*rWidths*/, Ucs2UIntMap& /*rUnicodeEnc*/) -{ -} - class Qt5CommonSalLayout : public GenericSalLayout { public: diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx index fc986eba5806..2bc08551c1cc 100644 --- a/vcl/quartz/salgdi.cxx +++ b/vcl/quartz/salgdi.cxx @@ -701,75 +701,6 @@ bool AquaSalGraphics::GetRawFontData( const PhysicalFontFace* pFontData, return true; } -void AquaSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFontData, bool bVertical, - std::vector< sal_Int32 >& rGlyphWidths, Ucs2UIntMap& rUnicodeEnc ) -{ - rGlyphWidths.clear(); - rUnicodeEnc.clear(); - - std::vector<unsigned char> aBuffer; - if( !GetRawFontData( pFontData, aBuffer, nullptr ) ) - return; - - // TODO: modernize psprint's horrible fontsubset C-API - // this probably only makes sense after the switch to another SCM - // that can preserve change history after file renames - - // use the font subsetter to get the widths - TrueTypeFont* pSftFont = nullptr; - SFErrCodes nRC = ::OpenTTFontBuffer( static_cast<void*>(aBuffer.data()), aBuffer.size(), 0, &pSftFont); - if( nRC != SFErrCodes::Ok ) - return; - - const int nGlyphCount = ::GetTTGlyphCount( pSftFont ); - if( nGlyphCount > 0 ) - { - // get glyph metrics - rGlyphWidths.resize(nGlyphCount); - std::vector<sal_uInt16> aGlyphIds(nGlyphCount); - for( int i = 0; i < nGlyphCount; i++ ) - { - aGlyphIds[i] = static_cast<sal_uInt16>(i); - } - - std::unique_ptr<sal_uInt16[]> pGlyphMetrics = ::GetTTSimpleGlyphMetrics( pSftFont, aGlyphIds.data(), - nGlyphCount, bVertical ); - if( pGlyphMetrics ) - { - for( int i = 0; i < nGlyphCount; ++i ) - { - rGlyphWidths[i] = pGlyphMetrics[i]; - } - pGlyphMetrics.reset(); - } - - rtl::Reference<CoreTextFontFace> rCTFontData(new CoreTextFontFace(*pFontData, pFontData->GetFontId())); - FontCharMapRef xFCMap = rCTFontData->GetFontCharMap(); - SAL_WARN_IF( !xFCMap.is() || !xFCMap->GetCharCount(), "vcl", "no charmap" ); - - // get unicode<->glyph encoding - // TODO? avoid sft mapping by using the xFCMap itself - int nCharCount = xFCMap->GetCharCount(); - sal_uInt32 nChar = xFCMap->GetFirstChar(); - for( ; --nCharCount >= 0; nChar = xFCMap->GetNextChar( nChar ) ) - { - if( nChar > 0xFFFF ) // TODO: allow UTF-32 chars - break; - - sal_Ucs nUcsChar = static_cast<sal_Ucs>(nChar); - sal_uInt32 nGlyph = ::MapChar( pSftFont, nUcsChar ); - if( nGlyph > 0 ) - { - rUnicodeEnc[ nUcsChar ] = nGlyph; - } - } - - xFCMap = nullptr; - } - - ::CloseTTFont( pSftFont ); -} - const void* AquaSalGraphics::GetEmbedFontData(const PhysicalFontFace*, long* /*pDataLen*/) { return nullptr; diff --git a/vcl/source/font/fontinstance.cxx b/vcl/source/font/fontinstance.cxx index 07aab6c38618..2cc239362f2a 100644 --- a/vcl/source/font/fontinstance.cxx +++ b/vcl/source/font/fontinstance.cxx @@ -142,6 +142,22 @@ void LogicalFontInstance::IgnoreFallbackForUnicode( sal_UCS4 cChar, FontWeight e mpUnicodeFallbackList->erase( it ); } +double LogicalFontInstance::GetGlyphWidth(sal_GlyphId nID, bool bVertical, bool bPS) +{ + hb_font_t* pHbFont = GetHbFont(); + double fWidth; + if (bVertical) + fWidth = hb_font_get_glyph_v_advance(pHbFont, nID); + else + fWidth = hb_font_get_glyph_h_advance(pHbFont, nID); + + // Translate to PostScript units (standard 1/1000) + if (bPS) + fWidth = (fWidth * 1000) / hb_face_get_upem(hb_font_get_face(pHbFont)); + + return fWidth; +} + bool LogicalFontInstance::GetGlyphBoundRect(sal_GlyphId nID, tools::Rectangle &rRect, bool bVertical) { if (mpFontCache && mpFontCache->GetCachedGlyphBoundRect(this, nID, rRect)) diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index b77eca31a389..fe768cb6dcb7 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -37,6 +37,8 @@ #include <fontselect.hxx> +#include <map> + #if !HB_VERSION_ATLEAST(1, 1, 0) // Disabled Unicode compatibility decomposition, see fdo#66715 static unsigned int unicodeDecomposeCompatibility(hb_unicode_funcs_t* /*ufuncs*/, diff --git a/vcl/source/gdi/pdffontcache.cxx b/vcl/source/gdi/pdffontcache.cxx deleted file mode 100644 index b79753c0ffb4..000000000000 --- a/vcl/source/gdi/pdffontcache.cxx +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <typeinfo> - -#include <sal/types.h> - -#include <PhysicalFontFace.hxx> -#include <salgdi.hxx> - -#include "pdffontcache.hxx" - -using namespace vcl; - -PDFFontCache::FontIdentifier::FontIdentifier( const PhysicalFontFace* pFont, bool bVertical ) : - m_nFontId( pFont->GetFontId() ), - m_bVertical( bVertical ), - m_typeFontFace( const_cast<std::type_info*>(&typeid(pFont)) ) -{ -} - -PDFFontCache::FontData& PDFFontCache::getFont( const PhysicalFontFace* pFont, bool bVertical ) -{ - FontIdentifier aId( pFont, bVertical ); - FontToIndexMap::iterator it = m_aFontToIndex.find( aId ); - if( it != m_aFontToIndex.end() ) - return m_aFonts[ it->second ]; - m_aFontToIndex[ aId ] = sal_uInt32(m_aFonts.size()); - m_aFonts.emplace_back( ); - return m_aFonts.back(); -} - -sal_Int32 PDFFontCache::getGlyphWidth( const PhysicalFontFace* pFont, sal_GlyphId nGlyph, bool bVertical, SalGraphics* pGraphics ) -{ - sal_Int32 nWidth = 0; - FontData& rFontData( getFont( pFont, bVertical ) ); - if( rFontData.m_nWidths.empty() ) - { - pGraphics->GetGlyphWidths( pFont, bVertical, rFontData.m_nWidths, rFontData.m_aGlyphIdToIndex ); - } - if( ! rFontData.m_nWidths.empty() ) - { - if (nGlyph < rFontData.m_nWidths.size()) - nWidth = rFontData.m_nWidths[nGlyph]; - } - return nWidth; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/gdi/pdffontcache.hxx b/vcl/source/gdi/pdffontcache.hxx deleted file mode 100644 index 79d6e96f37d6..000000000000 --- a/vcl/source/gdi/pdffontcache.hxx +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_VCL_SOURCE_GDI_PDFFONTCACHE_HXX -#define INCLUDED_VCL_SOURCE_GDI_PDFFONTCACHE_HXX - -#include <typeinfo> - -#include <sal/types.h> - -#include <salgdi.hxx> - -namespace vcl -{ - class PDFFontCache - { - struct FontIdentifier - { - sal_IntPtr const m_nFontId; - bool const m_bVertical; - std::type_info* const m_typeFontFace; - - FontIdentifier( const PhysicalFontFace*, bool bVertical ); - - // Less than needed for std::set and std::map - bool operator<( const FontIdentifier& rRight ) const - { - std::type_info *pType = rRight.m_typeFontFace; - - return m_nFontId < rRight.m_nFontId || - ( m_nFontId == rRight.m_nFontId && - ( m_typeFontFace->before( *pType ) || - ( *m_typeFontFace == *pType && m_bVertical < rRight.m_bVertical ) ) ); - } - }; - struct FontData - { - std::vector< sal_Int32 > m_nWidths; - Ucs2UIntMap m_aGlyphIdToIndex; - }; - typedef std::map< FontIdentifier, sal_uInt32 > FontToIndexMap; - - std::vector< FontData > m_aFonts; - FontToIndexMap m_aFontToIndex; - - FontData& getFont( const PhysicalFontFace*, bool bVertical ); - public: - PDFFontCache() {} - - sal_Int32 getGlyphWidth( const PhysicalFontFace*, sal_GlyphId, bool bVertical, SalGraphics* ); - }; -} - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index cb7070c78021..065a564589fd 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -2429,17 +2429,12 @@ std::map< sal_Int32, sal_Int32 > PDFWriterImpl::emitSystemFont( const PhysicalFo aInfo.m_nCapHeight = 1000; aInfo.m_aFontBBox = tools::Rectangle( Point( -200, -200 ), Size( 1700, 1700 ) ); aInfo.m_aPSName = pFont->GetFamilyName(); - sal_Int32 pWidths[256]; - memset( pWidths, 0, sizeof(pWidths) ); SalGraphics *pGraphics = GetGraphics(); assert(pGraphics); aSubType = OString( "/TrueType" ); - std::vector< sal_Int32 > aGlyphWidths; - Ucs2UIntMap aUnicodeMap; - pGraphics->GetGlyphWidths( pFont, false, aGlyphWidths, aUnicodeMap ); OUString aTmpName; osl_createTempFile( nullptr, nullptr, &aTmpName.pData ); @@ -2451,17 +2446,12 @@ std::map< sal_Int32, sal_Int32 > PDFWriterImpl::emitSystemFont( const PhysicalFo memset( pEncoding, 0, sizeof( pEncoding ) ); memset( pDuWidths, 0, sizeof( pDuWidths ) ); - for( sal_Ucs c = 32; c < 256; c++ ) + FontCharMapRef xFontCharMap = pFont->GetCharMap(); + for( int c = 32; c < 256; c++ ) { pEncoding[c] = c; - aGlyphIds[c] = 0; - if( aUnicodeMap.find( c ) != aUnicodeMap.end() ) - pWidths[ c ] = aGlyphWidths[ aUnicodeMap[ c ] ]; - } - //TODO: surely this is utterly broken because aGlyphIds is just all zeros, if we - //had the right glyphids here then I imagine we could replace pDuWidths with - //pWidths and remove pWidths assignment above. i.e. start with the glyph ids - //and map those to unicode rather than try and reverse map them ? + aGlyphIds[c] = xFontCharMap->GetGlyphIndex(c); + } pGraphics->CreateFontSubset( aTmpName, pFont, aGlyphIds, pEncoding, pDuWidths, 256, aInfo ); osl_removeFile( aTmpName.pData ); @@ -2487,7 +2477,7 @@ std::map< sal_Int32, sal_Int32 > PDFWriterImpl::emitSystemFont( const PhysicalFo "/Widths[" ); for( int i = 32; i < 256; i++ ) { - aLine.append( pWidths[i] ); + aLine.append( pDuWidths[i] ); aLine.append( ((i&15) == 15) ? "\n" : " " ); } aLine.append( "]\n" @@ -6093,8 +6083,9 @@ void PDFWriterImpl::drawHorizontalGlyphs( const Point aThisPos = aMat.transform( rGlyphs[nPos].m_aPos ); const Point aPrevPos = aMat.transform( rGlyphs[nPos-1].m_aPos ); double fAdvance = aThisPos.X() - aPrevPos.X(); + double fNativeWidth = rGlyphs[nPos-1].m_pGlyph->nativeWidth(true); fAdvance *= 1000.0 / nPixelFontHeight; - const double fAdjustment = rGlyphs[nPos-1].m_nNativeWidth - fAdvance + 0.5; + const double fAdjustment = fNativeWidth - fAdvance + 0.5; SAL_WARN_IF( fAdjustment < SAL_MIN_INT32 || fAdjustment > SAL_MAX_INT32, "vcl.pdfwriter", "adjustment " << fAdjustment << " outside 32-bit int"); @@ -6320,21 +6311,12 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool sal_Int32 nMappedFontObject; registerGlyph(pGlyph, pFont, aCodeUnits, nMappedGlyph, nMappedFontObject); - sal_Int32 nGlyphWidth = 0; - SalGraphics *pGraphics = GetGraphics(); - if (pGraphics) - nGlyphWidth = m_aFontCache.getGlyphWidth(pFont, - pGlyph->glyphId(), - pGlyph->IsVertical(), - pGraphics); - int nCharPos = -1; if (bUseActualText || pGlyph->IsInCluster()) nCharPos = pGlyph->charPos(); aGlyphs.emplace_back(aPos, pGlyph, - nGlyphWidth, nMappedFontObject, nMappedGlyph, nCharPos); diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx index 7e07d9e0d472..5ca1efc73129 100644 --- a/vcl/source/gdi/pdfwriter_impl.hxx +++ b/vcl/source/gdi/pdfwriter_impl.hxx @@ -25,6 +25,7 @@ #include <memory> #include <vector> +#include <salgdi.hxx> #include <com/sun/star/lang/Locale.hpp> #include <com/sun/star/util/XURLTransformer.hpp> #include <com/sun/star/uno/Sequence.h> @@ -45,7 +46,6 @@ #include <tools/stream.hxx> #include <outdata.hxx> -#include "pdffontcache.hxx" #include "pdfbuildin_fonts.hxx" class StyleSettings; @@ -564,19 +564,17 @@ public: struct PDFGlyph { Point const m_aPos; - const GlyphItem* m_pGlyph; - sal_Int32 const m_nNativeWidth; + const GlyphItem* m_pGlyph; sal_Int32 const m_nMappedFontId; sal_uInt8 const m_nMappedGlyphId; int const m_nCharPos; PDFGlyph( const Point& rPos, const GlyphItem* pGlyph, - sal_Int32 nNativeWidth, sal_Int32 nFontId, sal_uInt8 nMappedGlyphId, int nCharPos ) - : m_aPos( rPos ), m_pGlyph(pGlyph), m_nNativeWidth( nNativeWidth ), + : m_aPos( rPos ), m_pGlyph(pGlyph), m_nMappedFontId( nFontId ), m_nMappedGlyphId( nMappedGlyphId ), m_nCharPos(nCharPos) {} @@ -674,7 +672,6 @@ private: FontSubsetData m_aSubsets; FontEmbedData m_aSystemFonts; sal_Int32 m_nNextFID; - PDFFontCache m_aFontCache; static constexpr sal_Int32 g_nInheritedPageWidth = 595; // default A4 in inch/72 static constexpr sal_Int32 g_nInheritedPageHeight = 842; // default A4 in inch/72 diff --git a/vcl/unx/generic/fontmanager/fontmanager.cxx b/vcl/unx/generic/fontmanager/fontmanager.cxx index 87c1f2b84c70..f13705377426 100644 --- a/vcl/unx/generic/fontmanager/fontmanager.cxx +++ b/vcl/unx/generic/fontmanager/fontmanager.cxx @@ -52,10 +52,6 @@ #include <i18nlangtag/applelangid.hxx> #include <i18nlangtag/mslangid.hxx> -#include <sft.hxx> - -#include <PhysicalFontFace.hxx> - #if OSL_DEBUG_LEVEL > 1 #include <sys/times.h> #include <stdio.h> @@ -1105,59 +1101,6 @@ bool PrintFontManager::createFontSubset( return bSuccess; } -void PrintFontManager::getGlyphWidths( const PhysicalFontFace* pFace, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc ) -{ - PrintFont* pFont = getFont(pFace->GetFontId()); - if (!pFont) - return; - TrueTypeFont* pTTFont = nullptr; - OString aFromFile = getFontFile( pFont ); - if( OpenTTFontFile( aFromFile.getStr(), pFont->m_nCollectionEntry, &pTTFont ) != SFErrCodes::Ok ) - return; - int nGlyphs = GetTTGlyphCount(pTTFont); - if (nGlyphs > 0) - { - rWidths.resize(nGlyphs); - std::vector<sal_uInt16> aGlyphIds(nGlyphs); - for (int i = 0; i < nGlyphs; i++) - aGlyphIds[i] = sal_uInt16(i); - std::unique_ptr<sal_uInt16[]> pMetrics = GetTTSimpleGlyphMetrics(pTTFont, - aGlyphIds.data(), - nGlyphs, - bVertical); - if (pMetrics) - { - for (int i = 0; i< nGlyphs; i++) - rWidths[i] = pMetrics[i]; - pMetrics.reset(); - rUnicodeEnc.clear(); - } - - // fill the unicode map - FontCharMapRef xFontCharMap = pFace->GetCharMap(); - for (sal_uInt32 cOld = 0;;) - { - // get next unicode covered by font - const sal_uInt32 c = xFontCharMap->GetNextChar(cOld); - if (c == cOld) - break; - cOld = c; -#if 1 // TODO: remove when sal_Unicode covers all of unicode - if (c > sal_Unicode(~0)) - break; -#endif - // get the matching glyph index - const sal_GlyphId aGlyphId = xFontCharMap->GetGlyphIndex(c); - // update the requested map - rUnicodeEnc[static_cast<sal_Unicode>(c)] = aGlyphId; - } - } - CloseTTFont(pTTFont); -} - /// used by online unit tests via dlopen. extern "C" { SAL_DLLPUBLIC_EXPORT const char * unit_online_get_fonts(void) diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx index 7a6f44be779a..cc63b05ad394 100644 --- a/vcl/unx/generic/gdi/cairotextrender.cxx +++ b/vcl/unx/generic/gdi/cairotextrender.cxx @@ -536,17 +536,4 @@ void CairoTextRender::FreeEmbedFontData( const void* pData, long nLen ) GenPspGraphics::DoFreeEmbedFontData( pData, nLen ); } -void CairoTextRender::GetGlyphWidths( const PhysicalFontFace* pFont, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - Ucs2UIntMap& rUnicodeEnc ) -{ - // in this context the pFont->GetFontId() is a valid PSP - // font since they are the only ones left after the PDF - // export has filtered its list of subsettable fonts (for - // which this method was created). The correct way would - // be to have the GlyphCache search for the PhysicalFontFace pFont - GenPspGraphics::DoGetGlyphWidths(pFont, bVertical, rWidths, rUnicodeEnc); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/gdi/font.cxx b/vcl/unx/generic/gdi/font.cxx index 29b0f4daa715..b1d0be68bc22 100644 --- a/vcl/unx/generic/gdi/font.cxx +++ b/vcl/unx/generic/gdi/font.cxx @@ -143,12 +143,4 @@ void X11SalGraphics::FreeEmbedFontData( const void* pData, long nLen ) mxTextRenderImpl->FreeEmbedFontData(pData, nLen); } -void X11SalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - Ucs2UIntMap& rUnicodeEnc ) -{ - mxTextRenderImpl->GetGlyphWidths(pFont, bVertical, rWidths, rUnicodeEnc); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx index e3402014dac5..d52da62da4c0 100644 --- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx +++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx @@ -42,7 +42,6 @@ #include <langboost.hxx> #include <PhysicalFontCollection.hxx> -#include <sft.hxx> #include <ft2build.h> #include FT_FREETYPE_H diff --git a/vcl/unx/generic/print/genpspgraphics.cxx b/vcl/unx/generic/print/genpspgraphics.cxx index 768c6933900a..a8a08f263ab3 100644 --- a/vcl/unx/generic/print/genpspgraphics.cxx +++ b/vcl/unx/generic/print/genpspgraphics.cxx @@ -788,23 +788,6 @@ bool GenPspGraphics::CreateFontSubset( return bSuccess; } -void GenPspGraphics::GetGlyphWidths( const PhysicalFontFace* pFont, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - Ucs2UIntMap& rUnicodeEnc ) -{ - GenPspGraphics::DoGetGlyphWidths(pFont, bVertical, rWidths, rUnicodeEnc); -} - -void GenPspGraphics::DoGetGlyphWidths( const PhysicalFontFace* pFont, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - Ucs2UIntMap& rUnicodeEnc ) -{ - psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); - rMgr.getGlyphWidths(pFont, bVertical, rWidths, rUnicodeEnc); -} - FontAttributes GenPspGraphics::Info2FontAttributes( const psp::FastPrintFontInfo& rInfo ) { FontAttributes aDFA; diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index 24432782e951..f9b7646bdd7f 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -1651,75 +1651,4 @@ void WinSalGraphics::FreeEmbedFontData( const void* pData, long /*nLen*/ ) delete[] static_cast<char const *>(pData); } -void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont, - bool bVertical, - std::vector< sal_Int32 >& rWidths, - Ucs2UIntMap& rUnicodeEnc ) -{ - // create matching FontSelectPattern - // we need just enough to get to the font file data - FontSelectPattern aIFSD( *pFont, Size(0,1000), 1000.0, 0, false ); - - // TODO: much better solution: move SetFont and restoration of old font to caller - ScopedFont aOldFont(*this); - - float fScale = 0.0; - HFONT hOldFont = nullptr; - ImplDoSetFont(aIFSD, pFont, fScale, hOldFont); - - // get raw font file data - const RawFontData xRawFontData( getHDC() ); - if( !xRawFontData.get() ) - return; - - // open font file - sal_uInt32 nFaceNum = 0; - if( !*xRawFontData.get() ) // TTC candidate - nFaceNum = ~0U; // indicate "TTC font extracts only" - - ScopedTrueTypeFont aSftTTF; - SFErrCodes nRC = aSftTTF.open( xRawFontData.get(), xRawFontData.size(), nFaceNum ); - if( nRC != SFErrCodes::Ok ) - return; - - int nGlyphs = GetTTGlyphCount( aSftTTF.get() ); - if( nGlyphs > 0 ) - { - rWidths.resize(nGlyphs); - std::vector<sal_uInt16> aGlyphIds(nGlyphs); - for( int i = 0; i < nGlyphs; i++ ) - aGlyphIds[i] = sal_uInt16(i); - std::unique_ptr<sal_uInt16[]> pMetrics = ::GetTTSimpleGlyphMetrics( aSftTTF.get(), - &aGlyphIds[0], - nGlyphs, - bVertical ); - if( pMetrics ) - { - for( int i = 0; i< nGlyphs; i++ ) - rWidths[i] = pMetrics[i]; - pMetrics.reset(); - rUnicodeEnc.clear(); - } - const WinFontFace* pWinFont = static_cast<const WinFontFace*>(pFont); - FontCharMapRef xFCMap = pWinFont->GetCharMap(); - SAL_WARN_IF( !xFCMap.is() || !xFCMap->GetCharCount(), "vcl", "no map" ); - - int nCharCount = xFCMap->GetCharCount(); - sal_uInt32 nChar = xFCMap->GetFirstChar(); - for( int i = 0; i < nCharCount; i++ ) - { - if( nChar < 0x00010000 ) - { - sal_uInt16 nGlyph = ::MapChar( aSftTTF.get(), - static_cast<sal_Ucs>(nChar)); - if( nGlyph ) - rUnicodeEnc[ static_cast<sal_Unicode>(nChar) ] = nGlyph; - } - nChar = xFCMap->GetNextChar( nChar ); - } - - xFCMap = nullptr; - } -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 1a224b4d24d650ab2e1f11980ec90b299343d7f4 Author: Khaled Hosny <khaledho...@eglug.org> AuthorDate: Wed Aug 28 18:22:25 2019 +0200 Commit: Khaled Hosny <khaledho...@eglug.org> CommitDate: Wed Sep 11 12:38:11 2019 +0200 Consolidate GetFontCharMap() All implementations were basically doing the same thing. Move to PhysicalFontFace and use HarfBuzz API to get the raw OpeenType table data. While at make a few other places use that FontCharMap as well instead of parsing the cmap table again. Drop unused HasChar() as well. Change-Id: I06ff4feb61bcfb17291bf3c299caf11fc53afa4d diff --git a/vcl/inc/PhysicalFontFace.hxx b/vcl/inc/PhysicalFontFace.hxx index d827c7a10987..3992bb91bf41 100644 --- a/vcl/inc/PhysicalFontFace.hxx +++ b/vcl/inc/PhysicalFontFace.hxx @@ -25,6 +25,7 @@ #include <salhelper/simplereferenceobject.hxx> #include <rtl/ref.hxx> #include <vcl/dllapi.h> +#include <vcl/outdev.hxx> #include "fontattributes.hxx" @@ -68,6 +69,8 @@ public: sal_Int32 CompareWithSize( const PhysicalFontFace& ) const; sal_Int32 CompareIgnoreSize( const PhysicalFontFace& ) const; + const FontCharMapRef& GetCharMap() const; + hb_face_t* GetHbFace() const; virtual hb_blob_t* GetHbTable(hb_tag_t nTag) const = 0; @@ -79,6 +82,8 @@ protected: long mnHeight; // Height (in pixels) mutable hb_face_t* mpHbFace; + + mutable FontCharMapRef mxCharMap; }; #endif // INCLUDED_VCL_INC_PHYSICALFONTFACE_HXX diff --git a/vcl/inc/qt5/Qt5FontFace.hxx b/vcl/inc/qt5/Qt5FontFace.hxx index 1ecf01545f45..a179438cf2a5 100644 --- a/vcl/inc/qt5/Qt5FontFace.hxx +++ b/vcl/inc/qt5/Qt5FontFace.hxx @@ -42,9 +42,7 @@ public: int GetFontTable(const char pTagName[5], unsigned char*) const; - const FontCharMapRef& GetFontCharMap() const; bool GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities) const; - bool HasChar(sal_uInt32 cChar) const; rtl::Reference<LogicalFontInstance> CreateFontInstance(const FontSelectPattern& rFSD) const override; @@ -57,7 +55,6 @@ protected: private: const QString m_aFontId; - mutable FontCharMapRef m_xCharMap; mutable vcl::FontCapabilities m_aFontCapabilities; mutable bool m_bFontCapabilitiesRead; }; diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index 051585648f19..68c9aff47757 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -67,9 +67,7 @@ public: int GetFontTable( uint32_t nTagCode, unsigned char* ) const; int GetFontTable( const char pTagName[5], unsigned char* ) const; - FontCharMapRef GetFontCharMap() const; bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const; - bool HasChar( sal_uInt32 cChar ) const; rtl::Reference<LogicalFontInstance> CreateFontInstance(const FontSelectPattern&) const override; @@ -77,7 +75,6 @@ public: private: const sal_IntPtr mnFontId; - mutable FontCharMapRef mxCharMap; mutable vcl::FontCapabilities maFontCapabilities; mutable bool mbFontCapabilitiesRead; }; diff --git a/vcl/inc/unx/fontmanager.hxx b/vcl/inc/unx/fontmanager.hxx index 3c67adc70d8f..8d388013144a 100644 --- a/vcl/inc/unx/fontmanager.hxx +++ b/vcl/inc/unx/fontmanager.hxx @@ -42,6 +42,7 @@ class FontSubsetInfo; class FontConfigFontOptions; class FontSelectPattern; class GenericUnixSalData; +class PhysicalFontFace; namespace psp { class PPDParser; @@ -271,7 +272,7 @@ public: sal_Int32* pWidths, int nGlyphs ); - void getGlyphWidths( fontID nFont, + void getGlyphWidths( const PhysicalFontFace* pFace, bool bVertical, std::vector< sal_Int32 >& rWidths, std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc ); diff --git a/vcl/inc/unx/freetype_glyphcache.hxx b/vcl/inc/unx/freetype_glyphcache.hxx index 9873fa38059d..4fe24ffa4f90 100644 --- a/vcl/inc/unx/freetype_glyphcache.hxx +++ b/vcl/inc/unx/freetype_glyphcache.hxx @@ -76,8 +76,6 @@ public: void AnnounceFont( PhysicalFontCollection* ); - const FontCharMapRef& GetFontCharMap(); - private: FT_FaceRec_* maFaceFT; FreetypeFontFile* const mpFontFile; @@ -86,8 +84,6 @@ private: int mnRefCount; sal_IntPtr const mnFontId; FontAttributes maDevFontAttributes; - - FontCharMapRef mxFontCharMap; }; class FreetypeFontFace : public PhysicalFontFace diff --git a/vcl/inc/unx/genpspgraphics.h b/vcl/inc/unx/genpspgraphics.h index 73084a4f6a61..44ca12ebc458 100644 --- a/vcl/inc/unx/genpspgraphics.h +++ b/vcl/inc/unx/genpspgraphics.h @@ -55,7 +55,7 @@ public: static void DoFreeEmbedFontData( const void* pData, long nLen ); // helper methods for sharing with X11SalGraphics - static void DoGetGlyphWidths( psp::fontID aFont, + static void DoGetGlyphWidths( const PhysicalFontFace*, bool bVertical, std::vector< sal_Int32 >& rWidths, Ucs2UIntMap& rUnicodeEnc ); diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx index ccb25cab87e2..c072752db6a7 100644 --- a/vcl/inc/unx/glyphcache.hxx +++ b/vcl/inc/unx/glyphcache.hxx @@ -107,7 +107,6 @@ public: void GetFontMetric(ImplFontMetricDataRef const &) const; const unsigned char* GetTable( const char* pName, sal_uLong* pLength ) const; - FontCharMapRef GetFontCharMap() const; bool GetFontCapabilities(vcl::FontCapabilities &) const; bool GetGlyphBoundRect(sal_GlyphId, tools::Rectangle&, bool) const; diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 503b8f3aa062..9ccd62085a47 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -68,12 +68,9 @@ public: void SetFontId( sal_IntPtr nId ) { mnId = nId; } void UpdateFromHDC( HDC ) const; - bool HasChar( sal_uInt32 cChar ) const; - BYTE GetCharSet() const { return meWinCharSet; } BYTE GetPitchAndFamily() const { return mnPitchAndFamily; } - FontCharMapRef GetFontCharMap() const; bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const; hb_blob_t* GetHbTable(hb_tag_t nTag) const override; @@ -83,7 +80,6 @@ private: // some members that are initialized lazily when the font gets selected into a HDC mutable bool mbFontCapabilitiesRead; - mutable FontCharMapRef mxUnicodeMap; mutable vcl::FontCapabilities maFontCapabilities; BYTE meWinCharSet; @@ -91,7 +87,6 @@ private: bool mbAliasSymbolsHigh; bool mbAliasSymbolsLow; - void ReadCmapTable( HDC ) const; void GetFontCapabilities( HDC hDC ) const; mutable HDC mhDC; @@ -400,21 +395,6 @@ void ImplGetLogFontFromFontSelect( HDC, const FontSelectPattern&, #define MAX_64KSALPOINTS ((((sal_uInt16)0xFFFF)-8)/sizeof(POINTS)) -// called extremely often from just one spot => inline -inline bool WinFontFace::HasChar( sal_uInt32 cChar ) const -{ - if( mxUnicodeMap->HasChar( cChar ) ) - return true; - // second chance to allow symbol aliasing - if( mbAliasSymbolsLow && ((cChar-0xF000) <= 0xFF) ) - cChar -= 0xF000; - else if( mbAliasSymbolsHigh && (cChar <= 0xFF) ) - cChar += 0xF000; - else - return false; - return mxUnicodeMap->HasChar( cChar ); -} - #endif // INCLUDED_VCL_INC_WIN_SALGDI_H /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/qt5/Qt5FontFace.cxx b/vcl/qt5/Qt5FontFace.cxx index 2523f3424284..4c4bbb7ef6de 100644 --- a/vcl/qt5/Qt5FontFace.cxx +++ b/vcl/qt5/Qt5FontFace.cxx @@ -26,7 +26,6 @@ #include <Qt5Tools.hxx> #include <sft.hxx> -#include <impfontcharmap.hxx> #include <fontinstance.hxx> #include <fontselect.hxx> #include <PhysicalFontCollection.hxx> @@ -42,8 +41,6 @@ Qt5FontFace::Qt5FontFace(const Qt5FontFace& rSrc) : PhysicalFontFace(rSrc) , m_aFontId(rSrc.m_aFontId) { - if (rSrc.m_xCharMap.is()) - m_xCharMap = rSrc.m_xCharMap; } static FontWeight fromQFontWeight(int nWeight) @@ -143,29 +140,6 @@ Qt5FontFace::CreateFontInstance(const FontSelectPattern& rFSD) const return new Qt5Font(*this, rFSD); } -const FontCharMapRef& Qt5FontFace::GetFontCharMap() const -{ - if (m_xCharMap.is()) - return m_xCharMap; - - QFont aFont; - aFont.fromString(m_aFontId); - QRawFont aRawFont(QRawFont::fromFont(aFont)); - QByteArray aCMapTable = aRawFont.fontTable("cmap"); - if (aCMapTable.isEmpty()) - { - m_xCharMap = new FontCharMap(); - return m_xCharMap; - } - - CmapResult aCmapResult; - if (ParseCMAP(reinterpret_cast<const unsigned char*>(aCMapTable.data()), aCMapTable.size(), - aCmapResult)) - m_xCharMap = new FontCharMap(aCmapResult); - - return m_xCharMap; -} - bool Qt5FontFace::GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities) const { // read this only once per font diff --git a/vcl/qt5/Qt5Graphics_Text.cxx b/vcl/qt5/Qt5Graphics_Text.cxx index 85b51b82b1eb..73dd374493e7 100644 --- a/vcl/qt5/Qt5Graphics_Text.cxx +++ b/vcl/qt5/Qt5Graphics_Text.cxx @@ -71,7 +71,7 @@ FontCharMapRef Qt5Graphics::GetFontCharMap() const { if (!m_pTextStyle[0]) return FontCharMapRef(new FontCharMap()); - return static_cast<const Qt5FontFace*>(m_pTextStyle[0]->GetFontFace())->GetFontCharMap(); + return m_pTextStyle[0]->GetFontFace()->GetCharMap(); } bool Qt5Graphics::GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities) const diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx index 0d5ecab6a419..fc986eba5806 100644 --- a/vcl/quartz/salgdi.cxx +++ b/vcl/quartz/salgdi.cxx @@ -40,7 +40,6 @@ #include <quartz/ctfonts.hxx> #include <fontsubset.hxx> #include <impfont.hxx> -#include <impfontcharmap.hxx> #include <impfontmetricdata.hxx> #include <outdev.h> #include <PhysicalFontCollection.hxx> @@ -113,44 +112,6 @@ sal_IntPtr CoreTextFontFace::GetFontId() const return mnFontId; } -FontCharMapRef CoreTextFontFace::GetFontCharMap() const -{ - // return the cached charmap - if( mxCharMap.is() ) - return mxCharMap; - - // set the default charmap - FontCharMapRef pCharMap( new FontCharMap() ); - mxCharMap = pCharMap; - - // get the CMAP byte size - // allocate a buffer for the CMAP raw data - const int nBufSize = GetFontTable( "cmap", nullptr ); - SAL_WARN_IF( (nBufSize <= 0), "vcl", "CoreTextFontFace::GetFontCharMap : GetFontTable1 failed!"); - if( nBufSize <= 0 ) - return mxCharMap; - - // get the CMAP raw data - std::vector<unsigned char> aBuffer( nBufSize ); - const int nRawLength = GetFontTable( "cmap", aBuffer.data() ); - SAL_WARN_IF( (nRawLength <= 0), "vcl", "CoreTextFontFace::GetFontCharMap : GetFontTable2 failed!"); - if( nRawLength <= 0 ) - return mxCharMap; - - SAL_WARN_IF( (nBufSize!=nRawLength), "vcl", "CoreTextFontFace::GetFontCharMap : ByteCount mismatch!"); - - // parse the CMAP - CmapResult aCmapResult; - if( ParseCMAP( aBuffer.data(), nRawLength, aCmapResult ) ) - { - FontCharMapRef xDefFontCharMap( new FontCharMap(aCmapResult) ); - // create the matching charmap - mxCharMap = xDefFontCharMap; - } - - return mxCharMap; -} - bool CoreTextFontFace::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const { // read this only once per font @@ -514,7 +475,7 @@ FontCharMapRef AquaSalGraphics::GetFontCharMap() const return FontCharMapRef( new FontCharMap() ); } - return static_cast<const CoreTextFontFace*>(mpTextStyle[0]->GetFontFace())->GetFontCharMap(); + return mpTextStyle[0]->GetFontFace()->GetCharMap(); } bool AquaSalGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const diff --git a/vcl/source/font/PhysicalFontFace.cxx b/vcl/source/font/PhysicalFontFace.cxx index a8ca4dabbfd7..997b1c155160 100644 --- a/vcl/source/font/PhysicalFontFace.cxx +++ b/vcl/source/font/PhysicalFontFace.cxx @@ -17,12 +17,15 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <vcl/fontcharmap.hxx> + #include <sal/types.h> #include <tools/fontenum.hxx> #include <unotools/fontdefs.hxx> #include <fontattributes.hxx> #include <fontselect.hxx> +#include <impfontcharmap.hxx> #include <PhysicalFontFace.hxx> @@ -218,4 +221,31 @@ hb_face_t* PhysicalFontFace::GetHbFace() const return mpHbFace; } +const FontCharMapRef& PhysicalFontFace::GetCharMap() const +{ + if (mxCharMap.is()) + return mxCharMap; + + // Get the charmap and cache it. + CmapResult aCmapResult; + aCmapResult.mbSymbolic = IsSymbolFont(); + + hb_blob_t* pBlob = hb_face_reference_table(mpHbFace, HB_TAG('c', 'm', 'a', 'p')); + const unsigned char* pData = reinterpret_cast<const unsigned char*>(hb_blob_get_data(pBlob, nullptr)); + size_t nSize = hb_blob_get_length(pBlob); + if (nSize > 0 && ParseCMAP(pData, nSize, aCmapResult)) + { + FontCharMapRef xCharMap(new FontCharMap(aCmapResult)); + mxCharMap = xCharMap; + } + else + { + FontCharMapRef xCharMap(new FontCharMap()); + mxCharMap = xCharMap; + } + hb_blob_destroy(pBlob); + + return mxCharMap; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/fontmanager/fontmanager.cxx b/vcl/unx/generic/fontmanager/fontmanager.cxx index a4d07ec3bdbe..87c1f2b84c70 100644 --- a/vcl/unx/generic/fontmanager/fontmanager.cxx +++ b/vcl/unx/generic/fontmanager/fontmanager.cxx @@ -27,7 +27,6 @@ #include <unx/fontmanager.hxx> #include <fontsubset.hxx> -#include <impfontcharmap.hxx> #include <svdata.hxx> #include <unx/geninst.h> #include <unx/gendata.hxx> @@ -55,6 +54,8 @@ #include <sft.hxx> +#include <PhysicalFontFace.hxx> + #if OSL_DEBUG_LEVEL > 1 #include <sys/times.h> #include <stdio.h> @@ -1104,12 +1105,12 @@ bool PrintFontManager::createFontSubset( return bSuccess; } -void PrintFontManager::getGlyphWidths( fontID nFont, +void PrintFontManager::getGlyphWidths( const PhysicalFontFace* pFace, bool bVertical, std::vector< sal_Int32 >& rWidths, std::map< sal_Unicode, sal_uInt32 >& rUnicodeEnc ) { - PrintFont* pFont = getFont( nFont ); + PrintFont* pFont = getFont(pFace->GetFontId()); if (!pFont) return; TrueTypeFont* pTTFont = nullptr; @@ -1136,32 +1137,22 @@ void PrintFontManager::getGlyphWidths( fontID nFont, } // fill the unicode map - // TODO: isn't this map already available elsewhere in the fontmanager? - const sal_uInt8* pCmapData = nullptr; - int nCmapSize = 0; - if (GetSfntTable(pTTFont, O_cmap, &pCmapData, &nCmapSize)) + FontCharMapRef xFontCharMap = pFace->GetCharMap(); + for (sal_uInt32 cOld = 0;;) { - CmapResult aCmapResult; - if (ParseCMAP(pCmapData, nCmapSize, aCmapResult)) - { - FontCharMapRef xFontCharMap(new FontCharMap(aCmapResult)); - for (sal_uInt32 cOld = 0;;) - { - // get next unicode covered by font - const sal_uInt32 c = xFontCharMap->GetNextChar(cOld); - if (c == cOld) - break; - cOld = c; + // get next unicode covered by font + const sal_uInt32 c = xFontCharMap->GetNextChar(cOld); + if (c == cOld) + break; + cOld = c; #if 1 // TODO: remove when sal_Unicode covers all of unicode - if (c > sal_Unicode(~0)) - break; + if (c > sal_Unicode(~0)) + break; #endif - // get the matching glyph index - const sal_GlyphId aGlyphId = xFontCharMap->GetGlyphIndex(c); - // update the requested map - rUnicodeEnc[static_cast<sal_Unicode>(c)] = aGlyphId; - } - } + // get the matching glyph index + const sal_GlyphId aGlyphId = xFontCharMap->GetGlyphIndex(c); + // update the requested map + rUnicodeEnc[static_cast<sal_Unicode>(c)] = aGlyphId; } } CloseTTFont(pTTFont); diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx index 0b24cbf32d63..7a6f44be779a 100644 --- a/vcl/unx/generic/gdi/cairotextrender.cxx +++ b/vcl/unx/generic/gdi/cairotextrender.cxx @@ -371,7 +371,7 @@ FontCharMapRef CairoTextRender::GetFontCharMap() const if( !mpFreetypeFont[0] ) return nullptr; - return mpFreetypeFont[0]->GetFontCharMap(); + return mpFreetypeFont[0]->GetFontInstance()->GetFontFace()->GetCharMap(); } bool CairoTextRender::GetFontCapabilities(vcl::FontCapabilities &rGetImplFontCapabilities) const @@ -546,8 +546,7 @@ void CairoTextRender::GetGlyphWidths( const PhysicalFontFace* pFont, // export has filtered its list of subsettable fonts (for // which this method was created). The correct way would // be to have the GlyphCache search for the PhysicalFontFace pFont - psp::fontID aFont = pFont->GetFontId(); - GenPspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc ); + GenPspGraphics::DoGetGlyphWidths(pFont, bVertical, rWidths, rUnicodeEnc); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx index 8dbeab94013f..e3402014dac5 100644 --- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx +++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx @@ -66,7 +66,6 @@ #include <sys/stat.h> #include <sys/mman.h> #include <unx/fontmanager.hxx> -#include <impfontcharmap.hxx> #include <impfontcache.hxx> static FT_Library aLibFT = nullptr; @@ -708,39 +707,6 @@ bool FreetypeFont::GetAntialiasAdvice() const return !mpFontInstance->GetFontSelectPattern().mbNonAntialiased && (mnPrioAntiAlias > 0); } -// determine unicode ranges in font - -FontCharMapRef FreetypeFont::GetFontCharMap() const -{ - return mpFontInfo->GetFontCharMap(); -} - -const FontCharMapRef& FreetypeFontInfo::GetFontCharMap() -{ - // check if the charmap is already cached - if( mxFontCharMap.is() ) - return mxFontCharMap; - - // get the charmap and cache it - CmapResult aCmapResult; - aCmapResult.mbSymbolic = IsSymbolFont(); - - sal_uLong nLength = 0; - const unsigned char* pCmap = GetTable("cmap", &nLength); - if (pCmap && (nLength > 0) && ParseCMAP(pCmap, nLength, aCmapResult)) - { - FontCharMapRef xFontCharMap( new FontCharMap ( aCmapResult ) ); - mxFontCharMap = xFontCharMap; - } - else - { - FontCharMapRef xFontCharMap( new FontCharMap() ); - mxFontCharMap = xFontCharMap; - } - // mxFontCharMap on either branch now has a refcount of 1 - return mxFontCharMap; -} - bool FreetypeFont::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const { bool bRet = false; diff --git a/vcl/unx/generic/print/genpspgraphics.cxx b/vcl/unx/generic/print/genpspgraphics.cxx index 26c4163893e4..768c6933900a 100644 --- a/vcl/unx/generic/print/genpspgraphics.cxx +++ b/vcl/unx/generic/print/genpspgraphics.cxx @@ -607,7 +607,7 @@ FontCharMapRef GenPspGraphics::GetFontCharMap() const if( !m_pFreetypeFont[0] ) return nullptr; - return m_pFreetypeFont[0]->GetFontCharMap(); + return m_pFreetypeFont[0]->GetFontInstance()->GetFontFace()->GetCharMap(); } bool GenPspGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const @@ -793,22 +793,16 @@ void GenPspGraphics::GetGlyphWidths( const PhysicalFontFace* pFont, std::vector< sal_Int32 >& rWidths, Ucs2UIntMap& rUnicodeEnc ) { - // in this context the pFont->GetFontId() is a valid PSP - // font since they are the only ones left after the PDF - // export has filtered its list of subsettable fonts (for - // which this method was created). The correct way would - // be to have the GlyphCache search for the PhysicalFontFace pFont - psp::fontID aFont = pFont->GetFontId(); - GenPspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc ); + GenPspGraphics::DoGetGlyphWidths(pFont, bVertical, rWidths, rUnicodeEnc); } -void GenPspGraphics::DoGetGlyphWidths( psp::fontID aFont, +void GenPspGraphics::DoGetGlyphWidths( const PhysicalFontFace* pFont, bool bVertical, std::vector< sal_Int32 >& rWidths, Ucs2UIntMap& rUnicodeEnc ) { psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); - rMgr.getGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc ); + rMgr.getGlyphWidths(pFont, bVertical, rWidths, rUnicodeEnc); } FontAttributes GenPspGraphics::Info2FontAttributes( const psp::FastPrintFontInfo& rInfo ) diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index c87e00fb3405..24432782e951 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -57,7 +57,6 @@ #include <win/saldata.hxx> #include <win/salgdi.h> #include <win/winlayout.hxx> -#include <impfontcharmap.hxx> #include <impfontmetricdata.hxx> #include <impglyphitem.hxx> @@ -174,32 +173,7 @@ private: bool WinGlyphFallbackSubstititution::HasMissingChars(PhysicalFontFace* pFace, OUString& rMissingChars) const { WinFontFace* pWinFont = static_cast< WinFontFace* >(pFace); - FontCharMapRef xFontCharMap = pWinFont->GetFontCharMap(); - if( !xFontCharMap.is() ) - { - // construct a Size structure as the parameter of constructor of class FontSelectPattern - const Size aSize( pFace->GetWidth(), pFace->GetHeight() ); - // create a FontSelectPattern object for getting s LOGFONT - const FontSelectPattern aFSD( *pFace, aSize, static_cast<float>(aSize.Height()), 0, false ); - // construct log font - LOGFONTW aLogFont; - ImplGetLogFontFromFontSelect( mhDC, aFSD, pFace, aLogFont ); - - // create HFONT from log font - HFONT hNewFont = ::CreateFontIndirectW( &aLogFont ); - // select the new font into device - HFONT hOldFont = ::SelectFont( mhDC, hNewFont ); - - // read CMAP table to update their xFontCharMap - pWinFont->UpdateFromHDC( mhDC ); - - // cleanup temporary font - ::SelectFont( mhDC, hOldFont ); - ::DeleteFont( hNewFont ); - - // get the new charmap - xFontCharMap = pWinFont->GetFontCharMap(); - } + FontCharMapRef xFontCharMap = pWinFont->GetCharMap(); // avoid fonts with unknown CMAP subtables for glyph fallback if( !xFontCharMap.is() || xFontCharMap->IsDefaultMap() ) @@ -642,7 +616,6 @@ WinFontFace::WinFontFace( const FontAttributes& rDFS, WinFontFace::~WinFontFace() { - mxUnicodeMap.clear(); } sal_IntPtr WinFontFace::GetFontId() const @@ -679,53 +652,19 @@ static DWORD CalcTag( const char p[5]) { return (p[0]+(p[1]<<8)+(p[2]<<16)+(p[3] void WinFontFace::UpdateFromHDC( HDC hDC ) const { // short circuit if already initialized - if( mxUnicodeMap.is() ) + if (mhDC != nullptr) return; mhDC = hDC; - - ReadCmapTable( hDC ); GetFontCapabilities( hDC ); } -FontCharMapRef WinFontFace::GetFontCharMap() const -{ - return mxUnicodeMap; -} - bool WinFontFace::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const { rFontCapabilities = maFontCapabilities; return rFontCapabilities.oUnicodeRange || rFontCapabilities.oCodePageRange; } -void WinFontFace::ReadCmapTable( HDC hDC ) const -{ - if( mxUnicodeMap.is() ) - return; - - 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 ); - // parse the CMAP table if available - if( aRawFontData.get() ) { - CmapResult aResult; - ParseCMAP( aRawFontData.get(), aRawFontData.size(), aResult ); - aResult.mbSymbolic = bIsSymbolFont; - if( aResult.mnRangeCount > 0 ) - { - FontCharMapRef pUnicodeMap(new FontCharMap(aResult)); - mxUnicodeMap = pUnicodeMap; - } - } - - if( !mxUnicodeMap.is() ) - { - mxUnicodeMap = FontCharMap::GetDefaultMap( bIsSymbolFont ); - } -} - void WinFontFace::GetFontCapabilities( HDC hDC ) const { // read this only once per font @@ -1003,7 +942,7 @@ FontCharMapRef WinSalGraphics::GetFontCharMap() const { return FontCharMapRef( new FontCharMap() ); } - return mpWinFontEntry[0]->GetFontFace()->GetFontCharMap(); + return mpWinFontEntry[0]->GetFontFace()->GetCharMap(); } bool WinSalGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const @@ -1762,7 +1701,7 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont, rUnicodeEnc.clear(); } const WinFontFace* pWinFont = static_cast<const WinFontFace*>(pFont); - FontCharMapRef xFCMap = pWinFont->GetFontCharMap(); + FontCharMapRef xFCMap = pWinFont->GetCharMap(); SAL_WARN_IF( !xFCMap.is() || !xFCMap->GetCharCount(), "vcl", "no map" ); int nCharCount = xFCMap->GetCharCount(); commit a4d509179c5fecf2e6e0c2f1dec1b6979297c516 Author: Khaled Hosny <khaledho...@eglug.org> AuthorDate: Wed Aug 28 17:24:51 2019 +0200 Commit: Khaled Hosny <khaledho...@eglug.org> CommitDate: Wed Sep 11 11:39:26 2019 +0200 Move creating HarfBuzz face to PhysicalFontFace The two map to each other; there are many size-specific LogicalFontInstance's in each PhysicalFontFace, and the same goes for hb_face_t and hb_font_t. This will make it possible to access HarfBuzz face from PhysicalFontFace in the future. Change-Id: I029ad8c4b619b55a2c629f813b9e60bda29b1c08 diff --git a/vcl/inc/PhysicalFontFace.hxx b/vcl/inc/PhysicalFontFace.hxx index 23af5be9169e..d827c7a10987 100644 --- a/vcl/inc/PhysicalFontFace.hxx +++ b/vcl/inc/PhysicalFontFace.hxx @@ -20,6 +20,8 @@ #ifndef INCLUDED_VCL_INC_PHYSICALFONTFACE_HXX #define INCLUDED_VCL_INC_PHYSICALFONTFACE_HXX +#include <hb.h> + #include <salhelper/simplereferenceobject.hxx> #include <rtl/ref.hxx> #include <vcl/dllapi.h> @@ -54,6 +56,8 @@ public: class VCL_PLUGIN_PUBLIC PhysicalFontFace : public FontAttributes, public salhelper::SimpleReferenceObject { public: + ~PhysicalFontFace(); + virtual rtl::Reference<LogicalFontInstance> CreateFontInstance(const FontSelectPattern&) const = 0; int GetHeight() const { return mnHeight; } @@ -64,12 +68,17 @@ public: sal_Int32 CompareWithSize( const PhysicalFontFace& ) const; sal_Int32 CompareIgnoreSize( const PhysicalFontFace& ) const; + hb_face_t* GetHbFace() const; + virtual hb_blob_t* GetHbTable(hb_tag_t nTag) const = 0; + protected: explicit PhysicalFontFace(const FontAttributes&); void SetBitmapSize( int nW, int nH ) { mnWidth=nW; mnHeight=nH; } long mnWidth; // Width (in pixels) long mnHeight; // Height (in pixels) + + mutable hb_face_t* mpHbFace; }; #endif // INCLUDED_VCL_INC_PHYSICALFONTFACE_HXX diff --git a/vcl/inc/fontinstance.hxx b/vcl/inc/fontinstance.hxx index b57955f82a9e..5e234df72e0c 100644 --- a/vcl/inc/fontinstance.hxx +++ b/vcl/inc/fontinstance.hxx @@ -77,14 +77,12 @@ public: // TODO: make data members private int GetKashidaWidth(); void GetScale(double* nXScale, double* nYScale); - static inline void DecodeOpenTypeTag(const uint32_t nTableTag, char* pTagName); protected: explicit LogicalFontInstance(const PhysicalFontFace&, const 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(); } inline void ReleaseHbFont(); @@ -117,15 +115,6 @@ inline void LogicalFontInstance::ReleaseHbFont() m_pHbFont = nullptr; } -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; -} - #endif // INCLUDED_VCL_INC_FONTINSTANCE_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/qt5/Qt5FontFace.hxx b/vcl/inc/qt5/Qt5FontFace.hxx index c427a85445c3..1ecf01545f45 100644 --- a/vcl/inc/qt5/Qt5FontFace.hxx +++ b/vcl/inc/qt5/Qt5FontFace.hxx @@ -49,6 +49,8 @@ public: rtl::Reference<LogicalFontInstance> CreateFontInstance(const FontSelectPattern& rFSD) const override; + hb_blob_t* GetHbTable(hb_tag_t nTag) const override; + protected: Qt5FontFace(const Qt5FontFace&); Qt5FontFace(const FontAttributes& rFA, const QString& rFontID); diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index 338878e79529..051585648f19 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -73,6 +73,8 @@ public: rtl::Reference<LogicalFontInstance> CreateFontInstance(const FontSelectPattern&) const override; + hb_blob_t* GetHbTable(hb_tag_t nTag) const override; + private: const sal_IntPtr mnFontId; mutable FontCharMapRef mxCharMap; diff --git a/vcl/inc/unx/freetype_glyphcache.hxx b/vcl/inc/unx/freetype_glyphcache.hxx index 17084fcf5a75..9873fa38059d 100644 --- a/vcl/inc/unx/freetype_glyphcache.hxx +++ b/vcl/inc/unx/freetype_glyphcache.hxx @@ -61,6 +61,7 @@ public: int nFaceNum, int nFaceVariation, sal_IntPtr nFontId); ~FreetypeFontInfo(); + const unsigned char* GetTable( uint32_t, sal_uLong* pLength) const; const unsigned char* GetTable( const char*, sal_uLong* pLength) const; FT_FaceRec_* GetFaceFT(); @@ -99,6 +100,8 @@ public: virtual rtl::Reference<LogicalFontInstance> CreateFontInstance( const FontSelectPattern& ) const override; virtual sal_IntPtr GetFontId() const override { return mpFreetypeFontInfo->GetFontId(); } + + hb_blob_t* GetHbTable(hb_tag_t nTag) const override; }; // a class for cache entries for physical font instances that are based on serverfonts diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index d6d8dea14c24..503b8f3aa062 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -76,6 +76,8 @@ public: FontCharMapRef GetFontCharMap() const; bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const; + hb_blob_t* GetHbTable(hb_tag_t nTag) const override; + private: sal_IntPtr mnId; @@ -91,6 +93,8 @@ private: void ReadCmapTable( HDC ) const; void GetFontCapabilities( HDC hDC ) const; + + mutable HDC mhDC; }; /** Class that creates (and destroys) a compatible Device Context. diff --git a/vcl/qt5/Qt5Font.cxx b/vcl/qt5/Qt5Font.cxx index ee9d339266b2..ffa7e0a78415 100644 --- a/vcl/qt5/Qt5Font.cxx +++ b/vcl/qt5/Qt5Font.cxx @@ -80,26 +80,7 @@ Qt5Font::Qt5Font(const PhysicalFontFace& rPFF, const FontSelectPattern& rFSP) } } -static hb_blob_t* getFontTable(hb_face_t*, hb_tag_t nTableTag, void* pUserData) -{ - char pTagName[5]; - LogicalFontInstance::DecodeOpenTypeTag(nTableTag, pTagName); - - Qt5Font* pFont = static_cast<Qt5Font*>(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* Qt5Font::ImplInitHbFont() -{ - return InitHbFont(hb_face_create_for_tables(getFontTable, this, nullptr)); -} +hb_font_t* Qt5Font::ImplInitHbFont() { return InitHbFont(GetFontFace()->GetHbFace()); } bool Qt5Font::GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const { return false; } diff --git a/vcl/qt5/Qt5FontFace.cxx b/vcl/qt5/Qt5FontFace.cxx index a7837667f1dd..2523f3424284 100644 --- a/vcl/qt5/Qt5FontFace.cxx +++ b/vcl/qt5/Qt5FontFace.cxx @@ -191,4 +191,25 @@ bool Qt5FontFace::GetFontCapabilities(vcl::FontCapabilities& rFontCapabilities) return rFontCapabilities.oUnicodeRange || rFontCapabilities.oCodePageRange; } +hb_blob_t* Qt5FontFace::GetHbTable(hb_tag_t nTag) const +{ + char pName[5]; + pName[0] = static_cast<char>(nTag >> 24); + pName[1] = static_cast<char>(nTag >> 16); + pName[2] = static_cast<char>(nTag >> 8); + pName[3] = static_cast<char>(nTag); + pName[4] = 0; + + QFont aFont; + aFont.fromString(m_aFontId); + QRawFont aRawFont(QRawFont::fromFont(aFont)); + QByteArray aTable = aRawFont.fontTable(pName); + 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 252720a0aa4e..4bb749a7d11a 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; @@ -253,9 +252,7 @@ static hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pU hb_font_t* CoreTextStyle::ImplInitHbFont() { - hb_face_t* pHbFace = hb_face_create_for_tables(getFontTable, const_cast<PhysicalFontFace*>(GetFontFace()), nullptr); - - return InitHbFont(pHbFace); + return InitHbFont(GetFontFace()->GetHbFace()); } rtl::Reference<LogicalFontInstance> CoreTextFontFace::CreateFontInstance(const FontSelectPattern& rFSD) const diff --git a/vcl/source/font/PhysicalFontFace.cxx b/vcl/source/font/PhysicalFontFace.cxx index b16488ddc88d..a8ca4dabbfd7 100644 --- a/vcl/source/font/PhysicalFontFace.cxx +++ b/vcl/source/font/PhysicalFontFace.cxx @@ -30,6 +30,7 @@ PhysicalFontFace::PhysicalFontFace( const FontAttributes& rDFA ) : FontAttributes( rDFA ) , mnWidth(0) , mnHeight(0) + , mpHbFace(nullptr) { // StarSymbol is a unicode font, but it still deserves the symbol flag if( !IsSymbolFont() ) @@ -37,6 +38,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 @@ -196,4 +203,19 @@ bool PhysicalFontFace::IsBetterMatch( const FontSelectPattern& rFSD, 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) + { + const void* pUserData = this; + mpHbFace = hb_face_create_for_tables(getTable, const_cast<void*>(pUserData), nullptr); + } + return mpHbFace; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/font/fontinstance.cxx b/vcl/source/font/fontinstance.cxx index 808f2d0a5c27..07aab6c38618 100644 --- a/vcl/source/font/fontinstance.cxx +++ b/vcl/source/font/fontinstance.cxx @@ -74,8 +74,6 @@ hb_font_t* LogicalFontInstance::InitHbFont(hb_face_t* 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); return pHbFont; } diff --git a/vcl/source/gdi/pdfbuildin_fonts.hxx b/vcl/source/gdi/pdfbuildin_fonts.hxx index 69bdee5dcb9c..1a372c58ba69 100644 --- a/vcl/source/gdi/pdfbuildin_fonts.hxx +++ b/vcl/source/gdi/pdfbuildin_fonts.hxx @@ -71,6 +71,12 @@ public: sal_IntPtr GetFontId() const override { return reinterpret_cast<sal_IntPtr>(&mrBuildin); } static const BuildinFont& Get(int nId) { return m_aBuildinFonts[nId]; } + + hb_blob_t* GetHbTable(hb_tag_t /*nTag*/) const override + { + assert(false); + return hb_blob_get_empty(); + } }; } // namespace pdf diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx index d58c5bedc097..8dbeab94013f 100644 --- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx +++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx @@ -268,6 +268,12 @@ static const sal_uInt32 T_otto = 0x4f54544f; /* 'OTTO' */ const unsigned char* FreetypeFontInfo::GetTable( const char* pTag, sal_uLong* pLength ) const { + uint32_t nTag = HB_TAG(pTag[0], pTag[1], pTag[2], pTag[3]); + return GetTable(nTag, pLength); +} + +const unsigned char* FreetypeFontInfo::GetTable( uint32_t nTag, sal_uLong* pLength ) const +{ const unsigned char* pBuffer = mpFontFile->GetBuffer(); int nFileSize = mpFontFile->GetFileSize(); if( !pBuffer || nFileSize<1024 ) @@ -288,7 +294,7 @@ const unsigned char* FreetypeFontInfo::GetTable( const char* pTag, sal_uLong* pL return nullptr; for( int i = 0; i < nTables; ++i, p+=16 ) { - if( p[0]==pTag[0] && p[1]==pTag[1] && p[2]==pTag[2] && p[3]==pTag[3] ) + if( HB_TAG(p[0], p[1], p[2], p[3]) == nTag ) { sal_uLong nLength = GetUInt( p + 12 ); if( pLength != nullptr ) @@ -407,6 +413,19 @@ rtl::Reference<LogicalFontInstance> FreetypeFontFace::CreateFontInstance(const F return new FreetypeFontInstance(*this, rFSD); } +hb_blob_t* FreetypeFontFace::GetHbTable(hb_tag_t nTag) const +{ + sal_uLong nLength = 0; + const char* pBuffer = reinterpret_cast<const char*>( + mpFreetypeFontInfo->GetTable(nTag, &nLength)); + + hb_blob_t* pBlob = nullptr; + if (pBuffer != nullptr) + pBlob = hb_blob_create(pBuffer, nLength, HB_MEMORY_MODE_READONLY, nullptr, nullptr); + + return pBlob; +} + // FreetypeFont FreetypeFont::FreetypeFont(LogicalFontInstance* pFontInstance, FreetypeFontInfo* pFI ) diff --git a/vcl/unx/generic/glyphs/glyphcache.cxx b/vcl/unx/generic/glyphs/glyphcache.cxx index 558e3d8c3323..156cde1f0232 100644 --- a/vcl/unx/generic/glyphs/glyphcache.cxx +++ b/vcl/unx/generic/glyphs/glyphcache.cxx @@ -278,27 +278,9 @@ FreetypeFontInstance::~FreetypeFontInstance() { } -static hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pUserData) -{ - char pTagName[5]; - LogicalFontInstance::DecodeOpenTypeTag( nTableTag, pTagName ); - - sal_uLong nLength = 0; - FreetypeFontInstance* pFontInstance = static_cast<FreetypeFontInstance*>( pUserData ); - FreetypeFont* pFont = pFontInstance->GetFreetypeFont(); - const char* pBuffer = reinterpret_cast<const char*>( - pFont->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)); + hb_font_t* pRet = InitHbFont(GetFontFace()->GetHbFace()); assert(mpFreetypeFont); mpFreetypeFont->SetFontVariationsOnHBFont(pRet); return pRet; diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index 343e3f8b6208..c87e00fb3405 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -615,7 +615,8 @@ WinFontFace::WinFontFace( const FontAttributes& rDFS, meWinCharSet( eWinCharSet ), mnPitchAndFamily( nPitchAndFamily ), mbAliasSymbolsHigh( false ), - mbAliasSymbolsLow( false ) + mbAliasSymbolsLow( false ), + mhDC( nullptr ) { if( eWinCharSet == SYMBOL_CHARSET ) { @@ -649,6 +650,25 @@ sal_IntPtr WinFontFace::GetFontId() const return mnId; } +hb_blob_t* WinFontFace::GetHbTable(hb_tag_t nTag) const +{ + sal_uLong nLength = 0; + unsigned char* pBuffer = nullptr; + + nLength = ::GetFontData(mhDC, nTag, 0, nullptr, 0); + if (nLength > 0 && nLength != GDI_ERROR) + { + pBuffer = new unsigned char[nLength]; + ::GetFontData(mhDC, nTag, 0, pBuffer, nLength); + } + + hb_blob_t* pBlob = nullptr; + if (pBuffer != nullptr) + pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY, + pBuffer, [](void* data){ delete[] static_cast<unsigned char*>(data); }); + return pBlob; +} + rtl::Reference<LogicalFontInstance> WinFontFace::CreateFontInstance(const FontSelectPattern& rFSD) const { return new WinFontInstance(*this, rFSD); @@ -662,6 +682,8 @@ void WinFontFace::UpdateFromHDC( HDC hDC ) const if( mxUnicodeMap.is() ) return; + mhDC = hDC; + ReadCmapTable( hDC ); GetFontCapabilities( hDC ); } diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index 25949dc0692e..d82c2e89722f 100644 --- a/vcl/win/gdi/winlayout.cxx +++ b/vcl/win/gdi/winlayout.cxx @@ -327,41 +327,16 @@ float WinFontInstance::getHScale() const return nWidth / nHeight; } -static hb_blob_t* getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pUserData) -{ - sal_uLong nLength = 0; - unsigned char* pBuffer = nullptr; - WinFontInstance* pFont = static_cast<WinFontInstance*>(pUserData); - HDC hDC = pFont->GetGraphics()->getHDC(); - HFONT hFont = pFont->GetHFONT(); - assert(hDC); - assert(hFont); - - 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); - - hb_blob_t* pBlob = nullptr; - if (pBuffer != nullptr) - pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY, - pBuffer, [](void* data){ delete[] static_cast<unsigned char*>(data); }); - return pBlob; -} - hb_font_t* WinFontInstance::ImplInitHbFont() { assert(m_pGraphics); - hb_font_t* pHbFont = InitHbFont(hb_face_create_for_tables(getFontTable, this, nullptr)); + hb_face_t* pHbFace = GetFontFace()->GetHbFace(); + hb_font_t* pHbFont = InitHbFont(pHbFace); // Calculate the AverageWidthFactor, see LogicalFontInstance::GetScale(). if (GetFontSelectPattern().mnWidth) { - double nUPEM = hb_face_get_upem(hb_font_get_face(pHbFont)); + double nUPEM = hb_face_get_upem(pHbFace); LOGFONTW aLogFont; GetObjectW(m_hFont, sizeof(LOGFONTW), &aLogFont); commit 735af14843eab3e75ac9ed6f0773ce7bb3241c8a Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Sep 10 23:17:35 2019 +0200 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Sep 11 08:04:00 2019 +0200 external: update pdfium to 3896 Change-Id: I9d47d9afed47e01657b42fbfdb06e7fc91a150c8 Reviewed-on: https://gerrit.libreoffice.org/78806 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/download.lst b/download.lst index 27c5a433e233..846df448bacd 100644 --- a/download.lst +++ b/download.lst @@ -200,8 +200,8 @@ export OWNCLOUD_ANDROID_LIB_SHA256SUM := b18b3e3ef7fae6a79b62f2bb43cc47a5346b633 export OWNCLOUD_ANDROID_LIB_TARBALL := owncloud-android-library-0.9.4-no-binary-deps.tar.gz export PAGEMAKER_SHA256SUM := 66adacd705a7d19895e08eac46d1e851332adf2e736c566bef1164e7a442519d export PAGEMAKER_TARBALL := libpagemaker-0.0.4.tar.xz -export PDFIUM_SHA256SUM := 43ef702b65a21d66fc580b1b9c77893e33fe07dd764a17c2aac08ecec534c8ad -export PDFIUM_TARBALL := pdfium-3849.tar.bz2 +export PDFIUM_SHA256SUM := 7b08c4239e6eec685d9bfc99a041ba5df68d11fcd039ba908b91c9af90f941b1 ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits