[Libreoffice-commits] core.git: Branch 'feature/commonsallayout' - 8 commits - configure.ac external/harfbuzz vcl/headless vcl/inc vcl/Library_vcl.mk vcl/quartz vcl/README.vars vcl/source vcl/unx vcl/win

Akash Jain akash96j at gmail.com
Tue Jul 26 18:06:43 UTC 2016


Rebased ref, commits from common ancestor:
commit f8c9a451a50c4663e038f2543a85d4c956bca8db
Author: Akash Jain <akash96j at 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..68de96f 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -499,23 +499,23 @@ SalLayout* CairoTextRender::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackL
     if( mpServerFont[ nFallbackLevel ]
     && !(rArgs.mnFlags & SalLayoutFlags::DisableGlyphProcessing) )
     {
-#if ENABLE_GRAPHITE
-        // Is this a Graphite font?
-        if (!bDisableGraphite_ &&
-            GraphiteServerFontLayout::IsGraphiteEnabledFont(*mpServerFont[nFallbackLevel]))
+        if(getenv("SAL_USE_COMMON_LAYOUT"))
         {
-            pLayout = new GraphiteServerFontLayout(*mpServerFont[nFallbackLevel]);
+            pLayout = new CommonSalLayout( *mpServerFont[ nFallbackLevel ] );
         }
         else
-#endif
-            if(getenv("SAL_USE_COMMON_LAYOUT"))
+        {
+#if ENABLE_GRAPHITE
+            // Is this a Graphite font?
+            if (!bDisableGraphite_ &&
+                GraphiteServerFontLayout::IsGraphiteEnabledFont(*mpServerFont[nFallbackLevel]))
             {
-                pLayout = new CommonSalLayout( *mpServerFont[ nFallbackLevel ] );
+                pLayout = new GraphiteServerFontLayout(*mpServerFont[nFallbackLevel]);
             }
             else
-            {
+#endif
                 pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] );
-            }
+        }
     }
 
     return pLayout;
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 09a957b..4486864 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 CommonSalLayout& 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 02e7b11dbe9355a30ffdfbb6baa7be26c8544c06
Author: Akash Jain <akash96j at 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 237bf02c425501d4764caa9c19497f54653aff17
Author: Akash Jain <akash96j at 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 c1e9618..8c93efc 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -111,6 +111,7 @@ private:
     CFMutableDictionaryRef  mpStyleDict;
 
     friend class CTLayout;
+    friend class AquaSalGraphics;
     CFMutableDictionaryRef  GetStyleDict( void ) const { return mpStyleDict; }
 };
 
diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx
index eb6e88c5..c7b54d3 100644
--- a/vcl/quartz/ctfonts.cxx
+++ b/vcl/quartz/ctfonts.cxx
@@ -25,7 +25,7 @@
 #include <vcl/settings.hxx>
 
 
-#include "ctfonts.hxx"
+#include "quartz/ctfonts.hxx"
 #include "impfont.hxx"
 #ifdef MACOSX
 #include "osx/saldata.hxx"
diff --git a/vcl/quartz/ctlayout.cxx b/vcl/quartz/ctlayout.cxx
index 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 86f1d49..7dc1e5b 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -36,7 +36,7 @@
 #include <vcl/svapp.hxx>
 #include <vcl/sysdata.hxx>
 
-#include "ctfonts.hxx"
+#include "quartz/ctfonts.hxx"
 #include "fontsubset.hxx"
 #include "impfont.hxx"
 #include "impfontcharmap.hxx"
@@ -414,8 +414,39 @@ bool AquaSalGraphics::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect
     return bRC;
 }
 
-void AquaSalGraphics::DrawSalLayout( const CommonSalLayout& )
-{
+void AquaSalGraphics::DrawSalLayout( const CommonSalLayout& rLayout )
+{
+    CGContextRef context = mrContext;
+    SAL_INFO( "vcl.ct", "CGContextSaveGState(" << context << ")" );
+    CGContextSaveGState( context );
+    SAL_INFO( "vcl.ct", "CGContextScaleCTM(" << context << ",1.0,-1.0)" );
+    const CoreTextStyle& rCTStyle = rLayout.getFontData();
+
+    CTFontRef pFont = static_cast<CTFontRef>(CFDictionaryGetValue( rCTStyle.GetStyleDict(), kCTFontAttributeName ));
+    CGContextScaleCTM(context, 1.0, -1.0);
+    CGContextSetShouldAntialias(context, !mbNonAntialiasedText);
+    // rotate the matrix
+    const CGFloat fRadians = rCTStyle.mfFontRotation;
+    CGContextRotateCTM( context, +fRadians );
+    const CGAffineTransform aInvMatrix = CGAffineTransformMakeRotation( -fRadians );
+    CGContextSetFillColor( context, maTextColor.AsArray() );
+
+    // draw the text
+    Point aPos;
+    sal_GlyphId aGlyphId;
+    std::vector<CGGlyph> aGlyphIds;
+    std::vector<CGPoint> aGlyphPos;
+    int nStart = 0;
+    for(; rLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nStart ); )
+    {
+        aGlyphIds.push_back( aGlyphId & GF_IDXMASK );
+        aGlyphPos.push_back( CGPointApplyAffineTransform( CGPointMake( aPos.X(), -1*aPos.Y() ), aInvMatrix ) );
+    }
+    CTFontDrawGlyphs( pFont, aGlyphIds.data(), aGlyphPos.data(), nStart, context);
+
+    // restore the original graphic context transformations
+    SAL_INFO( "vcl.ct", "CGContextRestoreGState(" << context << ")" );
+    CGContextRestoreGState( context );
 }
 
 void AquaSalGraphics::SetFont( FontSelectPattern* pReqFont, int /*nFallbackLevel*/ )
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index 55834c6..24ff274 100755
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -57,7 +57,7 @@ static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pU
 
     hb_blob_t* pBlob = nullptr;
     if (pBuffer != nullptr)
-#if defined(_WIN32)
+#if defined(_WIN32) || defined(MACOSX) || defined(IOS)
         pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY,
                                const_cast<unsigned char*>(pBuffer), [](void* data){ delete[] reinterpret_cast<unsigned char*>(data); } );
 #else
commit e0313a9f6493486d02906155823e47b21c234215
Author: Akash Jain <akash96j at gmail.com>
Date:   Wed Jul 6 17:56:15 2016 +0530

    GSoC: Integrate new CommonSalLayout in win/ code
    
    Change-Id: Ifeb2fa7ca9e2cd0da1c504d4e770aa0bb1b0b0de

diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index 3c54dff..55834c6 100755
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -57,7 +57,12 @@ static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pU
 
     hb_blob_t* pBlob = nullptr;
     if (pBuffer != nullptr)
+#if defined(_WIN32)
+        pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY,
+                               const_cast<unsigned char*>(pBuffer), [](void* data){ delete[] reinterpret_cast<unsigned char*>(data); } );
+#else
         pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY, nullptr, nullptr);
+#endif
 
     return pBlob;
 }
@@ -74,12 +79,18 @@ static hb_unicode_funcs_t* getUnicodeFuncs()
 #if defined(_WIN32)
 CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance)
 :   mhDC(hDC),
+    mhFont((HFONT)GetCurrentObject(hDC, OBJ_FONT)),
     mpHBFace(nullptr),
     maFontSelData(rWinFontInstance.maFontSelData)
 {
     mpHBFace = hb_face_create_for_tables(getFontTable, &hDC, nullptr);
 }
 
+void CommonSalLayout::InitFont() const
+{
+    SelectObject( mhDC, mhFont );
+}
+
 #elif defined(MACOSX) || defined(IOS)
 CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle)
 :   mpHBFace(nullptr),
@@ -201,6 +212,12 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
     //XXX WinLayout object DOESN'T derive from GSL
     GenericSalLayout& rLayout = *this;
 
+// HACK. TODO: Get rid of HACK
+#if defined(_WIN32)
+    if(maFontSelData.mnWidth)
+        maFontSelData.mnWidth = (double)maFontSelData.mnWidth*1.812;
+#endif
+
     hb_font_t* pHBFont = hb_font_create(mpHBFace);
     hb_font_set_ppem(pHBFont, maFontSelData.mnWidth? maFontSelData.mnWidth:maFontSelData.mnHeight , maFontSelData.mnHeight);
     hb_font_set_scale(pHBFont, (uint64_t)(maFontSelData.mnWidth? maFontSelData.mnWidth:maFontSelData.mnHeight) << 6
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 95c9ae3..3d0f397 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -2614,7 +2614,4 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
     }
 }
 
-void WinSalGraphics::DrawSalLayout( const CommonSalLayout& )
-{}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index cbf0b58..09a957b 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 CommonSalLayout& 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 5290089b4db0a29b577f2674f8a9b46e8e06e623
Author: Akash Jain <akash96j at gmail.com>
Date:   Wed Jul 6 10:35:24 2016 +0530

    GSoC: Integrate new CommonSalLayout in unx/ code
    
    Change-Id: I991cb5cbd2adad4f4c9f62f807990b9fde2a5133

diff --git a/vcl/README.vars b/vcl/README.vars
index bf85485..b72d499 100644
--- a/vcl/README.vars
+++ b/vcl/README.vars
@@ -6,6 +6,7 @@ SAL_USE_VCLPLUGIN - use a VCL plugin
 SAL_NO_NWF - disable native widgets
 SAL_FORCEDPI - force a specific DPI (gtk & gtk3 plugins only)
 SAL_FORCE_HC - force high-contrast mode
+SAL_USE_COMMON_LAYOUT - use CommonSalLayout layout engine for text layout
 
 VCL_DOUBLEBUFFERING_AVOID_PAINT - don't paint the buffer, useful to see where we do direct painting
 VCL_DOUBLEBUFFERING_FORCE_ENABLE - enable double buffered painting
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index 0fdcd94..3c54dff 100755
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -372,7 +372,6 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
                 int32_t nYOffset =  pHbPositions[i].y_offset >> 6;
                 int32_t nXAdvance = pHbPositions[i].x_advance >> 6;
                 int32_t nYAdvance = pHbPositions[i].y_advance >> 6;
-
                 Point aNewPos = Point(aCurrPos.X() + nXOffset, -(aCurrPos.Y() + nYOffset));
                 // Definiton of glyphitem may have to change to support system graphics lib
                 const GlyphItem aGI(nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nXAdvance, nXOffset);
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
index 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 e648dd878f89039ded7df524c926bac735577b0c
Author: Akash Jain <akash96j at 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..d7545d4 100644
--- a/vcl/headless/svptext.cxx
+++ b/vcl/headless/svptext.cxx
@@ -23,6 +23,7 @@
 #include "headless/svpgdi.hxx"
 #include <config_cairo_canvas.h>
 #include "impfontmetricdata.hxx"
+#include "CommonSalLayout.hxx"
 
 void SvpSalGraphics::SetFont( FontSelectPattern* pIFSD, int nFallbackLevel )
 {
@@ -116,9 +117,14 @@ SalLayout* SvpSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe
     return m_aTextRenderImpl.GetTextLayout(rArgs, nFallbackLevel);
 }
 
-void SvpSalGraphics::DrawServerFontLayout( const ServerFontLayout& rSalLayout )
+void SvpSalGraphics::DrawSalLayout( const GenericSalLayout& rSalLayout, const ServerFont& rServerFont )
 {
-    m_aTextRenderImpl.DrawServerFontLayout(rSalLayout );
+    m_aTextRenderImpl.DrawSalLayout( rSalLayout, rServerFont );
+}
+
+void SvpSalGraphics::DrawSalLayout( const CommonSalLayout& rSalLayout )
+{
+    DrawSalLayout( rSalLayout, rSalLayout.getFontData() );
 }
 
 void SvpSalGraphics::SetTextColor( SalColor nSalColor )
diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx
index 76e4460..6320c1a 100644
--- a/vcl/inc/headless/svpgdi.hxx
+++ b/vcl/inc/headless/svpgdi.hxx
@@ -166,7 +166,8 @@ public:
     virtual bool            GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) override;
     virtual bool            GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) override;
     virtual SalLayout*      GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
-    virtual void            DrawServerFontLayout( const ServerFontLayout& ) override;
+    virtual void            DrawSalLayout( const CommonSalLayout& ) override;
+    virtual void            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..c1e9618 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -50,6 +50,7 @@ class AquaSalFrame;
 class FontAttributes;
 class CoreTextStyle;
 class XorEmulation;
+class CommonSalLayout;
 
 typedef sal_uInt32 sal_GlyphId;
 
@@ -402,7 +403,8 @@ public:
     virtual bool            GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) override;
 
     virtual SalLayout*      GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
-    virtual void            DrawServerFontLayout( const ServerFontLayout& ) override;
+    virtual void            DrawSalLayout( const CommonSalLayout& ) override;
+    virtual void            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..5a15192 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -43,7 +43,8 @@ class Rectangle;
 class FontSubsetInfo;
 class OpenGLContext;
 class OutputDevice;
-class ServerFontLayout;
+class ServerFont;
+class CommonSalLayout;
 struct SystemGraphicsData;
 
 #if ENABLE_CAIRO_CANVAS
@@ -216,7 +217,8 @@ public:
     virtual bool                GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) = 0;
 
     virtual SalLayout*          GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) = 0;
-    virtual void                DrawServerFontLayout( const ServerFontLayout& ) = 0;
+    virtual void                DrawSalLayout( const CommonSalLayout& ) = 0;
+    virtual void                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..b9ff6cc 100644
--- a/vcl/inc/textrender.hxx
+++ b/vcl/inc/textrender.hxx
@@ -26,7 +26,6 @@
 
 class ImplLayoutArgs;
 class ImplFontMetricData;
-class ServerFontLayout;
 class PhysicalFontCollection;
 class PhysicalFontFace;
 
@@ -71,7 +70,7 @@ public:
     virtual bool                    GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) = 0;
     virtual bool                    GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) = 0;
     virtual SalLayout*              GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) = 0;
-    virtual void                    DrawServerFontLayout( const ServerFontLayout& ) = 0;
+    virtual void                    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..2ca0b7d 100644
--- a/vcl/inc/unx/cairotextrender.hxx
+++ b/vcl/inc/unx/cairotextrender.hxx
@@ -118,7 +118,7 @@ public:
     virtual bool                GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) override;
     virtual bool                GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) override;
     virtual SalLayout*          GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
-    virtual void                DrawServerFontLayout( const ServerFontLayout& ) override;
+    virtual void                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..3acd97e 100644
--- a/vcl/inc/unx/genpspgraphics.h
+++ b/vcl/inc/unx/genpspgraphics.h
@@ -34,6 +34,7 @@ class PhysicalFontCollection;
 namespace psp { struct JobData; class PrinterGfx; }
 
 class ServerFont;
+class ServerFontLayout;
 class FontAttributes;
 class SalInfoPrinter;
 class GlyphCache;
@@ -131,7 +132,9 @@ public:
     virtual bool            GetGlyphBoundRect( sal_GlyphId, Rectangle& ) override;
     virtual bool            GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) override;
     virtual SalLayout*      GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
-    virtual void            DrawServerFontLayout( const ServerFontLayout& ) override;
+    virtual void            DrawSalLayout( const CommonSalLayout& ) {};
+    virtual void            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..a23f075 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -154,7 +154,8 @@ public:
     virtual bool                    GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) override;
     virtual bool                    GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) override;
     virtual SalLayout*              GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
-    virtual void                    DrawServerFontLayout( const ServerFontLayout& ) override;
+    virtual void                    DrawSalLayout( const CommonSalLayout& ) override;
+    virtual void                    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..fea3739 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -52,6 +52,7 @@ class PhysicalFontCollection;
 class SalGraphicsImpl;
 class WinOpenGLSalGraphicsImpl;
 class ImplFontMetricData;
+class CommonSalLayout;
 
 #define RGB_TO_PALRGB(nRGB)         ((nRGB)|0x02000000)
 #define PALRGB_TO_RGB(nPalRGB)      ((nPalRGB)&0x00ffffff)
@@ -450,7 +451,8 @@ public:
     virtual bool            GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) override;
 
     virtual SalLayout*      GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
-    virtual void            DrawServerFontLayout( const ServerFontLayout& ) override;
+    virtual void            DrawSalLayout( const CommonSalLayout& ) override;
+    virtual void            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..86f1d49 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -41,6 +41,7 @@
 #include "impfont.hxx"
 #include "impfontcharmap.hxx"
 #include "impfontmetricdata.hxx"
+#include "CommonSalLayout.hxx"
 
 #ifdef MACOSX
 #include "osx/salframe.h"
@@ -413,7 +414,7 @@ bool AquaSalGraphics::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect
     return bRC;
 }
 
-void AquaSalGraphics::DrawServerFontLayout( const ServerFontLayout& )
+void AquaSalGraphics::DrawSalLayout( const CommonSalLayout& )
 {
 }
 
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index 56d49e2..0fdcd94 100755
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -190,9 +190,10 @@ void CommonSalLayout::AdjustLayout(ImplLayoutArgs& rArgs)
 //XXX Kashida
 }
 
-void CommonSalLayout::DrawText( SalGraphics& ) const
+void CommonSalLayout::DrawText( SalGraphics& rSalGraphics ) const
 {
     //call platform dependent DrawText functions
+    rSalGraphics.DrawSalLayout( *this );
 }
 
 bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
index d1ad180..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..10b7803 100644
--- a/vcl/unx/generic/gdi/font.cxx
+++ b/vcl/unx/generic/gdi/font.cxx
@@ -24,6 +24,7 @@
 #include "unx/salgdi.h"
 #include "unx/salvd.h"
 #include "textrender.hxx"
+#include "CommonSalLayout.hxx"
 
 GC
 X11SalGraphics::GetFontGC()
@@ -52,9 +53,14 @@ X11SalGraphics::GetFontGC()
     return pFontGC_;
 }
 
-void X11SalGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout )
+void X11SalGraphics::DrawSalLayout( const GenericSalLayout& rLayout, const ServerFont& rServerFont )
 {
-    mxTextRenderImpl->DrawServerFontLayout(rLayout);
+    mxTextRenderImpl->DrawSalLayout(rLayout, rServerFont);
+}
+
+void X11SalGraphics::DrawSalLayout( const CommonSalLayout& rLayout )
+{
+    DrawSalLayout( rLayout, rLayout.getFontData() );
 }
 
 const FontCharMapPtr X11SalGraphics::GetFontCharMap() const
diff --git a/vcl/unx/generic/glyphs/gcach_layout.cxx b/vcl/unx/generic/glyphs/gcach_layout.cxx
index dc9a84f..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..95c9ae3 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -2614,7 +2614,7 @@ void WinSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
     }
 }
 
-void WinSalGraphics::DrawServerFontLayout( const ServerFontLayout& )
+void WinSalGraphics::DrawSalLayout( const CommonSalLayout& )
 {}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 3fe16ac82d031ab9ed3e6cff4409fed6a634fa97
Author: Akash Jain <akash96j at 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 c4478f3fb416e6130e01b06a22d2e5f6bbf1b4ba
Author: Akash Jain <akash96j at 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..01641ad
--- /dev/null
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -0,0 +1,67 @@
+/* -*- 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&);
+    const CoreTextStyle&    getFontData() const { return mrCoreTextStyle; };
+#else
+    explicit                CommonSalLayout(ServerFont&);
+    const ServerFont&       getFontData() const { return mrServerFont; };
+#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;
+}


More information about the Libreoffice-commits mailing list