[Libreoffice-commits] core.git: Branch 'feature/commonsallayout' - 275 commits - basic/source bin/module-deps.pl bin/removetooltip_markups.sh chart2/uiconfig cli_ure/source comphelper/source compilerplugins/clang config_host/config_kde4.h.in config_host.mk.in configmgr/qa configure.ac connectivity/source cui/source cui/uiconfig dbaccess/source desktop/qa desktop/source dictionaries download.lst drawinglayer/source editeng/source embeddedobj/source extensions/source external/harfbuzz external/liblangtag external/liborcus external/unixODBC extras/source filter/source formula/source fpicker/uiconfig framework/Library_fwk.mk framework/qa framework/source helpcontent2 hwpfilter/source i18npool/qa i18npool/source i18nutil/source icon-themes/breeze icon-themes/breeze_dark icon-themes/elementary icon-themes/galaxy icon-themes/sifr icon-themes/tango idlc/inc idl/inc idl/source include/basic include/canvas include/codemaker include/comphelper include/cppuhelper include/editeng include/filter include/formul a include/LibreOfficeKit include/oox include/sfx2 include/sot include/svl include/svtools include/svx include/ucbhelper include/uno include/unotools include/vcl include/xmloff libreofficekit/source lingucomponent/source linguistic/source odk/examples offapi/com officecfg/files.mk officecfg/registry oox/source postprocess/CustomTarget_registry.mk pyuno/inc qadevOOo/runner reportdesign/inc reportdesign/source reportdesign/uiconfig reportdesign/UIConfig_dbreport.mk RepositoryExternal.mk Repository.mk rsc/inc rsc/source sal/qa sal/rtl sc/inc sc/qa sc/sdi sc/source sc/uiconfig sc/UIConfig_scalc.mk sd/inc sd/source sd/uiconfig sfx2/source shell/source solenv/gbuild solenv/lldb sot/source starmath/inc starmath/qa starmath/source store/source svl/qa svl/source svtools/inc svtools/source svx/source svx/uiconfig swext/mediawiki sw/inc sw/Library_sw.mk sw/qa sw/sdi sw/source sw/uiconfig sw/UIConfig_swriter.mk test/Library_test_setupvcl.mk test/Library_test-setupvcl.mk test/Module_test.mk toolk it/source tools/source ucb/CppunitTest_ucb_webdav_res_access.mk ucbhelper/source ucb/Module_ucb.mk ucb/qa ucb/source uitest/calc_tests uitest/demo_ui uitest/impress_tests uitest/libreoffice uitest/uitest unotools/source vcl/CppunitTest_vcl_jpeg_read_write_test.mk vcl/CppunitTest_vcl_wmf_test.mk vcl/CustomTarget_tde_moc.mk vcl/headless vcl/inc vcl/Library_vcl.mk vcl/Library_vclplug_kde4.mk vcl/Module_vcl.mk vcl/osx vcl/qa vcl/quartz vcl/README.vars vcl/source vcl/unx vcl/win xmloff/source

Khaled Hosny khaledhosny at eglug.org
Fri Sep 30 11:18:08 UTC 2016


Rebased ref, commits from common ancestor:
commit 54abfb98f3fa8a8801707b15aebd82cfa5c570bc
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Mon Sep 26 19:09:52 2016 +0200

    First try on vertical text in CommonSalLayout
    
    Does not work quite right yet.
    
    Change-Id: I52a71c9c21ad75c7cb9c8574e5e7e3b7c1c0c0c3

diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index 8963624..7bcbf1d 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -381,6 +381,16 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
             LanguageTag &rTag = rArgs.maLanguageTag;
             OString sLanguage = OUStringToOString(rTag.getBcp47(), RTL_TEXTENCODING_ASCII_US);
 
+            bool bVertical = false;
+            if ((rArgs.mnFlags & SalLayoutFlags::Vertical) &&
+                (aHbScript == HB_SCRIPT_HAN ||
+                 aHbScript == HB_SCRIPT_HANGUL ||
+                 aHbScript == HB_SCRIPT_HIRAGANA ||
+                 aHbScript == HB_SCRIPT_KATAKANA))
+            {
+                bVertical = true;
+            }
+
             int nHbFlags = HB_BUFFER_FLAGS_DEFAULT;
             if (nMinRunPos == 0)
                 nHbFlags |= HB_BUFFER_FLAG_BOT; /* Beginning-of-text */
@@ -392,7 +402,10 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
 #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);
+            if (SAL_UNLIKELY(bVertical))
+              hb_buffer_set_direction(pHbBuffer, HB_DIRECTION_TTB);
+            else
+              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);
@@ -457,17 +470,31 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
                 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;
+                int32_t nXOffset;
+                int32_t nYOffset;
+                int32_t nXAdvance;
+                Point aNewPos;
+
+                if (SAL_UNLIKELY(bVertical))
+                {
+                    nXOffset =  pHbPositions[i].y_offset >> 6;
+                    nYOffset =  pHbPositions[i].x_offset >> 6;
+                    nXAdvance = pHbPositions[i].y_advance >> 6;
+                    nGlyphIndex |= GF_ROTL;
+                    aNewPos = Point(-(aCurrPos.X() + nXOffset), aCurrPos.Y() + nYOffset);
+                }
+                else
+                {
+                    nXOffset =  pHbPositions[i].x_offset >> 6;
+                    nYOffset =  pHbPositions[i].y_offset >> 6;
+                    nXAdvance = pHbPositions[i].x_advance >> 6;
+                    aNewPos = Point(aCurrPos.X() + nXOffset, -(aCurrPos.Y() + nYOffset));
+                }
 
-                Point aNewPos = Point(aCurrPos.X() + nXOffset, -(aCurrPos.Y() + nYOffset));
                 const GlyphItem aGI(nCharPos, nGlyphIndex, aNewPos, nGlyphFlags, nXAdvance, nXOffset);
                 AppendGlyph(aGI);
 
                 aCurrPos.X() += nXAdvance;
-                aCurrPos.Y() += nYAdvance;
             }
 
             hb_buffer_destroy(pHbBuffer);
commit de6e8187bb9cf898a4d9965ceb90ece762da69ce
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Sat Sep 24 23:13:47 2016 +0200

    Use range loop
    
    Change-Id: I5ce49e57ed57378b4b9e16c8bb020048644252a9

diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index f951e2b..8963624 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -371,12 +371,12 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
         if (bRightToLeft)
             std::reverse(aScriptSubRuns.begin(), aScriptSubRuns.end());
 
-        for (HbScriptRuns::iterator it = aScriptSubRuns.begin(); it != aScriptSubRuns.end(); ++it)
+        for (const auto& aScriptRun : aScriptSubRuns)
         {
-            int nMinRunPos = it->mnMin;
-            int nEndRunPos = it->mnEnd;
+            int nMinRunPos = aScriptRun.mnMin;
+            int nEndRunPos = aScriptRun.mnEnd;
             int nRunLen = nEndRunPos - nMinRunPos;
-            aHbScript = it->maScript;
+            aHbScript = aScriptRun.maScript;
             // hb_language_from_string() accept ISO639-3 language tag except for Chinese.
             LanguageTag &rTag = rArgs.maLanguageTag;
             OString sLanguage = OUStringToOString(rTag.getBcp47(), RTL_TEXTENCODING_ASCII_US);
commit 45703a8087b26ad7899cdc3a44c3202221bf9b0e
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Sat Sep 24 23:04:39 2016 +0200

    Use const reference
    
    Change-Id: I0f632f3a8b480f785608aa081add1b1d2fefd312

diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx
index 89214d4..e9116ba 100644
--- a/vcl/inc/CommonSalLayout.hxx
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -36,7 +36,7 @@
 class CommonSalLayout : public GenericSalLayout
 {
     hb_font_t* mpHbFont;
-    FontSelectPattern maFontSelData;
+    const FontSelectPattern& mrFontSelData;
     css::uno::Reference<css::i18n::XBreakIterator> mxBreak;
 #ifdef _WIN32
     HDC   mhDC;
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index 38d6117..f951e2b 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -129,7 +129,7 @@ static hb_unicode_funcs_t* getUnicodeFuncs()
 CommonSalLayout::CommonSalLayout(WinSalGraphics* WSL, WinFontInstance& rWinFontInstance, const WinFontFace& rWinFontFace)
 :   mhFont((HFONT)GetCurrentObject(WSL->getHDC(), OBJ_FONT)),
     mhDC(WSL->getHDC()),
-    maFontSelData(rWinFontInstance.maFontSelData),
+    mrFontSelData(rWinFontInstance.maFontSelData),
     mpD2DRenderer(nullptr)
 {
     mpHbFont = rWinFontFace.GetHbFont();
@@ -153,7 +153,7 @@ CommonSalLayout::CommonSalLayout(WinSalGraphics* WSL, WinFontInstance& rWinFontI
         hb_face_destroy(pHbFace);
     }
 
-    scaleHbFont(mpHbFont, maFontSelData);
+    scaleHbFont(mpHbFont, mrFontSelData);
 }
 
 void CommonSalLayout::InitFont() const
@@ -163,7 +163,7 @@ void CommonSalLayout::InitFont() const
 
 #elif defined(MACOSX) || defined(IOS)
 CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle)
-:   maFontSelData(rCoreTextStyle.maFontSelData),
+:   mrFontSelData(rCoreTextStyle.maFontSelData),
     mrCoreTextStyle(rCoreTextStyle)
 {
     mpHbFont = rCoreTextStyle.GetHbFont();
@@ -184,12 +184,12 @@ CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle)
         hb_face_destroy(pHbFace);
     }
 
-    scaleHbFont(mpHbFont, maFontSelData);
+    scaleHbFont(mpHbFont, mrFontSelData);
 }
 
 #else
 CommonSalLayout::CommonSalLayout(ServerFont& rServerFont)
-:   maFontSelData(rServerFont.GetFontSelData()),
+:   mrFontSelData(rServerFont.GetFontSelData()),
     mrServerFont(rServerFont)
 {
     mpHbFont = rServerFont.GetHbFont();
@@ -203,7 +203,7 @@ CommonSalLayout::CommonSalLayout(ServerFont& rServerFont)
         hb_face_destroy(pHbFace);
     }
 
-    scaleHbFont(mpHbFont, maFontSelData);
+    scaleHbFont(mpHbFont, mrFontSelData);
 }
 #endif
 
commit 8bee9a21bb23dc9a2efcf07a31a173602c79c8c7
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Fri Sep 23 18:34:09 2016 +0200

    Make sure HarfBuzz module depends on Graphite
    
    Change-Id: I9c1cc9c679ceebeb4e5cd898876aaa7b61c18f17

diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index 64eeacf..c818136 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -1368,6 +1368,8 @@ $(call gb_LinkTarget_add_libs,$(1),$(GRAPHITE_LIBS))
 
 endef
 
+gb_ExternalProject__use_graphite:=
+
 else # !SYSTEM_GRAPHITE
 
 define gb_LinkTarget__use_graphite
@@ -1382,6 +1384,10 @@ $(call gb_LinkTarget_use_static_libraries,$(1),\
 
 endef
 
+define gb_ExternalProject__use_graphite
+$(call gb_ExternalProject_use_external_project,$(1),graphite)
+
+endef
 endif # SYSTEM_GRAPHITE
 
 ifneq ($(SYSTEM_ICU),)
diff --git a/external/harfbuzz/ExternalProject_harfbuzz.mk b/external/harfbuzz/ExternalProject_harfbuzz.mk
index 1be5c6f..57cfc44 100644
--- a/external/harfbuzz/ExternalProject_harfbuzz.mk
+++ b/external/harfbuzz/ExternalProject_harfbuzz.mk
@@ -17,6 +17,7 @@ $(eval $(call gb_ExternalProject_register_targets,harfbuzz,\
 
 $(eval $(call gb_ExternalProject_use_externals,harfbuzz,\
 	icu \
+	graphite \
 ))
 
 $(call gb_ExternalProject_get_state_target,harfbuzz,build) :
commit 40f203f410c4a069c5eba7ff4f4180944d323af2
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Thu Sep 22 07:57:04 2016 -0700

    Build HarfBuzz with Core Text on Mac
    
    To enable support for AAT fonts.
    
    Change-Id: Ifcc7d1672e98f8c067482400b7e45226bed4dbf1

diff --git a/external/harfbuzz/ExternalProject_harfbuzz.mk b/external/harfbuzz/ExternalProject_harfbuzz.mk
index 4412815..1be5c6f 100644
--- a/external/harfbuzz/ExternalProject_harfbuzz.mk
+++ b/external/harfbuzz/ExternalProject_harfbuzz.mk
@@ -36,6 +36,7 @@ $(call gb_ExternalProject_get_state_target,harfbuzz,build) :
 			--with-cairo=no \
 			--with-glib=no \
 			--with-graphite2=yes \
+			$(if $(filter MACOSX,$(OS)),--with-coretext=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") \
commit db3ec5e4212e3b1991cbc88a410b171aec2ae272
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Thu Sep 22 19:48:10 2016 +0200

    Always pass BCP 47 tags to HarfBuzz
    
    This is what it is expecting anyway, no need to special case it for
    Chinese.
    
    Change-Id: I6732412375d19816b599005d78abd796f67599ee

diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index 16400bc..38d6117 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -379,7 +379,7 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
             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 );
+            OString sLanguage = OUStringToOString(rTag.getBcp47(), RTL_TEXTENCODING_ASCII_US);
 
             int nHbFlags = HB_BUFFER_FLAGS_DEFAULT;
             if (nMinRunPos == 0)
commit 1bac6e471e5bf4375022368b9b0cf519c9e3d3a4
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Thu Sep 22 19:45:23 2016 +0200

    Always build Graphite everywhere
    
    It is no longer an optional feature on any platform. The
    --enable-graphite stuff is kept as it controls the old Graphite
    integration code and it should be removed without.
    
    Change-Id: Ib4d76bba782a1439f02f93411b22d237a1987ea5

diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index e0f1337..64eeacf 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -1357,8 +1357,6 @@ endef
 
 endif # SYSTEM_FONTCONFIG
 
-ifeq ($(ENABLE_GRAPHITE),TRUE)
-
 ifneq ($(SYSTEM_GRAPHITE),)
 
 define gb_LinkTarget__use_graphite
@@ -1386,12 +1384,6 @@ endef
 
 endif # SYSTEM_GRAPHITE
 
-else # !ENABLE_GRAPHITE
-
-gb_LinkTarget__use_graphite :=
-
-endif # ENABLE_GRAPHITE
-
 ifneq ($(SYSTEM_ICU),)
 
 gb_LinkTarget__use_icu_headers:=
diff --git a/configure.ac b/configure.ac
index d67054b..1419367 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9240,19 +9240,20 @@ AC_SUBST(ICU_LIBS)
 dnl ===================================================================
 dnl Graphite
 dnl ===================================================================
+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
 
+# This is the old Graphite support that will eventually be removed
 AC_MSG_CHECKING([whether to enable graphite support])
 if test $_os != Darwin -a $_os != Android -a $_os != iOS -a \( -z "$enable_graphite" -o "$enable_graphite" != no \); then
     AC_MSG_RESULT([yes])
     ENABLE_GRAPHITE="TRUE"
     AC_DEFINE(ENABLE_GRAPHITE)
-    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])
@@ -9339,6 +9340,9 @@ if test "$COM" = "MSC"; then # override the above
     HARFBUZZ_LIBS="${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs/libharfbuzz.lib"
 fi
 if test "$with_system_harfbuzz" = "yes"; then
+    if test "$with_system_graphite" = "no"; then
+        AC_MSG_ERROR([--with-system-graphite must be used when --with-system-harfbuzz is used])
+    fi
     AC_MSG_CHECKING([whether system Harfbuzz is built with Graphite support])
     _save_libs="$LIBS"
     _save_cflags="$CFLAGS"
@@ -9347,6 +9351,10 @@ if test "$with_system_harfbuzz" = "yes"; then
     AC_CHECK_FUNC(hb_graphite2_face_get_gr_face,,[AC_MSG_ERROR([Harfbuzz needs to be built with Graphite support.])])
     LIBS="$_save_libs"
     CFLAGS="$_save_cflags"
+else
+    if test "$with_system_graphite" = "yes"; then
+        AC_MSG_ERROR([--without-system-graphite must be used when --without-system-harfbuzz is used])
+    fi
 fi
 
 AC_MSG_CHECKING([whether to use X11])
diff --git a/vcl/CppunitTest_vcl_wmf_test.mk b/vcl/CppunitTest_vcl_wmf_test.mk
index 51e9126..1de86d8 100644
--- a/vcl/CppunitTest_vcl_wmf_test.mk
+++ b/vcl/CppunitTest_vcl_wmf_test.mk
@@ -80,6 +80,7 @@ endif
 
 $(eval $(call gb_CppunitTest_use_externals,vcl_wmf_test,\
     gio \
+    graphite \
     harfbuzz \
     icuuc \
     lcms2 \
@@ -90,10 +91,6 @@ $(eval $(call gb_CppunitTest_use_externals,vcl_wmf_test,\
  ))
 endif
 
-ifeq ($(ENABLE_GRAPHITE),TRUE)
-$(eval $(call gb_CppunitTest_use_external,vcl_wmf_test,graphite))
-endif
-
 ifeq ($(OS),MACOSX)
 $(eval $(call gb_CppunitTest_use_system_darwin_frameworks,vcl_wmf_test,\
     ApplicationServices \
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 67bcbe5..2b0874a 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -116,6 +116,7 @@ $(eval $(call gb_Library_use_externals,vcl,\
 	boost_headers \
 	gio \
 	glm_headers \
+	graphite \
 	harfbuzz \
 	icu_headers \
 	icuuc \
@@ -434,8 +435,6 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
 ))
 endif
 
-$(eval $(call gb_Library_use_external,vcl,graphite))
-
 endif
 
 vcl_quartz_code= \
commit 3fa5db0919d5c0569689ddabca5e0bbcc3b25032
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Thu Sep 22 19:29:04 2016 +0200

    Always build HarfBuzz everywhere
    
    It is no longer an optional feature on any platform.
    
    Change-Id: I70cdcd2c0df69d961ecc5f36b4e8d035d251ef16

diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index 95241ab..e0f1337 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -1490,7 +1490,6 @@ endef
 
 endif # SYSTEM_ICU
 
-ifeq ($(ENABLE_HARFBUZZ),TRUE)
 ifneq ($(SYSTEM_HARFBUZZ),)
 
 define gb_LinkTarget__use_harfbuzz
@@ -1515,11 +1514,6 @@ $(call gb_LinkTarget_use_external_project,$(1),harfbuzz)
 endef
 
 endif # SYSTEM_HARFBUZZ
-else # ENABLE_HARFBUZZ != YES
-
-gb_LinkTarget__use_harfbuzz :=
-
-endif # ENABLE_HARFBUZZ
 
 ifeq ($(DISABLE_OPENSSL),TRUE)
 
diff --git a/config_host.mk.in b/config_host.mk.in
index 2e6d007..90c25a6 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -133,7 +133,6 @@ export ENABLE_FIREBIRD_SDBC=@ENABLE_FIREBIRD_SDBC@
 export ENABLE_GIO=@ENABLE_GIO@
 export ENABLE_GRAPHITE=@ENABLE_GRAPHITE@
 export ENABLE_ORCUS=@ENABLE_ORCUS@
-export ENABLE_HARFBUZZ=@ENABLE_HARFBUZZ@
 export ENABLE_GLTF=@ENABLE_GLTF@
 export SYSTEM_LIBGLTF=@SYSTEM_LIBGLTF@
 export LIBGLTF_CFLAGS=@LIBGLTF_CFLAGS@
diff --git a/configure.ac b/configure.ac
index 6dd2d10..d67054b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2135,12 +2135,6 @@ AC_ARG_WITH(iwyu,
          Use only if you are hacking on it.]),
 ,)
 
-AC_ARG_WITH(harfbuzz,
-    AS_HELP_STRING([--with-harfbuzz],
-        [Enable HarfBuzz support regardless of the platform.
-         Experimental only. Use only if working on it.]),
-,)
-
 dnl ===================================================================
 dnl Branding
 dnl ===================================================================
@@ -9340,32 +9334,20 @@ AC_SUBST(ENABLE_ORCUS)
 dnl ===================================================================
 dnl HarfBuzz
 dnl ===================================================================
-AC_MSG_CHECKING([whether to enable HarfBuzz support])
-if test "$with_harfbuzz" = "yes" -o \( $_os != WINNT -a $_os != Darwin -a $_os != iOS \); then
-    AC_MSG_RESULT([yes])
-    ENABLE_HARFBUZZ="TRUE"
-    if $PKG_CONFIG --atleast-version 0.9.18 harfbuzz; then
-        libo_CHECK_SYSTEM_MODULE([harfbuzz],[HARFBUZZ],[harfbuzz-icu >= 0.9.18],["-I${WORKDIR}/UnpackedTarball/harfbuzz/src"],["-L${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs -lharfbuzz"])
-    else
-        libo_CHECK_SYSTEM_MODULE([harfbuzz],[HARFBUZZ],[harfbuzz >= 0.9.10],[-I${WORKDIR}/UnpackedTarball/harfbuzz/src],["-L${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs -lharfbuzz"])
-    fi
-    if test "$COM" = "MSC"; then # override the above
-        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])
-        _save_libs="$LIBS"
-        _save_cflags="$CFLAGS"
-        LIBS="$LIBS $HARFBUZZ_LIBS"
-        CFLAGS="$CFLAGS $HARFBUZZ_CFLAGS"
-        AC_CHECK_FUNC(hb_graphite2_face_get_gr_face,,[AC_MSG_ERROR([Harfbuzz needs to be built with Graphite support.])])
-        LIBS="$_save_libs"
-        CFLAGS="$_save_cflags"
-    fi
-else
-    AC_MSG_RESULT([no])
+libo_CHECK_SYSTEM_MODULE([harfbuzz],[HARFBUZZ],[harfbuzz-icu >= 0.9.18],["-I${WORKDIR}/UnpackedTarball/harfbuzz/src"],["-L${WORKDIR}/UnpackedTarball/harfbuzz/src/.libs -lharfbuzz"])
+if test "$COM" = "MSC"; then # override the above
+    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])
+    _save_libs="$LIBS"
+    _save_cflags="$CFLAGS"
+    LIBS="$LIBS $HARFBUZZ_LIBS"
+    CFLAGS="$CFLAGS $HARFBUZZ_CFLAGS"
+    AC_CHECK_FUNC(hb_graphite2_face_get_gr_face,,[AC_MSG_ERROR([Harfbuzz needs to be built with Graphite support.])])
+    LIBS="$_save_libs"
+    CFLAGS="$_save_cflags"
 fi
-AC_SUBST(ENABLE_HARFBUZZ)
 
 AC_MSG_CHECKING([whether to use X11])
 dnl ***************************************
commit 45a93629b72029962c4716a516265e9a66c51b14
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Sun Sep 11 10:25:46 2016 +0200

    Override GetCharWidths and ApplyDXArray in CSL
    
    A much simpler and saner implementation. This also unbreaks Awami
    Nastaliq.
    
    Break kashida justification, will need to rewrite that one as well.
    
    Change-Id: I843679e937f2881e77df61f5cbd9516b6df1b3b6

diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx
index 83de5c1..89214d4 100644
--- a/vcl/inc/CommonSalLayout.hxx
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -65,4 +65,7 @@ public:
     virtual bool            LayoutText(ImplLayoutArgs&) override;
     virtual void            DrawText( SalGraphics& ) const override;
     std::shared_ptr<vcl::TextLayoutCache> CreateTextLayoutCache(OUString const&) const override;
+
+    virtual bool            GetCharWidths(DeviceCoordinate* pCharWidths) const override;
+    virtual void            ApplyDXArray(ImplLayoutArgs&) override;
 };
diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx
index cfb2930..1050943 100644
--- a/vcl/inc/sallayout.hxx
+++ b/vcl/inc/sallayout.hxx
@@ -326,7 +326,7 @@ public:
     void            AppendGlyph( const GlyphItem& );
     void            Reserve(int size) { m_GlyphItems.reserve(size + 1); }
     virtual void    AdjustLayout( ImplLayoutArgs& ) override;
-    void    ApplyDXArray( ImplLayoutArgs& );
+    virtual void    ApplyDXArray( ImplLayoutArgs& );
     void    Justify( DeviceCoordinate nNewWidth );
     void            KashidaJustify( long nIndex, int nWidth );
     void            ApplyAsianKerning(const OUString& rStr);
@@ -352,7 +352,7 @@ protected:
     virtual void    DropGlyph( int nStart ) override;
     virtual void    Simplify( bool bIsBase ) override;
 
-    bool            GetCharWidths( DeviceCoordinate* pCharWidths ) const;
+    virtual bool    GetCharWidths( DeviceCoordinate* pCharWidths ) const;
 
     std::vector<GlyphItem>     m_GlyphItems;
 
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index 9c68bdb..16400bc 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -486,3 +486,53 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
 
     return true;
 }
+
+bool CommonSalLayout::GetCharWidths(DeviceCoordinate* pCharWidths) const
+{
+    int nCharCount = mnEndCharPos - mnMinCharPos;
+
+    for (int i = 0; i < nCharCount; ++i)
+        pCharWidths[i] = 0;
+
+    for (auto const& aGlyphItem : m_GlyphItems)
+        pCharWidths[aGlyphItem.mnCharPos - mnMinCharPos] += aGlyphItem.mnNewWidth;
+
+    return true;
+}
+
+void CommonSalLayout::ApplyDXArray(ImplLayoutArgs& rArgs)
+{
+    int nCharCount = mnEndCharPos - mnMinCharPos;
+    std::unique_ptr<DeviceCoordinate[]> const pOldCharWidths(new DeviceCoordinate[nCharCount]);
+    std::unique_ptr<DeviceCoordinate[]> const pNewCharWidths(new DeviceCoordinate[nCharCount]);
+
+    GetCharWidths(pOldCharWidths.get());
+
+    for (int i = 0; i < nCharCount; ++i)
+    {
+        if (i == 0)
+          pNewCharWidths[i] = rArgs.mpDXArray[i];
+        else
+          pNewCharWidths[i] = rArgs.mpDXArray[i] - rArgs.mpDXArray[i - 1];
+    }
+
+    DeviceCoordinate nDelta = 0;
+    size_t i = 0;
+    while (i < m_GlyphItems.size())
+    {
+        int nCharPos = m_GlyphItems[i].mnCharPos - mnMinCharPos;
+        DeviceCoordinate nDiff = pNewCharWidths[nCharPos] - pOldCharWidths[nCharPos];
+
+        m_GlyphItems[i].maLinearPos.X() += nDelta;
+        size_t j = i;
+        while (++j < m_GlyphItems.size())
+        {
+            if (m_GlyphItems[j].mnCharPos != m_GlyphItems[i].mnCharPos)
+              break;
+            m_GlyphItems[j].maLinearPos.X() += nDelta;
+        }
+
+        nDelta += nDiff;
+        i = j;
+    }
+}
commit 649c5c7f8b4158d5f5085a2b9ad45db15bffbe02
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Wed Sep 7 23:26:14 2016 +0200

    Don’t check glyph class unnecessarily
    
    Don’t call hb_ot_layout_get_glyph_class() unless the glyph advance width
    is zero, as we really do not use its result otherwise.
    
    Change-Id: Id02238abef91b9343931f1886d54d966d7157f25

diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index fd7d59c..9c68bdb 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -439,9 +439,8 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
                 if (hb_ot_layout_has_glyph_classes(pHbFace))
                 {
                     // the font has GDEF table
-                    bool bMark = hb_ot_layout_get_glyph_class(pHbFace, nGlyphIndex) == HB_OT_LAYOUT_GLYPH_CLASS_MARK;
-                    if (bMark && pHbPositions[i].x_advance == 0)
-                        bDiacritic = true;
+                    if (pHbPositions[i].x_advance == 0)
+                        bDiacritic = hb_ot_layout_get_glyph_class(pHbFace, nGlyphIndex) == HB_OT_LAYOUT_GLYPH_CLASS_MARK;
                 }
                 else
                 {
commit 37d052fd1e2779b0b327849c281d12309da2c843
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Wed Sep 7 19:40:11 2016 +0200

    Cache HarfBuzz font
    
    We now create it only once per physical font, saves us few percents from
    the all over time spent on layout.
    
    Change-Id: I8de582cb20a168c93d72921e539c2477fa97fb54

diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx
index da75f0f..83de5c1 100644
--- a/vcl/inc/CommonSalLayout.hxx
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -35,7 +35,7 @@
 
 class CommonSalLayout : public GenericSalLayout
 {
-    hb_face_t* mpHbFace;
+    hb_font_t* mpHbFont;
     FontSelectPattern maFontSelData;
     css::uno::Reference<css::i18n::XBreakIterator> mxBreak;
 #ifdef _WIN32
@@ -48,7 +48,6 @@ class CommonSalLayout : public GenericSalLayout
     ServerFont& mrServerFont;
 #endif
 
-    hb_font_t*              GetHbFont();
 public:
 #if defined(_WIN32)
     explicit                CommonSalLayout(WinSalGraphics*, WinFontInstance&, const WinFontFace&);
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 00b2d8e..f7e5156 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -99,8 +99,8 @@ public:
     void       GetFontMetric( ImplFontMetricDataRef& ) const;
     bool       GetGlyphBoundRect( sal_GlyphId, Rectangle& ) const;
     bool       GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) const;
-    hb_face_t* GetHbFace() const { return mpHbFace; }
-    void       SetHbFace(hb_face_t* pHbFace) const { mpHbFace = pHbFace; }
+    hb_font_t* GetHbFont() const { return mpHbFont; }
+    void       SetHbFont(hb_font_t* pHbFont) const { mpHbFont = pHbFont; }
 
     const CoreTextFontFace*  mpFontData;
     /// <1.0: font is squeezed, >1.0 font is stretched, else 1.0
@@ -112,7 +112,7 @@ public:
 private:
     /// CoreText text style object
     CFMutableDictionaryRef  mpStyleDict;
-    mutable hb_face_t*      mpHbFace;
+    mutable hb_font_t*      mpHbFont;
 
     friend class CTLayout;
     friend class AquaSalGraphics;
diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx
index 38967bf..7cb2a84 100644
--- a/vcl/inc/unx/glyphcache.hxx
+++ b/vcl/inc/unx/glyphcache.hxx
@@ -182,8 +182,8 @@ public:
     sal_GlyphId             FixupGlyphIndex( sal_GlyphId aGlyphId, sal_UCS4 ) const;
     bool                    GetGlyphOutline( sal_GlyphId aGlyphId, basegfx::B2DPolyPolygon& ) const;
     bool                    GetAntialiasAdvice() const;
-    hb_face_t*              GetHbFace() { return mpHbFace; }
-    void                    SetHbFace( hb_face_t* pHbFace ) { mpHbFace=pHbFace; }
+    hb_font_t*              GetHbFont() { return mpHbFont; }
+    void                    SetHbFont( hb_font_t* pHbFont ) { mpHbFont = pHbFont; }
 
 private:
     friend class GlyphCache;
@@ -243,7 +243,7 @@ private:
     GlyphSubstitution       maGlyphSubstitution;
 
     ServerFontLayoutEngine* mpLayoutEngine;
-    hb_face_t*              mpHbFace;
+    hb_font_t*              mpHbFont;
 };
 
 // a class for cache entries for physical font instances that are based on serverfonts
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index e1d64c5..cdb0967 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -142,12 +142,12 @@ private:
 
     mutable std::unordered_set<sal_UCS4>      maGsubTable;
     mutable bool            mbGsubRead;
-    mutable hb_face_t*      mpHbFace;
+    mutable hb_font_t*      mpHbFont;
 public:
     bool                    HasGSUBstitutions( HDC ) const;
     bool                    IsGSUBstituted( sal_UCS4 ) const;
-    hb_face_t*              GetHbFace() const { return mpHbFace; }
-    void                    SetHbFace( hb_face_t* pHbFace ) const { mpHbFace = pHbFace; }
+    hb_font_t*              GetHbFont() const { return mpHbFont; }
+    void                    SetHbFont( hb_font_t* pHbFont ) const { mpHbFont = pHbFont; }
 };
 
 /** Class that creates (and destroys) a compatible Device Context.
diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx
index f183c10..ac17abc 100644
--- a/vcl/quartz/ctfonts.cxx
+++ b/vcl/quartz/ctfonts.cxx
@@ -50,7 +50,7 @@ CoreTextStyle::CoreTextStyle( const FontSelectPattern& rFSD )
     , mfFontRotation( 0.0 )
     , maFontSelData( rFSD )
     , mpStyleDict( nullptr )
-    , mpHbFace( nullptr )
+    , mpHbFont( nullptr )
 {
     const FontSelectPattern* const pReqFont = &rFSD;
 
@@ -117,8 +117,8 @@ CoreTextStyle::~CoreTextStyle()
 {
     if( mpStyleDict )
         CFRelease( mpStyleDict );
-    if( mpHbFace )
-        hb_face_destroy( mpHbFace );
+    if( mpHbFont )
+        hb_font_destroy( mpHbFont );
 }
 
 void CoreTextStyle::GetFontMetric( ImplFontMetricDataRef& rxFontMetric ) const
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index afdbdf8..fd7d59c 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -90,6 +90,32 @@ static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pU
     return pBlob;
 }
 
+static hb_font_t* createHbFont(hb_face_t* pHbFace)
+{
+    hb_font_t* pHbFont = hb_font_create(pHbFace);
+    hb_ot_font_set_funcs(pHbFont);
+
+    return pHbFont;
+}
+
+static void scaleHbFont(hb_font_t* pHbFont, const FontSelectPattern& aFontSelData)
+{
+    uint64_t nXScale = aFontSelData.mnWidth << 6;
+    uint64_t nYScale = aFontSelData.mnHeight << 6;
+
+#if defined(_WIN32)
+    // HACK to get stretched/shrunken text. TODO: Get rid of HACK
+    if (nXScale)
+        nXScale = double(nXScale) * 1.812;
+#endif
+
+    if (!nXScale)
+      nXScale = nYScale;
+
+    hb_font_set_ppem(pHbFont, nXScale, nYScale);
+    hb_font_set_scale(pHbFont, nXScale, nYScale);
+}
+
 static hb_unicode_funcs_t* getUnicodeFuncs()
 {
     static hb_unicode_funcs_t* ufuncs = hb_unicode_funcs_create(hb_icu_get_unicode_funcs());
@@ -103,16 +129,15 @@ static hb_unicode_funcs_t* getUnicodeFuncs()
 CommonSalLayout::CommonSalLayout(WinSalGraphics* WSL, WinFontInstance& rWinFontInstance, const WinFontFace& rWinFontFace)
 :   mhFont((HFONT)GetCurrentObject(WSL->getHDC(), OBJ_FONT)),
     mhDC(WSL->getHDC()),
-    mpHbFace(nullptr),
     maFontSelData(rWinFontInstance.maFontSelData),
     mpD2DRenderer(nullptr)
 {
-    mpHbFace = rWinFontFace.GetHbFace();
-    if(!mpHbFace)
+    mpHbFont = rWinFontFace.GetHbFont();
+    if (!mpHbFont)
     {
         mpD2DRenderer = dynamic_cast<D2DWriteTextOutRenderer*>(&TextOutRenderer::get());
         WinSalGraphicsWithIDFace* pWSLWithIDFace = new WinSalGraphicsWithIDFace(WSL, mpD2DRenderer->GetDWriteFontFace(mhDC));
-        mpHbFace= hb_face_create_for_tables( getFontTable, pWSLWithIDFace,
+        hb_face_t* pHbFace= hb_face_create_for_tables( getFontTable, pWSLWithIDFace,
                   [](void* pUserData)
                   {
                       WinSalGraphicsWithIDFace* pUData = static_cast<WinSalGraphicsWithIDFace*>( pUserData );
@@ -121,8 +146,14 @@ CommonSalLayout::CommonSalLayout(WinSalGraphics* WSL, WinFontInstance& rWinFontI
                       delete pUData;
                   }
                  );
-        rWinFontFace.SetHbFace(mpHbFace);
+
+        mpHbFont = createHbFont(pHbFace);
+        rWinFontFace.SetHbFont(mpHbFont);
+
+        hb_face_destroy(pHbFace);
     }
+
+    scaleHbFont(mpHbFont, maFontSelData);
 }
 
 void CommonSalLayout::InitFont() const
@@ -132,54 +163,49 @@ void CommonSalLayout::InitFont() const
 
 #elif defined(MACOSX) || defined(IOS)
 CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle)
-:   mpHbFace(nullptr),
-    maFontSelData(rCoreTextStyle.maFontSelData),
+:   maFontSelData(rCoreTextStyle.maFontSelData),
     mrCoreTextStyle(rCoreTextStyle)
 {
-    mpHbFace = rCoreTextStyle.GetHbFace();
-    if(!mpHbFace)
+    mpHbFont = rCoreTextStyle.GetHbFont();
+    if (!mpHbFont)
     {
+        hb_face_t* pHbFace;
         CTFontRef pCTFont = static_cast<CTFontRef>(CFDictionaryGetValue(rCoreTextStyle.GetStyleDict(), kCTFontAttributeName));
         CGFontRef pCGFont = CTFontCopyGraphicsFont(pCTFont, NULL);
         if (pCGFont)
-            mpHbFace = hb_coretext_face_create(pCGFont);
+            pHbFace = hb_coretext_face_create(pCGFont);
         else
-            mpHbFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr);
+            pHbFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr);
         CGFontRelease(pCGFont);
-        rCoreTextStyle.SetHbFace(mpHbFace);
+
+        mpHbFont = createHbFont(pHbFace);
+        rCoreTextStyle.SetHbFont(mpHbFont);
+
+        hb_face_destroy(pHbFace);
     }
+
+    scaleHbFont(mpHbFont, maFontSelData);
 }
 
 #else
 CommonSalLayout::CommonSalLayout(ServerFont& rServerFont)
-:   mpHbFace(nullptr),
-    maFontSelData(rServerFont.GetFontSelData()),
+:   maFontSelData(rServerFont.GetFontSelData()),
     mrServerFont(rServerFont)
 {
-    mpHbFace = rServerFont.GetHbFace();
-    if(!mpHbFace)
+    mpHbFont = rServerFont.GetHbFont();
+    if (!mpHbFont)
     {
-        mpHbFace = hb_face_create_for_tables(getFontTable, &rServerFont, nullptr);
-        mrServerFont.SetHbFace(mpHbFace);
-    }
-}
-#endif
+        hb_face_t* pHbFace = hb_face_create_for_tables(getFontTable, &rServerFont, nullptr);
 
-hb_font_t* CommonSalLayout::GetHbFont()
-{
-    // HACK. TODO: Get rid of HACK
-#if defined(_WIN32)
-    if(maFontSelData.mnWidth)
-        maFontSelData.mnWidth = (double)maFontSelData.mnWidth*1.812;
-#endif
+        mpHbFont = createHbFont(pHbFace);
+        mrServerFont.SetHbFont(mpHbFont);
 
-    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);
-    return pHbFont;
+        hb_face_destroy(pHbFace);
+    }
+
+    scaleHbFont(mpHbFont, maFontSelData);
 }
+#endif
 
 struct HbScriptRun
 {
@@ -267,18 +293,16 @@ void CommonSalLayout::AdjustLayout(ImplLayoutArgs& rArgs)
 
     if((rArgs.mnFlags & SalLayoutFlags::KashidaJustification) && rArgs.mpDXArray)
     {
-        hb_font_t* pHbFont = GetHbFont();
         hb_codepoint_t nKashidaCodePoint = 0x0640;
         hb_codepoint_t nKashidaGlyphIndex;
 
-        if(hb_font_get_glyph(pHbFont, nKashidaCodePoint, 0, &nKashidaGlyphIndex))
+        if(hb_font_get_glyph(mpHbFont, nKashidaCodePoint, 0, &nKashidaGlyphIndex))
         {
             if(nKashidaGlyphIndex)
             {
-                KashidaJustify(nKashidaGlyphIndex, hb_font_get_glyph_h_advance(pHbFont, nKashidaGlyphIndex) >> 6);
+                KashidaJustify(nKashidaGlyphIndex, hb_font_get_glyph_h_advance(mpHbFont, nKashidaGlyphIndex) >> 6);
             }
         }
-        hb_font_destroy(pHbFont);
     }
 }
 
@@ -290,7 +314,6 @@ void CommonSalLayout::DrawText( SalGraphics& rSalGraphics ) const
 
 bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
 {
-    hb_font_t* pHbFont = GetHbFont();
     hb_script_t aHbScript = HB_SCRIPT_INVALID;
 
     int nGlyphCapacity = 2 * (rArgs.mnEndCharPos - rArgs.mnMinCharPos);
@@ -379,7 +402,7 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
 #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);
+            hb_shape(mpHbFont, pHbBuffer, nullptr, 0);
 
             int nRunGlyphCount = hb_buffer_get_length(pHbBuffer);
             hb_glyph_info_t *pHbGlyphInfos = hb_buffer_get_glyph_infos(pHbBuffer, nullptr);
@@ -412,10 +435,11 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
                     nGlyphFlags |= GlyphItem::IS_IN_CLUSTER;
 
                 bool bDiacritic = false;
-                if (hb_ot_layout_has_glyph_classes(mpHbFace))
+                hb_face_t* pHbFace = hb_font_get_face(mpHbFont);
+                if (hb_ot_layout_has_glyph_classes(pHbFace))
                 {
                     // the font has GDEF table
-                    bool bMark = hb_ot_layout_get_glyph_class(mpHbFace, nGlyphIndex) == HB_OT_LAYOUT_GLYPH_CLASS_MARK;
+                    bool bMark = hb_ot_layout_get_glyph_class(pHbFace, nGlyphIndex) == HB_OT_LAYOUT_GLYPH_CLASS_MARK;
                     if (bMark && pHbPositions[i].x_advance == 0)
                         bDiacritic = true;
                 }
@@ -451,8 +475,6 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
         }
     }
 
-    hb_font_destroy(pHbFont);
-
     // sort glyphs in visual order
     // and then in logical order (e.g. diacritics after cluster start)
     // XXX: why?
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index 8cf7198..fbeb95e 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -462,7 +462,7 @@ ServerFont::ServerFont( const FontSelectPattern& rFSD, FreetypeFontInfo* pFI )
     mbArtBold( false ),
     mbUseGamma( false ),
     mpLayoutEngine( nullptr ),
-    mpHbFace( nullptr )
+    mpHbFont( nullptr )
 {
     // TODO: move update of mpFontInstance into FontEntry class when
     // it becomes responsible for the ServerFont instantiation
@@ -611,8 +611,8 @@ ServerFont::~ServerFont()
 
     mpFontInfo->ReleaseFaceFT();
 
-    if( mpHbFace )
-        hb_face_destroy( mpHbFace );
+    if( mpHbFont )
+        hb_font_destroy( mpHbFont );
 
     ReleaseFromGarbageCollect();
 }
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 7287de7..bded142 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -1009,7 +1009,7 @@ WinFontFace::WinFontFace( const FontAttributes& rDFS,
     mbAliasSymbolsHigh( false ),
     mbAliasSymbolsLow( false ),
     mbGsubRead( false ),
-    mpHbFace( nullptr )
+    mpHbFont( nullptr )
 {
     SetBitmapSize( 0, nHeight );
 
@@ -1051,8 +1051,8 @@ WinFontFace::~WinFontFace()
 #endif // ENABLE_GRAPHITE
     delete mpEncodingVector;
 
-    if( mpHbFace )
-        hb_face_destroy( mpHbFace );
+    if( mpHbFont )
+        hb_font_destroy( mpHbFont );
 }
 
 sal_IntPtr WinFontFace::GetFontId() const
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 4aafa44..9ab4dbe 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -4065,8 +4065,8 @@ PhysicalFontFace* WinFontFace::Clone() const
     if ( mpGraphiteData )
         mpGraphiteData->AddReference();
 #endif
-    if( mpHbFace )
-        hb_face_reference( mpHbFace );
+    if( mpHbFont )
+        hb_font_reference( mpHbFont );
 
     PhysicalFontFace* pClone = new WinFontFace( *this );
     return pClone;
commit 689ba3e35da110f3a4c0c5e6dd7f95c717f76ea7
Author: Akash Jain <akash96j at gmail.com>
Date:   Wed Aug 17 21:31:22 2016 +0530

    GSoC: Speed up CommonSalLayout by caching hb_face
    
    Cache hb_face so it is not created again and again.
    Switch from GDI to DirectWrite on Windows to obtain SFNT table data.
    
    Change-Id: I9c532cd72e1f6b57313f3b7d42a6b9b0633eb0ef

diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx
index ba93855..da75f0f 100644
--- a/vcl/inc/CommonSalLayout.hxx
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -41,6 +41,7 @@ class CommonSalLayout : public GenericSalLayout
 #ifdef _WIN32
     HDC   mhDC;
     HFONT mhFont;
+    D2DWriteTextOutRenderer* mpD2DRenderer;
 #elif defined(MACOSX) || defined(IOS)
     const CoreTextStyle& mrCoreTextStyle;
 #else
@@ -50,7 +51,7 @@ class CommonSalLayout : public GenericSalLayout
     hb_font_t*              GetHbFont();
 public:
 #if defined(_WIN32)
-    explicit                CommonSalLayout(HDC, WinFontInstance&);
+    explicit                CommonSalLayout(WinSalGraphics*, WinFontInstance&, const WinFontFace&);
     virtual void            InitFont() const override;
 #elif defined(MACOSX) || defined(IOS)
     explicit                CommonSalLayout(const CoreTextStyle&);
@@ -60,7 +61,6 @@ public:
     const ServerFont&       getFontData() const { return mrServerFont; };
 #endif
 
-    virtual                 ~CommonSalLayout();
     void                    SetNeedFallback(ImplLayoutArgs&, sal_Int32, bool);
     void                    AdjustLayout(ImplLayoutArgs&) override;
     virtual bool            LayoutText(ImplLayoutArgs&) override;
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 104699b..00b2d8e 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -45,6 +45,7 @@
 
 #include "quartz/salgdicommon.hxx"
 #include <unordered_map>
+#include <hb-ot.h>
 
 class AquaSalFrame;
 class FontAttributes;
@@ -98,6 +99,8 @@ public:
     void       GetFontMetric( ImplFontMetricDataRef& ) const;
     bool       GetGlyphBoundRect( sal_GlyphId, Rectangle& ) const;
     bool       GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) const;
+    hb_face_t* GetHbFace() const { return mpHbFace; }
+    void       SetHbFace(hb_face_t* pHbFace) const { mpHbFace = pHbFace; }
 
     const CoreTextFontFace*  mpFontData;
     /// <1.0: font is squeezed, >1.0 font is stretched, else 1.0
@@ -109,6 +112,7 @@ public:
 private:
     /// CoreText text style object
     CFMutableDictionaryRef  mpStyleDict;
+    mutable hb_face_t*      mpHbFace;
 
     friend class CTLayout;
     friend class AquaSalGraphics;
diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx
index 944ffff..38967bf 100644
--- a/vcl/inc/unx/glyphcache.hxx
+++ b/vcl/inc/unx/glyphcache.hxx
@@ -35,6 +35,7 @@
 #include <sallayout.hxx>
 #include "fontattributes.hxx"
 #include "impfontmetricdata.hxx"
+#include "hb-ot.h"
 
 #include <unordered_map>
 
@@ -181,6 +182,8 @@ public:
     sal_GlyphId             FixupGlyphIndex( sal_GlyphId aGlyphId, sal_UCS4 ) const;
     bool                    GetGlyphOutline( sal_GlyphId aGlyphId, basegfx::B2DPolyPolygon& ) const;
     bool                    GetAntialiasAdvice() const;
+    hb_face_t*              GetHbFace() { return mpHbFace; }
+    void                    SetHbFace( hb_face_t* pHbFace ) { mpHbFace=pHbFace; }
 
 private:
     friend class GlyphCache;
@@ -240,6 +243,7 @@ private:
     GlyphSubstitution       maGlyphSubstitution;
 
     ServerFontLayoutEngine* mpLayoutEngine;
+    hb_face_t*              mpHbFace;
 };
 
 // a class for cache entries for physical font instances that are based on serverfonts
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 2defd7f..e1d64c5 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -44,6 +44,9 @@
 #  include "postwin.h"
 #endif
 
+#include <hb-ot.h>
+#include <dwrite.h>
+
 class FontSelectPattern;
 class WinFontInstance;
 class ImplFontAttrCache;
@@ -139,10 +142,12 @@ private:
 
     mutable std::unordered_set<sal_UCS4>      maGsubTable;
     mutable bool            mbGsubRead;
+    mutable hb_face_t*      mpHbFace;
 public:
     bool                    HasGSUBstitutions( HDC ) const;
     bool                    IsGSUBstituted( sal_UCS4 ) const;
-    static int              GetTable( const char pTagName[5], const unsigned char*&, HDC );
+    hb_face_t*              GetHbFace() const { return mpHbFace; }
+    void                    SetHbFace( hb_face_t* pHbFace ) const { mpHbFace = pHbFace; }
 };
 
 /** Class that creates (and destroys) a compatible Device Context.
@@ -354,6 +359,7 @@ private:
     sal_uLong               GetKernPairs();
 
 public:
+    sal_uLong               GetTable( const char pTagName[5], const unsigned char*&, void*&, IDWriteFontFace*& );
     // public SalGraphics methods, the interface to the independent vcl part
 
     // get device resolution
diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx
index 28be80b..f183c10 100644
--- a/vcl/quartz/ctfonts.cxx
+++ b/vcl/quartz/ctfonts.cxx
@@ -50,6 +50,7 @@ CoreTextStyle::CoreTextStyle( const FontSelectPattern& rFSD )
     , mfFontRotation( 0.0 )
     , maFontSelData( rFSD )
     , mpStyleDict( nullptr )
+    , mpHbFace( nullptr )
 {
     const FontSelectPattern* const pReqFont = &rFSD;
 
@@ -116,6 +117,8 @@ CoreTextStyle::~CoreTextStyle()
 {
     if( mpStyleDict )
         CFRelease( mpStyleDict );
+    if( mpHbFace )
+        hb_face_destroy( mpHbFace );
 }
 
 void CoreTextStyle::GetFontMetric( ImplFontMetricDataRef& rxFontMetric ) const
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index eb5b6a2..afdbdf8 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -26,6 +26,21 @@
 #include <limits>
 #include <salgdi.hxx>
 
+#if defined(_WIN32)
+struct WinSalGraphicsWithIDFace
+{
+    WinSalGraphics*     mpWSL;
+    IDWriteFontFace*    mpIDFace;
+    void*               mpTableContext;
+
+    WinSalGraphicsWithIDFace( WinSalGraphics* pWSL, IDWriteFontFace* pIDFace )
+    : mpWSL( pWSL ),
+      mpIDFace( pIDFace ),
+      mpTableContext( nullptr )
+    {}
+};
+#endif
+
 static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pUserData)
 {
     char pTagName[5];
@@ -38,8 +53,8 @@ static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pU
     sal_uLong nLength=0;
 #if defined(_WIN32)
     const unsigned char* pBuffer = nullptr;
-    HDC* phDC = static_cast<HDC*>(pUserData);
-    nLength = WinFontFace::GetTable(pTagName, pBuffer, *phDC);
+    WinSalGraphicsWithIDFace* pWSLWithIDFace = static_cast<WinSalGraphicsWithIDFace*>(pUserData);
+    nLength = (pWSLWithIDFace->mpWSL)->GetTable(pTagName, pBuffer, pWSLWithIDFace->mpTableContext, pWSLWithIDFace->mpIDFace);
 #elif defined(MACOSX) || defined(IOS)
     unsigned char* pBuffer = nullptr;
     CoreTextFontFace* pFont = static_cast<CoreTextFontFace*>(pUserData);
@@ -57,7 +72,15 @@ static hb_blob_t *getFontTable(hb_face_t* /*face*/, hb_tag_t nTableTag, void* pU
 
     hb_blob_t* pBlob = nullptr;
     if (pBuffer != nullptr)
-#if defined(_WIN32) || defined(MACOSX) || defined(IOS)
+#if defined(_WIN32)
+        pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY, pWSLWithIDFace,
+                               [](void* pUserData)
+                               {
+                                   WinSalGraphicsWithIDFace* pUData = static_cast<WinSalGraphicsWithIDFace*>(pUserData);
+                                   pUData->mpIDFace->ReleaseFontTable(pUData->mpTableContext);
+                               }
+                              );
+#elif defined(MACOSX) || defined(IOS)
         pBlob = hb_blob_create(reinterpret_cast<const char*>(pBuffer), nLength, HB_MEMORY_MODE_READONLY,
                                const_cast<unsigned char*>(pBuffer), [](void* data){ delete[] reinterpret_cast<unsigned char*>(data); } );
 #else
@@ -77,13 +100,29 @@ static hb_unicode_funcs_t* getUnicodeFuncs()
 }
 
 #if defined(_WIN32)
-CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance)
-:   mhDC(hDC),
-    mhFont((HFONT)GetCurrentObject(hDC, OBJ_FONT)),
+CommonSalLayout::CommonSalLayout(WinSalGraphics* WSL, WinFontInstance& rWinFontInstance, const WinFontFace& rWinFontFace)
+:   mhFont((HFONT)GetCurrentObject(WSL->getHDC(), OBJ_FONT)),
+    mhDC(WSL->getHDC()),
     mpHbFace(nullptr),
-    maFontSelData(rWinFontInstance.maFontSelData)
+    maFontSelData(rWinFontInstance.maFontSelData),
+    mpD2DRenderer(nullptr)
 {
-    mpHbFace = hb_face_create_for_tables(getFontTable, &hDC, nullptr);
+    mpHbFace = rWinFontFace.GetHbFace();
+    if(!mpHbFace)
+    {
+        mpD2DRenderer = dynamic_cast<D2DWriteTextOutRenderer*>(&TextOutRenderer::get());
+        WinSalGraphicsWithIDFace* pWSLWithIDFace = new WinSalGraphicsWithIDFace(WSL, mpD2DRenderer->GetDWriteFontFace(mhDC));
+        mpHbFace= hb_face_create_for_tables( getFontTable, pWSLWithIDFace,
+                  [](void* pUserData)
+                  {
+                      WinSalGraphicsWithIDFace* pUData = static_cast<WinSalGraphicsWithIDFace*>( pUserData );
+                      if(pUData->mpIDFace)
+                          pUData->mpIDFace->Release();
+                      delete pUData;
+                  }
+                 );
+        rWinFontFace.SetHbFace(mpHbFace);
+    }
 }
 
 void CommonSalLayout::InitFont() const
@@ -97,13 +136,18 @@ CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle)
     maFontSelData(rCoreTextStyle.maFontSelData),
     mrCoreTextStyle(rCoreTextStyle)
 {
-    CTFontRef pCTFont = static_cast<CTFontRef>(CFDictionaryGetValue(rCoreTextStyle.GetStyleDict(), kCTFontAttributeName));
-    CGFontRef pCGFont = CTFontCopyGraphicsFont(pCTFont, NULL);
-    if (pCGFont)
-        mpHbFace = hb_coretext_face_create(pCGFont);
-    else
-        mpHbFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr);
-    CGFontRelease(pCGFont);
+    mpHbFace = rCoreTextStyle.GetHbFace();
+    if(!mpHbFace)
+    {
+        CTFontRef pCTFont = static_cast<CTFontRef>(CFDictionaryGetValue(rCoreTextStyle.GetStyleDict(), kCTFontAttributeName));
+        CGFontRef pCGFont = CTFontCopyGraphicsFont(pCTFont, NULL);
+        if (pCGFont)
+            mpHbFace = hb_coretext_face_create(pCGFont);
+        else
+            mpHbFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr);
+        CGFontRelease(pCGFont);
+        rCoreTextStyle.SetHbFace(mpHbFace);
+    }
 }
 
 #else
@@ -112,15 +156,15 @@ CommonSalLayout::CommonSalLayout(ServerFont& rServerFont)
     maFontSelData(rServerFont.GetFontSelData()),
     mrServerFont(rServerFont)
 {
-    mpHbFace = hb_face_create_for_tables(getFontTable, &rServerFont, nullptr);
+    mpHbFace = rServerFont.GetHbFace();
+    if(!mpHbFace)
+    {
+        mpHbFace = hb_face_create_for_tables(getFontTable, &rServerFont, nullptr);
+        mrServerFont.SetHbFace(mpHbFace);
+    }
 }
 #endif
 
-CommonSalLayout::~CommonSalLayout()
-{
-    hb_face_destroy(mpHbFace);
-}
-
 hb_font_t* CommonSalLayout::GetHbFont()
 {
     // HACK. TODO: Get rid of HACK
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index 55df59e..8cf7198 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -461,7 +461,8 @@ ServerFont::ServerFont( const FontSelectPattern& rFSD, FreetypeFontInfo* pFI )
     mbArtItalic( false ),
     mbArtBold( false ),
     mbUseGamma( false ),
-    mpLayoutEngine( nullptr )
+    mpLayoutEngine( nullptr ),
+    mpHbFace( nullptr )
 {
     // TODO: move update of mpFontInstance into FontEntry class when
     // it becomes responsible for the ServerFont instantiation
@@ -610,6 +611,9 @@ ServerFont::~ServerFont()
 
     mpFontInfo->ReleaseFaceFT();
 
+    if( mpHbFace )
+        hb_face_destroy( mpHbFace );
+
     ReleaseFromGarbageCollect();
 }
 
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 6ffd895..7287de7 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -1008,7 +1008,8 @@ WinFontFace::WinFontFace( const FontAttributes& rDFS,
     mnPitchAndFamily( nPitchAndFamily ),
     mbAliasSymbolsHigh( false ),
     mbAliasSymbolsLow( false ),
-    mbGsubRead( false )
+    mbGsubRead( false ),
+    mpHbFace( nullptr )
 {
     SetBitmapSize( 0, nHeight );
 
@@ -1049,6 +1050,9 @@ WinFontFace::~WinFontFace()
 #endif
 #endif // ENABLE_GRAPHITE
     delete mpEncodingVector;
+
+    if( mpHbFace )
+        hb_face_destroy( mpHbFace );
 }
 
 sal_IntPtr WinFontFace::GetFontId() const
@@ -1201,16 +1205,22 @@ void WinFontFace::ReadCmapTable( HDC hDC ) const
     }
 }
 
-int WinFontFace::GetTable(const char pTagName[5], const unsigned char*& pResBuffer, HDC hDC)
+sal_uLong WinSalGraphics::GetTable( const char pTagName[5], const unsigned char*& pResBuffer, void*& pTableContext, IDWriteFontFace*& pIDFace )
 {
-    const DWORD nTableTag = CalcTag( pTagName );
-    RawFontData aRawFontData( hDC, nTableTag );
-
-    if( !aRawFontData.get() )
+    if( !pIDFace )
         return 0;
-
-    pResBuffer = aRawFontData.steal();
-    return aRawFontData.size();
+    const void* pResBuf;
+    UINT32 nSize;
+    BOOL bExists;
+    HRESULT hr = S_OK;
+    const DWORD nTableTag = DWRITE_MAKE_OPENTYPE_TAG( pTagName[0], pTagName[1], pTagName[2], pTagName[3] );
+    hr = pIDFace->TryGetFontTable( nTableTag, &pResBuf, &nSize, &pTableContext, &bExists );
+    if( SUCCEEDED( hr ) && ( bExists ) )
+    {
+        pResBuffer = static_cast<const unsigned char*>(pResBuf);
+        return static_cast<sal_uLong>(nSize);
+    }
+    return 0;
 }
 
 void WinFontFace::GetFontCapabilities( HDC hDC ) const
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 538f46a..4aafa44 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -3518,6 +3518,24 @@ bool D2DWriteTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC,
     return (succeeded && nGlyphs >= 1 && pRectToErase);
 }
 
+IDWriteFontFace* D2DWriteTextOutRenderer::GetDWriteFontFace(HDC hDC) const
+{
+    IDWriteFontFace* pFontFace;
+    bool succeeded = false;
+    try
+    {
+        succeeded = SUCCEEDED(mpGdiInterop->CreateFontFaceFromHdc(hDC, &pFontFace));
+    }
+    catch (const std::exception& e)
+    {
+        SAL_WARN("vcl.gdi.opengl", "Error in dwrite while creating font face: " << e.what());
+        return nullptr;
+    }
+    if(succeeded)
+    return pFontFace;
+    else return nullptr;
+}
+
 bool D2DWriteTextOutRenderer::BindFont(HDC hDC)
 {
     // A TextOutRender can only be bound to one font at a time, so the
@@ -3884,7 +3902,7 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe
 
     if( getenv("SAL_USE_COMMON_LAYOUT") )
     {
-        return new CommonSalLayout( getHDC(), rFontInstance );
+        return new CommonSalLayout( this, rFontInstance, rFontFace );
     }
     else
     {
@@ -4047,6 +4065,9 @@ PhysicalFontFace* WinFontFace::Clone() const
     if ( mpGraphiteData )
         mpGraphiteData->AddReference();
 #endif
+    if( mpHbFace )
+        hb_face_reference( mpHbFace );
+
     PhysicalFontFace* pClone = new WinFontFace( *this );
     return pClone;
 }
commit 42dd004278bfec708c7e67e03bcb1745f5641170
Author: Akash Jain <akash96j at gmail.com>
Date:   Thu Aug 18 20:51:25 2016 +0530

    GSoC: Move TextOutRenderer definition to winlayout.hxx
    
    Change-Id: I705f92d5ad55d7612c6413436c801de13f5352a6

diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx
index 7905513..4c6874f 100755
--- a/vcl/inc/win/winlayout.hxx
+++ b/vcl/inc/win/winlayout.hxx
@@ -417,4 +417,105 @@ public:
 
 #endif
 
+class TextOutRenderer
+{
+protected:
+    explicit TextOutRenderer() = default;
+    TextOutRenderer(const TextOutRenderer &) = delete;
+    TextOutRenderer & operator = (const TextOutRenderer &) = delete;
+
+public:
+    static TextOutRenderer & get();
+
+    virtual ~TextOutRenderer() = default;
+
+    virtual bool operator ()(SalLayout const &rLayout, HDC hDC,
+        const Rectangle* pRectToErase,
+        Point* pPos, int* pGetNextGlypInfo) = 0;
+};
+
+class ExTextOutRenderer : public TextOutRenderer
+{
+    ExTextOutRenderer(const ExTextOutRenderer &) = delete;
+    ExTextOutRenderer & operator = (const ExTextOutRenderer &) = delete;
+
+public:
+    explicit ExTextOutRenderer() = default;
+    virtual ~ExTextOutRenderer() override = default;
+
+    bool operator ()(SalLayout const &rLayout, HDC hDC,
+        const Rectangle* pRectToErase,
+        Point* pPos, int* pGetNextGlypInfo) override;
+};
+
+#if ENABLE_GRAPHITE_DWRITE
+
+class D2DWriteTextOutRenderer : public TextOutRenderer
+{
+    typedef HRESULT(WINAPI *pD2D1CreateFactory_t)(D2D1_FACTORY_TYPE,
+        REFIID, const D2D1_FACTORY_OPTIONS *, void **);
+    typedef HRESULT(WINAPI *pDWriteCreateFactory_t)(DWRITE_FACTORY_TYPE,
+        REFIID, IUnknown **);
+
+    static HINSTANCE mmD2d1, mmDWrite;
+    static pD2D1CreateFactory_t     D2D1CreateFactory;
+    static pDWriteCreateFactory_t   DWriteCreateFactory;
+
+public:
+    static bool InitModules();
+
+    explicit D2DWriteTextOutRenderer();
+    virtual ~D2DWriteTextOutRenderer() override;
+
+    bool operator ()(SalLayout const &rLayout, HDC hDC,
+        const Rectangle* pRectToErase,
+        Point* pPos, int* pGetNextGlypInfo) override;
+
+    inline bool BindDC(HDC hDC, Rectangle const & rRect = Rectangle(0, 0, 0, 0)) {
+        RECT const rc = { rRect.Left(), rRect.Top(), rRect.Right(), rRect.Bottom() };
+        HRESULT ok= mpRT->BindDC(hDC, &rc);
+        return SUCCEEDED(ok);
+    }
+
+    bool BindFont(HDC hDC) /*override*/;
+    bool ReleaseFont() /*override*/;
+
+    std::vector<Rectangle>  GetGlyphInkBoxes(uint16_t * pGid, uint16_t * pGidEnd) const /*override*/;
+    ID2D1RenderTarget * GetRenderTarget() const { return mpRT; }
+    IDWriteFontFace*    GetDWriteFontFace(HDC) const;
+    IDWriteFontFace   * GetFontFace() const { return mpFontFace; }
+    float               GetEmHeight() const { return mlfEmHeight; }
+
+    inline HRESULT CreateRenderTarget() {
+        if (mpRT) mpRT->Release(); mpRT = nullptr;
+        return mpD2DFactory->CreateDCRenderTarget(&mRTProps, &mpRT);
+    }
+
+    inline bool Ready() const { return mpGdiInterop && mpRT; }
+
+private:
+    static void CleanupModules();
+
+    // This is a singleton object disable copy ctor and assignemnt operator
+    D2DWriteTextOutRenderer(const D2DWriteTextOutRenderer &) = delete;
+    D2DWriteTextOutRenderer & operator = (const D2DWriteTextOutRenderer &) = delete;
+
+    bool GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** ppFontFace, float * lfSize) const;
+    bool GetDWriteInkBox(IDWriteFontFace & rFontFace, SalLayout const &rLayout, float const lfEmHeight, Rectangle &) const;
+    bool DrawGlyphs(const Point & origin, uint16_t * pGid, uint16_t * pGidEnd,
+        float * pAdvances, Point * pOffsets) /*override*/;
+
+    ID2D1Factory        * mpD2DFactory;
+    IDWriteFactory      * mpDWriteFactory;
+    IDWriteGdiInterop   * mpGdiInterop;
+    ID2D1DCRenderTarget * mpRT;
+    const D2D1_RENDER_TARGET_PROPERTIES mRTProps;
+
+    IDWriteFontFace * mpFontFace;
+    float             mlfEmHeight;
+    HDC               mhDC;
+};
+
+#endif
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 48c40af..538f46a 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -17,8 +17,6 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include "win/winlayout.hxx"
-
 #include "osl/module.h"
 #include "osl/file.h"
 
@@ -56,104 +54,8 @@
 std::unique_ptr<GlobalGlyphCache> GlyphCache::gGlobalGlyphCache(new GlobalGlyphCache);
 GLuint WinFontInstance::mnGLyphyProgram = 0;
 
-class TextOutRenderer
-{
-protected:
-    explicit TextOutRenderer() = default;
-    TextOutRenderer(const TextOutRenderer &) = delete;
-    TextOutRenderer & operator = (const TextOutRenderer &) = delete;
-
-public:
-    static TextOutRenderer & get();
-
-    virtual ~TextOutRenderer() = default;
-
-    virtual bool operator ()(SalLayout const &rLayout, HDC hDC,
-        const Rectangle* pRectToErase,
-        Point* pPos, int* pGetNextGlypInfo) = 0;
-};
-
-class ExTextOutRenderer : public TextOutRenderer
-{
-    ExTextOutRenderer(const ExTextOutRenderer &) = delete;
-    ExTextOutRenderer & operator = (const ExTextOutRenderer &) = delete;
-
-public:
-    explicit ExTextOutRenderer() = default;
-    virtual ~ExTextOutRenderer() override = default;
-
-    bool operator ()(SalLayout const &rLayout, HDC hDC,
-        const Rectangle* pRectToErase,
-        Point* pPos, int* pGetNextGlypInfo) override;
-};
-
 #if ENABLE_GRAPHITE_DWRITE
 
-class D2DWriteTextOutRenderer : public TextOutRenderer
-{
-    typedef HRESULT(WINAPI *pD2D1CreateFactory_t)(D2D1_FACTORY_TYPE,
-        REFIID, const D2D1_FACTORY_OPTIONS *, void **);
-
-    typedef HRESULT(WINAPI *pDWriteCreateFactory_t)(DWRITE_FACTORY_TYPE,
-        REFIID, IUnknown **);
-
-    static HINSTANCE mmD2d1, mmDWrite;
-    static pD2D1CreateFactory_t     D2D1CreateFactory;
-    static pDWriteCreateFactory_t   DWriteCreateFactory;
-
-public:
-    static bool InitModules();
-
-    explicit D2DWriteTextOutRenderer();
-    virtual ~D2DWriteTextOutRenderer() override;
-
-    bool operator ()(SalLayout const &rLayout, HDC hDC,
-        const Rectangle* pRectToErase,
-        Point* pPos, int* pGetNextGlypInfo) override;
-
-    inline bool BindDC(HDC hDC, Rectangle const & rRect = Rectangle(0, 0, 0, 0)) {
-        RECT const rc = { rRect.Left(), rRect.Top(), rRect.Right(), rRect.Bottom() };
-        return SUCCEEDED(mpRT->BindDC(hDC, &rc));
-    }
-
-    bool BindFont(HDC hDC) /*override*/;
-    bool ReleaseFont() /*override*/;
-
-    std::vector<Rectangle>  GetGlyphInkBoxes(uint16_t * pGid, uint16_t * pGidEnd) const /*override*/;
-    ID2D1RenderTarget * GetRenderTarget() const { return mpRT; }
-    IDWriteFontFace   * GetFontFace() const { return mpFontFace; }
-    float               GetEmHeight() const { return mlfEmHeight; }
-
-    inline HRESULT CreateRenderTarget() {
-        if (mpRT) mpRT->Release(); mpRT = nullptr;
-        return mpD2DFactory->CreateDCRenderTarget(&mRTProps, &mpRT);
-    }
-
-    inline bool Ready() const { return mpGdiInterop && mpRT; }
-
-private:
-    static void CleanupModules();
-
-    // This is a singleton object disable copy ctor and assignemnt operator
-    D2DWriteTextOutRenderer(const D2DWriteTextOutRenderer &) = delete;
-    D2DWriteTextOutRenderer & operator = (const D2DWriteTextOutRenderer &) = delete;
-
-    bool GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** ppFontFace, float * lfSize) const;
-    bool GetDWriteInkBox(IDWriteFontFace & rFontFace, SalLayout const &rLayout, float const lfEmHeight, Rectangle &) const;
-    bool DrawGlyphs(const Point & origin, uint16_t * pGid, uint16_t * pGidEnd,
-        float * pAdvances, Point * pOffsets) /*override*/;
-
-    ID2D1Factory        * mpD2DFactory;
-    IDWriteFactory      * mpDWriteFactory;
-    IDWriteGdiInterop   * mpGdiInterop;
-    ID2D1DCRenderTarget * mpRT;
-    const D2D1_RENDER_TARGET_PROPERTIES mRTProps;
-
-    IDWriteFontFace * mpFontFace;
-    float             mlfEmHeight;
-    HDC               mhDC;
-};
-
 inline void WinFontInstance::CacheGlyphWidth( int nCharCode, int nCharWidth )
 {
     maWidthMap[ nCharCode ] = nCharWidth;
commit df965d49e08ea1c115d6c3720b6a989a7e8b0f30
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 6dabc15..d4bc0f7 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -532,23 +532,23 @@ SalLayout* CairoTextRender::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackL
     if( mpServerFont[ nFallbackLevel ]
     && !(rArgs.mnFlags & SalLayoutFlags::DisableGlyphProcessing) )
     {
-#if ENABLE_GRAPHITE
-        // Is this a Graphite font?
-        if (!bDisableGraphite_ &&
-            GraphiteServerFontLayout::IsGraphiteEnabledFont(*mpServerFont[nFallbackLevel]))
+        if(getenv("SAL_USE_COMMON_LAYOUT"))
         {
-            pLayout = new GraphiteServerFontLayout(*mpServerFont[nFallbackLevel]);
+            pLayout = new CommonSalLayout( *mpServerFont[ nFallbackLevel ] );
         }
         else
-#endif
-            if(getenv("SAL_USE_COMMON_LAYOUT"))
+        {
+#if ENABLE_GRAPHITE
+            // Is this a Graphite font?
+            if (!bDisableGraphite_ &&
+                GraphiteServerFontLayout::IsGraphiteEnabledFont(*mpServerFont[nFallbackLevel]))
             {
-                pLayout = new CommonSalLayout( *mpServerFont[ nFallbackLevel ] );
+                pLayout = new GraphiteServerFontLayout(*mpServerFont[nFallbackLevel]);
             }
             else
-            {
+#endif
                 pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] );
-            }
+        }
     }
 
     return pLayout;
commit edb26d411b07a663df3b81d56aa751a1d5cd942d
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 4df66cb..6dd2d10 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9252,10 +9252,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
@@ -9348,6 +9352,16 @@ if test "$with_harfbuzz" = "yes" -o \( $_os != WINNT -a $_os != Darwin -a $_os !
     if test "$COM" = "MSC"; then # override the above
         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])
+        _save_libs="$LIBS"
+        _save_cflags="$CFLAGS"
+        LIBS="$LIBS $HARFBUZZ_LIBS"
+        CFLAGS="$CFLAGS $HARFBUZZ_CFLAGS"
+        AC_CHECK_FUNC(hb_graphite2_face_get_gr_face,,[AC_MSG_ERROR([Harfbuzz needs to be built with Graphite support.])])
+        LIBS="$_save_libs"
+        CFLAGS="$_save_cflags"
+    fi
 else
     AC_MSG_RESULT([no])
 fi
diff --git a/external/harfbuzz/ExternalProject_harfbuzz.mk b/external/harfbuzz/ExternalProject_harfbuzz.mk
index 1bee5bb..4412815 100644
--- a/external/harfbuzz/ExternalProject_harfbuzz.mk
+++ b/external/harfbuzz/ExternalProject_harfbuzz.mk
@@ -23,6 +23,8 @@ $(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 \
@@ -33,6 +35,7 @@ $(call gb_ExternalProject_get_state_target,harfbuzz,build) :
 			--with-fontconfig=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") \
commit 29a5f5ee4abcfc524a9732a874dff28b23b60f66
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/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx
index 5a4c9a2..ba93855 100644
--- a/vcl/inc/CommonSalLayout.hxx
+++ b/vcl/inc/CommonSalLayout.hxx
@@ -23,6 +23,7 @@
 #elif defined(MACOSX) || defined(IOS)
 #include <com/sun/star/i18n/XBreakIterator.hpp>
 #include "quartz/ctfonts.hxx"
+#include <hb-coretext.h>
 
 #else
 #include "unx/freetype_glyphcache.hxx"
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 ba0200b..104699b 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -111,6 +111,8 @@ private:
     CFMutableDictionaryRef  mpStyleDict;
 
     friend class CTLayout;
+    friend class AquaSalGraphics;
+    friend class CommonSalLayout;
     CFMutableDictionaryRef  GetStyleDict( void ) const { return mpStyleDict; }
 };
 
diff --git a/vcl/quartz/ctfonts.cxx b/vcl/quartz/ctfonts.cxx
index 36b155d..28be80b 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 35f7143..0e80020 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 d0f73a8..8362696 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 f37a257..eb5b6a2 100644
--- 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
@@ -97,7 +97,13 @@ CommonSalLayout::CommonSalLayout(const CoreTextStyle& rCoreTextStyle)
     maFontSelData(rCoreTextStyle.maFontSelData),
     mrCoreTextStyle(rCoreTextStyle)
 {
-    mpHbFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr);
+    CTFontRef pCTFont = static_cast<CTFontRef>(CFDictionaryGetValue(rCoreTextStyle.GetStyleDict(), kCTFontAttributeName));
+    CGFontRef pCGFont = CTFontCopyGraphicsFont(pCTFont, NULL);
+    if (pCGFont)
+        mpHbFace = hb_coretext_face_create(pCGFont);
+    else
+        mpHbFace = hb_face_create_for_tables(getFontTable, const_cast<CoreTextFontFace*>(rCoreTextStyle.mpFontData), nullptr);
+    CGFontRelease(pCGFont);
 }
 
 #else
commit 5445a8f9a2465365d9f159fcde52cb5980996d2d
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 f19bcdd..f37a257 100644
--- 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),
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 80f32b3..6ffd895 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -2612,7 +2612,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..48c40af 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -34,6 +34,7 @@
 
 #include "sft.hxx"
 #include "sallayout.hxx"
+#include "CommonSalLayout.hxx"
 
 #include <cstdio>
 #include <cstdlib>
@@ -67,7 +68,7 @@ public:
 
     virtual ~TextOutRenderer() = default;
 
-    virtual bool operator ()(WinLayout const &rLayout, HDC hDC,
+    virtual bool operator ()(SalLayout const &rLayout, HDC hDC,
         const Rectangle* pRectToErase,
         Point* pPos, int* pGetNextGlypInfo) = 0;
 };
@@ -81,7 +82,7 @@ public:
     explicit ExTextOutRenderer() = default;
     virtual ~ExTextOutRenderer() override = default;
 
-    bool operator ()(WinLayout const &rLayout, HDC hDC,
+    bool operator ()(SalLayout const &rLayout, HDC hDC,
         const Rectangle* pRectToErase,
         Point* pPos, int* pGetNextGlypInfo) override;
 };
@@ -106,7 +107,7 @@ public:
     explicit D2DWriteTextOutRenderer();
     virtual ~D2DWriteTextOutRenderer() override;
 
-    bool operator ()(WinLayout const &rLayout, HDC hDC,
+    bool operator ()(SalLayout const &rLayout, HDC hDC,
         const Rectangle* pRectToErase,
         Point* pPos, int* pGetNextGlypInfo) override;
 
@@ -138,7 +139,7 @@ private:
     D2DWriteTextOutRenderer & operator = (const D2DWriteTextOutRenderer &) = delete;
 
     bool GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** ppFontFace, float * lfSize) const;
-    bool GetDWriteInkBox(IDWriteFontFace & rFontFace, WinLayout const &rLayout, float const lfEmHeight, Rectangle &) const;
+    bool GetDWriteInkBox(IDWriteFontFace & rFontFace, SalLayout const &rLayout, float const lfEmHeight, Rectangle &) const;
     bool DrawGlyphs(const Point & origin, uint16_t * pGid, uint16_t * pGidEnd,
         float * pAdvances, Point * pOffsets) /*override*/;
 
@@ -3485,7 +3486,7 @@ TextOutRenderer & TextOutRenderer::get()
 }
 
 
-bool ExTextOutRenderer::operator ()(WinLayout const &rLayout, HDC hDC,
+bool ExTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC,
     const Rectangle* pRectToErase,
     Point* pPos, int* pGetNextGlypInfo)
 {
@@ -3544,7 +3545,7 @@ D2DWriteTextOutRenderer::~D2DWriteTextOutRenderer()
     CleanupModules();
 }
 
-bool D2DWriteTextOutRenderer::operator ()(WinLayout const &rLayout, HDC hDC,
+bool D2DWriteTextOutRenderer::operator ()(SalLayout const &rLayout, HDC hDC,
     const Rectangle* pRectToErase,
     Point* pPos, int* pGetNextGlypInfo)
 {
@@ -3784,7 +3785,7 @@ bool D2DWriteTextOutRenderer::GetDWriteFaceFromHDC(HDC hDC, IDWriteFontFace ** p
     return succeeded;
 }
 
-bool D2DWriteTextOutRenderer::GetDWriteInkBox(IDWriteFontFace & rFontFace, WinLayout const &rLayout, float const /*lfEmHeight*/, Rectangle & rOut) const
+bool D2DWriteTextOutRenderer::GetDWriteInkBox(IDWriteFontFace & rFontFace, SalLayout const &rLayout, float const /*lfEmHeight*/, Rectangle & rOut) const
 {
     rOut.SetEmpty();
 
@@ -3979,66 +3980,73 @@ 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
-        }
+        return new CommonSalLayout( getHDC(), rFontInstance );
     }
     else
     {
-#if ENABLE_GRAPHITE
-        if (rFontFace.SupportsGraphite())
-        {
-            pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
-        }
-        else
-#endif // ENABLE_GRAPHITE
-        {
-            static bool bAvoidSimpleWinLayout = (std::getenv("VCL_NO_SIMPLEWINLAYOUT") != NULL);
+        bool bUseOpenGL = OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter;
 
-            if (!bAvoidSimpleWinLayout)
-            {
-                if( (rArgs.mnFlags & SalLayoutFlags::KerningPairs) && !rFontInstance.HasKernData() )
-                {
-                    // TODO: directly cache kerning info in the rFontInstance
-                    // TODO: get rid of kerning methods+data in WinSalGraphics object
-                    GetKernPairs();
-                    rFontInstance.SetKernData( mnFontKernPairCount, mpFontKernPairs );
-                }
+        if (!bUspInited)
+            InitUSP();
 
-                pWinLayout = new SimpleWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
+        if( !(rArgs.mnFlags & SalLayoutFlags::ComplexDisabled) )
+        {
+#if ENABLE_GRAPHITE
+            if (rFontFace.SupportsGraphite())
+            {
+                pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
             }
             else
+#endif // ENABLE_GRAPHITE
             {
+                // script complexity is determined in upper layers
                 pWinLayout = new UniscribeLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
                 // NOTE: it must be guaranteed that the WinSalGraphics lives longer than
                 // the created UniscribeLayout, otherwise the data passed into the
                 // constructor might become invalid too early
             }
         }
-    }
+        else
+        {
+#if ENABLE_GRAPHITE
+            if (rFontFace.SupportsGraphite())
+            {
+                pWinLayout = new GraphiteWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
+            }
+            else
+#endif // ENABLE_GRAPHITE
+            {
+                static bool bAvoidSimpleWinLayout = (std::getenv("VCL_NO_SIMPLEWINLAYOUT") != NULL);
+
+                if (!bAvoidSimpleWinLayout)
+                {
+                    if( (rArgs.mnFlags & SalLayoutFlags::KerningPairs) && !rFontInstance.HasKernData() )
+                    {
+                        // TODO: directly cache kerning info in the rFontInstance
+                        // TODO: get rid of kerning methods+data in WinSalGraphics object
+                        GetKernPairs();
+                        rFontInstance.SetKernData( mnFontKernPairCount, mpFontKernPairs );
+                    }
+
+                    pWinLayout = new SimpleWinLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
+                }
+                else
+                {
+                    pWinLayout = new UniscribeLayout(getHDC(), rFontFace, rFontInstance, bUseOpenGL);
+                    // NOTE: it must be guaranteed that the WinSalGraphics lives longer than
+                    // the created UniscribeLayout, otherwise the data passed into the
+                    // constructor might become invalid too early
+                }
+            }
+        }
 
-    if( mfFontScale[nFallbackLevel] != 1.0 )
-        pWinLayout->SetFontScale( mfFontScale[nFallbackLevel] );
+        if( mfFontScale[nFallbackLevel] != 1.0 )
+            pWinLayout->SetFontScale( mfFontScale[nFallbackLevel] );
 
-    return pWinLayout;
+        return pWinLayout;
+    }
 }
 
 int    WinSalGraphics::GetMinKashidaWidth()
@@ -4147,4 +4155,32 @@ LogicalFontInstance* WinFontFace::CreateFontInstance( FontSelectPattern& rFSD )
     return pFontInstance;
 }
 
+void WinSalGraphics::DrawSalLayout( const CommonSalLayout& rLayout )
+{
+    HDC hDC = getHDC();
+
+    if((std::getenv("SAL_DWRITE_COMMON_LAYOUT")))
+    {
+        Point aPos(0, 0);
+        int nGlyphCount(0);
+        TextOutRenderer &render = TextOutRenderer::get();
+        bool result = render( rLayout, hDC, nullptr, &aPos, &nGlyphCount );
+        assert( !result );
+    }
+    else
+    {
+        Point aPos;
+        sal_GlyphId aGlyphId;
+        int nFetchedGlyphs = 0;
+        UINT oldTa = GetTextAlign( hDC );
+        SetTextAlign( hDC, ( oldTa & ~TA_NOUPDATECP ) );
+        while( rLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nFetchedGlyphs ) )
+        {
+            ExtTextOutW( hDC, aPos.X(), aPos.Y(), ETO_GLYPH_INDEX, nullptr, reinterpret_cast<LPCWSTR>( &aGlyphId ),
+                         1, nullptr);
+        }
+        SetTextAlign(hDC, oldTa);
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 3d03fc49e6f407aaabd249956f059fa0a92c9f01
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/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
index 372cd4d..6dabc15 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"
 
 namespace {
 
@@ -540,7 +541,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 cf25c4d4350b84cc83ef1121077f1cbd92573f6d
Author: Akash Jain <akash96j at gmail.com>
Date:   Wed Jul 6 10:15:49 2016 +0530

    GSoC: Modify DrawServerFontLayout and add DrawSalLayout
    
    Modify the definiton of the DrawServerFontLayout method.
    Add new DrawSalLayout method which will be used for drawing text
    independent of the platform.
    
    Change-Id: Ie3eefb172b1781c685def1ef549db2538f672a62

diff --git a/vcl/headless/svptext.cxx b/vcl/headless/svptext.cxx
index 5202109..494cada 100644
--- a/vcl/headless/svptext.cxx
+++ b/vcl/headless/svptext.cxx
@@ -23,6 +23,7 @@
 #include "headless/svpgdi.hxx"
 #include <config_cairo_canvas.h>
 #include "impfontmetricdata.hxx"
+#include "CommonSalLayout.hxx"
 
 void SvpSalGraphics::SetFont( FontSelectPattern* pIFSD, int nFallbackLevel )
 {
@@ -116,9 +117,14 @@ SalLayout* SvpSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe
     return m_aTextRenderImpl.GetTextLayout(rArgs, nFallbackLevel);
 }
 
-void SvpSalGraphics::DrawServerFontLayout( const ServerFontLayout& rSalLayout )
+void SvpSalGraphics::DrawServerFontLayout( const GenericSalLayout& rSalLayout, const ServerFont& rServerFont )
 {
-    m_aTextRenderImpl.DrawServerFontLayout(rSalLayout );
+    m_aTextRenderImpl.DrawServerFontLayout( rSalLayout, rServerFont );
+}
+
+void SvpSalGraphics::DrawSalLayout( const CommonSalLayout& rSalLayout )
+{
+    DrawServerFontLayout( rSalLayout, rSalLayout.getFontData() );
 }
 
 void SvpSalGraphics::SetTextColor( SalColor nSalColor )
diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx
index 7d11138..ef723da 100644
--- a/vcl/inc/headless/svpgdi.hxx
+++ b/vcl/inc/headless/svpgdi.hxx
@@ -166,7 +166,8 @@ public:
     virtual bool            GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) override;
     virtual bool            GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) override;
     virtual SalLayout*      GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
-    virtual void            DrawServerFontLayout( const ServerFontLayout& ) override;
+    virtual void            DrawSalLayout( const CommonSalLayout& ) override;
+    virtual void            DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) override;
     virtual bool            supportsOperation( OutDevSupportType ) const override;
     virtual void            drawPixel( long nX, long nY ) override;
     virtual void            drawPixel( long nX, long nY, SalColor nSalColor ) override;
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 0f5c9f5..ba0200b 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -50,6 +50,7 @@ class AquaSalFrame;
 class FontAttributes;
 class CoreTextStyle;
 class XorEmulation;
+class CommonSalLayout;
 
 typedef sal_uInt32 sal_GlyphId;
 
@@ -402,7 +403,8 @@ public:
     virtual bool            GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) override;
 
     virtual SalLayout*      GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
-    virtual void            DrawServerFontLayout( const ServerFontLayout& ) override;
+    virtual void            DrawSalLayout( const CommonSalLayout& ) override;
+    virtual void            DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) override {};
     virtual bool            supportsOperation( OutDevSupportType ) const override;
 
 #ifdef MACOSX
diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx
index 0a151d2..5bab4e8 100644
--- a/vcl/inc/salgdi.hxx
+++ b/vcl/inc/salgdi.hxx
@@ -43,7 +43,8 @@ class Rectangle;
 class FontSubsetInfo;
 class OpenGLContext;
 class OutputDevice;
-class ServerFontLayout;
+class ServerFont;
+class CommonSalLayout;
 struct SystemGraphicsData;
 
 #if ENABLE_CAIRO_CANVAS
@@ -216,7 +217,8 @@ public:
     virtual bool                GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) = 0;
 
     virtual SalLayout*          GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) = 0;
-    virtual void                DrawServerFontLayout( const ServerFontLayout& ) = 0;
+    virtual void                DrawSalLayout( const CommonSalLayout& ) = 0;
+    virtual void                DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) = 0;
 
     virtual bool                supportsOperation( OutDevSupportType ) const = 0;
 
diff --git a/vcl/inc/textrender.hxx b/vcl/inc/textrender.hxx
index 70fc9d2..5c4335e 100644
--- a/vcl/inc/textrender.hxx
+++ b/vcl/inc/textrender.hxx
@@ -26,7 +26,6 @@
 
 class ImplLayoutArgs;
 class ImplFontMetricData;
-class ServerFontLayout;
 class PhysicalFontCollection;
 class PhysicalFontFace;
 
@@ -71,7 +70,7 @@ public:
     virtual bool                    GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) = 0;
     virtual bool                    GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) = 0;
     virtual SalLayout*              GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) = 0;
-    virtual void                    DrawServerFontLayout( const ServerFontLayout& ) = 0;
+    virtual void                    DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) = 0;
 #if ENABLE_CAIRO_CANVAS
     virtual SystemFontData          GetSysFontData( int nFallbackLevel ) const = 0;
 #endif // ENABLE_CAIRO_CANVAS
diff --git a/vcl/inc/unx/cairotextrender.hxx b/vcl/inc/unx/cairotextrender.hxx
index 5cb39d3..2eb87df 100644
--- a/vcl/inc/unx/cairotextrender.hxx
+++ b/vcl/inc/unx/cairotextrender.hxx
@@ -88,7 +88,7 @@ public:
     virtual bool                GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) override;
     virtual bool                GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) override;
     virtual SalLayout*          GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
-    virtual void                DrawServerFontLayout( const ServerFontLayout& ) override;
+    virtual void                DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) override;
 #if ENABLE_CAIRO_CANVAS
     virtual SystemFontData      GetSysFontData( int nFallbackLevel ) const override;
 #endif
diff --git a/vcl/inc/unx/genpspgraphics.h b/vcl/inc/unx/genpspgraphics.h
index 9810d5d..7691e1c 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,8 @@ 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& ) override {};
+    virtual void            DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) override;
     virtual bool            supportsOperation( OutDevSupportType ) const override;
     virtual void            drawPixel( long nX, long nY ) override;
     virtual void            drawPixel( long nX, long nY, SalColor nSalColor ) override;
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index 28d0628..63eb80a 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -154,7 +154,8 @@ public:
     virtual bool                    GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) override;
     virtual bool                    GetGlyphOutline( sal_GlyphId nIndex, basegfx::B2DPolyPolygon& ) override;
     virtual SalLayout*              GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
-    virtual void                    DrawServerFontLayout( const ServerFontLayout& ) override;
+    virtual void                    DrawSalLayout( const CommonSalLayout& ) override;
+    virtual void                    DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) override;
 
     virtual bool                    supportsOperation( OutDevSupportType ) const override;
     virtual void                    drawPixel( long nX, long nY ) override;
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 291dc08..2defd7f 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -52,6 +52,7 @@ class PhysicalFontCollection;
 class SalGraphicsImpl;
 class WinOpenGLSalGraphicsImpl;
 class ImplFontMetricData;
+class CommonSalLayout;
 
 #define RGB_TO_PALRGB(nRGB)         ((nRGB)|0x02000000)
 #define PALRGB_TO_RGB(nPalRGB)      ((nPalRGB)&0x00ffffff)
@@ -450,7 +451,8 @@ public:
     virtual bool            GetGlyphOutline( sal_GlyphId, basegfx::B2DPolyPolygon& ) override;
 
     virtual SalLayout*      GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) override;
-    virtual void            DrawServerFontLayout( const ServerFontLayout& ) override;
+    virtual void            DrawSalLayout( const CommonSalLayout& ) override;
+    virtual void            DrawServerFontLayout( const GenericSalLayout&, const ServerFont& ) {};
 
     virtual bool            supportsOperation( OutDevSupportType ) const override;
     // Query the platform layer for control support
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index 0d39e96..d0f73a8 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 f7fd257..f19bcdd 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -221,9 +221,10 @@ void CommonSalLayout::AdjustLayout(ImplLayoutArgs& rArgs)
     }
 }
 
-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 f697a0c..372cd4d 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -186,7 +186,7 @@ namespace
     }
 }
 
-void CairoTextRender::DrawServerFontLayout( const ServerFontLayout& rLayout )
+void CairoTextRender::DrawServerFontLayout( const GenericSalLayout& rLayout, const ServerFont& rFont )
 {
     std::vector<cairo_glyph_t> cairo_glyphs;
     std::vector<int> glyph_extrarotation;
@@ -219,7 +219,6 @@ void CairoTextRender::DrawServerFontLayout( const ServerFontLayout& rLayout )
     if (cairo_glyphs.empty())
         return;
 
-    ServerFont& rFont = rLayout.GetServerFont();
     const FontSelectPattern& rFSD = rFont.GetFontSelData();
     int nHeight = rFSD.mnHeight;
     int nWidth = rFSD.mnWidth ? rFSD.mnWidth : nHeight;
diff --git a/vcl/unx/generic/gdi/font.cxx b/vcl/unx/generic/gdi/font.cxx
index 36c7ecb..7353e24 100644
--- a/vcl/unx/generic/gdi/font.cxx
+++ b/vcl/unx/generic/gdi/font.cxx
@@ -24,6 +24,7 @@
 #include "unx/salgdi.h"
 #include "unx/salvd.h"
 #include "textrender.hxx"
+#include "CommonSalLayout.hxx"
 
 GC
 X11SalGraphics::GetFontGC()
@@ -52,9 +53,14 @@ X11SalGraphics::GetFontGC()
     return pFontGC_;
 }
 
-void X11SalGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout )
+void X11SalGraphics::DrawServerFontLayout( const GenericSalLayout& rLayout, const ServerFont& rServerFont )
 {
-    mxTextRenderImpl->DrawServerFontLayout(rLayout);
+    mxTextRenderImpl->DrawServerFontLayout(rLayout, rServerFont);
+}
+
+void X11SalGraphics::DrawSalLayout( const CommonSalLayout& rLayout )
+{
+    DrawServerFontLayout( rLayout, rLayout.getFontData() );
 }
 
 const FontCharMapRef X11SalGraphics::GetFontCharMap() const
diff --git a/vcl/unx/generic/glyphs/gcach_layout.cxx b/vcl/unx/generic/glyphs/gcach_layout.cxx
index 38d7e84..3e326cf 100644
--- a/vcl/unx/generic/glyphs/gcach_layout.cxx
+++ b/vcl/unx/generic/glyphs/gcach_layout.cxx
@@ -22,6 +22,7 @@
 #include <salgdi.hxx>
 #include <scrptrun.h>
 #include <limits>
+#include <unx/genpspgraphics.h>
 
 #include <i18nlangtag/mslangid.hxx>
 
@@ -47,7 +48,7 @@ ServerFontLayout::ServerFontLayout( ServerFont& rFont )
 
 void ServerFontLayout::DrawText( SalGraphics& rSalGraphics ) const
 {
-    rSalGraphics.DrawServerFontLayout( *this );
+    rSalGraphics.DrawServerFontLayout( *this, mrServerFont );
 }
 
 bool ServerFontLayout::LayoutText( ImplLayoutArgs& rArgs )

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list