vcl/inc/CommonSalLayout.hxx | 3 vcl/inc/quartz/salgdi.h | 4 vcl/inc/unx/glyphcache.hxx | 4 vcl/inc/win/salgdi.h | 8 + vcl/inc/win/winlayout.hxx | 101 ++++++++++++++++++++ vcl/quartz/ctfonts.cxx | 3 vcl/source/gdi/CommonSalLayout.cxx | 70 ++++++++++++-- vcl/unx/generic/glyphs/freetype_glyphcache.cxx | 6 + vcl/win/gdi/salfont.cxx | 28 +++-- vcl/win/gdi/winlayout.cxx | 121 ++++--------------------- 10 files changed, 226 insertions(+), 122 deletions(-)
New commits: commit 9c8747c112d6e37018cde25a02a437bbb2fabb9c Author: Akash Jain <akash...@gmail.com> Date: Thu Aug 18 22:46:56 2016 +0530 GSoC: Speed up CommonSalLayout in quartz/ Cache hb face to speed up layout in quartz/ Change-Id: I9c532cd72e1f6b57313f3b7d42a6b9b0633eb0ef diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index 7578768..678b0d1 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -45,6 +45,7 @@ #include "quartz/salgdicommon.hxx" #include <unordered_map> +#include <hb-ot.h> class AquaSalFrame; class FontAttributes; @@ -98,6 +99,8 @@ public: void GetFontMetric( ImplFontMetricDataPtr& ) const; bool GetGlyphBoundRect( sal_GlyphId, Rectangle& ) const; bool GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) const; + hb_face_t* GetHBFace() const { return mpHBFace; } + void SetHBFace(hb_face_t* pHBFace) const { mpHBFace = pHBFace; } const CoreTextFontFace* mpFontData; /// <1.0: font is squeezed, >1.0 font is stretched, else 1.0 @@ -109,6 +112,7 @@ public: private: /// CoreText text style object CFMutableDictionaryRef mpStyleDict; + mutable hb_face_t* mpHBFace; friend class CTLayout; friend class AquaSalGraphics; diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx index c7b54d3..d315705 100644 --- a/vcl/quartz/ctfonts.cxx +++ b/vcl/quartz/ctfonts.cxx @@ -50,6 +50,7 @@ CoreTextStyle::CoreTextStyle( const FontSelectPattern& rFSD ) , mfFontRotation( 0.0 ) , maFontSelData( rFSD ) , mpStyleDict( nullptr ) + , mpHBFace( nullptr ) { const FontSelectPattern* const pReqFont = &rFSD; @@ -116,6 +117,8 @@ CoreTextStyle::~CoreTextStyle() { if( mpStyleDict ) CFRelease( mpStyleDict ); + if( mpHBFace ) + hb_face_destroy( mpHBFace ); } void CoreTextStyle::GetFontMetric( ImplFontMetricDataPtr& rxFontMetric ) const diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index a530e2e..12b128b 100755 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -136,7 +136,12 @@ CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle) maFontSelData(rCoreTextStyle.maFontSelData), mrCoreTextStyle(rCoreTextStyle) { - mpHBFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr); + mpHBFace = rCoreTextStyle.GetHBFace(); + if(!mpHBFace) + { + mpHBFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr); + rCoreTextStyle.SetHBFace(mpHBFace); + } } #else @@ -156,11 +161,6 @@ CommonSalLayout::CommonSalLayout(ServerFont& rServerFont) CommonSalLayout::~CommonSalLayout() { -#if defined(_WIN32) -#elif defined(MACOSX) || defined(IOS) - hb_face_destroy(mpHBFace); -#else -#endif } struct HbScriptRun commit 6e947e0fc13c8a8b0604b02304304f841c6c7d8c Author: Akash Jain <akash...@gmail.com> Date: Thu Aug 18 21:10:08 2016 +0530 GSoC: Speed up CommonSalLayout in win/ Cache hb face to obtain speed up. Switch to DirectWrite from GDI for reading SFNT table data. Change-Id: I3c00c3e3c0faf340f024d7c78199ac0c78759410 diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx index 01641ad..24b4bbc 100755 --- a/vcl/inc/CommonSalLayout.hxx +++ b/vcl/inc/CommonSalLayout.hxx @@ -40,6 +40,7 @@ class CommonSalLayout : public GenericSalLayout #ifdef _WIN32 HDC mhDC; HFONT mhFont; + D2DWriteTextOutRenderer* mpD2DRenderer; #elif defined(MACOSX) || defined(IOS) const CoreTextStyle& mrCoreTextStyle; #else @@ -48,7 +49,7 @@ class CommonSalLayout : public GenericSalLayout public: #if defined(_WIN32) - explicit CommonSalLayout(HDC, WinFontInstance&); + explicit CommonSalLayout(WinSalGraphics*, WinFontInstance&, const WinFontFace&); virtual void InitFont() const override; #elif defined(MACOSX) || defined(IOS) explicit CommonSalLayout(const CoreTextStyle&); diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index bc5165d..961cb47 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -44,6 +44,9 @@ # include "postwin.h" #endif +#include <hb-ot.h> +#include <dwrite.h> + class FontSelectPattern; class WinFontInstance; class ImplFontAttrCache; @@ -139,10 +142,12 @@ private: mutable std::unordered_set<sal_UCS4> maGsubTable; mutable bool mbGsubRead; + mutable hb_face_t* mpHBFace; public: bool HasGSUBstitutions( HDC ) const; bool IsGSUBstituted( sal_UCS4 ) const; - static int GetTable( const char pTagName[5], const unsigned char*&, HDC ); + hb_face_t* GetHBFace() const { return mpHBFace; } + void SetHBFace( hb_face_t* pHBFace ) const { mpHBFace = pHBFace; } }; /** Class that creates (and destroys) a compatible Device Context. @@ -354,6 +359,7 @@ private: sal_uLong GetKernPairs(); public: + sal_uLong GetTable( const char pTagName[5], const unsigned char*&, void*&, IDWriteFontFace*& ); // public SalGraphics methods, the interface to the independent vcl part // get device resolution diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 14da8b4..a530e2e 100755 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -26,6 +26,21 @@ #include <limits> #include <salgdi.hxx> +#if defined(_WIN32) +struct WinSalGraphicsWithIDFace +{ + WinSalGraphics* mpWSL; + IDWriteFontFace* mpIDFace; + void* mpTableContext; + + WinSalGraphicsWithIDFace( WinSalGraphics* pWSL, IDWriteFontFace* pIDFace ) + : mpWSL( pWSL ), + mpIDFace( pIDFace ), + mpTableContext( nullptr ) + {} +}; +#endif + static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pUserData) { char pTagName[5]; @@ -38,8 +53,8 @@ static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pU sal_uLong nLength=0; #if defined(_WIN32) const unsigned char* pBuffer = nullptr; - HDC* phDC = static_cast<HDC*>(pUserData); - nLength = WinFontFace::GetTable(pTagName, pBuffer, *phDC); + WinSalGraphicsWithIDFace* pWSLWithIDFace = static_cast<WinSalGraphicsWithIDFace*>(pUserData); + nLength = (pWSLWithIDFace->mpWSL)->GetTable(pTagName, pBuffer, pWSLWithIDFace->mpTableContext, pWSLWithIDFace->mpIDFace); #elif defined(MACOSX) || defined(IOS) unsigned char* pBuffer = nullptr; CoreTextFontFace* pFont = static_cast<CoreTextFontFace*>(pUserData); @@ -57,7 +72,15 @@ static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pU hb_blob_t* pBlob = nullptr; if (pBuffer != nullptr) -#if defined(_WIN32) || defined(MACOSX) || defined(IOS) +#if defined(_WIN32) + pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY, pWSLWithIDFace, + [](void* pUserData) + { + WinSalGraphicsWithIDFace* pUData = static_cast<WinSalGraphicsWithIDFace*>(pUserData); + pUData->mpIDFace->ReleaseFontTable(pUData->mpTableContext); + } + ); +#elif defined(MACOSX) || defined(IOS) pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY, const_cast<unsigned char*>(pBuffer), [](void* data){ delete[] reinterpret_cast<unsigned char*>(data); } ); #else @@ -77,13 +100,29 @@ static hb_unicode_funcs_t* getUnicodeFuncs() } #if defined(_WIN32) -CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance) -: mhDC(hDC), - mhFont((HFONT)GetCurrentObject(hDC, OBJ_FONT)), +CommonSalLayout::CommonSalLayout(WinSalGraphics* WSL, WinFontInstance& rWinFontInstance, const WinFontFace& rWinFontFace) +: mhFont((HFONT)GetCurrentObject(WSL->getHDC(), OBJ_FONT)), + mhDC(WSL->getHDC()), mpHBFace(nullptr), - maFontSelData(rWinFontInstance.maFontSelData) + maFontSelData(rWinFontInstance.maFontSelData), + mpD2DRenderer(nullptr) { - mpHBFace = hb_face_create_for_tables(getFontTable, &hDC, nullptr); + mpHBFace = rWinFontFace.GetHBFace(); + if(!mpHBFace) + { + mpD2DRenderer = dynamic_cast<D2DWriteTextOutRenderer*>(&TextOutRenderer::get()); + WinSalGraphicsWithIDFace* pWSLWithIDFace = new WinSalGraphicsWithIDFace(WSL, mpD2DRenderer->GetDWriteFontFace(mhDC)); + mpHBFace= hb_face_create_for_tables( getFontTable, pWSLWithIDFace, + [](void* pUserData) + { + WinSalGraphicsWithIDFace* pUData = static_cast<WinSalGraphicsWithIDFace*>( pUserData ); + if(pUData->mpIDFace) + pUData->mpIDFace->Release(); + delete pUData; + } + ); + rWinFontFace.SetHBFace(mpHBFace); + } } void CommonSalLayout::InitFont() const @@ -118,7 +157,6 @@ CommonSalLayout::CommonSalLayout(ServerFont& rServerFont) CommonSalLayout::~CommonSalLayout() { #if defined(_WIN32) - hb_face_destroy(mpHBFace); #elif defined(MACOSX) || defined(IOS) hb_face_destroy(mpHBFace); #else diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index 3d0f397..f5cf5aa 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -1008,7 +1008,8 @@ WinFontFace::WinFontFace( const FontAttributes& rDFS, mnPitchAndFamily( nPitchAndFamily ), mbAliasSymbolsHigh( false ), mbAliasSymbolsLow( false ), - mbGsubRead( false ) + mbGsubRead( false ), + mpHBFace( nullptr ) { SetBitmapSize( 0, nHeight ); @@ -1049,6 +1050,9 @@ WinFontFace::~WinFontFace() #endif #endif // ENABLE_GRAPHITE delete mpEncodingVector; + + if( mpHBFace ) + hb_face_destroy( mpHBFace ); } sal_IntPtr WinFontFace::GetFontId() const @@ -1203,16 +1207,22 @@ void WinFontFace::ReadCmapTable( HDC hDC ) const } } -int WinFontFace::GetTable(const char pTagName[5], const unsigned char*& pResBuffer, HDC hDC) +sal_uLong WinSalGraphics::GetTable( const char pTagName[5], const unsigned char*& pResBuffer, void*& pTableContext, IDWriteFontFace*& pIDFace ) { - const DWORD nTableTag = CalcTag( pTagName ); - RawFontData aRawFontData( hDC, nTableTag ); - - if( !aRawFontData.get() ) + if( !pIDFace ) return 0; - - pResBuffer = aRawFontData.steal(); - return aRawFontData.size(); + const void* pResBuf; + UINT32 nSize; + BOOL bExists; + HRESULT hr = S_OK; + const DWORD nTableTag = DWRITE_MAKE_OPENTYPE_TAG( pTagName[0], pTagName[1], pTagName[2], pTagName[3] ); + hr = pIDFace->TryGetFontTable( nTableTag, &pResBuf, &nSize, &pTableContext, &bExists ); + if( SUCCEEDED( hr ) && ( bExists ) ) + { + pResBuffer = static_cast<const unsigned char*>(pResBuf); + return static_cast<sal_uLong>(nSize); + } + return 0; } void WinFontFace::GetFontCapabilities( HDC hDC ) const diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index 99537e5..8fa3872 100644 --- a/vcl/win/gdi/winlayout.cxx +++ b/vcl/win/gdi/winlayout.cxx @@ -3518,6 +3518,24 @@ bool D2DWriteTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC, return (succeeded && nGlyphs >= 1 && pRectToErase); } +IDWriteFontFace* D2DWriteTextOutRenderer::GetDWriteFontFace(HDC hDC) const +{ + IDWriteFontFace* pFontFace; + bool succeeded = false; + try + { + succeeded = SUCCEEDED(mpGdiInterop->CreateFontFaceFromHdc(hDC, &pFontFace)); + } + catch (const std::exception& e) + { + SAL_WARN("vcl.gdi.opengl", "Error in dwrite while creating font face: " << e.what()); + return nullptr; + } + if(succeeded) + return pFontFace; + else return nullptr; +} + bool D2DWriteTextOutRenderer::BindFont(HDC hDC) { // A TextOutRender can only be bound to one font at a time, so the @@ -3884,7 +3902,7 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe if( getenv("SAL_USE_COMMON_LAYOUT") ) { - CommonSalLayout* pCommonSalLayout = new CommonSalLayout( getHDC(), rFontInstance ); + CommonSalLayout* pCommonSalLayout = new CommonSalLayout( this, rFontInstance, rFontFace ); return pCommonSalLayout; } else @@ -4048,6 +4066,9 @@ PhysicalFontFace* WinFontFace::Clone() const if ( mpGraphiteData ) mpGraphiteData->AddReference(); #endif + if( mpHBFace ) + hb_face_reference( mpHBFace ); + PhysicalFontFace* pClone = new WinFontFace( *this ); return pClone; } commit 1e825029ce0060a0f59f99496884b560cefac574 Author: Akash Jain <akash...@gmail.com> Date: Thu Aug 18 20:51:25 2016 +0530 GSoC: Move TextOutRenderer definition to winlayout.hxx Change-Id: I705f92d5ad55d7612c6413436c801de13f5352a6 diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx index 7905513..4c6874f 100755 --- a/vcl/inc/win/winlayout.hxx +++ b/vcl/inc/win/winlayout.hxx @@ -417,4 +417,105 @@ public: #endif +class TextOutRenderer +{ +protected: + explicit TextOutRenderer() = default; + TextOutRenderer(const TextOutRenderer &) = delete; + TextOutRenderer & operator = (const TextOutRenderer &) = delete; + +public: + static TextOutRenderer & get(); + + virtual ~TextOutRenderer() = default; + + virtual bool operator ()(SalLayout const &rLayout, HDC hDC, + const Rectangle* pRectToErase, + Point* pPos, int* pGetNextGlypInfo) = 0; +}; + +class ExTextOutRenderer : public TextOutRenderer +{ + ExTextOutRenderer(const ExTextOutRenderer &) = delete; + ExTextOutRenderer & operator = (const ExTextOutRenderer &) = delete; + +public: + explicit ExTextOutRenderer() = default; + virtual ~ExTextOutRenderer() override = default; + + bool operator ()(SalLayout const &rLayout, HDC hDC, + const Rectangle* pRectToErase, + Point* pPos, int* pGetNextGlypInfo) override; +}; + +#if ENABLE_GRAPHITE_DWRITE + +class D2DWriteTextOutRenderer : public TextOutRenderer +{ + typedef HRESULT(WINAPI *pD2D1CreateFactory_t)(D2D1_FACTORY_TYPE, + REFIID, const D2D1_FACTORY_OPTIONS *, void **); + typedef HRESULT(WINAPI *pDWriteCreateFactory_t)(DWRITE_FACTORY_TYPE, + REFIID, IUnknown **); + + static HINSTANCE mmD2d1, mmDWrite; + static pD2D1CreateFactory_t D2D1CreateFactory; + static pDWriteCreateFactory_t DWriteCreateFactory; + +public: + static bool InitModules(); + + explicit D2DWriteTextOutRenderer(); + virtual ~D2DWriteTextOutRenderer() override; + + bool operator ()(SalLayout const &rLayout, HDC hDC, + const Rectangle* pRectToErase, + Point* pPos, int* pGetNextGlypInfo) override; + + inline bool BindDC(HDC hDC, Rectangle const & rRect = Rectangle(0, 0, 0, 0)) { + RECT const rc = { rRect.Left(), rRect.Top(), rRect.Right(), rRect.Bottom() }; + HRESULT ok= mpRT->BindDC(hDC, &rc); + return SUCCEEDED(ok); + } + + bool BindFont(HDC hDC) /*override*/; + bool ReleaseFont() /*override*/; + + std::vector<Rectangle> GetGlyphInkBoxes(uint16_t * pGid, uint16_t * pGidEnd) const /*override*/; + ID2D1RenderTarget * GetRenderTarget() const { return mpRT; } + IDWriteFontFace* GetDWriteFontFace(HDC) const; + IDWriteFontFace * GetFontFace() const { return mpFontFace; } + float GetEmHeight() const { return mlfEmHeight; } + + inline HRESULT CreateRenderTarget() { + if (mpRT) mpRT->Release(); mpRT = nullptr; + return mpD2DFactory->CreateDCRenderTarget(&mRTProps, &mpRT); + } + + inline bool Ready() const { return mpGdiInterop && mpRT; } + +private: + static void CleanupModules(); + + // This is a singleton object disable copy ctor and assignemnt operator + D2DWriteTextOutRenderer(const D2DWriteTextOutRenderer &) = delete; + D2DWriteTextOutRenderer & operator = (const D2DWriteTextOutRenderer &) = delete; + + bool GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** ppFontFace, float * lfSize) const; + bool GetDWriteInkBox(IDWriteFontFace & rFontFace, SalLayout const &rLayout, float const lfEmHeight, Rectangle &) const; + bool DrawGlyphs(const Point & origin, uint16_t * pGid, uint16_t * pGidEnd, + float * pAdvances, Point * pOffsets) /*override*/; + + ID2D1Factory * mpD2DFactory; + IDWriteFactory * mpDWriteFactory; + IDWriteGdiInterop * mpGdiInterop; + ID2D1DCRenderTarget * mpRT; + const D2D1_RENDER_TARGET_PROPERTIES mRTProps; + + IDWriteFontFace * mpFontFace; + float mlfEmHeight; + HDC mhDC; +}; + +#endif + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index 4486864..99537e5 100644 --- a/vcl/win/gdi/winlayout.cxx +++ b/vcl/win/gdi/winlayout.cxx @@ -17,8 +17,6 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#include "win/winlayout.hxx" - #include "osl/module.h" #include "osl/file.h" @@ -56,104 +54,8 @@ std::unique_ptr<GlobalGlyphCache> GlyphCache::gGlobalGlyphCache(new GlobalGlyphCache); GLuint WinFontInstance::mnGLyphyProgram = 0; -class TextOutRenderer -{ -protected: - explicit TextOutRenderer() = default; - TextOutRenderer(const TextOutRenderer &) = delete; - TextOutRenderer & operator = (const TextOutRenderer &) = delete; - -public: - static TextOutRenderer & get(); - - virtual ~TextOutRenderer() = default; - - virtual bool operator ()(SalLayout const &rLayout, HDC hDC, - const Rectangle* pRectToErase, - Point* pPos, int* pGetNextGlypInfo) = 0; -}; - -class ExTextOutRenderer : public TextOutRenderer -{ - ExTextOutRenderer(const ExTextOutRenderer &) = delete; - ExTextOutRenderer & operator = (const ExTextOutRenderer &) = delete; - -public: - explicit ExTextOutRenderer() = default; - virtual ~ExTextOutRenderer() override = default; - - bool operator ()(SalLayout const &rLayout, HDC hDC, - const Rectangle* pRectToErase, - Point* pPos, int* pGetNextGlypInfo) override; -}; - #if ENABLE_GRAPHITE_DWRITE -class D2DWriteTextOutRenderer : public TextOutRenderer -{ - typedef HRESULT(WINAPI *pD2D1CreateFactory_t)(D2D1_FACTORY_TYPE, - REFIID, const D2D1_FACTORY_OPTIONS *, void **); - - typedef HRESULT(WINAPI *pDWriteCreateFactory_t)(DWRITE_FACTORY_TYPE, - REFIID, IUnknown **); - - static HINSTANCE mmD2d1, mmDWrite; - static pD2D1CreateFactory_t D2D1CreateFactory; - static pDWriteCreateFactory_t DWriteCreateFactory; - -public: - static bool InitModules(); - - explicit D2DWriteTextOutRenderer(); - virtual ~D2DWriteTextOutRenderer() override; - - bool operator ()(SalLayout const &rLayout, HDC hDC, - const Rectangle* pRectToErase, - Point* pPos, int* pGetNextGlypInfo) override; - - inline bool BindDC(HDC hDC, Rectangle const & rRect = Rectangle(0, 0, 0, 0)) { - RECT const rc = { rRect.Left(), rRect.Top(), rRect.Right(), rRect.Bottom() }; - return SUCCEEDED(mpRT->BindDC(hDC, &rc)); - } - - bool BindFont(HDC hDC) /*override*/; - bool ReleaseFont() /*override*/; - - std::vector<Rectangle> GetGlyphInkBoxes(uint16_t * pGid, uint16_t * pGidEnd) const /*override*/; - ID2D1RenderTarget * GetRenderTarget() const { return mpRT; } - IDWriteFontFace * GetFontFace() const { return mpFontFace; } - float GetEmHeight() const { return mlfEmHeight; } - - inline HRESULT CreateRenderTarget() { - if (mpRT) mpRT->Release(); mpRT = nullptr; - return mpD2DFactory->CreateDCRenderTarget(&mRTProps, &mpRT); - } - - inline bool Ready() const { return mpGdiInterop && mpRT; } - -private: - static void CleanupModules(); - - // This is a singleton object disable copy ctor and assignemnt operator - D2DWriteTextOutRenderer(const D2DWriteTextOutRenderer &) = delete; - D2DWriteTextOutRenderer & operator = (const D2DWriteTextOutRenderer &) = delete; - - bool GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** ppFontFace, float * lfSize) const; - bool GetDWriteInkBox(IDWriteFontFace & rFontFace, SalLayout const &rLayout, float const lfEmHeight, Rectangle &) const; - bool DrawGlyphs(const Point & origin, uint16_t * pGid, uint16_t * pGidEnd, - float * pAdvances, Point * pOffsets) /*override*/; - - ID2D1Factory * mpD2DFactory; - IDWriteFactory * mpDWriteFactory; - IDWriteGdiInterop * mpGdiInterop; - ID2D1DCRenderTarget * mpRT; - const D2D1_RENDER_TARGET_PROPERTIES mRTProps; - - IDWriteFontFace * mpFontFace; - float mlfEmHeight; - HDC mhDC; -}; - inline void WinFontInstance::CacheGlyphWidth( int nCharCode, int nCharWidth ) { maWidthMap[ nCharCode ] = nCharWidth; commit d1e1974df1186ca508ca46ae515a7327d636b40a Author: Akash Jain <akash...@gmail.com> Date: Wed Aug 17 21:31:22 2016 +0530 GSoC: Speed up CommonSalLayout in unx/ Speed up CommonSalLayout by caching hb face Change-Id: I5ac65998974360f5726661357c4eee62b22943bd diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx index 04723cb..1c356c5 100644 --- a/vcl/inc/unx/glyphcache.hxx +++ b/vcl/inc/unx/glyphcache.hxx @@ -35,6 +35,7 @@ #include <sallayout.hxx> #include "fontattributes.hxx" #include "impfontmetricdata.hxx" +#include "hb-ot.h" #include <unordered_map> @@ -181,6 +182,8 @@ public: sal_GlyphId FixupGlyphIndex( sal_GlyphId aGlyphId, sal_UCS4 ) const; bool GetGlyphOutline( sal_GlyphId aGlyphId, basegfx::B2DPolyPolygon& ) const; bool GetAntialiasAdvice() const; + hb_face_t* GetHBFace() { return mpHBFace; } + void SetHBFace( hb_face_t* pHBFace ) { mpHBFace=pHBFace; } private: friend class GlyphCache; @@ -240,6 +243,7 @@ private: GlyphSubstitution maGlyphSubstitution; ServerFontLayoutEngine* mpLayoutEngine; + hb_face_t* mpHBFace; }; // a class for cache entries for physical font instances that are based on serverfonts diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 24ff274..14da8b4 100755 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -106,13 +106,23 @@ CommonSalLayout::CommonSalLayout(ServerFont& rServerFont) maFontSelData(rServerFont.GetFontSelData()), mrServerFont(rServerFont) { - mpHBFace = hb_face_create_for_tables(getFontTable, &rServerFont, nullptr); + mpHBFace = rServerFont.GetHBFace(); + if(!mpHBFace) + { + mpHBFace = hb_face_create_for_tables(getFontTable, &rServerFont, nullptr); + mrServerFont.SetHBFace(mpHBFace); + } } #endif CommonSalLayout::~CommonSalLayout() { +#if defined(_WIN32) hb_face_destroy(mpHBFace); +#elif defined(MACOSX) || defined(IOS) + hb_face_destroy(mpHBFace); +#else +#endif } struct HbScriptRun diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx index 7023a5f..3214c9d 100644 --- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx +++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx @@ -461,7 +461,8 @@ ServerFont::ServerFont( const FontSelectPattern& rFSD, FreetypeFontInfo* pFI ) mbArtItalic( false ), mbArtBold( false ), mbUseGamma( false ), - mpLayoutEngine( nullptr ) + mpLayoutEngine( nullptr ), + mpHBFace( nullptr ) { // TODO: move update of mpFontInstance into FontEntry class when // it becomes responsible for the ServerFont instantiation @@ -610,6 +611,9 @@ ServerFont::~ServerFont() mpFontInfo->ReleaseFaceFT(); + if( mpHBFace ) + hb_face_destroy( mpHBFace ); + ReleaseFromGarbageCollect(); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits