Rebased ref, commits from common ancestor: commit 8e91f5987c28db7edd17989d570c34ac3e8fb292 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 0f6f15c..b961eef 100644 --- a/vcl/unx/generic/gdi/cairotextrender.cxx +++ b/vcl/unx/generic/gdi/cairotextrender.cxx @@ -504,7 +504,14 @@ SalLayout* CairoTextRender::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackL if (!bDisableGraphite_ && GraphiteServerFontLayout::IsGraphiteEnabledFont(*mpServerFont[nFallbackLevel])) { - pLayout = new GraphiteServerFontLayout(*mpServerFont[nFallbackLevel]); + if(getenv("SAL_USE_COMMON_LAYOUT")) + { + pLayout = new CommonSalLayout( *mpServerFont[ nFallbackLevel ] ); + } + else + { + pLayout = new GraphiteServerFontLayout(*mpServerFont[nFallbackLevel]); + } } else #endif diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index b503401..3ff6e77 100644 --- a/vcl/win/gdi/winlayout.cxx +++ b/vcl/win/gdi/winlayout.cxx @@ -68,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; }; @@ -82,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; }; @@ -107,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; @@ -139,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*/; @@ -3486,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) { @@ -3545,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) { @@ -3785,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(); @@ -4160,20 +4160,28 @@ void WinSalGraphics::DrawSalLayout( const GenericSalLayout& rLayout ) { HDC hDC = getHDC(); - Point aPos; - sal_GlyphId aGlyphId; - int nFetchedGlyphs = 0 ; - - UINT oldTa = GetTextAlign( hDC ); - SetTextAlign( hDC, ( oldTa & ~TA_NOUPDATECP ) ); - - while( rLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nFetchedGlyphs ) ) + if((std::getenv("SAL_DWRITE_COMMON_LAYOUT"))) { - ExtTextOutW( hDC, aPos.X(), aPos.Y(), ETO_GLYPH_INDEX, nullptr, reinterpret_cast<LPCWSTR>( &aGlyphId ), - 1, nullptr); + 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); } - - SetTextAlign(hDC, oldTa); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 3fc0ba8bd38a0c5e0c0c676171f5b474be1aa6a1 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 26fac32..a9a041b 100644 --- a/configure.ac +++ b/configure.ac @@ -9207,10 +9207,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 @@ -9301,7 +9305,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 f0a2e3bca5f106ffb09dab061c1b69d0a53aa08c 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 b128489..bb3ce33 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -110,6 +110,7 @@ private: CFMutableDictionaryRef mpStyleDict; friend class CTLayout; + friend class AquaSalGraphics; CFMutableDictionaryRef GetStyleDict( void ) const { return mpStyleDict; } }; @@ -402,8 +403,9 @@ public: virtual bool GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) override; virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override; - virtual void DrawSalLayout( const GenericSalLayout& ) override; + virtual void DrawSalLayout( const GenericSalLayout& ) {}; virtual void DrawSalLayout( const GenericSalLayout&, const ServerFont& ) {}; + virtual void DrawSalLayout( const GenericSalLayout& , const CoreTextStyle& ); virtual bool supportsOperation( OutDevSupportType ) const override; #ifdef MACOSX 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 0c46c95..f0ea9e6 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 097c087..9848e05 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" @@ -413,8 +413,38 @@ bool AquaSalGraphics::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect return bRC; } -void AquaSalGraphics::DrawSalLayout( const GenericSalLayout& ) -{ +void AquaSalGraphics::DrawSalLayout( const GenericSalLayout& rLayout, const CoreTextStyle& rCTStyle ) +{ + CGContextRef context = mrContext; + SAL_INFO( "vcl.ct", "CGContextSaveGState(" << context << ")" ); + CGContextSaveGState( context ); + SAL_INFO( "vcl.ct", "CGContextScaleCTM(" << context << ",1.0,-1.0)" ); + + 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 c988565..9afab84 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 @@ -207,6 +207,7 @@ void CommonSalLayout::DrawText( SalGraphics& rSalGraphics ) const #if defined(_WIN32) rSalGraphics.DrawSalLayout( *this ); #elif defined(MACOSX) || defined(IOS) + reinterpret_cast<AquaSalGraphics&>(rSalGraphics).DrawSalLayout( *this, mrCoreTextStyle ); #else rSalGraphics.DrawSalLayout( *this, mrServerFont ); #endif commit 632fa2c553768aa644e20815a339f4504f2ac6b8 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 da9a94e..c988565 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), @@ -194,6 +205,7 @@ void CommonSalLayout::DrawText( SalGraphics& rSalGraphics ) const { //call platform dependent DrawText functions #if defined(_WIN32) + rSalGraphics.DrawSalLayout( *this ); #elif defined(MACOSX) || defined(IOS) #else rSalGraphics.DrawSalLayout( *this, mrServerFont ); @@ -205,6 +217,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 d034faf..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 GenericSalLayout& ) -{} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index cbf0b58..b503401 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> @@ -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( mfFontScale[nFallbackLevel] != 1.0 ) - pWinLayout->SetFontScale( mfFontScale[nFallbackLevel] ); + 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 ); + } - return pWinLayout; + 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] ); + + return pWinLayout; + } } int WinSalGraphics::GetMinKashidaWidth() @@ -4147,4 +4156,24 @@ LogicalFontInstance* WinFontFace::CreateFontInstance( FontSelectPattern& rFSD ) return pFontInstance; } +void WinSalGraphics::DrawSalLayout( const GenericSalLayout& rLayout ) +{ + HDC hDC = getHDC(); + + 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 7beb604c046ee1c2a369c178216fa4ac18886e58 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 56d49e2..da9a94e 100755 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -190,9 +190,14 @@ void CommonSalLayout::AdjustLayout(ImplLayoutArgs& rArgs) //XXX Kashida } -void CommonSalLayout::DrawText( SalGraphics& ) const +void CommonSalLayout::DrawText( SalGraphics& rSalGraphics ) const { //call platform dependent DrawText functions +#if defined(_WIN32) +#elif defined(MACOSX) || defined(IOS) +#else + rSalGraphics.DrawSalLayout( *this, mrServerFont ); +#endif } bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) @@ -371,7 +376,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 5b1c454..0f6f15c 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 @@ -507,7 +508,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 0c10c9ded382bf5ec903957b39a8ab88f0779e76 Author: Akash Jain <akash...@gmail.com> Date: Wed Jul 6 10:15:49 2016 +0530 GSoC: Remove DrawServerFontLayout and add DrawSalLayout DrawServerFontLayout is removed. A more generic function DrawSalLayout with two different signatures is added. This allows the appropriate function to be used depending on the platform. Change-Id: Ie3eefb172b1781c685def1ef549db2538f672a62 diff --git a/vcl/headless/svptext.cxx b/vcl/headless/svptext.cxx index ac7d3dc..ecd094d 100644 --- a/vcl/headless/svptext.cxx +++ b/vcl/headless/svptext.cxx @@ -116,9 +116,9 @@ SalLayout* SvpSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe return m_aTextRenderImpl.GetTextLayout(rArgs, nFallbackLevel); } -void SvpSalGraphics::DrawServerFontLayout( const ServerFontLayout& rSalLayout ) +void SvpSalGraphics::DrawSalLayout( const GenericSalLayout& rSalLayout, const ServerFont& rServerFont ) { - m_aTextRenderImpl.DrawServerFontLayout(rSalLayout ); + m_aTextRenderImpl.DrawSalLayout( rSalLayout, rServerFont ); } void SvpSalGraphics::SetTextColor( SalColor nSalColor ) diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index 76e4460..2f08522 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 GenericSalLayout& ) {}; + virtual void DrawSalLayout( 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..b128489 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -402,7 +402,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 GenericSalLayout& ) override; + virtual void DrawSalLayout( 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 51b5e3e..9a7011d 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -43,7 +43,7 @@ class Rectangle; class FontSubsetInfo; class OpenGLContext; class OutputDevice; -class ServerFontLayout; +class ServerFont; struct SystemGraphicsData; #if ENABLE_CAIRO_CANVAS @@ -216,7 +216,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 GenericSalLayout& ) = 0; + virtual void DrawSalLayout( 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..52a1de7f 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,8 @@ 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 DrawSalLayout( const GenericSalLayout& ) = 0; + virtual void DrawSalLayout( 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..e153b1c 100644 --- a/vcl/inc/unx/cairotextrender.hxx +++ b/vcl/inc/unx/cairotextrender.hxx @@ -118,7 +118,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 GenericSalLayout& ) {}; + virtual void DrawSalLayout( 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..10e331c 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 GenericSalLayout& ) {}; + virtual void DrawSalLayout( const GenericSalLayout&, const ServerFont& ) {}; + virtual void DrawSalLayout( 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..021f697 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 GenericSalLayout& ) {}; + virtual void DrawSalLayout( 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..1a9ac159 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -450,7 +450,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 GenericSalLayout& ) override; + virtual void DrawSalLayout( 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..097c087 100644 --- a/vcl/quartz/salgdi.cxx +++ b/vcl/quartz/salgdi.cxx @@ -413,7 +413,7 @@ bool AquaSalGraphics::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect return bRC; } -void AquaSalGraphics::DrawServerFontLayout( const ServerFontLayout& ) +void AquaSalGraphics::DrawSalLayout( const GenericSalLayout& ) { } diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx index d1ad180..5b1c454 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::DrawSalLayout( const GenericSalLayout& rLayout, const ServerFont& rServerFont ) { std::vector<cairo_glyph_t> cairo_glyphs; std::vector<int> glyph_extrarotation; @@ -185,7 +185,7 @@ void CairoTextRender::DrawServerFontLayout( const ServerFontLayout& rLayout ) if (cairo_glyphs.empty()) return; - ServerFont& rFont = rLayout.GetServerFont(); + const ServerFont& rFont = rServerFont; 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..c2bba39 100644 --- a/vcl/unx/generic/gdi/font.cxx +++ b/vcl/unx/generic/gdi/font.cxx @@ -52,9 +52,9 @@ X11SalGraphics::GetFontGC() return pFontGC_; } -void X11SalGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout ) +void X11SalGraphics::DrawSalLayout( const GenericSalLayout& rLayout, const ServerFont& rServerFont ) { - mxTextRenderImpl->DrawServerFontLayout(rLayout); + mxTextRenderImpl->DrawSalLayout(rLayout, rServerFont); } 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..97a14d2 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.DrawSalLayout( *this, mrServerFont ); } bool ServerFontLayout::LayoutText( ImplLayoutArgs& rArgs ) diff --git a/vcl/unx/generic/print/genpspgraphics.cxx b/vcl/unx/generic/print/genpspgraphics.cxx index 51dfdc8..8c68ffd 100644 --- a/vcl/unx/generic/print/genpspgraphics.cxx +++ b/vcl/unx/generic/print/genpspgraphics.cxx @@ -761,7 +761,7 @@ void PspFontLayout::DrawText( SalGraphics& ) const DrawPrinterLayout( *this, mrPrinterGfx, false ); } -void GenPspGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout ) +void GenPspGraphics::DrawSalLayout( const ServerFontLayout& rLayout ) { // print complex text DrawPrinterLayout( rLayout, *m_pPrinterGfx, true ); diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index 0c05700..d034faf 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 GenericSalLayout& ) {} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit d27ad2365d5e1dba524c82f3cb0f963f15fc35ac Author: Akash Jain <akash...@gmail.com> Date: Tue Jun 14 14:52:16 2016 +0530 GSoC: Modify HARFBUZZ_LIBS flag if compiling with MSVC MSVC has a different format for specifying libs to be linked. Therefore, modify libs flag accordingly. Change-Id: Ib919c4b6b0cdac47a8a6ad6730d20e19bc05b0d4 diff --git a/configure.ac b/configure.ac index b9e7217..26fac32 100644 --- a/configure.ac +++ b/configure.ac @@ -9300,6 +9300,9 @@ if test "$with_harfbuzz" = "yes" -o \( $_os != WINNT -a $_os != Darwin -a $_os ! else 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" + fi else AC_MSG_RESULT([no]) fi commit 6c288f54d470964a57121346e5d21f53d4e88c9b Author: Akash Jain <akash...@gmail.com> Date: Tue Jun 14 14:38:12 2016 +0530 GSoC: New CommonSalLayout class created Change-Id: Ic11e573da2f5fd6ef931f53ab674f8894815c3b4 diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index fac270d..55e8391 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -303,6 +303,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/gdi/virdev \ vcl/source/gdi/wall \ vcl/source/gdi/scrptrun \ + vcl/source/gdi/CommonSalLayout \ vcl/source/bitmap/bitmapfilter \ vcl/source/bitmap/bitmapscalesuper \ vcl/source/bitmap/BitmapScaleConvolution \ diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx new file mode 100755 index 0000000..02eed49 --- /dev/null +++ b/vcl/inc/CommonSalLayout.hxx @@ -0,0 +1,65 @@ +/* -*- 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 . + */ + +#ifdef _WIN32 +#include "win/winlayout.hxx" + +#elif defined(MACOSX) || defined(IOS) +#include <com/sun/star/i18n/XBreakIterator.hpp> +#include "quartz/ctfonts.hxx" + +#else +#include "unx/freetype_glyphcache.hxx" +#endif + +#include <sallayout.hxx> +#include <hb-icu.h> +#include <hb-ot.h> + +class CommonSalLayout : public GenericSalLayout +{ + hb_face_t* mpHBFace; + FontSelectPattern maFontSelData; + css::uno::Reference<css::i18n::XBreakIterator> mxBreak; +#ifdef _WIN32 + HDC mhDC; + HFONT mhFont; +#elif defined(MACOSX) || defined(IOS) + const CoreTextStyle& mrCoreTextStyle; +#else + ServerFont& mrServerFont; +#endif + +public: +#if defined(_WIN32) + explicit CommonSalLayout(HDC, WinFontInstance&); + virtual void InitFont() const override; +#elif defined(MACOSX) || defined(IOS) + explicit CommonSalLayout(const CoreTextStyle&); +#else + explicit CommonSalLayout(ServerFont&); +#endif + + virtual ~CommonSalLayout(); + void SetNeedFallback(ImplLayoutArgs&, sal_Int32, bool); + void AdjustLayout(ImplLayoutArgs&) override; + virtual bool LayoutText(ImplLayoutArgs&) override; + virtual void DrawText( SalGraphics& ) const override; + std::shared_ptr<vcl::TextLayoutCache> CreateTextLayoutCache(OUString const&) const override; +}; diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index 3cf501d..0903966 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -103,6 +103,7 @@ public: float mfFontStretch; /// text rotation in radian float mfFontRotation; + FontSelectPattern maFontSelData; private: /// CoreText text style object diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx index 5bd6e7b..eb6e88c5 100644 --- a/vcl/quartz/ctfonts.cxx +++ b/vcl/quartz/ctfonts.cxx @@ -48,6 +48,7 @@ CoreTextStyle::CoreTextStyle( const FontSelectPattern& rFSD ) : mpFontData( static_cast<CoreTextFontFace const *>(rFSD.mpFontData) ) , mfFontStretch( 1.0 ) , mfFontRotation( 0.0 ) + , maFontSelData( rFSD ) , mpStyleDict( nullptr ) { const FontSelectPattern* const pReqFont = &rFSD; diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx new file mode 100755 index 0000000..56d49e2 --- /dev/null +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -0,0 +1,398 @@ +/* -*- 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 "CommonSalLayout.hxx" + +#include <vcl/unohelp.hxx> +#include <scrptrun.h> +#include <com/sun/star/i18n/CharacterIteratorMode.hpp> +#include <i18nlangtag/mslangid.hxx> +#include <limits> +#include <salgdi.hxx> + +static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pUserData) +{ + char pTagName[5]; + pTagName[0] = (char)(nTableTag >> 24); + pTagName[1] = (char)(nTableTag >> 16); + pTagName[2] = (char)(nTableTag >> 8); + pTagName[3] = (char)(nTableTag); + pTagName[4] = 0; + + sal_uLong nLength=0; +#if defined(_WIN32) + const unsigned char* pBuffer = nullptr; + HDC* phDC = static_cast<HDC*>(pUserData); + nLength = WinFontFace::GetTable(pTagName, pBuffer, *phDC); +#elif defined(MACOSX) || defined(IOS) + unsigned char* pBuffer = nullptr; + CoreTextFontFace* pFont = static_cast<CoreTextFontFace*>(pUserData); + nLength = pFont->GetFontTable(pTagName, nullptr); + if( nLength>0 ) + { + pBuffer = new unsigned char[nLength]; + } + pFont->GetFontTable(pTagName, pBuffer); +#else + const unsigned char* pBuffer = nullptr; + ServerFont* pFont = static_cast<ServerFont*>(pUserData); + pBuffer = pFont->GetTable(pTagName, &nLength); +#endif + + hb_blob_t* pBlob = nullptr; + if (pBuffer != nullptr) + pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY, nullptr, nullptr); + + return pBlob; +} + +static hb_unicode_funcs_t* getUnicodeFuncs() +{ + static hb_unicode_funcs_t* ufuncs = hb_unicode_funcs_create(hb_icu_get_unicode_funcs()); +#if !HB_VERSION_ATLEAST(1, 1, 0) + hb_unicode_funcs_set_decompose_compatibility_func(ufuncs, unicodeDecomposeCompatibility, nullptr, nullptr); +#endif + return ufuncs; +} + +#if defined(_WIN32) +CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance) +: mhDC(hDC), + mpHBFace(nullptr), + maFontSelData(rWinFontInstance.maFontSelData) +{ + mpHBFace = hb_face_create_for_tables(getFontTable, &hDC, nullptr); +} + +#elif defined(MACOSX) || defined(IOS) +CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle) +: mpHBFace(nullptr), + maFontSelData(rCoreTextStyle.maFontSelData), + mrCoreTextStyle(rCoreTextStyle) +{ + mpHBFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr); +} + +#else +CommonSalLayout::CommonSalLayout(ServerFont& rServerFont) +: mpHBFace(nullptr), + maFontSelData(rServerFont.GetFontSelData()), + mrServerFont(rServerFont) +{ + mpHBFace = hb_face_create_for_tables(getFontTable, &rServerFont, nullptr); +} +#endif + +CommonSalLayout::~CommonSalLayout() +{ + hb_face_destroy(mpHBFace); +} + +struct HbScriptRun +{ + int32_t mnMin; + int32_t mnEnd; + hb_script_t maScript; + + HbScriptRun(int32_t nMin, int32_t nEnd, UScriptCode aScript) + : mnMin(nMin), mnEnd(nEnd), + maScript(hb_icu_script_to_script(aScript)) + {} +}; + +typedef std::vector<HbScriptRun> HbScriptRuns; + +namespace vcl { + struct Run + { + int32_t nStart; + int32_t nEnd; + UScriptCode nCode; + Run(int32_t nStart_, int32_t nEnd_, UScriptCode nCode_) + : nStart(nStart_), nEnd(nEnd_), nCode(nCode_) + {} + }; + + class TextLayoutCache + { + public: + std::vector<vcl::Run> runs; + TextLayoutCache(sal_Unicode const* pStr, sal_Int32 const nEnd) + { + vcl::ScriptRun aScriptRun( + reinterpret_cast<const UChar *>(pStr), + nEnd); + while (aScriptRun.next()) + { + runs.push_back(Run(aScriptRun.getScriptStart(), + aScriptRun.getScriptEnd(), aScriptRun.getScriptCode())); + } + } + }; +} + +std::shared_ptr<vcl::TextLayoutCache> CommonSalLayout::CreateTextLayoutCache(OUString const& rString) const +{ + return std::make_shared<vcl::TextLayoutCache>(rString.getStr(), rString.getLength()); +} + +void CommonSalLayout::SetNeedFallback(ImplLayoutArgs& rArgs, sal_Int32 nCharPos, bool bRightToLeft) +{ + if (nCharPos < 0) + return; + + using namespace ::com::sun::star; + + if (!mxBreak.is()) + mxBreak = vcl::unohelper::CreateBreakIterator(); + + lang::Locale aLocale(rArgs.maLanguageTag.getLocale()); + + //if position nCharPos is missing in the font, grab the entire grapheme and + //mark all glyphs as missing so the whole thing is rendered with the same + //font + sal_Int32 nDone; + sal_Int32 nGraphemeStartPos = + mxBreak->previousCharacters(rArgs.mrStr, nCharPos+1, aLocale, + i18n::CharacterIteratorMode::SKIPCELL, 1, nDone); + sal_Int32 nGraphemeEndPos = + mxBreak->nextCharacters(rArgs.mrStr, nCharPos, aLocale, + i18n::CharacterIteratorMode::SKIPCELL, 1, nDone); + + rArgs.NeedFallback(nGraphemeStartPos, nGraphemeEndPos, bRightToLeft); +} + +void CommonSalLayout::AdjustLayout(ImplLayoutArgs& rArgs) +{ + GenericSalLayout::AdjustLayout(rArgs); + + // apply asian kerning if the glyphs are not already formatted + if( (rArgs.mnFlags & SalLayoutFlags::KerningAsian) + && !(rArgs.mnFlags & SalLayoutFlags::Vertical) ) + if( (rArgs.mpDXArray != nullptr) || (rArgs.mnLayoutWidth != 0) ) + ApplyAsianKerning(rArgs.mrStr); +//XXX Kashida +} + +void CommonSalLayout::DrawText( SalGraphics& ) const +{ + //call platform dependent DrawText functions +} + +bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs) +{ + //XXX WinLayout object DOESN'T derive from GSL + GenericSalLayout& rLayout = *this; + + 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 + , (uint64_t)maFontSelData.mnHeight << 6); + hb_ot_font_set_funcs(pHBFont); + + int nGlyphCapacity = 2 * (rArgs.mnEndCharPos - rArgs.mnMinCharPos); + rLayout.Reserve(nGlyphCapacity); + + const int nLength = rArgs.mrStr.getLength(); + const sal_Unicode *pStr = rArgs.mrStr.getStr(); + + std::unique_ptr<vcl::TextLayoutCache> pNewScriptRun; + vcl::TextLayoutCache const* pTextLayout; + if (rArgs.m_pTextLayoutCache) + { + pTextLayout = rArgs.m_pTextLayoutCache; // use cache! + } + else + { + pNewScriptRun.reset(new vcl::TextLayoutCache(pStr, rArgs.mnEndCharPos)); + pTextLayout = pNewScriptRun.get(); + } + + Point aCurrPos(0, 0); + while (true) + { + int nBidiMinRunPos, nBidiEndRunPos; + bool bRightToLeft; + if (!rArgs.GetNextRun(&nBidiMinRunPos, &nBidiEndRunPos, &bRightToLeft)) + break; + + // Find script subruns. + int nCurrentPos = nBidiMinRunPos; + HbScriptRuns aScriptSubRuns; + size_t k = 0; + for (; k < pTextLayout->runs.size(); ++k) + { + vcl::Run const& rRun(pTextLayout->runs[k]); + if (rRun.nStart <= nCurrentPos && nCurrentPos < rRun.nEnd) + { + break; + } + } + + while (nCurrentPos < nBidiEndRunPos && k < pTextLayout->runs.size()) + { + int32_t nMinRunPos = nCurrentPos; + int32_t nEndRunPos = std::min(pTextLayout->runs[k].nEnd, nBidiEndRunPos); + HbScriptRun aRun(nMinRunPos, nEndRunPos, pTextLayout->runs[k].nCode); + aScriptSubRuns.push_back(aRun); + + nCurrentPos = nEndRunPos; + ++k; + } + + // RTL subruns should be reversed to ensure that final glyph order is + // correct. + if (bRightToLeft) + std::reverse(aScriptSubRuns.begin(), aScriptSubRuns.end()); + + for (HbScriptRuns::iterator it = aScriptSubRuns.begin(); it != aScriptSubRuns.end(); ++it) + { + int nMinRunPos = it->mnMin; + int nEndRunPos = it->mnEnd; + int nRunLen = nEndRunPos - nMinRunPos; + hb_script_t aHbScript = it->maScript; + // hb_language_from_string() accept ISO639-3 language tag except for Chinese. + LanguageTag &rTag = rArgs.maLanguageTag; + OString sLanguage = OUStringToOString( MsLangId::isChinese(rTag.getLanguageType()) ? rTag.getBcp47():rTag.getLanguage() , RTL_TEXTENCODING_UTF8 ); + + int nHbFlags = HB_BUFFER_FLAGS_DEFAULT; + if (nMinRunPos == 0) + nHbFlags |= HB_BUFFER_FLAG_BOT; /* Beginning-of-text */ + if (nEndRunPos == nLength) + nHbFlags |= HB_BUFFER_FLAG_EOT; /* End-of-text */ + + hb_buffer_t *pHbBuffer = hb_buffer_create(); + static hb_unicode_funcs_t* pHbUnicodeFuncs = getUnicodeFuncs(); +#if !HB_VERSION_ATLEAST(1, 1, 0) + hb_buffer_set_unicode_funcs(pHbBuffer, pHbUnicodeFuncs); +#endif + hb_buffer_set_direction(pHbBuffer, bRightToLeft ? HB_DIRECTION_RTL: HB_DIRECTION_LTR); + hb_buffer_set_script(pHbBuffer, aHbScript); + hb_buffer_set_language(pHbBuffer, hb_language_from_string(sLanguage.getStr(), -1)); + hb_buffer_set_flags(pHbBuffer, (hb_buffer_flags_t) nHbFlags); + hb_buffer_add_utf16( + pHbBuffer, reinterpret_cast<uint16_t const *>(pStr), nLength, + nMinRunPos, nRunLen); +#if HB_VERSION_ATLEAST(0, 9, 42) + hb_buffer_set_cluster_level(pHbBuffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); +#endif + hb_shape(pHBFont, pHbBuffer, nullptr, 0); + + int nRunGlyphCount = hb_buffer_get_length(pHbBuffer); + hb_glyph_info_t *pHbGlyphInfos = hb_buffer_get_glyph_infos(pHbBuffer, nullptr); + hb_glyph_position_t *pHbPositions = hb_buffer_get_glyph_positions(pHbBuffer, nullptr); + + sal_Int32 nGraphemeStartPos = std::numeric_limits<sal_Int32>::max(); + sal_Int32 nGraphemeEndPos = std::numeric_limits<sal_Int32>::min(); + com::sun::star::lang::Locale aLocale(rArgs.maLanguageTag.getLocale()); + if (!mxBreak.is()) + mxBreak = vcl::unohelper::CreateBreakIterator(); + + for (int i = 0; i < nRunGlyphCount; ++i) { + int32_t nGlyphIndex = pHbGlyphInfos[i].codepoint; + int32_t nCharPos = pHbGlyphInfos[i].cluster; + + // if needed request glyph fallback by updating LayoutArgs + if (!nGlyphIndex) + { + SetNeedFallback(rArgs, nCharPos, bRightToLeft); + if (SalLayoutFlags::ForFallback & rArgs.mnFlags) + continue; + } + + sal_Int32 indexUtf16 = nCharPos; + sal_UCS4 aChar = rArgs.mrStr.iterateCodePoints(&indexUtf16, 0); + + bool bInCluster = false; + if(bRightToLeft && (nCharPos < nGraphemeStartPos)) + { + sal_Int32 nDone; + nGraphemeStartPos = mxBreak->previousCharacters(rArgs.mrStr, nCharPos+1, aLocale, + com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 1, nDone); + } + else if(!bRightToLeft && (nCharPos >= nGraphemeEndPos)) + { + sal_Int32 nDone; + nGraphemeEndPos = mxBreak->nextCharacters(rArgs.mrStr, nCharPos, aLocale, + com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 1, nDone); + } + else + { + bInCluster = true; + } + + long nGlyphFlags = 0; + if (bRightToLeft) + nGlyphFlags |= GlyphItem::IS_RTL_GLYPH; + + if (bInCluster) + nGlyphFlags |= GlyphItem::IS_IN_CLUSTER; + + bool bDiacritic = false; + if (hb_ot_layout_has_glyph_classes(mpHBFace)) + { + // the font has GDEF table + bool bMark = hb_ot_layout_get_glyph_class(mpHBFace, nGlyphIndex) == HB_OT_LAYOUT_GLYPH_CLASS_MARK; + if (bMark && pHbPositions[i].x_advance == 0) + bDiacritic = true; + } + else + { +#if HB_VERSION_ATLEAST(0, 9, 42) + if(hb_unicode_general_category (pHbUnicodeFuncs, aChar) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) + bDiacritic = true; +#else + // the font lacks GDEF table + if (pHbPositions[i].x_advance == 0) + bDiacritic = true; +#endif + } + + if (bDiacritic) + nGlyphFlags |= GlyphItem::IS_DIACRITIC; + + int32_t nXOffset = pHbPositions[i].x_offset >> 6; + 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); + rLayout.AppendGlyph(aGI); + + aCurrPos.X() += nXAdvance; + aCurrPos.Y() += nYAdvance; + } + + hb_buffer_destroy(pHbBuffer); + } + } + + hb_font_destroy(pHBFont); + + rLayout.SortGlyphItems(); + + /* XXX seems to be broken + if((rArgs.mpDXArray || rArgs.mnLayoutWidth) + && ((maHbScript == HB_SCRIPT_ARABIC) || (maHbScript == HB_SCRIPT_SYRIAC))) + rArgs.mnFlags |= SalLayoutFlags::KashidaJustification; + */ + return true; +} commit b194af9f5ba69511a040bded7af422e6fca66713 Author: Akash Jain <akash...@gmail.com> Date: Tue Jun 14 13:46:18 2016 +0530 GSoC: Move code from winlayout.cxx to winlayout.hxx WinFontInstance definition moved to winlayout.hxx. It has to be used in the new layout class. Code and headers which WinFontInstance depends on also moved to winlayout.hxx Change-Id: Idc8f87e6601c220d504398671326b1f23d1779a3 diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx old mode 100644 new mode 100755 index 6709cb1..7905513 --- a/vcl/inc/win/winlayout.hxx +++ b/vcl/inc/win/winlayout.hxx @@ -28,15 +28,195 @@ #include <usp10.h> +#include "opengl/PackedTextureAtlas.hxx" + +typedef std::unordered_map<int,int> IntMap; + // Graphite headers #include <config_graphite.h> #if ENABLE_GRAPHITE #include <graphite_layout.hxx> +#include <i18nlangtag/languagetag.hxx> +#include <graphite_features.hxx> +#if ENABLE_GRAPHITE_DWRITE +#include <d2d1.h> +#include <dwrite.h> +#endif #endif +// This needs to come after any includes for d2d1.h, otherwise we get lots of errors +#include "glyphy/demo.hxx" + class WinFontInstance; struct VisualItem; +namespace +{ +// Extra space at the top and bottom of the glyph in total = tmHeight / GLYPH_SPACE_RATIO; +const int GLYPH_SPACE_RATIO = 8; +// Border size at the top of the glyph = tmHeight / GLYPH_OFFSET_RATIO; +const int GLYPH_OFFSET_RATIO = GLYPH_SPACE_RATIO * 2; +} + +struct OpenGLGlyphDrawElement +{ + Rectangle maLocation; + int maLeftOverhangs; + OpenGLTexture maTexture; + int mnBaselineOffset; + int mnHeight; + bool mbVertical; + bool mbRealGlyphIndices; + + int getExtraSpace() const + { + return std::max(mnHeight / GLYPH_SPACE_RATIO, 4); + } + + int getExtraOffset() const + { + return std::max(mnHeight / GLYPH_OFFSET_RATIO, 2); + } +}; + +class GlyphCache; + +struct GlobalGlyphCache +{ + GlobalGlyphCache() + : maPackedTextureAtlas(2048, 2048) + {} + + PackedTextureAtlasManager maPackedTextureAtlas; + std::unordered_set<GlyphCache*> maGlyphCaches; +}; + +class GlyphCache +{ +private: + static std::unique_ptr<GlobalGlyphCache> gGlobalGlyphCache; + std::unordered_map<int, OpenGLGlyphDrawElement> maOpenGLTextureCache; + +public: + GlyphCache() + { + gGlobalGlyphCache.get()->maGlyphCaches.insert(this); + } + + ~GlyphCache() + { + gGlobalGlyphCache.get()->maGlyphCaches.erase(this); + } + + bool ReserveTextureSpace(OpenGLGlyphDrawElement& rElement, int nWidth, int nHeight) + { + GlobalGlyphCache* pGlobalGlyphCache = gGlobalGlyphCache.get(); + rElement.maTexture = pGlobalGlyphCache->maPackedTextureAtlas.Reserve(nWidth, nHeight); + if (!rElement.maTexture) + return false; + std::vector<GLuint> aTextureIDs = pGlobalGlyphCache->maPackedTextureAtlas.ReduceTextureNumber(8); + if (!aTextureIDs.empty()) + { + for (auto& pGlyphCache: pGlobalGlyphCache->maGlyphCaches) + { + pGlyphCache->RemoveTextures(aTextureIDs); + } + } + return true; + } + + void RemoveTextures(std::vector<GLuint>& rTextureIDs) + { + auto it = maOpenGLTextureCache.begin(); + + while (it != maOpenGLTextureCache.end()) + { + GLuint nTextureID = it->second.maTexture.Id(); + + if (std::find(rTextureIDs.begin(), rTextureIDs.end(), nTextureID) != rTextureIDs.end()) + { + it = maOpenGLTextureCache.erase(it); + } + else + { + ++it; + } + } + } + + void PutDrawElementInCache(const OpenGLGlyphDrawElement& rElement, int nGlyphIndex) + { + assert(!IsGlyphCached(nGlyphIndex)); + maOpenGLTextureCache[nGlyphIndex] = OpenGLGlyphDrawElement(rElement); + } + + OpenGLGlyphDrawElement& GetDrawElement(int nGlyphIndex) + { + assert(IsGlyphCached(nGlyphIndex)); + return maOpenGLTextureCache[nGlyphIndex]; + } + + bool IsGlyphCached(int nGlyphIndex) const + { + return maOpenGLTextureCache.find(nGlyphIndex) != maOpenGLTextureCache.end(); + } +}; + +// win32 specific physical font instance +class WinFontInstance : public LogicalFontInstance +{ +public: + explicit WinFontInstance( FontSelectPattern& ); + virtual ~WinFontInstance(); + void setupGLyphy(HDC hDC); + +private: + // TODO: also add HFONT??? Watch out for issues with too many active fonts... + +public: + bool HasKernData() const; + void SetKernData( int, const KERNINGPAIR* ); + int GetKerning( sal_Unicode, sal_Unicode ) const; + +private: + KERNINGPAIR* mpKerningPairs; + int mnKerningPairs; + +public: + SCRIPT_CACHE& GetScriptCache() const + { return maScriptCache; } +private: + mutable SCRIPT_CACHE maScriptCache; + +public: + int GetCachedGlyphWidth( int nCharCode ) const; + void CacheGlyphWidth( int nCharCode, int nCharWidth ); + + bool InitKashidaHandling( HDC ); + int GetMinKashidaWidth() const { return mnMinKashidaWidth; } + int GetMinKashidaGlyph() const { return mnMinKashidaGlyph; } + + static GLuint mnGLyphyProgram; + demo_atlas_t* mpGLyphyAtlas; + demo_font_t* mpGLyphyFont; + +private: + GlyphCache maGlyphCache; +public: + bool CacheGlyphToAtlas(bool bRealGlyphIndices, int nGlyphIndex, const WinLayout& rLayout, SalGraphics& rGraphics); + + GlyphCache& GetGlyphCache() + { + return maGlyphCache; + } + +private: + IntMap maWidthMap; + mutable int mnMinKashidaWidth; + mutable int mnMinKashidaGlyph; + bool mbGLyphySetupCalled; +}; + class WinLayout : public SalLayout { public: diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index f8675a6..cbf0b58 100644 --- a/vcl/win/gdi/winlayout.cxx +++ b/vcl/win/gdi/winlayout.cxx @@ -26,7 +26,6 @@ #include <opengl/texture.hxx> #include <opengl/win/gdiimpl.hxx> -#include "opengl/PackedTextureAtlas.hxx" #include <vcl/opengl/OpenGLHelper.hxx> #include <win/salgdi.h> @@ -50,193 +49,10 @@ #include <unordered_map> #include <unordered_set> -// Graphite headers -#include <config_graphite.h> -#if ENABLE_GRAPHITE -#include <i18nlangtag/languagetag.hxx> -#include <graphite_features.hxx> -#if ENABLE_GRAPHITE_DWRITE -#include <d2d1.h> -#include <dwrite.h> -#endif -#endif - -// This needs to come after any includes for d2d1.h, otherwise we get lots of errors -#include "glyphy/demo.hxx" - - #define DROPPED_OUTGLYPH 0xFFFF -namespace -{ -// Extra space at the top and bottom of the glyph in total = tmHeight / GLYPH_SPACE_RATIO; -const int GLYPH_SPACE_RATIO = 8; -// Border size at the top of the glyph = tmHeight / GLYPH_OFFSET_RATIO; -const int GLYPH_OFFSET_RATIO = GLYPH_SPACE_RATIO * 2; -} - -struct OpenGLGlyphDrawElement -{ - Rectangle maLocation; - int maLeftOverhangs; - OpenGLTexture maTexture; - int mnBaselineOffset; - int mnHeight; - bool mbVertical; - bool mbRealGlyphIndices; - - int getExtraSpace() const - { - return std::max(mnHeight / GLYPH_SPACE_RATIO, 4); - } - - int getExtraOffset() const - { - return std::max(mnHeight / GLYPH_OFFSET_RATIO, 2); - } -}; - -class GlyphCache; - -struct GlobalGlyphCache -{ - GlobalGlyphCache() - : maPackedTextureAtlas(2048, 2048) - {} - - PackedTextureAtlasManager maPackedTextureAtlas; - std::unordered_set<GlyphCache*> maGlyphCaches; -}; - -class GlyphCache -{ -private: - static std::unique_ptr<GlobalGlyphCache> gGlobalGlyphCache; - std::unordered_map<int, OpenGLGlyphDrawElement> maOpenGLTextureCache; - -public: - GlyphCache() - { - gGlobalGlyphCache.get()->maGlyphCaches.insert(this); - } - - ~GlyphCache() - { - gGlobalGlyphCache.get()->maGlyphCaches.erase(this); - } - - bool ReserveTextureSpace(OpenGLGlyphDrawElement& rElement, int nWidth, int nHeight) - { - GlobalGlyphCache* pGlobalGlyphCache = gGlobalGlyphCache.get(); - rElement.maTexture = pGlobalGlyphCache->maPackedTextureAtlas.Reserve(nWidth, nHeight); - if (!rElement.maTexture) - return false; - std::vector<GLuint> aTextureIDs = pGlobalGlyphCache->maPackedTextureAtlas.ReduceTextureNumber(8); - if (!aTextureIDs.empty()) - { - for (auto& pGlyphCache: pGlobalGlyphCache->maGlyphCaches) - { - pGlyphCache->RemoveTextures(aTextureIDs); - } - } - return true; - } - - void RemoveTextures(std::vector<GLuint>& rTextureIDs) - { - auto it = maOpenGLTextureCache.begin(); - - while (it != maOpenGLTextureCache.end()) - { - GLuint nTextureID = it->second.maTexture.Id(); - - if (std::find(rTextureIDs.begin(), rTextureIDs.end(), nTextureID) != rTextureIDs.end()) - { - it = maOpenGLTextureCache.erase(it); - } - else - { - ++it; - } - } - } - - void PutDrawElementInCache(const OpenGLGlyphDrawElement& rElement, int nGlyphIndex) - { - assert(!IsGlyphCached(nGlyphIndex)); - maOpenGLTextureCache[nGlyphIndex] = OpenGLGlyphDrawElement(rElement); - } - - OpenGLGlyphDrawElement& GetDrawElement(int nGlyphIndex) - { - assert(IsGlyphCached(nGlyphIndex)); - return maOpenGLTextureCache[nGlyphIndex]; - } - - bool IsGlyphCached(int nGlyphIndex) const - { - return maOpenGLTextureCache.find(nGlyphIndex) != maOpenGLTextureCache.end(); - } -}; - // static initialization std::unique_ptr<GlobalGlyphCache> GlyphCache::gGlobalGlyphCache(new GlobalGlyphCache); - -// win32 specific physical font instance -class WinFontInstance : public LogicalFontInstance -{ -public: - explicit WinFontInstance( FontSelectPattern& ); - virtual ~WinFontInstance(); - void setupGLyphy(HDC hDC); - -private: - // TODO: also add HFONT??? Watch out for issues with too many active fonts... - -public: - bool HasKernData() const; - void SetKernData( int, const KERNINGPAIR* ); - int GetKerning( sal_Unicode, sal_Unicode ) const; - -private: - KERNINGPAIR* mpKerningPairs; - int mnKerningPairs; - -public: - SCRIPT_CACHE& GetScriptCache() const - { return maScriptCache; } -private: - mutable SCRIPT_CACHE maScriptCache; - -public: - int GetCachedGlyphWidth( int nCharCode ) const; - void CacheGlyphWidth( int nCharCode, int nCharWidth ); - - bool InitKashidaHandling( HDC ); - int GetMinKashidaWidth() const { return mnMinKashidaWidth; } - int GetMinKashidaGlyph() const { return mnMinKashidaGlyph; } - - static GLuint mnGLyphyProgram; - demo_atlas_t* mpGLyphyAtlas; - demo_font_t* mpGLyphyFont; - -private: - GlyphCache maGlyphCache; -public: - bool CacheGlyphToAtlas(bool bRealGlyphIndices, int nGlyphIndex, const WinLayout& rLayout, SalGraphics& rGraphics); - - GlyphCache& GetGlyphCache() - { - return maGlyphCache; - } - -private: - std::unordered_map<int, int> maWidthMap; - mutable int mnMinKashidaWidth; - mutable int mnMinKashidaGlyph; - bool mbGLyphySetupCalled; -}; - GLuint WinFontInstance::mnGLyphyProgram = 0; class TextOutRenderer commit 860767970796ae6ccc585e7b4029e20227f17110 Author: Akash Jain <akash...@gmail.com> Date: Tue Jun 14 13:37:18 2016 +0530 GSoC: Move winlayout header file to vcl/inc/win The winlayout header file will need to be included in the new layout class. Its better to move it to vcl/inc. Change-Id: Ifb4170e1948dc56b5ec1728380eff7c2b4a07137 diff --git a/vcl/win/gdi/winlayout.hxx b/vcl/inc/win/winlayout.hxx similarity index 100% rename from vcl/win/gdi/winlayout.hxx rename to vcl/inc/win/winlayout.hxx diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index d0f0b9a..f8675a6 100644 --- a/vcl/win/gdi/winlayout.cxx +++ b/vcl/win/gdi/winlayout.cxx @@ -17,7 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#include "winlayout.hxx" +#include "win/winlayout.hxx" #include "osl/module.h" #include "osl/file.h" commit e0bbbe687f7cba0d413c0304a8e7659c539f0102 Author: Akash Jain <akash...@gmail.com> Date: Tue Jun 14 13:12:12 2016 +0530 GSoC: Move scrptrun header and source file out of unx Scrptrun class will be used by the new layout engine for script itemisation. It will need to be compiled on all platforms. Therefore move the header and source file to vcl/inc/ and vcl/source/gdi/ respectively. Change-Id: If4e1e0e76ffb94f9d0ca08f7d5f9982dd907c1c6 diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 0b26fdf..fac270d 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -302,6 +302,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\ vcl/source/gdi/textlayout \ vcl/source/gdi/virdev \ vcl/source/gdi/wall \ + vcl/source/gdi/scrptrun \ vcl/source/bitmap/bitmapfilter \ vcl/source/bitmap/bitmapscalesuper \ vcl/source/bitmap/BitmapScaleConvolution \ @@ -552,7 +553,6 @@ vcl_headless_freetype_code=\ vcl/unx/generic/glyphs/freetype_glyphcache \ vcl/unx/generic/glyphs/gcach_layout \ vcl/unx/generic/glyphs/glyphcache \ - vcl/unx/generic/glyphs/scrptrun \ vcl/unx/generic/fontmanager/fontsubst \ vcl/unx/generic/fontmanager/fontcache \ vcl/unx/generic/fontmanager/fontconfig \ diff --git a/vcl/unx/generic/glyphs/scrptrun.h b/vcl/inc/scrptrun.h old mode 100644 new mode 100755 similarity index 100% rename from vcl/unx/generic/glyphs/scrptrun.h rename to vcl/inc/scrptrun.h diff --git a/vcl/unx/generic/glyphs/scrptrun.cxx b/vcl/source/gdi/scrptrun.cxx old mode 100644 new mode 100755 similarity index 100% rename from vcl/unx/generic/glyphs/scrptrun.cxx rename to vcl/source/gdi/scrptrun.cxx _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits