Rebased ref, commits from common ancestor: commit 4119cdc3b41e5a23fe4402727fac7d7efefd7fa0 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 1df7f933af1643f970143112d772e1179aa64822 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 626d17422f0c6a4b3f8805e9d2ce1eab4e44ae90 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 21d179036ed0e6f7cdd66fa4b6c637be073f259f 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 79744b2..fdf5265 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(); } commit 9efdeffafd8235306dba52d89a0c43c92bceddea Author: Akash Jain <akash...@gmail.com> Date: Sat Jul 23 21:41:40 2016 +0530 GSoC: Add Graphite support for CommonSalLayout Enable Graphite font rendering in CommonSalLayout through Harfbuzz Change-Id: Ia6a00a1bb6ea1a7bd705ed91d4f4f6cb9803e062 diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx index 0278965..9ee998b 100644 --- a/vcl/unx/generic/gdi/cairotextrender.cxx +++ b/vcl/unx/generic/gdi/cairotextrender.cxx @@ -498,23 +498,23 @@ SalLayout* CairoTextRender::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackL if( mpServerFont[ nFallbackLevel ] && !(rArgs.mnFlags & SalLayoutFlags::DisableGlyphProcessing) ) { -#if ENABLE_GRAPHITE - // Is this a Graphite font? - if (!bDisableGraphite_ && - GraphiteServerFontLayout::IsGraphiteEnabledFont(*mpServerFont[nFallbackLevel])) + if(getenv("SAL_USE_COMMON_LAYOUT")) { - pLayout = new GraphiteServerFontLayout(*mpServerFont[nFallbackLevel]); + pLayout = new CommonSalLayout( *mpServerFont[ nFallbackLevel ] ); } else -#endif - if(getenv("SAL_USE_COMMON_LAYOUT")) + { +#if ENABLE_GRAPHITE + // Is this a Graphite font? + if (!bDisableGraphite_ && + GraphiteServerFontLayout::IsGraphiteEnabledFont(*mpServerFont[nFallbackLevel])) { - pLayout = new CommonSalLayout( *mpServerFont[ nFallbackLevel ] ); + pLayout = new GraphiteServerFontLayout(*mpServerFont[nFallbackLevel]); } else - { +#endif pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] ); - } + } } return pLayout; commit b6bc11bb1f87eba12b8ddb3d50eb45e16332ccb5 Author: Akash Jain <akash...@gmail.com> Date: Sat Jul 23 21:21:46 2016 +0530 GSoC: Enable building Harfbuzz with Graphite Harfbuzz will now need to be built with Graphite support. This allows Harfbuzz to handle Graphite fonts. In case we all building with system Harfbuzz, then it should be built with Graphite support else we error out. Change-Id: I156ec08b9e5ad7ce87cc15e4b5852d9c57c98f7f diff --git a/configure.ac b/configure.ac index 0fb9784..a4fcf6d 100644 --- a/configure.ac +++ b/configure.ac @@ -9292,10 +9292,14 @@ if test $_os != Darwin -a $_os != Android -a $_os != iOS -a \( -z "$enable_graph AC_MSG_RESULT([yes]) ENABLE_GRAPHITE="TRUE" AC_DEFINE(ENABLE_GRAPHITE) - libo_CHECK_SYSTEM_MODULE([graphite],[GRAPHITE],[graphite2 >= 0.9.3]) + libo_CHECK_SYSTEM_MODULE([graphite],[GRAPHITE],[graphite2 >= 0.9.3],["-I${WORKDIR}/UnpackedTarball/graphite/include"],["-L${WORKDIR}/LinkTarget/StaticLibrary -lgraphite"]) if test "$with_system_graphite" = "yes"; then libo_MINGW_CHECK_DLL([libgraphite2]) fi + if test "$COM" = "MSC"; then # override the above + GRAPHITE_LIBS="${WORKDIR}/LinkTarget/StaticLibrary/graphite.lib" + fi + else AC_MSG_RESULT([no]) fi @@ -9386,7 +9390,11 @@ if test "$with_harfbuzz" = "yes" -o \( $_os != WINNT -a $_os != Darwin -a $_os ! libo_CHECK_SYSTEM_MODULE([harfbuzz],[HARFBUZZ],[harfbuzz >= 0.9.10],[-I${WORKDIR}/UnpackedTarball/harfbuzz/src],["-L${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs -lharfbuzz -lharfbuzz-icu"]) fi if test "$COM" = "MSC"; then # override the above - HARFBUZZ_LIBS="${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs/libharfbuzz.lib ${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs/libharfbuzz-icu.lib" + HARFBUZZ_LIBS="${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs/libharfbuzz.lib" + fi + if test "$with_system_harfbuzz" = "yes"; then + AC_MSG_CHECKING([whether system Harfbuzz is built with Graphite support]) + AC_CHECK_FUNC(hb_graphite2_face_get_gr_face,,[AC_MSG_ERROR([Harfbuzz needs to be built with Graphite support.])]) fi else AC_MSG_RESULT([no]) diff --git a/external/harfbuzz/ExternalProject_harfbuzz.mk b/external/harfbuzz/ExternalProject_harfbuzz.mk index 9e01833..f6a2d49 100644 --- a/external/harfbuzz/ExternalProject_harfbuzz.mk +++ b/external/harfbuzz/ExternalProject_harfbuzz.mk @@ -23,19 +23,22 @@ $(call gb_ExternalProject_get_state_target,harfbuzz,build) : $(call gb_ExternalProject_run,build,\ $(if $(CROSS_COMPILING),ICU_CONFIG=$(SRCDIR)/external/icu/cross-bin/icu-config) \ $(if $(SYSTEM_ICU),,ICU_CONFIG=$(SRCDIR)/external/icu/cross-bin/icu-config) \ + GRAPHITE2_CFLAGS="$(GRAPHITE_CFLAGS)" \ + GRAPHITE2_LIBS="$(GRAPHITE_LIBS)" \ ./configure \ --enable-static \ --disable-shared \ --disable-gtk-doc \ --with-pic \ - --with-icu=yes \ + --with-icu=builtin \ --with-freetype=no \ --with-cairo=no \ --with-glib=no \ + --with-graphite2=yes \ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \ $(if $(CROSS_COMPILING),--build=$(BUILD_PLATFORM) --host=$(HOST_PLATFORM)) \ $(if $(filter LINUX,$(OS)),CXXFLAGS="$(CXXFLAGS) -fvisibility=hidden") \ - && (cd $(EXTERNAL_WORKDIR)/src && $(MAKE)) \ + && (cd $(EXTERNAL_WORKDIR)/src && $(MAKE) lib) \ ) # vim: set noet sw=4 ts=4: commit 58297cc16fb47f36457abacce15112fe3369d7bc Author: Akash Jain <akash...@gmail.com> Date: Wed Jul 20 23:51:56 2016 +0530 GSoC: Integrate new CommonSalLayout in quartz/ code Change-Id: I07a9c956f09be5d43ee58ff0784ba0f81f52cd9a diff --git a/vcl/quartz/ctfonts.hxx b/vcl/inc/quartz/ctfonts.hxx similarity index 100% rename from vcl/quartz/ctfonts.hxx rename to vcl/inc/quartz/ctfonts.hxx diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index 3458e54..7578768 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -111,6 +111,7 @@ private: CFMutableDictionaryRef mpStyleDict; friend class CTLayout; + friend class AquaSalGraphics; CFMutableDictionaryRef GetStyleDict( void ) const { return mpStyleDict; } }; diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx index eb6e88c5..c7b54d3 100644 --- a/vcl/quartz/ctfonts.cxx +++ b/vcl/quartz/ctfonts.cxx @@ -25,7 +25,7 @@ #include <vcl/settings.hxx> -#include "ctfonts.hxx" +#include "quartz/ctfonts.hxx" #include "impfont.hxx" #ifdef MACOSX #include "osx/saldata.hxx" diff --git a/vcl/quartz/ctlayout.cxx b/vcl/quartz/ctlayout.cxx index 2415298..5e031ec 100644 --- a/vcl/quartz/ctlayout.cxx +++ b/vcl/quartz/ctlayout.cxx @@ -25,9 +25,10 @@ #include <sal/types.h> #include <tools/debug.hxx> -#include "ctfonts.hxx" +#include "quartz/ctfonts.hxx" #include "CTRunData.hxx" #include "quartz/utils.h" +#include "CommonSalLayout.hxx" class CTLayout : public SalLayout @@ -781,7 +782,14 @@ void CTLayout::Simplify( bool /*bIsBase*/ ) {} SalLayout* CoreTextStyle::GetTextLayout() const { - return new CTLayout( this); + if( getenv("SAL_USE_COMMON_LAYOUT") ) + { + return new CommonSalLayout( *this ); + } + else + { + return new CTLayout( this); + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx index 86f1d49..7dc1e5b 100644 --- a/vcl/quartz/salgdi.cxx +++ b/vcl/quartz/salgdi.cxx @@ -36,7 +36,7 @@ #include <vcl/svapp.hxx> #include <vcl/sysdata.hxx> -#include "ctfonts.hxx" +#include "quartz/ctfonts.hxx" #include "fontsubset.hxx" #include "impfont.hxx" #include "impfontcharmap.hxx" @@ -414,8 +414,39 @@ bool AquaSalGraphics::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect return bRC; } -void AquaSalGraphics::DrawSalLayout( const CommonSalLayout& ) -{ +void AquaSalGraphics::DrawSalLayout( const CommonSalLayout& rLayout ) +{ + CGContextRef context = mrContext; + SAL_INFO( "vcl.ct", "CGContextSaveGState(" << context << ")" ); + CGContextSaveGState( context ); + SAL_INFO( "vcl.ct", "CGContextScaleCTM(" << context << ",1.0,-1.0)" ); + const CoreTextStyle& rCTStyle = rLayout.getFontData(); + + CTFontRef pFont = static_cast<CTFontRef>(CFDictionaryGetValue( rCTStyle.GetStyleDict(), kCTFontAttributeName )); + CGContextScaleCTM(context, 1.0, -1.0); + CGContextSetShouldAntialias(context, !mbNonAntialiasedText); + // rotate the matrix + const CGFloat fRadians = rCTStyle.mfFontRotation; + CGContextRotateCTM( context, +fRadians ); + const CGAffineTransform aInvMatrix = CGAffineTransformMakeRotation( -fRadians ); + CGContextSetFillColor( context, maTextColor.AsArray() ); + + // draw the text + Point aPos; + sal_GlyphId aGlyphId; + std::vector<CGGlyph> aGlyphIds; + std::vector<CGPoint> aGlyphPos; + int nStart = 0; + for(; rLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nStart ); ) + { + aGlyphIds.push_back( aGlyphId & GF_IDXMASK ); + aGlyphPos.push_back( CGPointApplyAffineTransform( CGPointMake( aPos.X(), -1*aPos.Y() ), aInvMatrix ) ); + } + CTFontDrawGlyphs( pFont, aGlyphIds.data(), aGlyphPos.data(), nStart, context); + + // restore the original graphic context transformations + SAL_INFO( "vcl.ct", "CGContextRestoreGState(" << context << ")" ); + CGContextRestoreGState( context ); } void AquaSalGraphics::SetFont( FontSelectPattern* pReqFont, int /*nFallbackLevel*/ ) diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 55834c6..24ff274 100755 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -57,7 +57,7 @@ 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) +#if defined(_WIN32) || 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 commit 10775220bee916205e74b6d553778d0680e5e3db Author: Akash Jain <akash...@gmail.com> Date: Wed Jul 6 17:56:15 2016 +0530 GSoC: Integrate new CommonSalLayout in win/ code Change-Id: Ifeb2fa7ca9e2cd0da1c504d4e770aa0bb1b0b0de diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 3c54dff..55834c6 100755 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -57,7 +57,12 @@ 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) + 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 pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY, nullptr, nullptr); +#endif return pBlob; } @@ -74,12 +79,18 @@ static hb_unicode_funcs_t* getUnicodeFuncs() #if defined(_WIN32) CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance) : mhDC(hDC), + mhFont((HFONT)GetCurrentObject(hDC, OBJ_FONT)), mpHBFace(nullptr), maFontSelData(rWinFontInstance.maFontSelData) { mpHBFace = hb_face_create_for_tables(getFontTable, &hDC, nullptr); } +void CommonSalLayout::InitFont() const +{ + SelectObject( mhDC, mhFont ); +} + #elif defined(MACOSX) || defined(IOS) CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle) : mpHBFace(nullptr), @@ -201,6 +212,12 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) //XXX WinLayout object DOESN'T derive from GSL GenericSalLayout& rLayout = *this; +// HACK. TODO: Get rid of HACK +#if defined(_WIN32) + if(maFontSelData.mnWidth) + maFontSelData.mnWidth = (double)maFontSelData.mnWidth*1.812; +#endif + hb_font_t* pHBFont = hb_font_create(mpHBFace); hb_font_set_ppem(pHBFont, maFontSelData.mnWidth? maFontSelData.mnWidth:maFontSelData.mnHeight , maFontSelData.mnHeight); hb_font_set_scale(pHBFont, (uint64_t)(maFontSelData.mnWidth? maFontSelData.mnWidth:maFontSelData.mnHeight) << 6 diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index 95c9ae3..3d0f397 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -2614,7 +2614,4 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont, } } -void WinSalGraphics::DrawSalLayout( const CommonSalLayout& ) -{} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index cbf0b58..4486864 100644 --- a/vcl/win/gdi/winlayout.cxx +++ b/vcl/win/gdi/winlayout.cxx @@ -34,6 +34,7 @@ #include "sft.hxx" #include "sallayout.hxx" +#include "CommonSalLayout.hxx" #include <cstdio> #include <cstdlib> @@ -67,7 +68,7 @@ public: virtual ~TextOutRenderer() = default; - virtual bool operator ()(WinLayout const &rLayout, HDC hDC, + virtual bool operator ()(SalLayout const &rLayout, HDC hDC, const Rectangle* pRectToErase, Point* pPos, int* pGetNextGlypInfo) = 0; }; @@ -81,7 +82,7 @@ public: explicit ExTextOutRenderer() = default; virtual ~ExTextOutRenderer() override = default; - bool operator ()(WinLayout const &rLayout, HDC hDC, + bool operator ()(SalLayout const &rLayout, HDC hDC, const Rectangle* pRectToErase, Point* pPos, int* pGetNextGlypInfo) override; }; @@ -106,7 +107,7 @@ public: explicit D2DWriteTextOutRenderer(); virtual ~D2DWriteTextOutRenderer() override; - bool operator ()(WinLayout const &rLayout, HDC hDC, + bool operator ()(SalLayout const &rLayout, HDC hDC, const Rectangle* pRectToErase, Point* pPos, int* pGetNextGlypInfo) override; @@ -138,7 +139,7 @@ private: D2DWriteTextOutRenderer & operator = (const D2DWriteTextOutRenderer &) = delete; bool GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** ppFontFace, float * lfSize) const; - bool GetDWriteInkBox(IDWriteFontFace & rFontFace, WinLayout const &rLayout, float const lfEmHeight, Rectangle &) 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*/; @@ -3485,7 +3486,7 @@ TextOutRenderer & TextOutRenderer::get() } -bool ExTextOutRenderer::operator ()(WinLayout const &rLayout, HDC hDC, +bool ExTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC, const Rectangle* pRectToErase, Point* pPos, int* pGetNextGlypInfo) { @@ -3544,7 +3545,7 @@ D2DWriteTextOutRenderer::~D2DWriteTextOutRenderer() CleanupModules(); } -bool D2DWriteTextOutRenderer::operator ()(WinLayout const &rLayout, HDC hDC, +bool D2DWriteTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC, const Rectangle* pRectToErase, Point* pPos, int* pGetNextGlypInfo) { @@ -3784,7 +3785,7 @@ bool D2DWriteTextOutRenderer::GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** p return succeeded; } -bool D2DWriteTextOutRenderer::GetDWriteInkBox(IDWriteFontFace & rFontFace, WinLayout const &rLayout, float const /*lfEmHeight*/, Rectangle & rOut) const +bool D2DWriteTextOutRenderer::GetDWriteInkBox(IDWriteFontFace & rFontFace, SalLayout const &rLayout, float const /*lfEmHeight*/, Rectangle & rOut) const { rOut.SetEmpty(); @@ -3979,66 +3980,74 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe const WinFontFace& rFontFace = *mpWinFontData[ nFallbackLevel ]; WinFontInstance& rFontInstance = *mpWinFontEntry[ nFallbackLevel ]; - bool bUseOpenGL = OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter; - - if (!bUspInited) - InitUSP(); - - if( !(rArgs.mnFlags & SalLayoutFlags::ComplexDisabled) ) + if( getenv("SAL_USE_COMMON_LAYOUT") ) { -#if ENABLE_GRAPHITE - if (rFontFace.SupportsGraphite()) - { - pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); - } - else -#endif // ENABLE_GRAPHITE - { - // script complexity is determined in upper layers - pWinLayout = new UniscribeLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); - // NOTE: it must be guaranteed that the WinSalGraphics lives longer than - // the created UniscribeLayout, otherwise the data passed into the - // constructor might become invalid too early - } + CommonSalLayout* pCommonSalLayout = new CommonSalLayout( getHDC(), rFontInstance ); + return pCommonSalLayout; } else { -#if ENABLE_GRAPHITE - if (rFontFace.SupportsGraphite()) - { - pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); - } - else -#endif // ENABLE_GRAPHITE - { - static bool bAvoidSimpleWinLayout = (std::getenv("VCL_NO_SIMPLEWINLAYOUT") != NULL); + bool bUseOpenGL = OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter; - if (!bAvoidSimpleWinLayout) - { - if( (rArgs.mnFlags & SalLayoutFlags::KerningPairs) && !rFontInstance.HasKernData() ) - { - // TODO: directly cache kerning info in the rFontInstance - // TODO: get rid of kerning methods+data in WinSalGraphics object - GetKernPairs(); - rFontInstance.SetKernData( mnFontKernPairCount, mpFontKernPairs ); - } + if (!bUspInited) + InitUSP(); - pWinLayout = new SimpleWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); + if( !(rArgs.mnFlags & SalLayoutFlags::ComplexDisabled) ) + { +#if ENABLE_GRAPHITE + if (rFontFace.SupportsGraphite()) + { + pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); } else +#endif // ENABLE_GRAPHITE { + // script complexity is determined in upper layers pWinLayout = new UniscribeLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); // NOTE: it must be guaranteed that the WinSalGraphics lives longer than // the created UniscribeLayout, otherwise the data passed into the // constructor might become invalid too early } } - } + else + { +#if ENABLE_GRAPHITE + if (rFontFace.SupportsGraphite()) + { + pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); + } + else +#endif // ENABLE_GRAPHITE + { + static bool bAvoidSimpleWinLayout = (std::getenv("VCL_NO_SIMPLEWINLAYOUT") != NULL); + + if (!bAvoidSimpleWinLayout) + { + if( (rArgs.mnFlags & SalLayoutFlags::KerningPairs) && !rFontInstance.HasKernData() ) + { + // TODO: directly cache kerning info in the rFontInstance + // TODO: get rid of kerning methods+data in WinSalGraphics object + GetKernPairs(); + rFontInstance.SetKernData( mnFontKernPairCount, mpFontKernPairs ); + } + + pWinLayout = new SimpleWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); + } + else + { + pWinLayout = new UniscribeLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL); + // NOTE: it must be guaranteed that the WinSalGraphics lives longer than + // the created UniscribeLayout, otherwise the data passed into the + // constructor might become invalid too early + } + } + } - if( mfFontScale[nFallbackLevel] != 1.0 ) - pWinLayout->SetFontScale( mfFontScale[nFallbackLevel] ); + if( mfFontScale[nFallbackLevel] != 1.0 ) + pWinLayout->SetFontScale( mfFontScale[nFallbackLevel] ); - return pWinLayout; + return pWinLayout; + } } int WinSalGraphics::GetMinKashidaWidth() @@ -4147,4 +4156,32 @@ LogicalFontInstance* WinFontFace::CreateFontInstance( FontSelectPattern& rFSD ) return pFontInstance; } +void WinSalGraphics::DrawSalLayout( const CommonSalLayout& rLayout ) +{ + HDC hDC = getHDC(); + + if((std::getenv("SAL_DWRITE_COMMON_LAYOUT"))) + { + Point aPos(0, 0); + int nGlyphCount(0); + TextOutRenderer &render = TextOutRenderer::get(); + bool result = render( rLayout, hDC, nullptr, &aPos, &nGlyphCount ); + assert( !result ); + } + else + { + Point aPos; + sal_GlyphId aGlyphId; + int nFetchedGlyphs = 0; + UINT oldTa = GetTextAlign( hDC ); + SetTextAlign( hDC, ( oldTa & ~TA_NOUPDATECP ) ); + while( rLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nFetchedGlyphs ) ) + { + ExtTextOutW( hDC, aPos.X(), aPos.Y(), ETO_GLYPH_INDEX, nullptr, reinterpret_cast<LPCWSTR>( &aGlyphId ), + 1, nullptr); + } + SetTextAlign(hDC, oldTa); + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit d815ef5a746eaa175cdf916d4bbf292999afb364 Author: Akash Jain <akash...@gmail.com> Date: Wed Jul 6 10:35:24 2016 +0530 GSoC: Integrate new CommonSalLayout in unx/ code Change-Id: I991cb5cbd2adad4f4c9f62f807990b9fde2a5133 diff --git a/vcl/README.vars b/vcl/README.vars index bf85485..b72d499 100644 --- a/vcl/README.vars +++ b/vcl/README.vars @@ -6,6 +6,7 @@ SAL_USE_VCLPLUGIN - use a VCL plugin SAL_NO_NWF - disable native widgets SAL_FORCEDPI - force a specific DPI (gtk & gtk3 plugins only) SAL_FORCE_HC - force high-contrast mode +SAL_USE_COMMON_LAYOUT - use CommonSalLayout layout engine for text layout VCL_DOUBLEBUFFERING_AVOID_PAINT - don't paint the buffer, useful to see where we do direct painting VCL_DOUBLEBUFFERING_FORCE_ENABLE - enable double buffered painting diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 0fdcd94..3c54dff 100755 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -372,7 +372,6 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) int32_t nYOffset = pHbPositions[i].y_offset >> 6; int32_t nXAdvance = pHbPositions[i].x_advance >> 6; int32_t nYAdvance = pHbPositions[i].y_advance >> 6; - Point aNewPos = Point(aCurrPos.X() + nXOffset, -(aCurrPos.Y() + nYOffset)); // Definiton of glyphitem may have to change to support system graphics lib const GlyphItem aGI(nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nXAdvance, nXOffset); diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx index b855446..0278965 100644 --- a/vcl/unx/generic/gdi/cairotextrender.cxx +++ b/vcl/unx/generic/gdi/cairotextrender.cxx @@ -42,6 +42,7 @@ #include <cairo.h> #include <cairo-ft.h> +#include "CommonSalLayout.hxx" CairoTextRender::CairoTextRender() : mnTextColor(MAKE_SALCOLOR(0x00, 0x00, 0x00)) //black @@ -506,7 +507,14 @@ SalLayout* CairoTextRender::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackL } else #endif - pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] ); + if(getenv("SAL_USE_COMMON_LAYOUT")) + { + pLayout = new CommonSalLayout( *mpServerFont[ nFallbackLevel ] ); + } + else + { + pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] ); + } } return pLayout; commit fba2c9a89a8221da3eec64f96e00a530a7099db1 Author: Akash Jain <akash...@gmail.com> Date: Wed Jul 6 10:15:49 2016 +0530 GSoC: Modify DrawServerFontLayout and add DrawSalLayout Modify the definiton of the DrawServerFontLayout method. Add new DrawSalLayout method which will be used for drawing text independent of the platform. Change-Id: Ie3eefb172b1781c685def1ef549db2538f672a62 diff --git a/vcl/headless/svptext.cxx b/vcl/headless/svptext.cxx index ac7d3dc..2c10d26 100644 --- a/vcl/headless/svptext.cxx +++ b/vcl/headless/svptext.cxx @@ -23,6 +23,7 @@ #include "headless/svpgdi.hxx" #include <config_cairo_canvas.h> #include "impfontmetricdata.hxx" +#include "CommonSalLayout.hxx" void SvpSalGraphics::SetFont( FontSelectPattern* pIFSD, int nFallbackLevel ) { @@ -116,9 +117,14 @@ SalLayout* SvpSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe return m_aTextRenderImpl.GetTextLayout(rArgs, nFallbackLevel); } -void SvpSalGraphics::DrawServerFontLayout( const ServerFontLayout& rSalLayout ) +void SvpSalGraphics::DrawServerFontLayout( const GenericSalLayout& rSalLayout, const ServerFont& rServerFont ) { - m_aTextRenderImpl.DrawServerFontLayout(rSalLayout ); + m_aTextRenderImpl.DrawServerFontLayout( rSalLayout, rServerFont ); +} + +void SvpSalGraphics::DrawSalLayout( const CommonSalLayout& rSalLayout ) +{ + DrawServerFontLayout( rSalLayout, rSalLayout.getFontData() ); } void SvpSalGraphics::SetTextColor( SalColor nSalColor ) diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index 76e4460..8615452 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -166,7 +166,8 @@ public: virtual bool GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) override; virtual bool GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) override; virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override; - virtual void DrawServerFontLayout( const ServerFontLayout& ) override; + virtual void DrawSalLayout( const CommonSalLayout& ) override; + virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) override; virtual bool supportsOperation( OutDevSupportType ) const override; virtual void drawPixel( long nX, long nY ) override; virtual void drawPixel( long nX, long nY, SalColor nSalColor ) override; diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index 0903966..3458e54 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -50,6 +50,7 @@ class AquaSalFrame; class FontAttributes; class CoreTextStyle; class XorEmulation; +class CommonSalLayout; typedef sal_uInt32 sal_GlyphId; @@ -402,7 +403,8 @@ public: virtual bool GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) override; virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override; - virtual void DrawServerFontLayout( const ServerFontLayout& ) override; + virtual void DrawSalLayout( const CommonSalLayout& ) override; + virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) {}; virtual bool supportsOperation( OutDevSupportType ) const override; #ifdef MACOSX diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx index c8f9a1c..3efbb2d 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -43,7 +43,8 @@ class Rectangle; class FontSubsetInfo; class OpenGLContext; class OutputDevice; -class ServerFontLayout; +class ServerFont; +class CommonSalLayout; struct SystemGraphicsData; #if ENABLE_CAIRO_CANVAS @@ -216,7 +217,8 @@ public: virtual bool GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) = 0; virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) = 0; - virtual void DrawServerFontLayout( const ServerFontLayout& ) = 0; + virtual void DrawSalLayout( const CommonSalLayout& ) = 0; + virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) = 0; virtual bool supportsOperation( OutDevSupportType ) const = 0; diff --git a/vcl/inc/textrender.hxx b/vcl/inc/textrender.hxx index 29559aa..d29bbf5 100644 --- a/vcl/inc/textrender.hxx +++ b/vcl/inc/textrender.hxx @@ -26,7 +26,6 @@ class ImplLayoutArgs; class ImplFontMetricData; -class ServerFontLayout; class PhysicalFontCollection; class PhysicalFontFace; @@ -71,7 +70,7 @@ public: virtual bool GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) = 0; virtual bool GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) = 0; virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) = 0; - virtual void DrawServerFontLayout( const ServerFontLayout& ) = 0; + virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) = 0; #if ENABLE_CAIRO_CANVAS virtual SystemFontData GetSysFontData( int nFallbackLevel ) const = 0; #endif // ENABLE_CAIRO_CANVAS diff --git a/vcl/inc/unx/cairotextrender.hxx b/vcl/inc/unx/cairotextrender.hxx index 1e2eb9c..771a8f3 100644 --- a/vcl/inc/unx/cairotextrender.hxx +++ b/vcl/inc/unx/cairotextrender.hxx @@ -118,7 +118,7 @@ public: virtual bool GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) override; virtual bool GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) override; virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override; - virtual void DrawServerFontLayout( const ServerFontLayout& ) override; + virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) override; #if ENABLE_CAIRO_CANVAS virtual SystemFontData GetSysFontData( int nFallbackLevel ) const override; #endif diff --git a/vcl/inc/unx/genpspgraphics.h b/vcl/inc/unx/genpspgraphics.h index f38dc0e..3f07162 100644 --- a/vcl/inc/unx/genpspgraphics.h +++ b/vcl/inc/unx/genpspgraphics.h @@ -34,6 +34,7 @@ class PhysicalFontCollection; namespace psp { struct JobData; class PrinterGfx; } class ServerFont; +class ServerFontLayout; class FontAttributes; class SalInfoPrinter; class GlyphCache; @@ -131,7 +132,9 @@ public: virtual bool GetGlyphBoundRect( sal_GlyphId, Rectangle& ) override; virtual bool GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) override; virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override; - virtual void DrawServerFontLayout( const ServerFontLayout& ) override; + virtual void DrawSalLayout( const CommonSalLayout& ) {}; + virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) {}; + virtual void DrawServerFontLayout( const ServerFontLayout& ); virtual bool supportsOperation( OutDevSupportType ) const override; virtual void drawPixel( long nX, long nY ) override; virtual void drawPixel( long nX, long nY, SalColor nSalColor ) override; diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index a9c91ed..2b453de 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -154,7 +154,8 @@ public: virtual bool GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) override; virtual bool GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) override; virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override; - virtual void DrawServerFontLayout( const ServerFontLayout& ) override; + virtual void DrawSalLayout( const CommonSalLayout& ) override; + virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) override; virtual bool supportsOperation( OutDevSupportType ) const override; virtual void drawPixel( long nX, long nY ) override; diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 7ad53b1..bc5165d 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -52,6 +52,7 @@ class PhysicalFontCollection; class SalGraphicsImpl; class WinOpenGLSalGraphicsImpl; class ImplFontMetricData; +class CommonSalLayout; #define RGB_TO_PALRGB(nRGB) ((nRGB)|0x02000000) #define PALRGB_TO_RGB(nPalRGB) ((nPalRGB)&0x00ffffff) @@ -450,7 +451,8 @@ public: virtual bool GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) override; virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override; - virtual void DrawServerFontLayout( const ServerFontLayout& ) override; + virtual void DrawSalLayout( const CommonSalLayout& ) override; + virtual void DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) {}; virtual bool supportsOperation( OutDevSupportType ) const override; // Query the platform layer for control support diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx index c28290a..86f1d49 100644 --- a/vcl/quartz/salgdi.cxx +++ b/vcl/quartz/salgdi.cxx @@ -41,6 +41,7 @@ #include "impfont.hxx" #include "impfontcharmap.hxx" #include "impfontmetricdata.hxx" +#include "CommonSalLayout.hxx" #ifdef MACOSX #include "osx/salframe.h" @@ -413,7 +414,7 @@ bool AquaSalGraphics::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect return bRC; } -void AquaSalGraphics::DrawServerFontLayout( const ServerFontLayout& ) +void AquaSalGraphics::DrawSalLayout( const CommonSalLayout& ) { } diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index 56d49e2..0fdcd94 100755 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -190,9 +190,10 @@ void CommonSalLayout::AdjustLayout(ImplLayoutArgs& rArgs) //XXX Kashida } -void CommonSalLayout::DrawText( SalGraphics& ) const +void CommonSalLayout::DrawText( SalGraphics& rSalGraphics ) const { //call platform dependent DrawText functions + rSalGraphics.DrawSalLayout( *this ); } bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx index d1ad180..b855446 100644 --- a/vcl/unx/generic/gdi/cairotextrender.cxx +++ b/vcl/unx/generic/gdi/cairotextrender.cxx @@ -152,7 +152,7 @@ namespace } } -void CairoTextRender::DrawServerFontLayout( const ServerFontLayout& rLayout ) +void CairoTextRender::DrawServerFontLayout( const GenericSalLayout& rLayout, const ServerFont& rFont ) { std::vector<cairo_glyph_t> cairo_glyphs; std::vector<int> glyph_extrarotation; @@ -185,7 +185,6 @@ void CairoTextRender::DrawServerFontLayout( const ServerFontLayout& rLayout ) if (cairo_glyphs.empty()) return; - ServerFont& rFont = rLayout.GetServerFont(); const FontSelectPattern& rFSD = rFont.GetFontSelData(); int nHeight = rFSD.mnHeight; int nWidth = rFSD.mnWidth ? rFSD.mnWidth : nHeight; diff --git a/vcl/unx/generic/gdi/font.cxx b/vcl/unx/generic/gdi/font.cxx index 3cc6510..9a6d6be 100644 --- a/vcl/unx/generic/gdi/font.cxx +++ b/vcl/unx/generic/gdi/font.cxx @@ -24,6 +24,7 @@ #include "unx/salgdi.h" #include "unx/salvd.h" #include "textrender.hxx" +#include "CommonSalLayout.hxx" GC X11SalGraphics::GetFontGC() @@ -52,9 +53,14 @@ X11SalGraphics::GetFontGC() return pFontGC_; } -void X11SalGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout ) +void X11SalGraphics::DrawServerFontLayout( const GenericSalLayout& rLayout, const ServerFont& rServerFont ) { - mxTextRenderImpl->DrawServerFontLayout(rLayout); + mxTextRenderImpl->DrawServerFontLayout(rLayout, rServerFont); +} + +void X11SalGraphics::DrawSalLayout( const CommonSalLayout& rLayout ) +{ + DrawServerFontLayout( rLayout, rLayout.getFontData() ); } const FontCharMapPtr X11SalGraphics::GetFontCharMap() const diff --git a/vcl/unx/generic/glyphs/gcach_layout.cxx b/vcl/unx/generic/glyphs/gcach_layout.cxx index dc9a84f..14be641 100644 --- a/vcl/unx/generic/glyphs/gcach_layout.cxx +++ b/vcl/unx/generic/glyphs/gcach_layout.cxx @@ -47,7 +47,7 @@ ServerFontLayout::ServerFontLayout( ServerFont& rFont ) void ServerFontLayout::DrawText( SalGraphics& rSalGraphics ) const { - rSalGraphics.DrawServerFontLayout( *this ); + rSalGraphics.DrawServerFontLayout( *this, mrServerFont ); } bool ServerFontLayout::LayoutText( ImplLayoutArgs& rArgs ) diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index 0c05700..95c9ae3 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -2614,7 +2614,7 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont, } } -void WinSalGraphics::DrawServerFontLayout( const ServerFontLayout& ) +void WinSalGraphics::DrawSalLayout( const CommonSalLayout& ) {} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits