Rebased ref, commits from common ancestor: commit 0ff787a1889f84c74f8dcdea4527bdfe6ae04ab5 Author: Akash Jain <akash...@gmail.com> Date: Thu Jul 21 00:00:46 2016 +0530
GSoC: Integrate new CommonSalLayout in quartz/ code Change-Id: I07a9c956f09be5d43ee58ff0784ba0f81f52cd9a diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index bed6358..543cfdc 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; } }; @@ -403,8 +404,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/ctlayout.cxx b/vcl/quartz/ctlayout.cxx index 19a6cc5..dc92d9b 100644 --- a/vcl/quartz/ctlayout.cxx +++ b/vcl/quartz/ctlayout.cxx @@ -28,6 +28,7 @@ #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 eabb476..b194f4f 100644 --- a/vcl/quartz/salgdi.cxx +++ b/vcl/quartz/salgdi.cxx @@ -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 ebe67c8..707ff04 100755 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -69,7 +69,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 @@ -220,6 +220,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 eff5ac49b7791ee663439e00d611ab7971b10b89 Author: Akash Jain <akash...@gmail.com> Date: Wed Jul 20 23:51:56 2016 +0530 GSoC: Move ctfonts.hxx header from quartz/ to inc/quartz/ Change-Id: I047363c363937985060784c93bd30ab5a30d77e2 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/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx index aad3334..e25058f 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 6bdcad3..19a6cc5 100644 --- a/vcl/quartz/ctlayout.cxx +++ b/vcl/quartz/ctlayout.cxx @@ -25,7 +25,7 @@ #include <sal/types.h> #include <tools/debug.hxx> -#include "ctfonts.hxx" +#include "quartz/ctfonts.hxx" #include "CTRunData.hxx" #include "quartz/utils.h" diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx index e52452b..eabb476 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" commit 3a9b3179a859ccaddeb179dab1975403c9ceaaec 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 94d9eb1..ebe67c8 100755 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -69,7 +69,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; } @@ -86,6 +91,7 @@ static hb_unicode_funcs_t* getUnicodeFuncs() #if defined(_WIN32) CommonSalLayout::CommonSalLayout(HDC hDC, const WinFontFace& rWinFontFace, WinFontInstance& rWinFontInstance) : mhDC(hDC), + mhFont((HFONT)GetCurrentObject(hDC, OBJ_FONT)), mpHBFace(nullptr), maFontSelData(rWinFontInstance.maFontSelData) { @@ -93,6 +99,11 @@ CommonSalLayout::CommonSalLayout(HDC hDC, const WinFontFace& rWinFontFace, WinFo mpHBFace = hb_face_create_for_tables(getFontTable, &rWinFontFaceWithHDC, nullptr); } +void CommonSalLayout::InitFont() const +{ + SelectObject( mhDC, mhFont ); +} + #elif defined(MACOSX) || defined(IOS) CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle) : mpHBFace(nullptr), @@ -207,6 +218,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 ); @@ -218,6 +230,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 e740835..845333f 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -2606,7 +2606,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 4e0c0eb..0db5286 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> @@ -3967,66 +3968,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(), rFontFace, 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() @@ -4135,4 +4144,39 @@ LogicalFontInstance* WinFontFace::CreateFontInstance( FontSelectPattern& rFSD ) return pFontInstance; } +void WinSalGraphics::DrawSalLayout( const GenericSalLayout& rLayout ) +{ + HDC hDC = getHDC(); + + Point aStartPos; + sal_GlyphId aGlyphId; + int nFetchedGlyphs = 0 ; + + UINT oldTa = GetTextAlign( hDC ); + SetTextAlign( hDC, ( oldTa & ~TA_NOUPDATECP ) ); + + while( rLayout.GetNextGlyphs( 1, &aGlyphId, aStartPos, nFetchedGlyphs ) ) + { + std::vector<uint16_t> aGlyphIds; + std::vector<const int> aGlyphDx; + Point aCurPos, aNextPos; + int nGlyphCount; + + aGlyphIds.push_back( aGlyphId & GF_IDXMASK ); + aCurPos = aStartPos; + nGlyphCount = 1; + + for( ; nGlyphCount < 8192 && rLayout.GetNextGlyphs( 1, &aGlyphId, aNextPos, nFetchedGlyphs ); nGlyphCount++ ) + { + aGlyphIds.push_back( aGlyphId & GF_IDXMASK ); + aGlyphDx.push_back( (aNextPos.X() - aCurPos.X()) ); + aCurPos = aNextPos; + } + + ExtTextOutW( hDC, aStartPos.X(), aStartPos.Y(), ETO_GLYPH_INDEX, nullptr, reinterpret_cast<LPCWSTR>( aGlyphIds.data() ), + nGlyphCount, aGlyphDx.data() ); + } + SetTextAlign(hDC, oldTa); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 2c34f9ed8c76be30b566fcf2d98e9ec62af22beb Author: Akash Jain <akash...@gmail.com> Date: Wed Jul 6 10:35:24 2016 +0530 GSoC: Integrate new CommonSalLayout class in unx/ 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 2aa4f83..94d9eb1 100755 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -203,9 +203,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) @@ -384,7 +389,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 1b60065..10079c9 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 fef669c2f35a4427c539a0a0d0b9bb08a7b9c884 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 e8fd525..3a3f300 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 dc88a60..c3dd5c3 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -152,7 +152,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 78b7433..bed6358 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -403,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 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 56fe42d..ee40d61 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 @@ -217,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 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 e08274e..6e44d7c 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 612daae..b73d637 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 b7658b9..ab8d1d1 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 40aa91b..a1472e3 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 b6e8cce..385ccf5 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -451,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 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 6c62b81..e52452b 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 513f5e5..1b60065 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 1669465..2183ab2 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 78eee82..6a1d912 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 4c8865e..e740835 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -2606,7 +2606,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 2c2f04ab483ee57ba85dfaaef56657a3cc3f5793 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 b9565a9..e0993b4 100644 --- a/configure.ac +++ b/configure.ac @@ -9219,6 +9219,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 4b964ca3ed7e2b0330291f80d4117eaca30a3aac 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 a43402b..026a42d 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -299,6 +299,8 @@ $(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/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..aa9d3ad --- /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, const WinFontFace&, 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 09dc619..78b7433 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -104,6 +104,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 5f4347b..aad3334 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..2aa4f83 --- /dev/null +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -0,0 +1,411 @@ +/* -*- 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> + +#if defined(_WIN32) +struct WinFontFaceWithHDC +{ + const WinFontFace& mrWinFontFace; + HDC mhDC; + WinFontFaceWithHDC(const WinFontFace& rWFF, HDC hDC) + : mrWinFontFace(rWFF), + mhDC(hDC) + {} +}; +#endif + +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; + WinFontFaceWithHDC* pWinFontFaceWithHDC = static_cast<WinFontFaceWithHDC*>(pUserData); + nLength = pWinFontFaceWithHDC->mrWinFontFace.GetTable(pTagName, pBuffer, pWinFontFaceWithHDC->mhDC); +#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, const WinFontFace& rWinFontFace, WinFontInstance& rWinFontInstance) +: mhDC(hDC), + mpHBFace(nullptr), + maFontSelData(rWinFontInstance.maFontSelData) +{ + WinFontFaceWithHDC rWinFontFaceWithHDC(rWinFontFace, mhDC); + mpHBFace = hb_face_create_for_tables(getFontTable, &rWinFontFaceWithHDC, 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; +} _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits