[Libreoffice-commits] core.git: Branch 'distro/lhm/libreoffice-4-1-6+backports' - 33 commits - download.lst editeng/source expat/expat-2.1.0.patch expat/StaticLibrary_expat.mk expat/StaticLibrary_expat_x64.mk expat/UnpackedTarball_expat.mk graphite/graphite2.issue1030.patch.1 graphite/graphite2.issue1115.patch.1 graphite/graphite2.patch graphite/graphite2.win64.patch.1 graphite/README graphite/StaticLibrary_graphite.mk graphite/ubsan.patch graphite/UnpackedTarball_graphite.mk libxml2/0001-Fix-buffer-size-checks-in-xmlSnprintfElementContent.patch.1 libxml2/0001-Fix-handling-of-parameter-entity-references.patch.1 libxml2/0001-Fix-type-confusion-in-xmlValidateOneNamespace.patch.1 libxml2/0001-Increase-buffer-space-for-port-in-HTTP-redirect-supp.patch.1 libxml2/0001-Prevent-unwanted-external-entity-reference.patch.1 libxml2/ExternalPackage_xml2.mk libxml2/libxml2-aix.patch libxml2/libxml2-android.patch libxml2/libxml2-config.patch.1 libxml2/libxml2-configure.patch libxml2/libxml2-global-symbols.patch libxml2/libxml2-gnome599717.patch libxml2/libxml2-latin.patch libxml2/libxml2-long-path.patch libxml2/libxml2-mingw.patch libxml2/libxml2-no-c99.patch libxml2/libxml2-vc10.patch libxml2/libxml2-xpath.patch libxml2/UnpackedTarball_xml2.mk libxslt/0001-Fix-for-type-confusion-in-preprocessing-attributes.patch.1 libxslt/ExternalPackage_xslt.mk libxslt/ExternalProject_xslt.mk libxslt/libxslt-aix.patch libxslt/libxslt-config.patch.1 libxslt/libxslt-configure.patch libxslt/libxslt-freebsd.patch.1 libxslt/libxslt-internal-symbols.patch libxslt/libxslt-mingw.patch libxslt/libxslt-win_manifest.patch libxslt/UnpackedTarball_xslt.mk Makefile.fetch solenv/gbuild vcl/generic vcl/inc vcl/source vcl/win

Michael Meeks michael.meeks at collabora.com
Thu Jul 12 17:14:37 UTC 2018


 Makefile.fetch                                                            |    6 
 download.lst                                                              |   13 
 editeng/source/editeng/impedit3.cxx                                       |    6 
 expat/StaticLibrary_expat.mk                                              |    1 
 expat/StaticLibrary_expat_x64.mk                                          |    1 
 expat/UnpackedTarball_expat.mk                                            |    3 
 expat/expat-2.1.0.patch                                                   |   13 
 graphite/README                                                           |    3 
 graphite/StaticLibrary_graphite.mk                                        |    9 
 graphite/UnpackedTarball_graphite.mk                                      |    8 
 graphite/graphite2.issue1030.patch.1                                      |   12 
 graphite/graphite2.issue1115.patch.1                                      |    6 
 graphite/graphite2.patch                                                  |   29 
 graphite/graphite2.win64.patch.1                                          |   60 
 graphite/ubsan.patch                                                      |   40 
 libxml2/0001-Fix-buffer-size-checks-in-xmlSnprintfElementContent.patch.1  |  116 +
 libxml2/0001-Fix-handling-of-parameter-entity-references.patch.1          |  287 +++
 libxml2/0001-Fix-type-confusion-in-xmlValidateOneNamespace.patch.1        |   43 
 libxml2/0001-Increase-buffer-space-for-port-in-HTTP-redirect-supp.patch.1 |   31 
 libxml2/0001-Prevent-unwanted-external-entity-reference.patch.1           |   35 
 libxml2/ExternalPackage_xml2.mk                                           |   10 
 libxml2/UnpackedTarball_xml2.mk                                           |   14 
 libxml2/libxml2-aix.patch                                                 |   21 
 libxml2/libxml2-android.patch                                             |    2 
 libxml2/libxml2-config.patch.1                                            |   69 
 libxml2/libxml2-configure.patch                                           |  152 -
 libxml2/libxml2-global-symbols.patch                                      |    4 
 libxml2/libxml2-gnome599717.patch                                         |   20 
 libxml2/libxml2-latin.patch                                               |   32 
 libxml2/libxml2-long-path.patch                                           |   34 
 libxml2/libxml2-mingw.patch                                               |   11 
 libxml2/libxml2-no-c99.patch                                              |   31 
 libxml2/libxml2-vc10.patch                                                |   17 
 libxml2/libxml2-xpath.patch                                               |   70 
 libxslt/0001-Fix-for-type-confusion-in-preprocessing-attributes.patch.1   |   29 
 libxslt/ExternalPackage_xslt.mk                                           |   19 
 libxslt/ExternalProject_xslt.mk                                           |    1 
 libxslt/UnpackedTarball_xslt.mk                                           |    7 
 libxslt/libxslt-aix.patch                                                 |   21 
 libxslt/libxslt-config.patch.1                                            |   35 
 libxslt/libxslt-configure.patch                                           |   99 -
 libxslt/libxslt-freebsd.patch.1                                           |   28 
 libxslt/libxslt-internal-symbols.patch                                    |   12 
 libxslt/libxslt-mingw.patch                                               |   36 
 libxslt/libxslt-win_manifest.patch                                        |   11 
 solenv/gbuild/UnpackedTarball.mk                                          |    3 
 vcl/generic/glyphs/gcach_ftyp.cxx                                         |    5 
 vcl/inc/graphite_features.hxx                                             |    1 
 vcl/inc/graphite_layout.hxx                                               |   11 
 vcl/inc/graphite_static.hxx                                               |   17 
 vcl/inc/win/salgdi.h                                                      |    3 
 vcl/source/fontsubset/sft.cxx                                             |    3 
 vcl/source/gdi/pdfwriter_impl.cxx                                         |   15 
 vcl/source/gdi/textlayout.cxx                                             |    2 
 vcl/source/glyphs/graphite_layout.cxx                                     |  800 +++-------
 vcl/source/window/winproc.cxx                                             |   11 
 vcl/win/source/gdi/winlayout.cxx                                          |   15 
 vcl/win/source/window/salframe.cxx                                        |    4 
 58 files changed, 1214 insertions(+), 1183 deletions(-)

New commits:
commit b7bdb072112076668268296d848f7af8a4f3560a
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri Dec 13 13:20:10 2013 +0000

    graphite2: get visibility right for static linkage on windows.
    
    Change-Id: I79fa15d539bcb86610dd4def08536c33bd2a10c2
    (cherry picked from commit 8949d6f32acb9046cb3ddceb4f6fbe39dcc04383)
    (cherry picked from commit bc7813272754f95f3705eac4f7726c63c646f985)

diff --git a/vcl/generic/glyphs/gcach_ftyp.cxx b/vcl/generic/glyphs/gcach_ftyp.cxx
index 854433bbbcf5..d233439233c1 100644
--- a/vcl/generic/glyphs/gcach_ftyp.cxx
+++ b/vcl/generic/glyphs/gcach_ftyp.cxx
@@ -30,8 +30,9 @@
 #include <impfont.hxx>
 #include <config_graphite.h>
 #if ENABLE_GRAPHITE
-#include <graphite2/Font.h>
-#include <graphite_layout.hxx>
+#  include <graphite_static.hxx>
+#  include <graphite2/Font.h>
+#  include <graphite_layout.hxx>
 #endif
 
 #include "tools/poly.hxx"
diff --git a/vcl/inc/graphite_features.hxx b/vcl/inc/graphite_features.hxx
index da8e619fd64c..0202497ae95a 100644
--- a/vcl/inc/graphite_features.hxx
+++ b/vcl/inc/graphite_features.hxx
@@ -23,6 +23,7 @@
 // 1001=1&2002=2&fav1=0
 #include <sal/types.h>
 #include <rtl/ustring.hxx>
+#include <graphite_static.hxx>
 #include <graphite2/Font.h>
 
 namespace grutils
diff --git a/vcl/inc/graphite_layout.hxx b/vcl/inc/graphite_layout.hxx
index 22566c50627a..275294c3c57c 100644
--- a/vcl/inc/graphite_layout.hxx
+++ b/vcl/inc/graphite_layout.hxx
@@ -31,6 +31,7 @@
 #include <map>
 #include <utility>
 // Libraries
+#include <graphite_static.hxx>
 #include <graphite2/Font.h>
 #include <graphite2/Segment.h>
 // Platform
diff --git a/vcl/inc/graphite_static.hxx b/vcl/inc/graphite_static.hxx
new file mode 100644
index 000000000000..4c70cf1b95ab
--- /dev/null
+++ b/vcl/inc/graphite_static.hxx
@@ -0,0 +1,17 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifdef WNT
+#  ifndef GRAPHITE2_STATIC
+#    define GRAPHITE2_STATIC 1
+#  endif
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 31a04dce6ee9..7add4b12c96a 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -31,7 +31,8 @@
 
 #include <config_graphite.h>
 #if ENABLE_GRAPHITE
-#include <graphite2/Font.h>
+#  include <graphite_static.hxx>
+#  include <graphite2/Font.h>
 #endif
 
 class FontSelectPattern;
diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx
index 55c0efd13bf9..25016b8e6ac7 100644
--- a/vcl/source/glyphs/graphite_layout.cxx
+++ b/vcl/source/glyphs/graphite_layout.cxx
@@ -55,6 +55,7 @@
 #include <com/sun/star/i18n/UnicodeType.hpp>
 
 // Graphite Libraries (must be after vcl headers on windows)
+#include <graphite_static.hxx>
 #include <graphite2/Segment.h>
 
 #include <graphite_layout.hxx>
commit b043eb5e3312d9d39ee896914dbf654a172ff5be
Author: David Tardon <dtardon at redhat.com>
Date:   Thu Jun 15 16:02:48 2017 +0200

    upload graphite 1.3.10
    
    Reviewed-on: https://gerrit.libreoffice.org/38837
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    
    also includes patch edit from:
    
    new release of Graphite lib: 1.3.9
    
    Reviewed-on: https://gerrit.libreoffice.org/30771
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    (cherry picked from commit 0220020a620a69eae493070ddd88cc74825400b1)
    
    Conflicts:
            download.lst
    
    (cherry picked from commit 1d88031f0016f368d3b149f8eb74691582d2fc55)
    
    Change-Id: I4e9a7ebf323848a03e02da3e9ed39377d1df6715

diff --git a/Makefile.fetch b/Makefile.fetch
index 392c10572f7c..b1653b7d993b 100644
--- a/Makefile.fetch
+++ b/Makefile.fetch
@@ -76,6 +76,7 @@ $(WORKDIR)/download: $(BUILDDIR)/config_host.mk $(SRCDIR)/download.lst $(SRCDIR)
 	$(foreach item, \
 		$(call fetch_Optional,CDR,CDR_TARBALL) \
 		$(call fetch_Optional,EXPAT,EXPAT_TARBALL) \
+		$(call fetch_Optional,GRAPHITE,GRAPHITE_TARBALL) \
 		$(call fetch_Optional,MSPUB,MSPUB_TARBALL) \
 		$(call fetch_Optional,MWAW,MWAW_TARBALL) \
 		$(call fetch_Optional,VISIO,VISIO_TARBALL) \
@@ -110,7 +111,6 @@ $(WORKDIR)/download: $(BUILDDIR)/config_host.mk $(SRCDIR)/download.lst $(SRCDIR)
 		$(call fetch_Optional,MORE_FONTS,$(FONT_SOURCECODE_TARBALL)) \
 		$(call fetch_Optional,FONTCONFIG,$(FONTCONFIG_TARBALL)) \
 		$(call fetch_Optional,FREETYPE,$(FREETYPE_TARBALL)) \
-		$(call fetch_Optional,GRAPHITE,$(GRAPHITE_TARBALL)) \
 		$(GOOGLE_DOCS_EXTENSION_PACK) \
 		$(call fetch_Optional,GLIBC,$(GLIBC_TARBALL)) \
 		$(call fetch_Optional,HSQLDB,$(HSQLDB_TARBALL)) \
diff --git a/download.lst b/download.lst
index dafc22939ac2..2d4c2ecfbbc1 100644
--- a/download.lst
+++ b/download.lst
@@ -1,5 +1,7 @@
 CDR_MD5SUM := d88f9b94df880d2c05be943b000ca112
 export CDR_TARBALL := libcdr-0.0.14.tar.bz2
+GRAPHITE_MD5SUM := 9c499b8ec9f1b81fd0bb6a3b986f4b0f
+export GRAPHITE_TARBALL := graphite2-minimal-1.3.10.tgz
 MSPUB_MD5SUM := 1120705cd0f0d9bd5506360bf57b6c2e
 export MSPUB_TARBALL := libmspub-0.0.6.tar.bz2
 MWAW_MD5SUM := 828dd03510791fbe037081a2b4a1a8ff
@@ -40,7 +42,6 @@ export FONT_SOURCECODE_TARBALL := 0279a21fab6f245e85a6f85fea54f511-source-code-f
 export FONT_SOURCESANS_TARBALL := 1e9ddfe25ac9577da709d7b2ea36f939-source-sans-font-1.036.tar.gz
 export FREETYPE_TARBALL := dbf2caca1d3afd410a29217a9809d397-freetype-2.4.8.tar.bz2
 export GLIBC_TARBALL := 4a660ce8466c9df01f19036435425c3a-glibc-2.1.3-stub.tar.gz
-export GRAPHITE_TARBALL := 17df8301bcc459e83f8a8f3aca6183b2-graphite-minimal-1.3.6.tgz
 export HSQLDB_TARBALL := 17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip
 export HUNSPELL_TARBALL := 3121aaf3e13e5d88dfff13fb4a5f1ab8-hunspell-1.3.2.tar.gz
 export HARFBUZZ_TARBALL := c48827713e93539dc7285f9e86ffbdc5-harfbuzz-0.9.17.tar.bz2
diff --git a/graphite/graphite2.win64.patch.1 b/graphite/graphite2.win64.patch.1
index 4e1172ad8222..d7cf11e63189 100644
--- a/graphite/graphite2.win64.patch.1
+++ b/graphite/graphite2.win64.patch.1
@@ -21,7 +21,7 @@ diff -urN graphite2-1.3.4.orig/src/inc/Main.h graphite2-1.3.4/src/inc/Main.h
 +#ifdef _WIN32
 +#pragma warning(disable: 4510 4610)
 +#endif
- 
+
  #include <cstdlib>
  #include "graphite2/Types.h"
 diff -urN graphite2-1.3.4.orig/src/json.cpp graphite2-1.3.4/src/json.cpp
@@ -36,11 +36,11 @@ diff -urN graphite2-1.3.4.orig/src/json.cpp graphite2-1.3.4/src/json.cpp
 +#endif
  json & json::operator << (json::boolean b) throw()  { context(seq); fputs(b ? "true" : "false", _stream); return *this; }
  json & json::operator << (json::_null_t) throw()    { context(seq); fputs("null",_stream); return *this; }
- 
+
 diff -urN graphite2-1.3.4.orig/src/Pass.cpp graphite2-1.3.4/src/Pass.cpp
 --- graphite2-1.3.4.orig/src/Pass.cpp	2015-12-22 14:25:46.399566417 +0100
 +++ graphite2-1.3.4/src/Pass.cpp	2015-12-22 14:26:13.439722846 +0100
-@@ -554,7 +554,7 @@
+@@ -568,7 +568,7 @@
          if (r->rule->preContext > fsm.slots.context())
              continue;
          *fsm.dbgout << json::flat << json::object
@@ -49,8 +49,8 @@ diff -urN graphite2-1.3.4.orig/src/Pass.cpp graphite2-1.3.4/src/Pass.cpp
                      << "failed" << true
                      << "input" << json::flat << json::object
                          << "start" << objectid(dslot(&fsm.slots.segment, input_slot(fsm.slots, -r->rule->preContext)))
-@@ -568,7 +568,7 @@
- void Pass::dumpRuleEventOutput(const FiniteStateMachine & fsm, Machine & m, const Rule & r, Slot * const last_slot) const
+@@ -582,7 +582,7 @@
+ void Pass::dumpRuleEventOutput(const FiniteStateMachine & fsm, const Rule & r, Slot * const last_slot) const
  {
      *fsm.dbgout     << json::item << json::flat << json::object
 -                        << "id"     << &r - m_rules
commit ea432d1077d1e67e456aafc8fb99dd1eedce7219
Author: Martin Hosken <martin_hosken at sil.org>
Date:   Fri Apr 1 11:17:30 2016 +0700

    Fix up upgrade to graphite 1.3.8
    
    Reviewed-on: https://gerrit.libreoffice.org/23716
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Martin Hosken <martin_hosken at sil.org>
    (cherry picked from commit 2973476aac4a7bde6c17b93808a258fd205b8f37)
    
    Change-Id: Idd7945176e1f667c29ff11144dc78870110bf562

diff --git a/graphite/ubsan.patch b/graphite/ubsan.patch
index b1617b138630..2f3bf5e7baf6 100644
--- a/graphite/ubsan.patch
+++ b/graphite/ubsan.patch
@@ -1,14 +1,3 @@
---- src/Pass.cpp
-+++ src/Pass.cpp
-@@ -294,7 +294,7 @@
-         s->rules = begin;
-         s->rules_end = (end - begin <= FiniteStateMachine::MAX_RULES)? end :
-             begin + FiniteStateMachine::MAX_RULES;
--        qsort(begin, end - begin, sizeof(RuleEntry), &cmpRuleEntry);
-+        if (end != begin) qsort(begin, end - begin, sizeof(RuleEntry), &cmpRuleEntry);
-     }
- 
-     return true;
 --- src/gr_face.cpp
 +++ src/gr_face.cpp
 @@ -87,7 +87,7 @@
commit 72ccf02fa96eaab60249d5040ffa4db2bde5320e
Author: Tomáš Chvátal <tchvatal at suse.com>
Date:   Tue Dec 22 15:41:25 2015 +0100

    Refresh graphite2.win64.patch.1 to apply using sle11 patch binary.
    
    Change-Id: If43ca99631fab5a3a04e7dead9b694cf52944666
    Reviewed-on: https://gerrit.libreoffice.org/20882
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    Tested-by: Michael Stahl <mstahl at redhat.com>
    (cherry picked from commit 817192b3f55be0b0a4a6e877a3c1ab95d3a4b4cb)
    Reviewed-on: https://gerrit.libreoffice.org/22845
    Tested-by: Christian Lohmaier <lohmaier+LibreOffice at googlemail.com>
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice at googlemail.com>
    (cherry picked from commit 1699670212cbb4e4e6a1271c374ef8c5bd9ea73e)

diff --git a/graphite/graphite2.win64.patch.1 b/graphite/graphite2.win64.patch.1
index e7c36c63c21b..4e1172ad8222 100644
--- a/graphite/graphite2.win64.patch.1
+++ b/graphite/graphite2.win64.patch.1
@@ -1,19 +1,6 @@
-diff -ur graphite.org/src/inc/Main.h graphite/src/inc/Main.h
---- graphite.org/src/inc/Main.h	2015-09-07 20:09:25.572279671 +0700
---- graphite/src/inc/Main.h	2015-09-07 20:09:25.572279671 +0700
-@@ -25,6 +25,9 @@
- of the License or (at your option) any later version.
- */
- #pragma once
-+#ifdef _WIN32
-+#pragma warning(disable: 4510 4610)
-+#endif
- 
- #include <cstdlib>
- #include "graphite2/Types.h"
-diff -ur graphite.org/src/inc/json.h graphite/src/inc/json.h
---- graphite.org/src/inc/json.h	2015-02-03 14:49:24.408101900 +0100
-+++ graphite/src/inc/json.h	2015-02-03 14:50:59.697552200 +0100
+diff -urN graphite2-1.3.4.orig/src/inc/json.h graphite2-1.3.4/src/inc/json.h
+--- graphite2-1.3.4.orig/src/inc/json.h	2015-12-22 14:25:46.403566441 +0100
++++ graphite2-1.3.4/src/inc/json.h	2015-12-22 14:26:13.439722846 +0100
 @@ -85,6 +85,9 @@
      json & operator << (string) throw();
      json & operator << (number) throw();
@@ -24,10 +11,24 @@ diff -ur graphite.org/src/inc/json.h graphite/src/inc/json.h
      json & operator << (long unsigned int d) throw();
      json & operator << (boolean) throw();
      json & operator << (_null_t) throw();
-diff -ur graphite.org/src/json.cpp graphite/src/json.cpp
---- graphite.org/src/json.cpp	2015-02-03 14:49:24.409102000 +0100
-+++ graphite/src/json.cpp	2015-02-03 14:50:49.814986900 +0100
-@@ -134,5 +134,8 @@
+diff -urN graphite2-1.3.4.orig/src/inc/Main.h graphite2-1.3.4/src/inc/Main.h
+--- graphite2-1.3.4.orig/src/inc/Main.h	2015-12-22 14:25:46.399566417 +0100
++++ graphite2-1.3.4/src/inc/Main.h	2015-12-22 14:26:13.439722846 +0100
+@@ -25,6 +25,9 @@
+ of the License or (at your option) any later version.
+ */
+ #pragma once
++#ifdef _WIN32
++#pragma warning(disable: 4510 4610)
++#endif
+ 
+ #include <cstdlib>
+ #include "graphite2/Types.h"
+diff -urN graphite2-1.3.4.orig/src/json.cpp graphite2-1.3.4/src/json.cpp
+--- graphite2-1.3.4.orig/src/json.cpp	2015-12-22 14:25:46.399566417 +0100
++++ graphite2-1.3.4/src/json.cpp	2015-12-22 14:26:13.439722846 +0100
+@@ -133,6 +133,9 @@
+ }
  json & json::operator << (json::integer d) throw()  { context(seq); fprintf(_stream, "%ld", d); return *this; }
  json & json::operator << (long unsigned d) throw()  { context(seq); fprintf(_stream, "%ld", d); return *this; }
 +#ifdef _WIN64
@@ -36,10 +37,10 @@ diff -ur graphite.org/src/json.cpp graphite/src/json.cpp
  json & json::operator << (json::boolean b) throw()  { context(seq); fputs(b ? "true" : "false", _stream); return *this; }
  json & json::operator << (json::_null_t) throw()    { context(seq); fputs("null",_stream); return *this; }
  
-diff -ur graphite.org/src/Pass.cpp graphite/src/Pass.cpp
---- graphite.org/src/Pass.cpp	2015-02-03 14:49:24.413102200 +0100
-+++ graphite/src/Pass.cpp	2015-02-03 14:50:37.873303900 +0100
-@@ -544,7 +544,7 @@
+diff -urN graphite2-1.3.4.orig/src/Pass.cpp graphite2-1.3.4/src/Pass.cpp
+--- graphite2-1.3.4.orig/src/Pass.cpp	2015-12-22 14:25:46.399566417 +0100
++++ graphite2-1.3.4/src/Pass.cpp	2015-12-22 14:26:13.439722846 +0100
+@@ -554,7 +554,7 @@
          if (r->rule->preContext > fsm.slots.context())
              continue;
          *fsm.dbgout << json::flat << json::object
@@ -48,7 +49,7 @@ diff -ur graphite.org/src/Pass.cpp graphite/src/Pass.cpp
                      << "failed" << true
                      << "input" << json::flat << json::object
                          << "start" << objectid(dslot(&fsm.slots.segment, input_slot(fsm.slots, -r->rule->preContext)))
-@@ -558,7 +558,7 @@
+@@ -568,7 +568,7 @@
  void Pass::dumpRuleEventOutput(const FiniteStateMachine & fsm, Machine & m, const Rule & r, Slot * const last_slot) const
  {
      *fsm.dbgout     << json::item << json::flat << json::object
commit 8e054825bc441d28d13cfa00f5baf2c90f3525ab
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date:   Mon Apr 30 14:01:29 2018 +0200

    Update graphite to 1.3.6
    
    (cherry picked from commit 4dfa1db246c60e9bc7a723fe010bbb47f9d0cfe8)
    
    Change-Id: I4cd07ffd7cd2be94a830c9ecdeedb59950b115bb

diff --git a/download.lst b/download.lst
index 568d55469b75..dafc22939ac2 100644
--- a/download.lst
+++ b/download.lst
@@ -40,7 +40,7 @@ export FONT_SOURCECODE_TARBALL := 0279a21fab6f245e85a6f85fea54f511-source-code-f
 export FONT_SOURCESANS_TARBALL := 1e9ddfe25ac9577da709d7b2ea36f939-source-sans-font-1.036.tar.gz
 export FREETYPE_TARBALL := dbf2caca1d3afd410a29217a9809d397-freetype-2.4.8.tar.bz2
 export GLIBC_TARBALL := 4a660ce8466c9df01f19036435425c3a-glibc-2.1.3-stub.tar.gz
-export GRAPHITE_TARBALL := 28935e208c311761c29983c739db08d8-graphite2-minimal-1.3.5.tgz
+export GRAPHITE_TARBALL := 17df8301bcc459e83f8a8f3aca6183b2-graphite-minimal-1.3.6.tgz
 export HSQLDB_TARBALL := 17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip
 export HUNSPELL_TARBALL := 3121aaf3e13e5d88dfff13fb4a5f1ab8-hunspell-1.3.2.tar.gz
 export HARFBUZZ_TARBALL := c48827713e93539dc7285f9e86ffbdc5-harfbuzz-0.9.17.tar.bz2
commit 89126946f0eaca8ca70b19b717c4f5514802d109
Author: Thorsten Behrens <Thorsten.Behrens at CIB.de>
Date:   Mon Apr 30 13:45:25 2018 +0200

    fixup update graphite to 1.3.5
    
    (cherry picked from commit 873af2dcd018d3e791a5073928582771580ac333)
    
    Change-Id: I50c07f8698c06c96bc922845e11e7e7e57b2ca1d

diff --git a/Makefile.fetch b/Makefile.fetch
index b1653b7d993b..392c10572f7c 100644
--- a/Makefile.fetch
+++ b/Makefile.fetch
@@ -76,7 +76,6 @@ $(WORKDIR)/download: $(BUILDDIR)/config_host.mk $(SRCDIR)/download.lst $(SRCDIR)
 	$(foreach item, \
 		$(call fetch_Optional,CDR,CDR_TARBALL) \
 		$(call fetch_Optional,EXPAT,EXPAT_TARBALL) \
-		$(call fetch_Optional,GRAPHITE,GRAPHITE_TARBALL) \
 		$(call fetch_Optional,MSPUB,MSPUB_TARBALL) \
 		$(call fetch_Optional,MWAW,MWAW_TARBALL) \
 		$(call fetch_Optional,VISIO,VISIO_TARBALL) \
@@ -111,6 +110,7 @@ $(WORKDIR)/download: $(BUILDDIR)/config_host.mk $(SRCDIR)/download.lst $(SRCDIR)
 		$(call fetch_Optional,MORE_FONTS,$(FONT_SOURCECODE_TARBALL)) \
 		$(call fetch_Optional,FONTCONFIG,$(FONTCONFIG_TARBALL)) \
 		$(call fetch_Optional,FREETYPE,$(FREETYPE_TARBALL)) \
+		$(call fetch_Optional,GRAPHITE,$(GRAPHITE_TARBALL)) \
 		$(GOOGLE_DOCS_EXTENSION_PACK) \
 		$(call fetch_Optional,GLIBC,$(GLIBC_TARBALL)) \
 		$(call fetch_Optional,HSQLDB,$(HSQLDB_TARBALL)) \
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index ec6ac711a421..8c46fcf0f6f2 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -7789,7 +7789,7 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const String& rText, bool bT
                         aUnicodes.push_back(rText.GetChar(sal::static_int_cast<xub_StrLen>(start + n)));
                 }
                 else
-                    aUnicodes.push_back( rText[ pCharPosAry[i] ] );
+                    aUnicodes.push_back( rText.GetChar(sal::static_int_cast<xub_StrLen>(pCharPosAry[i])));
                 // #i36691# hack that is needed because currently the pGlyphs[]
                 // argument is ignored for embeddable fonts and so the layout
                 // engine's glyph work is ignored (i.e. char mirroring)
diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx
index 51b8bff5361a..55c0efd13bf9 100644
--- a/vcl/source/glyphs/graphite_layout.cxx
+++ b/vcl/source/glyphs/graphite_layout.cxx
@@ -703,7 +703,7 @@ unsigned int GraphiteLayout::ScanFwdForChar(int &findChar, bool fallback) const
 
 void GraphiteLayout::ApplyDXArray(ImplLayoutArgs &args, std::vector<int> & rDeltaWidth)
 {
-    bool bRtl(mnLayoutFlags & SalLayoutFlags::BiDiRtl);
+    bool bRtl(mnLayoutFlags & SAL_LAYOUT_BIDI_RTL);
     int startChar = args.mnMinCharPos < mnMinCharPos ? mnMinCharPos : args.mnMinCharPos;
     int endChar = args.mnEndCharPos >= mnEndCharPos ? mnEndCharPos - 1 : args.mnEndCharPos;
     unsigned int startGi = ScanFwdForChar(startChar, !bRtl);
commit bd1e2939aa5bbb6f1888b336f78979236a29bb8f
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu Jul 12 18:07:04 2018 +0200

    Revert "Revert "Fix some round() confusion""
    
    This reverts commit 13e06b3e8133dddf808c945777b43303a70900d3.
    
    Unrevert it now that the other patch is in.
    
    Change-Id: I56f8cb70e9b1fd0dd9d109c0459c0938d1428ff8

diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx
index c6c3c7b3dd31..51b8bff5361a 100644
--- a/vcl/source/glyphs/graphite_layout.cxx
+++ b/vcl/source/glyphs/graphite_layout.cxx
@@ -40,6 +40,8 @@
 #include <deque>
 
 // Platform
+#include <config_global.h>
+
 #include <svsys.h>
 
 #include <salgdi.hxx>
@@ -86,7 +88,7 @@ static FILE * grLog()
 
 namespace
 {
-    inline long round(const float n) {
+    inline long round_to_long(const float n) {
         return long(n + (n < 0 ? -0.5 : 0.5));
     }
 
@@ -223,7 +225,7 @@ GraphiteLayout::fillFrom(gr_segment * pSegment, ImplLayoutArgs &rArgs, float fSc
         }
 
         int baseGlyph = mvGlyphs.size();
-        int scaledGlyphPos = round(gr_slot_origin_X(baseSlot) * fScaling) + mnWidth + nDxOffset;
+        int scaledGlyphPos = round_to_long(gr_slot_origin_X(baseSlot) * fScaling) + mnWidth + nDxOffset;
         if (mvChar2Glyph[firstChar - mnMinCharPos] == -1 || mvGlyphs[mvChar2Glyph[firstChar - mnMinCharPos]].maLinearPos.X() < scaledGlyphPos)
         {
             mvChar2Glyph[firstChar - mnMinCharPos] = mvGlyphs.size();
@@ -237,8 +239,8 @@ GraphiteLayout::fillFrom(gr_segment * pSegment, ImplLayoutArgs &rArgs, float fSc
         if (nextBoundary > fMaxX && (nextChar < mnMinCharPos || nextChar >= mnEndCharPos || !isWhite(pStr[nextChar]) || fMaxX <= 0.0f))
             fMaxX = nextBoundary;
     }
-    long nXOffset = round(fMinX * fScaling);
-    long nXEnd = round(fMaxX * fScaling);
+    long nXOffset = round_to_long(fMinX * fScaling);
+    long nXEnd = round_to_long(fMaxX * fScaling);
     int nCharRequested = minimum<int>(lastCharPos, mnEndCharPos) - mnMinCharPos;
     int firstCharOffset = maximum<int>(mnSegCharOffset, mnMinCharPos) - mnMinCharPos;
     // fill up non-base char dx with cluster widths from previous base glyph
@@ -311,8 +313,8 @@ GraphiteLayout::append(gr_segment *pSeg, ImplLayoutArgs &rArgs,
 
     long glyphId = gr_slot_gid(gi);
     long deltaOffset = 0;
-    int scaledGlyphPos = round(gr_slot_origin_X(gi) * scaling) + mnWidth + rDXOffset;
-    int glyphWidth = round((nextGlyphOrigin - gOrigin) * scaling);
+    int scaledGlyphPos = round_to_long(gr_slot_origin_X(gi) * scaling) + mnWidth + rDXOffset;
+    int glyphWidth = round_to_long((nextGlyphOrigin - gOrigin) * scaling);
     if (!bIsBase)
     {
         mvChar2BaseGlyph[firstChar - mnMinCharPos] = baseGlyph;
@@ -357,11 +359,11 @@ GraphiteLayout::append(gr_segment *pSeg, ImplLayoutArgs &rArgs,
     nGlyphFlags |= (bRtl)? GlyphItem::IS_RTL_GLYPH : 0;
     GlyphItem aGlyphItem(mvGlyphs.size(),
         glyphId,
-        Point(scaledGlyphPos, round((-gr_slot_origin_Y(gi) * scaling))),
+        Point(scaledGlyphPos, round_to_long((-gr_slot_origin_Y(gi) * scaling))),
         nGlyphFlags,
         glyphWidth);
     if (glyphId != static_cast<long>(GF_DROPPED))
-        aGlyphItem.mnOrigWidth = round(gr_slot_advance_X(gi, mpFace, mpFont) * scaling);
+        aGlyphItem.mnOrigWidth = round_to_long(gr_slot_advance_X(gi, mpFace, mpFont) * scaling);
     mvGlyphs.push_back(aGlyphItem);
 
     // update the offset if this glyph was dropped
commit 12e6ae03ded622c9eb93599fae0f6aa59b2f98d0
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Mon Jun 29 12:26:16 2015 +0200

    update graphite to 1.3.5
    
    (cherry picked from commit c64ea526dc71da6e3aad188ac71e58047ed74b5a)
    
    and sync the various upgrade patches together
    
    Reviewed-on: https://gerrit.libreoffice.org/22210
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit 3149dcb247617c71175fdf31f56f45b9c3ea58f4)
    
    Change-Id: I3287d51430d7a0901dd8bbf2458b845bcf92a8d2

diff --git a/download.lst b/download.lst
index d5a5c2ff0d20..568d55469b75 100644
--- a/download.lst
+++ b/download.lst
@@ -6,8 +6,6 @@ MWAW_MD5SUM := 828dd03510791fbe037081a2b4a1a8ff
 export MWAW_TARBALL := libmwaw-0.1.11.tar.bz2
 VISIO_MD5SUM := 82628333418f101a20cd21f980cf9f40
 export VISIO_TARBALL := libvisio-0.0.31.tar.bz2
-GRAPHITE_MD5SUM := 2ef839348fe28e3b923bf8cced440227
-export GRAPHITE_TARBALL := graphite2-1.2.4.tgz
 ZLIB_MD5SUM := 85adef240c5f370b308da8c938951a68
 export ZLIB_TARBALL := zlib-1.2.11.tar.xz
 
@@ -42,6 +40,7 @@ export FONT_SOURCECODE_TARBALL := 0279a21fab6f245e85a6f85fea54f511-source-code-f
 export FONT_SOURCESANS_TARBALL := 1e9ddfe25ac9577da709d7b2ea36f939-source-sans-font-1.036.tar.gz
 export FREETYPE_TARBALL := dbf2caca1d3afd410a29217a9809d397-freetype-2.4.8.tar.bz2
 export GLIBC_TARBALL := 4a660ce8466c9df01f19036435425c3a-glibc-2.1.3-stub.tar.gz
+export GRAPHITE_TARBALL := 28935e208c311761c29983c739db08d8-graphite2-minimal-1.3.5.tgz
 export HSQLDB_TARBALL := 17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip
 export HUNSPELL_TARBALL := 3121aaf3e13e5d88dfff13fb4a5f1ab8-hunspell-1.3.2.tar.gz
 export HARFBUZZ_TARBALL := c48827713e93539dc7285f9e86ffbdc5-harfbuzz-0.9.17.tar.bz2
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index 9a82eb3dc042..f44992e16391 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -734,6 +734,8 @@ sal_Bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY )
     EditLine aSaveLine( *pLine );
     SvxFont aTmpFont( pNode->GetCharAttribs().GetDefFont() );
 
+    ImplInitLayoutMode( GetRefDevice(), nPara, nIndex );
+
     sal_Bool bCalcCharPositions = sal_True;
     sal_Int32* pBuf = new sal_Int32[ pNode->Len() ];
 
@@ -1058,6 +1060,8 @@ sal_Bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY )
                 aTmpFont.SetPhysFont( GetRefDevice() );
                 ImplInitDigitMode(GetRefDevice(), aTmpFont.GetLanguage());
 
+                pPortion->SetRightToLeft( GetRightToLeft( nPara, nTmpPos+1 ) );
+
                 if ( bCalcCharPositions || !pPortion->HasValidSize() )
                 {
                     pPortion->GetSize() = aTmpFont.QuickGetTextSize( GetRefDevice(), pParaPortion->GetNode()->GetString(), nTmpPos, pPortion->GetLen(), pBuf );
@@ -1089,8 +1093,6 @@ sal_Bool ImpEditEngine::CreateLines( sal_Int32 nPara, sal_uInt32 nStartPosY )
 
                 nTmpWidth += pPortion->GetSize().Width();
 
-                pPortion->SetRightToLeft( GetRightToLeft( nPara, nTmpPos+1 ) );
-
                 sal_uInt16 _nPortionEnd = nTmpPos + pPortion->GetLen();
                 if( bScriptSpace && ( _nPortionEnd < pNode->Len() ) && ( nTmpWidth < nXWidth ) && IsScriptChange( EditPaM( pNode, _nPortionEnd ) ) )
                 {
diff --git a/graphite/StaticLibrary_graphite.mk b/graphite/StaticLibrary_graphite.mk
index de3950f10b86..ddbf9955e6d7 100644
--- a/graphite/StaticLibrary_graphite.mk
+++ b/graphite/StaticLibrary_graphite.mk
@@ -19,8 +19,8 @@ $(eval $(call gb_StaticLibrary_set_include,graphite,\
 ))
 
 $(eval $(call gb_StaticLibrary_add_defs,graphite,\
-	-DDISABLE_TRACING \
-	-DGR2_STATIC \
+	-DGRAPHITE2_NTRACING \
+	-DGRAPHITE2_STATIC \
 ))
 
 ifeq ($(COM),GCC)
@@ -43,19 +43,22 @@ $(eval $(call gb_StaticLibrary_add_generated_cxxobjects,graphite,\
 	UnpackedTarball/graphite/src/gr_segment \
 	UnpackedTarball/graphite/src/gr_slot \
 	UnpackedTarball/graphite/src/json \
-	UnpackedTarball/graphite/src/Bidi \
 	UnpackedTarball/graphite/src/CachedFace \
 	UnpackedTarball/graphite/src/CmapCache \
 	UnpackedTarball/graphite/src/Code \
+	UnpackedTarball/graphite/src/Collider \
+	UnpackedTarball/graphite/src/Decompressor \
 	UnpackedTarball/graphite/src/Face \
 	UnpackedTarball/graphite/src/FeatureMap \
 	UnpackedTarball/graphite/src/FileFace \
 	UnpackedTarball/graphite/src/Font \
 	UnpackedTarball/graphite/src/GlyphCache \
 	UnpackedTarball/graphite/src/GlyphFace \
+	UnpackedTarball/graphite/src/Intervals \
 	UnpackedTarball/graphite/src/Justifier \
 	UnpackedTarball/graphite/src/NameTable \
 	UnpackedTarball/graphite/src/Pass \
+	UnpackedTarball/graphite/src/Position \
 	UnpackedTarball/graphite/src/SegCache \
 	UnpackedTarball/graphite/src/SegCacheEntry \
 	UnpackedTarball/graphite/src/SegCacheStore \
diff --git a/graphite/UnpackedTarball_graphite.mk b/graphite/UnpackedTarball_graphite.mk
index 85ebde52a9f6..6b6fc945f621 100644
--- a/graphite/UnpackedTarball_graphite.mk
+++ b/graphite/UnpackedTarball_graphite.mk
@@ -11,10 +11,12 @@ $(eval $(call gb_UnpackedTarball_UnpackedTarball,graphite))
 
 $(eval $(call gb_UnpackedTarball_set_tarball,graphite,$(GRAPHITE_TARBALL)))
 
-# http://projects.palaso.org/issues/1115
+$(eval $(call gb_UnpackedTarball_set_patchlevel,graphite,0))
+
 $(eval $(call gb_UnpackedTarball_add_patches,graphite,\
 	graphite/graphite2.issue1115.patch.1 \
     graphite/graphite2.win64.patch.1 \
+    graphite/ubsan.patch \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/graphite/graphite2.issue1115.patch.1 b/graphite/graphite2.issue1115.patch.1
index f19c8a3749f4..454114bb32c9 100644
--- a/graphite/graphite2.issue1115.patch.1
+++ b/graphite/graphite2.issue1115.patch.1
@@ -1,6 +1,6 @@
 --- graphite/src/Code.cpp
 +++ graphite/src/Code.cpp
-@@ -169,8 +169,8 @@ Machine::Code::Code(bool is_constraint,
+@@ -175,8 +175,8 @@ Machine::Code::Code(bool is_constraint,
          bytecode_end,
          pre_context,
          rule_length,
@@ -11,7 +11,7 @@
          face.numFeatures(), 
          {1,1,1,1,1,1,1,1, 
           1,1,1,1,1,1,1,255,
-@@ -178,7 +178,7 @@ Machine::Code::Code(bool is_constraint,
+@@ -184,7 +184,7 @@ Machine::Code::Code(bool is_constraint,
           1,1,1,1,1,1,0,0, 
           0,0,0,0,0,0,0,0, 
           0,0,0,0,0,0,0,0, 
@@ -19,4 +19,4 @@
 +         0,0,0,0,0,0,0, static_cast<byte>(silf.numUser())}
      };
      
-     decoder dec(lims, *this);
+     decoder dec(lims, *this, pt);
diff --git a/graphite/graphite2.win64.patch.1 b/graphite/graphite2.win64.patch.1
index 6bf8c88907d1..e7c36c63c21b 100644
--- a/graphite/graphite2.win64.patch.1
+++ b/graphite/graphite2.win64.patch.1
@@ -1,7 +1,20 @@
+diff -ur graphite.org/src/inc/Main.h graphite/src/inc/Main.h
+--- graphite.org/src/inc/Main.h	2015-09-07 20:09:25.572279671 +0700
+--- graphite/src/inc/Main.h	2015-09-07 20:09:25.572279671 +0700
+@@ -25,6 +25,9 @@
+ of the License or (at your option) any later version.
+ */
+ #pragma once
++#ifdef _WIN32
++#pragma warning(disable: 4510 4610)
++#endif
+ 
+ #include <cstdlib>
+ #include "graphite2/Types.h"
 diff -ur graphite.org/src/inc/json.h graphite/src/inc/json.h
 --- graphite.org/src/inc/json.h	2015-02-03 14:49:24.408101900 +0100
 +++ graphite/src/inc/json.h	2015-02-03 14:50:59.697552200 +0100
-@@ -78,6 +78,9 @@
+@@ -85,6 +85,9 @@
      json & operator << (string) throw();
      json & operator << (number) throw();
      json & operator << (integer) throw();
@@ -14,8 +27,7 @@ diff -ur graphite.org/src/inc/json.h graphite/src/inc/json.h
 diff -ur graphite.org/src/json.cpp graphite/src/json.cpp
 --- graphite.org/src/json.cpp	2015-02-03 14:49:24.409102000 +0100
 +++ graphite/src/json.cpp	2015-02-03 14:50:49.814986900 +0100
-@@ -119,6 +119,9 @@
- json & json::operator << (json::number f) throw()   { context(seq); fprintf(_stream, "%g", f); return *this; }
+@@ -134,5 +134,8 @@
  json & json::operator << (json::integer d) throw()  { context(seq); fprintf(_stream, "%ld", d); return *this; }
  json & json::operator << (long unsigned d) throw()  { context(seq); fprintf(_stream, "%ld", d); return *this; }
 +#ifdef _WIN64
@@ -27,17 +39,17 @@ diff -ur graphite.org/src/json.cpp graphite/src/json.cpp
 diff -ur graphite.org/src/Pass.cpp graphite/src/Pass.cpp
 --- graphite.org/src/Pass.cpp	2015-02-03 14:49:24.413102200 +0100
 +++ graphite/src/Pass.cpp	2015-02-03 14:50:37.873303900 +0100
-@@ -466,7 +466,7 @@
-     {
-         if (r->rule->preContext > fsm.slots.context())  continue;
-     *fsm.dbgout << json::flat << json::object
--                    << "id"     << r->rule - m_rules
-+                    << "id"     << static_cast<size_t>(r->rule - m_rules)
+@@ -544,7 +544,7 @@
+         if (r->rule->preContext > fsm.slots.context())
+             continue;
+         *fsm.dbgout << json::flat << json::object
+-                    << "id" << r->rule - m_rules
++                    << "id" << static_cast<size_t>(r->rule - m_rules)
                      << "failed" << true
                      << "input" << json::flat << json::object
                          << "start" << objectid(dslot(&fsm.slots.segment, input_slot(fsm.slots, -r->rule->preContext)))
-@@ -480,7 +480,7 @@
- void Pass::dumpRuleEventOutput(const FiniteStateMachine & fsm, const Rule & r, Slot * const last_slot) const
+@@ -558,7 +558,7 @@
+ void Pass::dumpRuleEventOutput(const FiniteStateMachine & fsm, Machine & m, const Rule & r, Slot * const last_slot) const
  {
      *fsm.dbgout     << json::item << json::flat << json::object
 -                        << "id"     << &r - m_rules
diff --git a/graphite/ubsan.patch b/graphite/ubsan.patch
new file mode 100644
index 000000000000..b1617b138630
--- /dev/null
+++ b/graphite/ubsan.patch
@@ -0,0 +1,51 @@
+--- src/Pass.cpp
++++ src/Pass.cpp
+@@ -294,7 +294,7 @@
+         s->rules = begin;
+         s->rules_end = (end - begin <= FiniteStateMachine::MAX_RULES)? end :
+             begin + FiniteStateMachine::MAX_RULES;
+-        qsort(begin, end - begin, sizeof(RuleEntry), &cmpRuleEntry);
++        if (end != begin) qsort(begin, end - begin, sizeof(RuleEntry), &cmpRuleEntry);
+     }
+ 
+     return true;
+--- src/gr_face.cpp
++++ src/gr_face.cpp
+@@ -87,7 +87,7 @@
+ 
+     Face *res = new Face(appFaceHandle, *ops);
+     if (res && load_face(*res, faceOptions))
+-        return static_cast<gr_face *>(res);
++        return reinterpret_cast<gr_face *>(res);
+ 
+     delete res;
+     return 0;
+@@ -195,7 +195,7 @@
+ 
+ void gr_face_destroy(gr_face *face)
+ {
+-    delete face;
++    delete static_cast<Face *>(face);
+ }
+ 
+ 
+--- src/gr_font.cpp
++++ src/gr_font.cpp
+@@ -50,7 +50,7 @@
+     if (face == 0)  return 0;
+ 
+     Font * const res = new Font(ppm, *face, appFontHandle, font_ops);
+-    return static_cast<gr_font*>(res);
++    return reinterpret_cast<gr_font*>(res);
+ }
+ 
+ gr_font* gr_make_font_with_advance_fn(float ppm/*pixels per em*/, const void* appFontHandle/*non-NULL*/, gr_advance_fn getAdvance, const gr_face * face/*needed for scaling*/)
+@@ -61,7 +61,7 @@
+ 
+ void gr_font_destroy(gr_font *font)
+ {
+-    delete font;
++    delete static_cast<Font *>(font);
+ }
+ 
+ 
diff --git a/vcl/inc/graphite_layout.hxx b/vcl/inc/graphite_layout.hxx
index b81083458e1a..22566c50627a 100644
--- a/vcl/inc/graphite_layout.hxx
+++ b/vcl/inc/graphite_layout.hxx
@@ -97,9 +97,10 @@ public:
 private:
     const gr_face *         mpFace; // not owned by layout
     gr_font *               mpFont; // not owned by layout
-    int                     mnSegCharOffset; // relative to ImplLayoutArgs::mpStr
+    unsigned int            mnSegCharOffset; // relative to ImplLayoutArgs::mpStr
     long                    mnWidth;
     std::vector<int>        mvChar2BaseGlyph;
+    std::vector<int>        mvChar2Glyph;
     std::vector<int>        mvGlyph2Char;
     std::vector<int>        mvCharDxs;
     std::vector<int>        mvCharBreaks;
@@ -113,8 +114,6 @@ public:
     // used by upper layers
     virtual bool  LayoutText( ImplLayoutArgs& );    // first step of layout
     // split into two stages to allow dc to be restored on the segment
-    gr_segment * CreateSegment(ImplLayoutArgs& rArgs);
-    bool LayoutGlyphs(ImplLayoutArgs& rArgs, gr_segment * pSegment);
 
     virtual void  AdjustLayout( ImplLayoutArgs& );  // adjusting positions
 
@@ -149,13 +148,14 @@ public:
     static const int EXTRA_CONTEXT_LENGTH;
 private:
     void expandOrCondense(ImplLayoutArgs &rArgs);
-    void    fillFrom(gr_segment * rSeg, ImplLayoutArgs & rArgs, float fScaling);
+    void    fillFrom(gr_segment * rSeg, ImplLayoutArgs & rArgs, float fScaling, bool bRtl, int firstCharOffset);
 
     float append(gr_segment * pSeg,
                 ImplLayoutArgs & rArgs,
                 const gr_slot * pSlot, float gOrigin,
                 float nextGlyphOrigin, float fScaling,
-                long & rDXOffset, bool bIsBase, int baseChar);
+                long & rDXOffset, bool bIsBase, int baseChar, int baseGlyph, bool bRtl);
+    unsigned int ScanFwdForChar(int &findChar, bool fallback) const;
 };
 
 #endif // _SV_GRAPHITELAYOUT_HXX
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 91717b7f2aa7..cc4d644d85e0 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1806,6 +1806,9 @@ int GetTTGlyphComponents(TrueTypeFont *ttf, sal_uInt32 glyphID, std::vector< sal
 
     const sal_uInt8* glyf = getTable(ttf, O_glyf);
     const sal_uInt8* ptr = glyf + ttf->goffsets[glyphID];
+    const sal_uInt8* nptr = glyf + ttf->goffsets[glyphID+1];
+    if (nptr <= ptr)
+        return 0;
 
     glyphlist.push_back( glyphID );
 
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index f7a5b155057d..ec6ac711a421 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -7769,22 +7769,27 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const String& rText, bool bT
             else if( pCharPosAry[i] >= nMinCharPos && pCharPosAry[i] <= nMaxCharPos )
             {
                 int nChars = 1;
-                aUnicodes.push_back( rText.GetChar( sal::static_int_cast<xub_StrLen>(pCharPosAry[i]) ) );
                 pUnicodesPerGlyph[i] = 1;
                 // try to handle ligatures and such
                 if( i < nGlyphs-1 )
                 {
                     nChars = pCharPosAry[i+1] - pCharPosAry[i];
+                    int start = pCharPosAry[i];
                     // #i115618# fix for simple RTL+CTL cases
-                    // TODO: sanitize for RTL ligatures, more complex CTL, etc.
+                    // supports RTL ligatures. TODO: more complex CTL, etc.
                     if( nChars < 0 )
+                    {
                         nChars = -nChars;
-                    else if( nChars == 0 )
+                        start = pCharPosAry[i+1] + 1;
+                    }
+                    else if (nChars == 0)
                         nChars = 1;
                     pUnicodesPerGlyph[i] = nChars;
-                    for( int n = 1; n < nChars; n++ )
-                        aUnicodes.push_back( rText.GetChar( sal::static_int_cast<xub_StrLen>(pCharPosAry[i]+n) ) );
+                    for( int n = 0; n < nChars; n++ )
+                        aUnicodes.push_back(rText.GetChar(sal::static_int_cast<xub_StrLen>(start + n)));
                 }
+                else
+                    aUnicodes.push_back( rText[ pCharPosAry[i] ] );
                 // #i36691# hack that is needed because currently the pGlyphs[]
                 // argument is ignored for embeddable fonts and so the layout
                 // engine's glyph work is ignored (i.e. char mirroring)
diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx
index 230583b191af..c6c3c7b3dd31 100644
--- a/vcl/source/glyphs/graphite_layout.cxx
+++ b/vcl/source/glyphs/graphite_layout.cxx
@@ -27,7 +27,7 @@
 #undef NDEBUG
 #endif
 
-// #define GRLAYOUT_DEBUG 1
+//#define GRLAYOUT_DEBUG 1
 
 // Header files
 //
@@ -105,23 +105,6 @@ namespace
         return is_subrange(s.first, s.second, b, e);
     }
 
-    int findSameDirLimit(const sal_Unicode* buffer, int charCount, bool rtl)
-    {
-        UErrorCode status = U_ZERO_ERROR;
-        UBiDi *ubidi = ubidi_openSized(charCount, 0, &status);
-        int limit = 0;
-        ubidi_setPara(ubidi, reinterpret_cast<const UChar *>(buffer), charCount,
-            (rtl)?UBIDI_DEFAULT_RTL:UBIDI_DEFAULT_LTR, NULL, &status);
-        UBiDiLevel level = 0;
-        ubidi_getLogicalRun(ubidi, 0, &limit, &level);
-        ubidi_close(ubidi);
-        if ((rtl && !(level & 1)) || (!rtl && (level & 1)))
-        {
-            limit = 0;
-        }
-        return limit;
-    }
-
     template <typename T>
     T maximum(T a, T b)
     {
@@ -141,43 +124,21 @@ namespace
 //        o Querying clustering relationships.
 //        o manipulations that affect neighouring glyphs.
 
-const int GraphiteLayout::EXTRA_CONTEXT_LENGTH = 10;
+const int GraphiteLayout::EXTRA_CONTEXT_LENGTH = 32;
 
-// find first slot of cluster and first slot of subsequent cluster
-static void findFirstClusterSlot(const gr_slot* base, gr_slot const** first, gr_slot const** after, int * firstChar, int * lastChar, bool bRtl)
+const gr_slot *get_next_base(const gr_slot *slot, bool bRtl)
 {
-    if (gr_slot_attached_to(base) == NULL)
-    {
-        *first = base;
-        *after = (bRtl)? gr_slot_prev_in_segment(base) :
-            gr_slot_next_in_segment(base);
-        *firstChar = gr_slot_before(base);
-        *lastChar = gr_slot_after(base);
-    }
-    const gr_slot * attachment = gr_slot_first_attachment(base);
-    while (attachment)
-    {
-        if (gr_slot_origin_X(*first) > gr_slot_origin_X(attachment))
-            *first = attachment;
-        const gr_slot* attachmentNext = (bRtl)?
-            gr_slot_prev_in_segment(attachment) : gr_slot_next_in_segment(attachment);
-        if (attachmentNext)
-        {
-            if (*after && (gr_slot_origin_X(*after) < gr_slot_origin_X(attachmentNext)))
-                *after = attachmentNext;
-        }
-        else
-        {
-            *after = NULL;
-        }
-        if (gr_slot_before(attachment) < *firstChar)
-            *firstChar = gr_slot_before(attachment);
-        if (gr_slot_after(attachment) > *lastChar)
-            *lastChar = gr_slot_after(attachment);
-        if (gr_slot_first_attachment(attachment))
-            findFirstClusterSlot(attachment, first, after, firstChar, lastChar, bRtl);
-        attachment = gr_slot_next_sibling_attachment(attachment);
-    }
+    for ( ; slot; slot = bRtl ? gr_slot_prev_in_segment(slot) : gr_slot_next_in_segment(slot))
+        if (!gr_slot_attached_to(slot) || gr_slot_can_insert_before(slot))
+            break;
+    return slot;
+}
+
+bool isWhite(sal_Unicode nChar)
+{
+    if (nChar <= 0x0020 || nChar == 0x00A0 || (nChar >= 0x2000 && nChar <= 0x200F) || nChar == 0x3000)
+        return true;
+    return false;
 }
 
 // The Graphite glyph stream is really a sequence of glyph attachment trees
@@ -185,202 +146,130 @@ static void findFirstClusterSlot(const gr_slot* base, gr_slot const** first, gr_
 //  finds each non-attached base glyph and calls append to record them as a
 //  sequence of clusters.
 void
-GraphiteLayout::fillFrom(gr_segment * pSegment, ImplLayoutArgs &rArgs, float fScaling)
+GraphiteLayout::fillFrom(gr_segment * pSegment, ImplLayoutArgs &rArgs, float fScaling, bool bRtl, int lastCharPos)
 {
-    bool bRtl = (rArgs.mnFlags & SAL_LAYOUT_BIDI_RTL);
-    int nCharRequested = rArgs.mnEndCharPos - rArgs.mnMinCharPos;
-    int nChar = gr_seg_n_cinfo(pSegment);
     float fMinX = gr_seg_advance_X(pSegment);
     float fMaxX = 0.0f;
     long nDxOffset = 0; // from dropped glyphs
-    int nFirstCharInCluster = 0;
-    int nLastCharInCluster = 0;
+    int origNumGlyphs = mvGlyphs.size();
     unsigned int nGlyphs = gr_seg_n_slots(pSegment);
-    mvGlyph2Char.assign(nGlyphs, -1);
-    mvGlyphs.reserve(nGlyphs);
-
-    if (bRtl)
+    mvGlyph2Char.resize(mvGlyph2Char.size() + nGlyphs, -1);
+    mvGlyphs.reserve(mvGlyphs.size() + nGlyphs);
+    int clusterStart = -1;
+    int clusterFirstChar = -1;
+    const gr_slot *nextBaseSlot;
+    const sal_Unicode *pStr = rArgs.mpStr;
+    int firstChar;
+
+    if (!nGlyphs || lastCharPos - mnSegCharOffset == 0) return;
+    const gr_slot* baseSlot = bRtl ? gr_seg_last_slot(pSegment) : gr_seg_first_slot(pSegment);
+    // find first base
+    while (baseSlot && gr_slot_attached_to(baseSlot) != NULL && !gr_slot_can_insert_before(baseSlot))
+        baseSlot = bRtl ? gr_slot_prev_in_segment(baseSlot) : gr_slot_next_in_segment(baseSlot);
+    assert(baseSlot);
+    int nextChar = gr_cinfo_base(gr_seg_cinfo(pSegment, gr_slot_before(baseSlot))) + mnSegCharOffset;
+    float thisBoundary = 0.;
+    float nextBoundary = gr_slot_origin_X(baseSlot);
+    // now loop over bases
+    for ( ; baseSlot; baseSlot = nextBaseSlot)
     {
-        const gr_slot* baseSlot = gr_seg_last_slot(pSegment);
-        // find first base
-        while (baseSlot && (gr_slot_attached_to(baseSlot) != NULL))
-            baseSlot = gr_slot_prev_in_segment(baseSlot);
-        int iChar = nChar - 1;
-        int iNextChar = nChar - 1;
-        bool reordered = false;
-        int nBaseGlyphIndex = 0;
-        // now loop over bases
-        while (baseSlot)
+        firstChar = nextChar;
+        thisBoundary = nextBoundary;
+        nextBaseSlot = get_next_base(bRtl ? gr_slot_prev_in_segment(baseSlot) : gr_slot_next_in_segment(baseSlot), bRtl);
+        nextChar = nextBaseSlot ? gr_cinfo_base(gr_seg_cinfo(pSegment, gr_slot_before(nextBaseSlot))) + mnSegCharOffset : -1;
+        nextBoundary = nextBaseSlot ? gr_slot_origin_X(nextBaseSlot) : gr_seg_advance_X(pSegment);
+
+        if (firstChar < mnMinCharPos || firstChar >= mnEndCharPos)
         {
-            bool bCluster = !reordered;
-            const gr_slot * clusterFirst = NULL;
-            const gr_slot * clusterAfter = NULL;
-            int firstChar = -1;
-            int lastChar = -1;
-            findFirstClusterSlot(baseSlot, &clusterFirst, &clusterAfter, &firstChar, &lastChar, bRtl);
-            iNextChar = minimum<int>(firstChar, iNextChar);
-            if (bCluster)
-            {
-                nBaseGlyphIndex = mvGlyphs.size();
-                mvGlyph2Char[nBaseGlyphIndex] = iChar + mnSegCharOffset;
-                nFirstCharInCluster = firstChar;
-                nLastCharInCluster = lastChar;
-            }
-            else
-            {
-                mvGlyph2Char[mvGlyphs.size()] = firstChar + mnSegCharOffset;
-                nFirstCharInCluster = minimum<int>(firstChar, nFirstCharInCluster);
-                nLastCharInCluster = maximum<int>(firstChar, nLastCharInCluster);
-            }
-            float leftBoundary = gr_slot_origin_X(clusterFirst);
-            float rightBoundary = (clusterAfter)?
-                gr_slot_origin_X(clusterAfter) : gr_seg_advance_X(pSegment);
-            if (
-                lastChar < iChar &&
-                 (gr_cinfo_after(gr_seg_cinfo(pSegment, iChar)) >
-                 static_cast<int>(gr_slot_index(clusterAfter)))
-               )
-            {
-                reordered = true;
-            }
-            else
-            {
-                reordered = false;
-                iChar = iNextChar - 1;
-            }
-            if (mnSegCharOffset + nFirstCharInCluster >= mnMinCharPos &&
-                mnSegCharOffset + nFirstCharInCluster < mnEndCharPos)
-            {
-                fMinX = minimum<float>(fMinX, leftBoundary);
-                fMaxX = maximum<float>(fMaxX, rightBoundary);
-                if (!reordered)
-                {
-                    for (int i = nFirstCharInCluster; i <= nLastCharInCluster; i++)
-                    {
-                        if (mnSegCharOffset + i >= mnEndCharPos)
-                            break;
-                        // from the point of view of the dx array, the xpos is
-                        // the origin of the first glyph of the cluster rtl
-                        mvCharDxs[mnSegCharOffset + i - mnMinCharPos] =
-                            static_cast<int>(leftBoundary * fScaling) + nDxOffset;
-                        mvCharBreaks[mnSegCharOffset + i - mnMinCharPos] = gr_cinfo_break_weight(gr_seg_cinfo(pSegment, i));
-                    }
-                    mvChar2BaseGlyph[mnSegCharOffset + nFirstCharInCluster - mnMinCharPos] = nBaseGlyphIndex;
-                }
-                append(pSegment, rArgs, baseSlot, gr_slot_origin_X(baseSlot), rightBoundary, fScaling,
-                       nDxOffset, bCluster, mnSegCharOffset + firstChar);
-            }
-            if (mnSegCharOffset + nLastCharInCluster < mnMinCharPos)
-                break;
-            baseSlot = gr_slot_next_sibling_attachment(baseSlot);
+            // handle clipping of diacritic from base
+            nextBaseSlot = bRtl ? gr_slot_prev_in_segment(baseSlot) : gr_slot_next_in_segment(baseSlot);
+            nextBoundary = nextBaseSlot ? gr_slot_origin_X(nextBaseSlot) : gr_seg_advance_X(pSegment);
+            nextChar = nextBaseSlot ? gr_cinfo_base(gr_seg_cinfo(pSegment, gr_slot_before(nextBaseSlot))) + mnSegCharOffset : -1;
+            continue;
         }
-    }
-    else
-    {
-        const gr_slot* baseSlot = gr_seg_first_slot(pSegment);
-        // find first base
-        while (baseSlot && (gr_slot_attached_to(baseSlot) != NULL))
-            baseSlot = gr_slot_next_in_segment(baseSlot);
-        int iChar = 0; // relative to segment
-        int iNextChar = 0;
-        bool reordered = false;
-        int nBaseGlyphIndex = 0;
-        // now loop over bases
-        while (baseSlot)
+        // handle reordered clusters. Presumes reordered glyphs have monotonic opposite char index until the cluster base.
+        bool isReordered = (nextBaseSlot && ((bRtl != (gr_cinfo_base(gr_seg_cinfo(pSegment, gr_slot_before(nextBaseSlot))) < firstChar - mnSegCharOffset))
+                                             || gr_cinfo_base(gr_seg_cinfo(pSegment, gr_slot_before(nextBaseSlot))) == firstChar - mnSegCharOffset));
+        if (clusterStart >= 0 && !isReordered)      // we hit the base (end) of a reordered cluster
         {
-            bool bCluster = !reordered;
-            const gr_slot * clusterFirst = NULL;
-            const gr_slot * clusterAfter = NULL;
-            int firstChar = -1;
-            int lastChar = -1;
-            findFirstClusterSlot(baseSlot, &clusterFirst, &clusterAfter, &firstChar, &lastChar, bRtl);
-            iNextChar = maximum<int>(lastChar, iNextChar);
-            if (bCluster)
-            {
-                nBaseGlyphIndex = mvGlyphs.size();
-                mvGlyph2Char[nBaseGlyphIndex] = iChar + mnSegCharOffset;
-                nFirstCharInCluster = firstChar;
-                nLastCharInCluster = lastChar;
-            }
-            else
-            {
-                mvGlyph2Char[mvGlyphs.size()] = firstChar + mnSegCharOffset;
-                nFirstCharInCluster = minimum<int>(firstChar, nFirstCharInCluster);
-                nLastCharInCluster = maximum<int>(lastChar, nLastCharInCluster);
-            }
-            if (
-                firstChar > iChar &&
-                 (gr_cinfo_before(gr_seg_cinfo(pSegment, iChar)) >
-                 static_cast<int>(gr_slot_index(clusterFirst)))
-               )
+            int clusterEnd = mvGlyphs.size();
+            for (int i = clusterStart; i < clusterEnd; ++i)
+                mvGlyph2Char[i] = firstChar;
+            if (bRtl)
             {
-                reordered = true;
+                for ( ; clusterFirstChar < firstChar; ++clusterFirstChar)
+                    if (clusterFirstChar >= mnMinCharPos && clusterFirstChar < mnEndCharPos)
+                    {
+                        mvChar2BaseGlyph[clusterFirstChar - mnMinCharPos] = clusterStart;  // lowest glyphItem index
+                        mvCharDxs[clusterFirstChar - mnMinCharPos] = static_cast<int>(thisBoundary * fScaling) + mnWidth + nDxOffset;
+                    }
             }
             else
             {
-                reordered = false;
-                iChar = iNextChar + 1;
-            }
-            float leftBoundary = gr_slot_origin_X(clusterFirst);
-            float rightBoundary = (clusterAfter)?
-                gr_slot_origin_X(clusterAfter) : gr_seg_advance_X(pSegment);
-            int bFirstChar = gr_cinfo_base(gr_seg_cinfo(pSegment, nFirstCharInCluster));
-            if (mnSegCharOffset + bFirstChar >= mnMinCharPos &&
-                mnSegCharOffset + bFirstChar < mnEndCharPos)
-            {
-                fMinX = minimum<float>(fMinX, leftBoundary);
-                fMaxX = maximum<float>(fMaxX, rightBoundary);
-                if (!reordered)
-                {
-                    for (int i = nFirstCharInCluster; i <= nLastCharInCluster; i++)
+                for ( ; clusterFirstChar > firstChar; --clusterFirstChar)
+                    if (clusterFirstChar < mnEndCharPos && clusterFirstChar >= mnMinCharPos)
                     {
-                        int ibase = gr_cinfo_base(gr_seg_cinfo(pSegment, i));
-                        if (mnSegCharOffset + ibase >= mnEndCharPos)
-                            break;
-                        // from the point of view of the dx array, the xpos is
-                        // the origin of the first glyph of the next cluster ltr
-                        mvCharDxs[mnSegCharOffset + ibase - mnMinCharPos] =
-                            static_cast<int>(rightBoundary * fScaling) + nDxOffset;
-                        mvCharBreaks[mnSegCharOffset + ibase - mnMinCharPos] = gr_cinfo_break_weight(gr_seg_cinfo(pSegment, i));
+                        mvChar2BaseGlyph[clusterFirstChar - mnMinCharPos] = clusterStart;
+                        mvCharDxs[clusterFirstChar - mnMinCharPos] = static_cast<int>(nextBoundary * fScaling) + mnWidth + nDxOffset;
                     }
-                    // only set mvChar2BaseGlyph for first character of cluster
-                    mvChar2BaseGlyph[mnSegCharOffset + bFirstChar - mnMinCharPos] = nBaseGlyphIndex;
-                }
-                append(pSegment, rArgs, baseSlot, gr_slot_origin_X(baseSlot), rightBoundary, fScaling,
-                       nDxOffset, true, mnSegCharOffset + firstChar);
             }
-            if (mnSegCharOffset + bFirstChar >= mnEndCharPos)
-                break;
-            baseSlot = gr_slot_next_sibling_attachment(baseSlot);
+            clusterStart = -1;
+            clusterFirstChar = -1;
         }
+        else if (clusterStart < 0 && isReordered) // we hit the start of a reordered cluster
+        {
+            clusterStart = mvGlyphs.size();
+            clusterFirstChar = firstChar;
+        }
+
+        int baseGlyph = mvGlyphs.size();
+        int scaledGlyphPos = round(gr_slot_origin_X(baseSlot) * fScaling) + mnWidth + nDxOffset;
+        if (mvChar2Glyph[firstChar - mnMinCharPos] == -1 || mvGlyphs[mvChar2Glyph[firstChar - mnMinCharPos]].maLinearPos.X() < scaledGlyphPos)
+        {
+            mvChar2Glyph[firstChar - mnMinCharPos] = mvGlyphs.size();
+            mvCharDxs[firstChar - mnMinCharPos] = static_cast<int>((bRtl ? thisBoundary : nextBoundary) * fScaling) + mnWidth + nDxOffset;
+            mvChar2BaseGlyph[firstChar - mnMinCharPos] = baseGlyph;
+            mvCharBreaks[firstChar - mnMinCharPos] = gr_cinfo_break_weight(gr_seg_cinfo(pSegment, gr_slot_before(baseSlot)));
+        }
+        mvGlyph2Char[baseGlyph] = firstChar;
+        append(pSegment, rArgs, baseSlot, thisBoundary, nextBoundary, fScaling, nDxOffset, true, firstChar, baseGlyph, bRtl);
+        if (thisBoundary < fMinX) fMinX = thisBoundary;
+        if (nextBoundary > fMaxX && (nextChar < mnMinCharPos || nextChar >= mnEndCharPos || !isWhite(pStr[nextChar]) || fMaxX <= 0.0f))
+            fMaxX = nextBoundary;
     }
     long nXOffset = round(fMinX * fScaling);
-    mnWidth = round(fMaxX * fScaling) - nXOffset + nDxOffset;
-    if (mnWidth < 0)
-    {
-        // This can happen when there was no base inside the range
-        mnWidth = 0;
-    }
+    long nXEnd = round(fMaxX * fScaling);
+    int nCharRequested = minimum<int>(lastCharPos, mnEndCharPos) - mnMinCharPos;
+    int firstCharOffset = maximum<int>(mnSegCharOffset, mnMinCharPos) - mnMinCharPos;
     // fill up non-base char dx with cluster widths from previous base glyph
     if (bRtl)
     {
         if (mvCharDxs[nCharRequested-1] == -1)
-            mvCharDxs[nCharRequested-1] = 0;
+            mvCharDxs[nCharRequested-1] = nXEnd - nXOffset + mnWidth + nDxOffset;
         else
-            mvCharDxs[nCharRequested-1] -= nXOffset;
-        for (int i = nCharRequested - 2; i >= 0; i--)
+            mvCharDxs[nCharRequested-1] = nXEnd - mvCharDxs[nCharRequested-1] + 2 * (mnWidth + nDxOffset);
+#ifdef GRLAYOUT_DEBUG
+            fprintf(grLog(),"%d,%d ", nCharRequested - 1, (int)mvCharDxs[nCharRequested-1]);
+#endif
+        for (int i = nCharRequested - 2; i >= firstCharOffset; i--)
         {
             if (mvCharDxs[i] == -1) mvCharDxs[i] = mvCharDxs[i+1];
-            else mvCharDxs[i] -= nXOffset;
+            else mvCharDxs[i] = nXEnd - mvCharDxs[i] + 2 * (mnWidth + nDxOffset);
+#ifdef GRLAYOUT_DEBUG
+            fprintf(grLog(),"%d,%d ", (int)i, (int)mvCharDxs[i]);
+#endif
         }
     }
     else
     {
-        if (mvCharDxs[0] == -1)
-            mvCharDxs[0] = 0;
+        if (mvCharDxs[firstCharOffset] == -1)
+            mvCharDxs[firstCharOffset] = 0;
         else
-            mvCharDxs[0] -= nXOffset;
-        for (int i = 1; i < nCharRequested; i++)
+            mvCharDxs[firstCharOffset] -= nXOffset;
+#ifdef GRLAYOUT_DEBUG
+            fprintf(grLog(),"%d,%d ", firstCharOffset, (int)mvCharDxs[firstCharOffset]);
+#endif
+        for (int i = firstCharOffset + 1; i < nCharRequested; i++)
         {
             if (mvCharDxs[i] == -1) mvCharDxs[i] = mvCharDxs[i-1];
             else mvCharDxs[i] -= nXOffset;
@@ -392,11 +281,17 @@ GraphiteLayout::fillFrom(gr_segment * pSegment, ImplLayoutArgs &rArgs, float fSc
     // remove offset due to context if there is one
     if (nXOffset != 0)
     {
-        for (size_t i = 0; i < mvGlyphs.size(); i++)
+        for (size_t i = origNumGlyphs; i < mvGlyphs.size(); i++)
             mvGlyphs[i].maLinearPos.X() -= nXOffset;
     }
+    mnWidth += nXEnd - nXOffset + nDxOffset;
+    if (mnWidth < 0)
+    {
+        // This can happen when there was no base inside the range
+        mnWidth = 0;
+    }
 #ifdef GRLAYOUT_DEBUG
-    fprintf(grLog(), "fillFrom %" SAL_PRI_SIZET "u glyphs offset %ld width %ld\n", mvGlyphs.size(), nXOffset, mnWidth);
+    fprintf(grLog(), "fillFrom %" SAL_PRI_SIZET "u glyphs offset %ld width %ld for %d\n", mvGlyphs.size(), nXOffset, mnWidth, nCharRequested);
 #endif
 }
 
@@ -405,37 +300,29 @@ GraphiteLayout::fillFrom(gr_segment * pSegment, ImplLayoutArgs &rArgs, float fSc
 float
 GraphiteLayout::append(gr_segment *pSeg, ImplLayoutArgs &rArgs,
     const gr_slot * gi, float gOrigin, float nextGlyphOrigin, float scaling, long & rDXOffset,
-    bool bIsBase, int baseChar)
+    bool bIsBase, int baseChar, int baseGlyph, bool bRtl)
 {
-    bool bRtl = (rArgs.mnFlags & SAL_LAYOUT_BIDI_RTL);
-    float nextOrigin;
     assert(gi);
-    assert(gr_slot_before(gi) <= gr_slot_after(gi));
-    int firstChar = gr_slot_before(gi) + mnSegCharOffset;
+    // assert(gr_slot_before(gi) <= gr_slot_after(gi));
+    int firstChar = gr_cinfo_base(gr_seg_cinfo(pSeg, gr_slot_before(gi))) + mnSegCharOffset;
     assert(mvGlyphs.size() < mvGlyph2Char.size());
-    if (!bIsBase) mvGlyph2Char[mvGlyphs.size()] = baseChar;//firstChar;
-    // is the next glyph attached or in the next cluster?
-    //glyph_set_range_t iAttached = gi.attachedClusterGlyphs();
-    const gr_slot * pFirstAttached = gr_slot_first_attachment(gi);
-    const gr_slot * pNextSibling = gr_slot_next_sibling_attachment(gi);
-    if (pFirstAttached)
-        nextOrigin = gr_slot_origin_X(pFirstAttached);
-    else if (!bIsBase && pNextSibling)
-        nextOrigin = gr_slot_origin_X(pNextSibling);
-    else
-        nextOrigin = nextGlyphOrigin;
+    if (firstChar < mnMinCharPos || firstChar >= mnEndCharPos)
+        return nextGlyphOrigin;
+
     long glyphId = gr_slot_gid(gi);
     long deltaOffset = 0;
-    int scaledGlyphPos = round(gr_slot_origin_X(gi) * scaling);
-    int glyphWidth = round((nextOrigin - gOrigin) * scaling);
-//    if (glyphWidth < 0)
-//    {
-//        nextOrigin = gOrigin;
-//        glyphWidth = 0;
-//    }
+    int scaledGlyphPos = round(gr_slot_origin_X(gi) * scaling) + mnWidth + rDXOffset;
+    int glyphWidth = round((nextGlyphOrigin - gOrigin) * scaling);
+    if (!bIsBase)
+    {
+        mvChar2BaseGlyph[firstChar - mnMinCharPos] = baseGlyph;
+        mvCharDxs[firstChar - mnMinCharPos] = mvCharDxs[baseChar - mnMinCharPos];
+        mvCharBreaks[firstChar - mnMinCharPos] = gr_cinfo_break_weight(gr_seg_cinfo(pSeg, gr_slot_before(gi)));
+    }
+
 #ifdef GRLAYOUT_DEBUG
-    fprintf(grLog(),"c%d g%ld,X%d W%d nX%f ", firstChar, glyphId,
-        (int)(gr_slot_origin_X(gi) * scaling), glyphWidth, nextOrigin * scaling);
+    fprintf(grLog(),"c%d g%ld,X%d W%d nX%f @%d=%d ", firstChar, glyphId,
+        scaledGlyphPos, glyphWidth, nextGlyphOrigin * scaling, mvChar2Glyph[firstChar-mnMinCharPos], mvCharDxs[firstChar-mnMinCharPos]);
 #endif
     if (glyphId == 0)
     {
@@ -465,11 +352,12 @@ GraphiteLayout::append(gr_segment *pSeg, ImplLayoutArgs &rArgs,
     }
     // append this glyph. Set the cluster flag if this glyph is attached to another
     long nGlyphFlags = bIsBase ? 0 : GlyphItem::IS_IN_CLUSTER;
+    if (gr_slot_attached_to(gi))
+        nGlyphFlags |= GlyphItem::IS_DIACRITIC;
     nGlyphFlags |= (bRtl)? GlyphItem::IS_RTL_GLYPH : 0;
     GlyphItem aGlyphItem(mvGlyphs.size(),
         glyphId,
-        Point(scaledGlyphPos + rDXOffset,
-            round((-gr_slot_origin_Y(gi) * scaling))),
+        Point(scaledGlyphPos, round((-gr_slot_origin_Y(gi) * scaling))),
         nGlyphFlags,
         glyphWidth);
     if (glyphId != static_cast<long>(GF_DROPPED))
@@ -480,9 +368,10 @@ GraphiteLayout::append(gr_segment *pSeg, ImplLayoutArgs &rArgs,
     rDXOffset += deltaOffset;
 
     // Recursively append all the attached glyphs.
-    float cOrigin = nextOrigin;
+    float cOrigin = nextGlyphOrigin;
     for (const gr_slot * agi = gr_slot_first_attachment(gi); agi != NULL; agi = gr_slot_next_sibling_attachment(agi))
-        cOrigin = append(pSeg, rArgs, agi, cOrigin, nextGlyphOrigin, scaling, rDXOffset, false, baseChar);
+        if (!gr_slot_can_insert_before(agi))
+            cOrigin = append(pSeg, rArgs, agi, cOrigin, nextGlyphOrigin, scaling, rDXOffset, false, baseChar, baseGlyph, bRtl);
 
     return cOrigin;
 }
@@ -516,6 +405,7 @@ void GraphiteLayout::clear()
     mvGlyphs.clear();
     mvCharDxs.clear();
     mvChar2BaseGlyph.clear();
+    mvChar2Glyph.clear();
     mvGlyph2Char.clear();
 
     // Reset the state to the empty state.
@@ -526,168 +416,61 @@ void GraphiteLayout::clear()
 // This method shouldn't be called on windows, since it needs the dc reset
 bool GraphiteLayout::LayoutText(ImplLayoutArgs & rArgs)
 {
+    clear();
     bool success = true;
-    if (rArgs.mnMinCharPos < rArgs.mnEndCharPos)
-    {
-        gr_segment * pSegment = CreateSegment(rArgs);
-        if (!pSegment)
-            return false;
-        success = LayoutGlyphs(rArgs, pSegment);
-        if (pSegment)
-        {
-            gr_seg_destroy(pSegment);
-            pSegment = NULL;
-        }
-    }
-    else
-    {
-        clear();
-    }
-    return success;
-}
-
-
-gr_segment * GraphiteLayout::CreateSegment(ImplLayoutArgs& rArgs)
-{
-    assert(rArgs.mnLength >= 0);
-
-    gr_segment * pSegment = NULL;
-
+    if (rArgs.mnMinCharPos >= rArgs.mnEndCharPos)
+        return success;
     // Set the SalLayouts values to be the initial ones.
     SalLayout::AdjustLayout(rArgs);
     // TODO check if this is needed
     if (mnUnitsPerPixel > 1)
         mfScaling = 1.0f / mnUnitsPerPixel;
+    mvCharDxs.assign(mnEndCharPos - mnMinCharPos, -1);
+    mvChar2BaseGlyph.assign(mnEndCharPos - mnMinCharPos, -1);
+    mvChar2Glyph.assign(mnEndCharPos - mnMinCharPos, -1);
+    mvCharBreaks.assign(mnEndCharPos - mnMinCharPos, 0);
 
-    // Clear out any previous buffers
-    clear();
-    bool bRtl = mnLayoutFlags & SAL_LAYOUT_BIDI_RTL;
-    try
+#ifdef GRLAYOUT_DEBUG
+    fprintf(grLog(), "New Graphite LayoutText\n");
+#endif
+    success = false;
+    while (true)
     {
-        // Don't set RTL if font doesn't support it otherwise it forces rtl on
-        // everything
-        //if (bRtl && (mrFont.getSupportedScriptDirections() & gr::kfsdcHorizRtl))
-        //    maLayout.setRightToLeft(bRtl);
-
-        // Context is often needed beyond the specified end, however, we don't
-        // want it if there has been a direction change, since it is hard
-        // to tell between reordering within one direction and multi-directional
-        // text. Extra context, can also cause problems with ligatures stradling
-        // a hyphenation point, so disable if CTL is disabled.
-        mnSegCharOffset = rArgs.mnMinCharPos;
-        int limit = rArgs.mnEndCharPos;
-        if (!(SAL_LAYOUT_COMPLEX_DISABLED & rArgs.mnFlags))
-        {
-            const int nSegCharMin = maximum<int>(0, mnMinCharPos - EXTRA_CONTEXT_LENGTH);
-            const int nSegCharLimit = minimum(rArgs.mnLength, mnEndCharPos + EXTRA_CONTEXT_LENGTH);
-            if (nSegCharMin < mnSegCharOffset)
-            {
-                int sameDirEnd = findSameDirLimit(rArgs.mpStr + nSegCharMin,
-                    rArgs.mnEndCharPos - nSegCharMin, bRtl);
-                if (sameDirEnd == rArgs.mnEndCharPos)
-                    mnSegCharOffset = nSegCharMin;
-            }
-            if (nSegCharLimit > limit)
-            {
-                limit += findSameDirLimit(rArgs.mpStr + rArgs.mnEndCharPos,
-                    nSegCharLimit - rArgs.mnEndCharPos, bRtl);
-            }
-        }
+        int nBidiMinRunPos, nBidiEndRunPos;
+        bool bRightToLeft;
+        if (!rArgs.GetNextRun(&nBidiMinRunPos, &nBidiEndRunPos, &bRightToLeft))
+            break;
 
-        size_t numchars = gr_count_unicode_characters(gr_utf16, rArgs.mpStr + mnSegCharOffset,
-                 rArgs.mpStr + (rArgs.mnLength > limit + 64 ? limit + 64 : rArgs.mnLength), NULL);
-        static com::sun::star::uno::Reference< com::sun::star::i18n::XCharacterClassification > xCharClass;
-        if ( !xCharClass.is() )
-            xCharClass = vcl::unohelper::CreateCharacterClassification();
-        size_t numchars2 = rArgs.mnEndCharPos - mnSegCharOffset; // fdo#52540, fdo#68313, fdo#70666 avoid bad ligature replacement
-        if (numchars > numchars2 && xCharClass->getType(rArgs.mpStr, numchars2 + 1) == ::com::sun::star::i18n::UnicodeType::LOWERCASE_LETTER)
-            numchars = numchars2;
-        if (mpFeatures)
-            pSegment = gr_make_seg(mpFont, mpFace, 0, mpFeatures->values(), gr_utf16,
-                                        rArgs.mpStr + mnSegCharOffset, numchars, bRtl);
-        else
-            pSegment = gr_make_seg(mpFont, mpFace, 0, NULL, gr_utf16,
-                                        rArgs.mpStr + mnSegCharOffset, numchars, bRtl);
+        if (nBidiEndRunPos < mnMinCharPos || nBidiMinRunPos >= mnEndCharPos)
+            continue;
+
+        if (nBidiMinRunPos == mnMinCharPos)
+            nBidiMinRunPos = maximum<int>(0, nBidiMinRunPos - EXTRA_CONTEXT_LENGTH);
+        if (nBidiEndRunPos == mnEndCharPos)
+            nBidiEndRunPos = minimum<int>(rArgs.mnLength, nBidiEndRunPos + EXTRA_CONTEXT_LENGTH);
+        size_t numchars = gr_count_unicode_characters(gr_utf16, rArgs.mpStr + nBidiMinRunPos,
+                 rArgs.mpStr + nBidiEndRunPos, NULL);
+        gr_segment * pSegment = gr_make_seg(mpFont, mpFace, 0, mpFeatures ? mpFeatures->values() : NULL,
+                                gr_utf16, rArgs.mpStr + nBidiMinRunPos, numchars, 2 | int(bRightToLeft));
 
-        //pSegment = new gr::RangeSegment((gr::Font *)&mrFont, mpTextSrc, &maLayout, mnMinCharPos, limit);
         if (pSegment != NULL)
         {
+            success = true;
+            mnSegCharOffset = nBidiMinRunPos;
 #ifdef GRLAYOUT_DEBUG
-            fprintf(grLog(),"Gr::LayoutText %d-%d, context %d, len %d, numchars %d, rtl %d scaling %f:", rArgs.mnMinCharPos,
-               rArgs.mnEndCharPos, limit, rArgs.mnLength, numchars, bRtl, mfScaling);
-            for (int i = mnSegCharOffset; i < limit; ++i)
+            fprintf(grLog(),"Gr::LayoutText %d-%d, context %d-%d, len %d, numchars %" SAL_PRI_SIZET "u, rtl %d scaling %f:",
+                rArgs.mnMinCharPos, rArgs.mnEndCharPos,
+                nBidiMinRunPos, nBidiEndRunPos,
+                rArgs.mnLength, numchars, bRightToLeft, mfScaling);
+            for (int i = mnSegCharOffset; i < nBidiEndRunPos; ++i)
                 fprintf(grLog(), " %04X", rArgs.mpStr[i]);
             fprintf(grLog(), "\n");
 #endif
-        }
-        else
-        {
-#ifdef GRLAYOUT_DEBUG
-            fprintf(grLog(), "Gr::LayoutText failed: ");
-            for (int i = mnMinCharPos; i < limit; i++)
-            {
-                fprintf(grLog(), "%04x ", rArgs.mpStr[i]);
-            }
-            fprintf(grLog(), "\n");
-#endif
-            clear();
-            return NULL;
-        }
-    }
-    catch (...)
-    {
-        clear();  // destroy the text source and any partially built segments.
-        return NULL;
-    }
-    return pSegment;
-}
-
-bool GraphiteLayout::LayoutGlyphs(ImplLayoutArgs& rArgs, gr_segment * pSegment)
-{
-    // Calculate the initial character dxs.
-    mvCharDxs.assign(mnEndCharPos - mnMinCharPos, -1);
-    mvChar2BaseGlyph.assign(mnEndCharPos - mnMinCharPos, -1);
-    mvCharBreaks.assign(mnEndCharPos - mnMinCharPos, 0);
-    mnWidth = 0;
-    if (mvCharDxs.size() > 0)
-    {
-        // Discover all the clusters.
-        try
-        {
-            bool bRtl = mnLayoutFlags & SAL_LAYOUT_BIDI_RTL;
-            fillFrom(pSegment, rArgs, mfScaling);
-
-            if (bRtl)
-            {
-                // not needed for adjacent differences, but for mouse clicks to char
-                std::transform(mvCharDxs.begin(), mvCharDxs.end(), mvCharDxs.begin(),
-                    std::bind1st(std::minus<long>(), mnWidth));
-                // fixup last dx to ensure it always equals the width
-                mvCharDxs[mvCharDxs.size() - 1] = mnWidth;
-            }
-        }
-        catch (const std::exception &e)
-        {
-#ifdef GRLAYOUT_DEBUG
-            fprintf(grLog(),"LayoutGlyphs failed %s\n", e.what());
-#else
-            (void)e;
-#endif
-            return false;
-        }
-        catch (...)
-        {
-#ifdef GRLAYOUT_DEBUG
-            fprintf(grLog(),"LayoutGlyphs failed with exception");
-#endif
-            return false;
+            fillFrom(pSegment, rArgs, mfScaling, bRightToLeft, nBidiEndRunPos);
+            gr_seg_destroy(pSegment);
         }
     }
-    else
-    {
-        mnWidth = 0;
-    }
-    return true;
+    return success;
 }
 
 int GraphiteLayout::GetTextBreak(long maxmnWidth, long char_extra, int factor) const
@@ -709,12 +492,12 @@ int GraphiteLayout::GetTextBreak(long maxmnWidth, long char_extra, int factor) c
     {
         nWidth += char_extra;
         if (nWidth > maxmnWidth) break;
-        if (mvChar2BaseGlyph[i] != -1)
+        int gi = mvChar2BaseGlyph[i];
+        if (gi != -1)
         {
-            if (
+            if (!mvGlyphs[gi].IsDiacritic() &&
                 (mvCharBreaks[i] > -35 || (mvCharBreaks[i-1] > 0 && mvCharBreaks[i-1] < 35)) &&
-                (mvCharBreaks[i-1] < 35 || (mvCharBreaks[i] < 0 && mvCharBreaks[i] > -35))
-               )
+                (mvCharBreaks[i-1] < 35 || (mvCharBreaks[i] < 0 && mvCharBreaks[i] > -35)))
             {
                 nLastBreak = static_cast<int>(i);
                 wLastBreak = nWidth;
@@ -767,10 +550,6 @@ long GraphiteLayout::FillDXArray( sal_Int32* pDXArray ) const
             fprintf(grLog(),"%d,%d,%d ", (int)i, (int)mvCharDxs[i], pDXArray[i]);
 #endif
         }
-        //std::adjacent_difference(mvCharDxs.begin(), mvCharDxs.end(), pDXArray);
-        //for (size_t i = 0; i < mvCharDxs.size(); i++)
-        //    fprintf(grLog(),"%d,%d,%d ", (int)i, (int)mvCharDxs[i], pDXArray[i]);
-        //fprintf(grLog(),"FillDX %ld,%d\n", mnWidth, std::accumulate(pDXArray, pDXArray + mvCharDxs.size(), 0));
     }
 #ifdef GRLAYOUT_DEBUG
     fprintf(grLog(),"FillDXArray %d-%d=%ld\n", mnMinCharPos, mnEndCharPos, mnWidth);
@@ -781,7 +560,7 @@ long GraphiteLayout::FillDXArray( sal_Int32* pDXArray ) const
 void  GraphiteLayout::AdjustLayout(ImplLayoutArgs& rArgs)
 {
     SalLayout::AdjustLayout(rArgs);
-    if(rArgs.mpDXArray)
+    if(rArgs.mpDXArray && mvGlyphs.size())
     {
         std::vector<int> vDeltaWidths(mvGlyphs.size(), 0);
         ApplyDXArray(rArgs, vDeltaWidths);
@@ -829,11 +608,14 @@ void GraphiteLayout::expandOrCondense(ImplLayoutArgs &rArgs)
         int nClusterCount = 0;
         for (size_t j = 0; j < mvGlyphs.size(); j++)
         {
-            if (mvGlyphs[j].IsClusterStart())
+            if (mvGlyphs[j].IsClusterStart() && !mvGlyphs[j].IsDiacritic())
             {
                 ++nClusterCount;
             }
         }
+#ifdef GRLAYOUT_DEBUG
+            fprintf(grLog(), "Expand by width %f for %ld clusters\n", nDeltaWidth, nClusterCount);
+#endif
         if (nClusterCount > 1)
         {
             float fExtraPerCluster = static_cast<float>(nDeltaWidth) / static_cast<float>(nClusterCount - 1);
@@ -841,7 +623,7 @@ void GraphiteLayout::expandOrCondense(ImplLayoutArgs &rArgs)
             int nOffset = 0;
             for (size_t i = 0; i < mvGlyphs.size(); i++)
             {
-                if (mvGlyphs[i].IsClusterStart())
+                if (mvGlyphs[i].IsClusterStart() && !mvGlyphs[i].IsDiacritic())
                 {
                     nOffset = static_cast<int>(fExtraPerCluster * nCluster);
                     int nCharIndex = mvGlyph2Char[i];
@@ -894,135 +676,126 @@ void GraphiteLayout::expandOrCondense(ImplLayoutArgs &rArgs)
     mnWidth = rArgs.mnLayoutWidth;
 }
 
+unsigned int GraphiteLayout::ScanFwdForChar(int &findChar, bool fallback) const
+{
+    int res = mvChar2Glyph[findChar - mnMinCharPos];
+    int done = 3;
+    while (res == -1 && --done)
+    {
+        if (fallback)
+        {
+            for (++findChar; findChar - mnMinCharPos < int(mvChar2Glyph.size()); ++findChar)
+                if ((res = mvChar2Glyph[findChar - mnMinCharPos]) != -1)
+                    return res;
+        }
+        else
+        {
+            for (--findChar; findChar >= mnMinCharPos; --findChar)
+                if ((res = mvChar2Glyph[findChar - mnMinCharPos]) != -1)
+                    return res;
+        }
+        fallback = !fallback;
+    }
+    return unsigned(res);
+}
+
 void GraphiteLayout::ApplyDXArray(ImplLayoutArgs &args, std::vector<int> & rDeltaWidth)
 {
-    const size_t nChars = args.mnEndCharPos - args.mnMinCharPos;
-    if (nChars == 0) return;
+    bool bRtl(mnLayoutFlags & SalLayoutFlags::BiDiRtl);
+    int startChar = args.mnMinCharPos < mnMinCharPos ? mnMinCharPos : args.mnMinCharPos;
+    int endChar = args.mnEndCharPos >= mnEndCharPos ? mnEndCharPos - 1 : args.mnEndCharPos;
+    unsigned int startGi = ScanFwdForChar(startChar, !bRtl);
+    unsigned int endGi = ScanFwdForChar(endChar, bRtl);
+    int nChars = endChar - startChar + 1;
+    if (nChars <= 0) return;
+    if (startGi > endGi)
+    {
+        unsigned int temp = endGi;
+        endGi = startGi;
+        startGi = temp;
+    }
+    ++endGi;
 
 #ifdef GRLAYOUT_DEBUG
     for (size_t iDx = 0; iDx < mvCharDxs.size(); iDx++)
-         fprintf(grLog(),"%d,%d,%d ", (int)iDx, (int)mvCharDxs[iDx], args.mpDXArray[iDx]);
-    fprintf(grLog(),"ApplyDx\n");
+         fprintf(grLog(),"%d,%d,%ld ", (int)iDx, (int)mvCharDxs[iDx], args.mpDXArray[iDx]);
+    fprintf(grLog(),"ApplyDx %d-%d=%d-%d\n", startChar, endChar, startGi, endGi);
 #endif
-    bool bRtl = mnLayoutFlags & SAL_LAYOUT_BIDI_RTL;
-    int nXOffset = 0;
-    if (bRtl)
-    {
-        nXOffset = args.mpDXArray[nChars - 1] - mvCharDxs[nChars - 1];
-    }
-    int nPrevClusterGlyph = (bRtl)? (signed)mvGlyphs.size() : -1;
-    int nPrevClusterLastChar = -1;
-    for (size_t i = 0; i < nChars; i++)
+
+    for (unsigned int i = startGi; i < endGi; ++i)
     {
-        int nChar2Base = mvChar2BaseGlyph[i];
-        if ((nChar2Base > -1) && (nChar2Base != nPrevClusterGlyph))
+        // calculate visual cluster bounds
+        int firstChar = mvGlyph2Char[i];
+        unsigned int nBaseGlyph = mvChar2BaseGlyph[firstChar - mnMinCharPos];
+        while (nBaseGlyph == ~0U && i < endGi)
         {
-            assert((nChar2Base > -1) && (nChar2Base < (signed)mvGlyphs.size()));
-            GlyphItem & gi = mvGlyphs[nChar2Base];
-            if (!gi.IsClusterStart())
-                continue;
-
-            // find last glyph of this cluster
-            size_t j = i + 1;
-            int nLastChar = i;
-            int nLastGlyph = nChar2Base;
-            int nChar2BaseJ = -1;
-            for (; j < nChars; j++)
+            ++i;
+            firstChar = mvGlyph2Char[i];
+            nBaseGlyph = unsigned(mvChar2BaseGlyph[firstChar - mnMinCharPos]);
+        }
+        int lastChar = firstChar;
+        unsigned int nLastGlyph = i;
+        // firstGlyph = i
+        for ( ; nLastGlyph < endGi; nLastGlyph++)
+        {
+            int thisChar = mvGlyph2Char[nLastGlyph];
+            if (thisChar == -1) continue;
+            if (unsigned(mvChar2BaseGlyph[thisChar - mnMinCharPos]) != nBaseGlyph)
             {
-                nChar2BaseJ = mvChar2BaseGlyph[j];
-                assert((nChar2BaseJ >= -1) && (nChar2BaseJ < (signed)mvGlyphs.size()));
-                if (nChar2BaseJ != -1 )
-                {
-                    nLastGlyph = nChar2BaseJ + ((bRtl)? +1 : -1);
-                    nLastChar = j - 1;
+                if (!mvGlyphs[nLastGlyph].IsDiacritic())
                     break;
-                }
-            }
-            if (nLastGlyph < 0)
-            {
-                nLastGlyph = nChar2Base;
-            }
-            // Its harder to find the last glyph rtl, since the first of
-            // cluster is still on the left so we need to search towards
-            // the previous cluster to the right
-            if (bRtl)
-            {
-                nLastGlyph = nChar2Base;
-                while (nLastGlyph + 1 < (signed)mvGlyphs.size() &&
-                       !mvGlyphs[nLastGlyph+1].IsClusterStart())
-                {
-                    ++nLastGlyph;
-                }
-            }
-            if (j == nChars)
-            {
-                nLastChar = nChars - 1;
-                if (!bRtl) nLastGlyph = mvGlyphs.size() - 1;
-            }
-            int nBaseCount = 0;
-            // count bases within cluster - may be more than 1 with reordering
-            for (int k = nChar2Base; k <= nLastGlyph; k++)
-            {
-                if (mvGlyphs[k].IsClusterStart()) ++nBaseCount;
-            }
-            assert((nLastChar > -1) && (nLastChar < (signed)nChars));
-            long nNewClusterWidth = args.mpDXArray[nLastChar];
-            long nOrigClusterWidth = mvCharDxs[nLastChar];
-            long nDGlyphOrigin = 0;
-            if (nPrevClusterLastChar > - 1)
-            {
-                assert(nPrevClusterLastChar < (signed)nChars);
-                nNewClusterWidth -= args.mpDXArray[nPrevClusterLastChar];
-                nOrigClusterWidth -= mvCharDxs[nPrevClusterLastChar];
-                nDGlyphOrigin = args.mpDXArray[nPrevClusterLastChar] - mvCharDxs[nPrevClusterLastChar];
-            }
-            long nDWidth = nNewClusterWidth - nOrigClusterWidth;
-#ifdef GRLAYOUT_DEBUG
-            fprintf(grLog(), "c%lu last glyph %d/%lu\n", i, nLastGlyph, mvGlyphs.size());
-#endif
-            assert((nLastGlyph > -1) && (nLastGlyph < (signed)mvGlyphs.size()));
-            mvGlyphs[nLastGlyph].mnNewWidth += nDWidth;
-            if (gi.mnGlyphIndex != GF_DROPPED)
-                mvGlyphs[nLastGlyph].mnNewWidth += nDWidth;
-            else
-                nDGlyphOrigin += nDWidth;
-            long nDOriginPerBase = (nBaseCount > 0)? nDWidth / nBaseCount : 0;
-            nBaseCount = -1;
-            // update glyph positions
-            if (bRtl)
-            {
-                for (int n = nChar2Base; n <= nLastGlyph; n++)
-                {
-                    if (mvGlyphs[n].IsClusterStart()) ++nBaseCount;
-                    assert((n > - 1) && (n < (signed)mvGlyphs.size()));
-                    mvGlyphs[n].maLinearPos.X() += -(nDGlyphOrigin + nDOriginPerBase * nBaseCount) + nXOffset;
-                }
-            }
-            else
-            {
-                for (int n = nChar2Base; n <= nLastGlyph; n++)
-                {
-                    if (mvGlyphs[n].IsClusterStart()) ++nBaseCount;
-                    assert((n > - 1) && (n < (signed)mvGlyphs.size()));
-                    mvGlyphs[n].maLinearPos.X() += nDGlyphOrigin + (nDOriginPerBase * nBaseCount) + nXOffset;
-                }
+                else
+                    nBaseGlyph = mvChar2BaseGlyph[thisChar - mnMinCharPos];
             }
-            rDeltaWidth[nChar2Base] = nDWidth;
+            if (thisChar > lastChar) lastChar = thisChar;
+            if (thisChar < firstChar) firstChar = thisChar;
+        }
+
+        // calculate visual cluster widths
+        if (lastChar > args.mnEndCharPos) lastChar = args.mnEndCharPos;
+        if (firstChar < args.mnMinCharPos) firstChar = args.mnMinCharPos;
+        long nOrigClusterWidth = mvCharDxs[lastChar - mnMinCharPos];
+        long nNewClusterWidth = args.mpDXArray[lastChar - args.mnMinCharPos];
+        long nDGlyphOrigin = 0;
+        if (firstChar > args.mnMinCharPos)
+        {
+            //nNewClusterWidth -= args.mpDXArray[firstChar - args.mnMinCharPos];
+            //nOrigClusterWidth -= mvCharDxs[firstChar - mnMinCharPos];
+            nDGlyphOrigin = args.mpDXArray[firstChar - args.mnMinCharPos - 1]
+                                - mvCharDxs[firstChar - mnMinCharPos - 1];
+        }
+
+        // update visual cluster
+        long nDWidth = nNewClusterWidth - nOrigClusterWidth;
+        if (firstChar >= args.mnMinCharPos)
+            for (int n = firstChar; n <= lastChar; ++n)
+                if (n > mnMinCharPos && mvCharDxs[n - mnMinCharPos - 1] != -1)
+                    mvCharDxs[n - mnMinCharPos - 1] += nDGlyphOrigin; // + nDWidth;
+        for (unsigned int n = i; n < nLastGlyph; n++)
+            //mvGlyphs[n].maLinearPos.X() += (nDGlyphOrigin + nDWidth) * (bRtl ? -1 : 1);
+            mvGlyphs[n].maLinearPos.X() += nDGlyphOrigin * (bRtl ? -1 : 1);
+
+        rDeltaWidth[nBaseGlyph] = nDWidth;
 #ifdef GRLAYOUT_DEBUG
-            fprintf(grLog(),"c%d g%d-%d dW%ld-%ld=%ld dX%ld x%ld\t", (int)i, nChar2Base, nLastGlyph, nNewClusterWidth, nOrigClusterWidth, nDWidth, nDGlyphOrigin, mvGlyphs[nChar2Base].maLinearPos.X());
+        fprintf(grLog(),"c%d=%d g%d-%d dW%ld-%ld=%ld dX%ld x%ld @%d=%d\n", firstChar, lastChar, i, nLastGlyph, nNewClusterWidth, nOrigClusterWidth, nDWidth, nDGlyphOrigin, mvGlyphs[i].maLinearPos.X(), mvCharDxs[lastChar - mnMinCharPos], args.mpDXArray[lastChar - args.mnMinCharPos]);
 #endif
-            nPrevClusterGlyph = nChar2Base;
-            nPrevClusterLastChar = nLastChar;
-            i = nLastChar;
-        }
+        i = nLastGlyph - 1;
+        if (i >= endGi - 1)
+            mnWidth += nDGlyphOrigin + nDWidth;
     }
     // Update the dx vector with the new values.
     std::copy(args.mpDXArray, args.mpDXArray + nChars,
       mvCharDxs.begin() + (args.mnMinCharPos - mnMinCharPos));
+    //args.mpDXArray[0] = 0;
 #ifdef GRLAYOUT_DEBUG
     fprintf(grLog(),"ApplyDx %d(%ld)\n", args.mpDXArray[nChars - 1], mnWidth);
 #endif
-    mnWidth = args.mpDXArray[nChars - 1];
+    if (bRtl)
+    {
+        int diff = mvGlyphs[0].maLinearPos.X();
+        for (size_t i = 0; i < mvGlyphs.size(); ++i)
+            mvGlyphs[i].maLinearPos.X() -= diff;
+    }
 }
 
 void GraphiteLayout::kashidaJustify(std::vector<int>& rDeltaWidths, sal_GlyphId nKashidaIndex, int nKashidaWidth)
diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx
index 6fdc5ba6d21d..7b6d1557f54a 100644
--- a/vcl/win/source/gdi/winlayout.cxx
+++ b/vcl/win/source/gdi/winlayout.cxx
@@ -2780,11 +2780,6 @@ GraphiteWinLayout::GraphiteWinLayout(HDC hDC, const ImplWinFontData& rWFD, ImplW
 
 bool GraphiteWinLayout::LayoutText( ImplLayoutArgs & args)
 {
-    if (args.mnMinCharPos >= args.mnEndCharPos)
-    {
-        maImpl.clear();
-        return true;
-    }
     HFONT hUnRotatedFont = 0;
     if (args.mnOrientation)
     {
@@ -2798,15 +2793,7 @@ bool GraphiteWinLayout::LayoutText( ImplLayoutArgs & args)
     }
     WinLayout::AdjustLayout(args);
     maImpl.SetFontScale(WinLayout::mfFontScale);
-    gr_segment * pSegment = maImpl.CreateSegment(args);
-    bool bSucceeded = false;
-    if (pSegment)
-    {
-        // replace the DC on the font within the segment
-        // create glyph vectors
-        bSucceeded = maImpl.LayoutGlyphs(args, pSegment);
-        gr_seg_destroy(pSegment);
-    }
+    bool bSucceeded = maImpl.LayoutText(args);
     if (args.mnOrientation)
     {
         // restore the rotated font
commit 84292bcf40e3078dd0b15a4279ded1c9193084bd
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Jun 19 17:51:18 2013 +0100

    WaE: for higher debugging levels
    
    Change-Id: Ibcf081c0c64381e8c188764f036687a8bfc0ea0e
    (cherry picked from commit bbabdfd84135bf2b8db09a4c1fb1d6f390ea5dba)

diff --git a/vcl/source/gdi/textlayout.cxx b/vcl/source/gdi/textlayout.cxx
index ebac54121f83..7be750d52ee3 100644
--- a/vcl/source/gdi/textlayout.cxx
+++ b/vcl/source/gdi/textlayout.cxx
@@ -188,7 +188,7 @@ namespace vcl
             aTrace.append( " ): " );
             aTrace.append( nTextWidth );
             aTrace.append( " = ( " );
-            for ( size_t i=0; i<_nLength; )
+            for ( sal_Int32 i=0; i<_nLength; )
             {
                 aTrace.append( _pDXAry[i] );
                 if ( ++i < _nLength )
diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx
index 8452221914a8..230583b191af 100644
--- a/vcl/source/glyphs/graphite_layout.cxx
+++ b/vcl/source/glyphs/graphite_layout.cxx
@@ -613,7 +613,7 @@ gr_segment * GraphiteLayout::CreateSegment(ImplLayoutArgs& rArgs)
         if (pSegment != NULL)
         {
 #ifdef GRLAYOUT_DEBUG
-            fprintf(grLog(),"Gr::LayoutText %d-%d, context %d, len %d, numchars %" SAL_PRI_SIZET "u, rtl %d scaling %f:", rArgs.mnMinCharPos,
+            fprintf(grLog(),"Gr::LayoutText %d-%d, context %d, len %d, numchars %d, rtl %d scaling %f:", rArgs.mnMinCharPos,
                rArgs.mnEndCharPos, limit, rArgs.mnLength, numchars, bRtl, mfScaling);
             for (int i = mnSegCharOffset; i < limit; ++i)
                 fprintf(grLog(), " %04X", rArgs.mpStr[i]);
diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx
index 73e5a7a6e800..8485971971f0 100644
--- a/vcl/source/window/winproc.cxx
+++ b/vcl/source/window/winproc.cxx
@@ -51,17 +51,6 @@
 #include <com/sun/star/datatransfer/dnd/XDragSource.hpp>
 #include <com/sun/star/awt/MouseEvent.hpp>
 
-#if OSL_DEBUG_LEVEL > 1
-char dbgbuffer[1024];
-#ifndef WNT
-#include <stdio.h>
-#define MyOutputDebugString(s) (fprintf(stderr, s ))
-#else
-extern void MyOutputDebugString( char *s);
-#endif
-#endif
-
-
 // =======================================================================
 
 #define IMPL_MIN_NEEDSYSWIN         49
diff --git a/vcl/win/source/window/salframe.cxx b/vcl/win/source/window/salframe.cxx
index bc7dc2766628..eaf454447f49 100644
--- a/vcl/win/source/window/salframe.cxx
+++ b/vcl/win/source/window/salframe.cxx
@@ -112,10 +112,6 @@ using namespace ::com::sun::star::beans;
 # define WM_MOUSEHWHEEL 0x020E
 #endif
 
-#if OSL_DEBUG_LEVEL > 1
-void MyOutputDebugString( char *s) { OutputDebugString( s ); }
-#endif
-
 // =======================================================================
 
 const unsigned int WM_USER_SYSTEM_WINDOW_ACTIVATED = RegisterWindowMessageA("SYSTEM_WINDOW_ACTIVATED");
commit 31a6dd821d0d65ae68fbcacb89d6f21bbfeb1484
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Apr 9 16:19:21 2014 +0100

    WaE: -Werror=sign-compare
    
    Change-Id: I160a760a13c8e5140d6df295a9dffd05cf5e7b81
    (cherry picked from commit 75508e5d4292c506d8c68caae5b23f90284416a0)

diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx
index bc9f6ea8efc7..8452221914a8 100644
--- a/vcl/source/glyphs/graphite_layout.cxx
+++ b/vcl/source/glyphs/graphite_layout.cxx
@@ -599,7 +599,7 @@ gr_segment * GraphiteLayout::CreateSegment(ImplLayoutArgs& rArgs)
         static com::sun::star::uno::Reference< com::sun::star::i18n::XCharacterClassification > xCharClass;
         if ( !xCharClass.is() )
             xCharClass = vcl::unohelper::CreateCharacterClassification();
-        int numchars2 = rArgs.mnEndCharPos - mnSegCharOffset; // fdo#52540, fdo#68313, fdo#70666 avoid bad ligature replacement
+        size_t numchars2 = rArgs.mnEndCharPos - mnSegCharOffset; // fdo#52540, fdo#68313, fdo#70666 avoid bad ligature replacement
         if (numchars > numchars2 && xCharClass->getType(rArgs.mpStr, numchars2 + 1) == ::com::sun::star::i18n::UnicodeType::LOWERCASE_LETTER)
             numchars = numchars2;
         if (mpFeatures)
commit 4f66ed6d43b7395fab68dd8b81cf0941819e781d
Author: László Németh <nemeth at numbertext.org>
Date:   Wed Apr 9 12:10:15 2014 +0200

    fdo#70666 avoid only bad Graphite ligature replacement
    
    Change-Id: Ibd42c70edbd8a5ca5eba34bcb92e801c8dc97ba0
    (cherry picked from commit 4a8cf5221f425118a7ec79e0cbf9cb0fb47bf823)

diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx
index c135c6a6187d..bc9f6ea8efc7 100644
--- a/vcl/source/glyphs/graphite_layout.cxx
+++ b/vcl/source/glyphs/graphite_layout.cxx
@@ -594,12 +594,14 @@ gr_segment * GraphiteLayout::CreateSegment(ImplLayoutArgs& rArgs)
             }
         }
 
+        size_t numchars = gr_count_unicode_characters(gr_utf16, rArgs.mpStr + mnSegCharOffset,
+                 rArgs.mpStr + (rArgs.mnLength > limit + 64 ? limit + 64 : rArgs.mnLength), NULL);
         static com::sun::star::uno::Reference< com::sun::star::i18n::XCharacterClassification > xCharClass;
         if ( !xCharClass.is() )
             xCharClass = vcl::unohelper::CreateCharacterClassification();
-        int numchars = rArgs.mnEndCharPos - mnSegCharOffset; // fdo#52540, fdo#68313, fdo#70666 avoid bad ligature replacement
-        if (xCharClass->getType(rArgs.mpStr, numchars + 1) != ::com::sun::star::i18n::UnicodeType::LOWERCASE_LETTER)
-            numchars += 64;
+        int numchars2 = rArgs.mnEndCharPos - mnSegCharOffset; // fdo#52540, fdo#68313, fdo#70666 avoid bad ligature replacement
+        if (numchars > numchars2 && xCharClass->getType(rArgs.mpStr, numchars2 + 1) == ::com::sun::star::i18n::UnicodeType::LOWERCASE_LETTER)
+            numchars = numchars2;
         if (mpFeatures)
             pSegment = gr_make_seg(mpFont, mpFace, 0, mpFeatures->values(), gr_utf16,
                                         rArgs.mpStr + mnSegCharOffset, numchars, bRtl);
commit e03a7262bd7a9ff2af9f0edc8e0526cdd0aca530
Author: László Németh <nemeth at numbertext.org>
Date:   Tue Feb 4 19:10:44 2014 +0100

    fdo#70666 fix Graphite ligature replacement at line breaks
    
    Change-Id: I5b7c149f7f419ba18bd2cc59f4e77a0b61280caa
    (cherry picked from commit a831930986166a8c5cb231821426f5cf4d976df2)

diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx
index 581768105e27..c135c6a6187d 100644
--- a/vcl/source/glyphs/graphite_layout.cxx
+++ b/vcl/source/glyphs/graphite_layout.cxx
@@ -48,6 +48,10 @@
 #include <unicode/ubidi.h>
 #include <unicode/uscript.h>
 
+#include <vcl/unohelp.hxx>
+#include <com/sun/star/i18n/XCharacterClassification.hpp>
+#include <com/sun/star/i18n/UnicodeType.hpp>
+
 // Graphite Libraries (must be after vcl headers on windows)
 #include <graphite2/Segment.h>
 
@@ -589,9 +593,13 @@ gr_segment * GraphiteLayout::CreateSegment(ImplLayoutArgs& rArgs)
                     nSegCharLimit - rArgs.mnEndCharPos, bRtl);
             }
         }
-//        int numchars = gr_count_unicode_characters(gr_utf16, rArgs.mpStr + mnSegCharOffset,
-//                rArgs.mpStr + (rArgs.mnLength > limit + 64 ? limit + 64 : rArgs.mnLength), NULL);
-          int numchars = rArgs.mnEndCharPos - mnSegCharOffset; // fdo#52540, fdo#68313, FIXME
+
+        static com::sun::star::uno::Reference< com::sun::star::i18n::XCharacterClassification > xCharClass;
+        if ( !xCharClass.is() )
+            xCharClass = vcl::unohelper::CreateCharacterClassification();
+        int numchars = rArgs.mnEndCharPos - mnSegCharOffset; // fdo#52540, fdo#68313, fdo#70666 avoid bad ligature replacement
+        if (xCharClass->getType(rArgs.mpStr, numchars + 1) != ::com::sun::star::i18n::UnicodeType::LOWERCASE_LETTER)
+            numchars += 64;
         if (mpFeatures)
             pSegment = gr_make_seg(mpFont, mpFace, 0, mpFeatures->values(), gr_utf16,
                                         rArgs.mpStr + mnSegCharOffset, numchars, bRtl);
commit 37bbd293fee3d2466efc9878f2e33846344939a4
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu Jul 12 16:34:44 2018 +0200

    break indent here to sync
    
    Change-Id: I44ba850fb698709f6c71018c9e34a7d60cb9f065

diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx
index a9cb7cc4e21b..581768105e27 100644
--- a/vcl/source/glyphs/graphite_layout.cxx
+++ b/vcl/source/glyphs/graphite_layout.cxx
@@ -591,7 +591,7 @@ gr_segment * GraphiteLayout::CreateSegment(ImplLayoutArgs& rArgs)
         }
 //        int numchars = gr_count_unicode_characters(gr_utf16, rArgs.mpStr + mnSegCharOffset,
 //                rArgs.mpStr + (rArgs.mnLength > limit + 64 ? limit + 64 : rArgs.mnLength), NULL);
-        int numchars = rArgs.mnEndCharPos - mnSegCharOffset; // fdo#52540, fdo#68313, FIXME
+          int numchars = rArgs.mnEndCharPos - mnSegCharOffset; // fdo#52540, fdo#68313, FIXME
         if (mpFeatures)
             pSegment = gr_make_seg(mpFont, mpFace, 0, mpFeatures->values(), gr_utf16,
                                         rArgs.mpStr + mnSegCharOffset, numchars, bRtl);
commit 28672586081a72480915a285ed2dba09cc1ca72e
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu Jul 12 16:21:37 2018 +0200

    Revert "Fix some round() confusion"
    
    This reverts commit 3aa051f9c94b7bc0311c51a063f43322a9f6f772.
    
    Temporary revert because it conflicts with the horrible graphite upgrade
    patch.
    
    Change-Id: I8bbaccc27a6a01b397d5f3d085f5dcfb998b64e7

diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx
index 76d70468c107..a9cb7cc4e21b 100644
--- a/vcl/source/glyphs/graphite_layout.cxx
+++ b/vcl/source/glyphs/graphite_layout.cxx
@@ -40,8 +40,6 @@
 #include <deque>
 
 // Platform
-#include <config_global.h>
-
 #include <svsys.h>
 
 #include <salgdi.hxx>
@@ -84,7 +82,7 @@ static FILE * grLog()
 
 namespace
 {
-    inline long round_to_long(const float n) {
+    inline long round(const float n) {
         return long(n + (n < 0 ? -0.5 : 0.5));
     }
 
@@ -352,8 +350,8 @@ GraphiteLayout::fillFrom(gr_segment * pSegment, ImplLayoutArgs &rArgs, float fSc
             baseSlot = gr_slot_next_sibling_attachment(baseSlot);
         }
     }
-    long nXOffset = round_to_long(fMinX * fScaling);
-    mnWidth = round_to_long(fMaxX * fScaling) - nXOffset + nDxOffset;
+    long nXOffset = round(fMinX * fScaling);
+    mnWidth = round(fMaxX * fScaling) - nXOffset + nDxOffset;
     if (mnWidth < 0)
     {
         // This can happen when there was no base inside the range
@@ -424,8 +422,8 @@ GraphiteLayout::append(gr_segment *pSeg, ImplLayoutArgs &rArgs,
         nextOrigin = nextGlyphOrigin;
     long glyphId = gr_slot_gid(gi);
     long deltaOffset = 0;
-    int scaledGlyphPos = round_to_long(gr_slot_origin_X(gi) * scaling);
-    int glyphWidth = round_to_long((nextOrigin - gOrigin) * scaling);
+    int scaledGlyphPos = round(gr_slot_origin_X(gi) * scaling);
+    int glyphWidth = round((nextOrigin - gOrigin) * scaling);
 //    if (glyphWidth < 0)
 //    {
 //        nextOrigin = gOrigin;
@@ -467,11 +465,11 @@ GraphiteLayout::append(gr_segment *pSeg, ImplLayoutArgs &rArgs,
     GlyphItem aGlyphItem(mvGlyphs.size(),
         glyphId,
         Point(scaledGlyphPos + rDXOffset,
-            round_to_long((-gr_slot_origin_Y(gi) * scaling))),
+            round((-gr_slot_origin_Y(gi) * scaling))),
         nGlyphFlags,
         glyphWidth);
     if (glyphId != static_cast<long>(GF_DROPPED))
-        aGlyphItem.mnOrigWidth = round_to_long(gr_slot_advance_X(gi, mpFace, mpFont) * scaling);
+        aGlyphItem.mnOrigWidth = round(gr_slot_advance_X(gi, mpFace, mpFont) * scaling);
     mvGlyphs.push_back(aGlyphItem);
 
     // update the offset if this glyph was dropped
commit cb38eb4274908e8569bdf7b97fa51c94d1b08b24
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Sat Jun 22 11:25:19 2013 +0200

    Fix indentation
    
    Change-Id: Iece106040fb7c0962d7f918151bff8c4488704a3
    (cherry picked from commit d6fd801c62e41c1fb229cbe97c0ef767705de304)

diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index ed550024d07a..f7a5b155057d 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -7779,7 +7779,7 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const String& rText, bool bT
                     // TODO: sanitize for RTL ligatures, more complex CTL, etc.
                     if( nChars < 0 )
                         nChars = -nChars;
-            else if( nChars == 0 )
+                    else if( nChars == 0 )
                         nChars = 1;
                     pUnicodesPerGlyph[i] = nChars;
                     for( int n = 1; n < nChars; n++ )
commit f58dd929c04267a4ce4d7c76a25931e950a7fe30
Author: David Ostrovsky <david at ostrovsky.org>
Date:   Tue Feb 3 14:58:11 2015 +0100

    Fix graphite on windows 64 bit
    
    Reviewed-on: https://gerrit.libreoffice.org/14316
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    (cherry picked from commit 2bb5d4c840f95e5a3dd81122af479a9625db6dfc)
    
    Change-Id: I509fcf9194d3cc0d4454e31a9f7dfbb7f22c421c

diff --git a/graphite/UnpackedTarball_graphite.mk b/graphite/UnpackedTarball_graphite.mk
index a62cb545ad45..85ebde52a9f6 100644
--- a/graphite/UnpackedTarball_graphite.mk
+++ b/graphite/UnpackedTarball_graphite.mk
@@ -14,6 +14,7 @@ $(eval $(call gb_UnpackedTarball_set_tarball,graphite,$(GRAPHITE_TARBALL)))
 # http://projects.palaso.org/issues/1115
 $(eval $(call gb_UnpackedTarball_add_patches,graphite,\
 	graphite/graphite2.issue1115.patch.1 \
+    graphite/graphite2.win64.patch.1 \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/graphite/graphite2.win64.patch.1 b/graphite/graphite2.win64.patch.1
new file mode 100644
index 000000000000..6bf8c88907d1
--- /dev/null
+++ b/graphite/graphite2.win64.patch.1
@@ -0,0 +1,47 @@
+diff -ur graphite.org/src/inc/json.h graphite/src/inc/json.h
+--- graphite.org/src/inc/json.h	2015-02-03 14:49:24.408101900 +0100
++++ graphite/src/inc/json.h	2015-02-03 14:50:59.697552200 +0100
+@@ -78,6 +78,9 @@
+     json & operator << (string) throw();
+     json & operator << (number) throw();
+     json & operator << (integer) throw();
++#ifdef _WIN64
++    json & operator << (size_t) throw();
++#endif
+     json & operator << (long unsigned int d) throw();
+     json & operator << (boolean) throw();
+     json & operator << (_null_t) throw();
+diff -ur graphite.org/src/json.cpp graphite/src/json.cpp
+--- graphite.org/src/json.cpp	2015-02-03 14:49:24.409102000 +0100
++++ graphite/src/json.cpp	2015-02-03 14:50:49.814986900 +0100
+@@ -119,6 +119,9 @@
+ json & json::operator << (json::number f) throw()   { context(seq); fprintf(_stream, "%g", f); return *this; }
+ json & json::operator << (json::integer d) throw()  { context(seq); fprintf(_stream, "%ld", d); return *this; }
+ json & json::operator << (long unsigned d) throw()  { context(seq); fprintf(_stream, "%ld", d); return *this; }
++#ifdef _WIN64
++json & json::operator << (size_t d) throw()         { context(seq); fprintf(_stream, "%ld", d); return *this; }
++#endif
+ json & json::operator << (json::boolean b) throw()  { context(seq); fputs(b ? "true" : "false", _stream); return *this; }
+ json & json::operator << (json::_null_t) throw()    { context(seq); fputs("null",_stream); return *this; }
+ 
+diff -ur graphite.org/src/Pass.cpp graphite/src/Pass.cpp
+--- graphite.org/src/Pass.cpp	2015-02-03 14:49:24.413102200 +0100
++++ graphite/src/Pass.cpp	2015-02-03 14:50:37.873303900 +0100
+@@ -466,7 +466,7 @@
+     {
+         if (r->rule->preContext > fsm.slots.context())  continue;
+     *fsm.dbgout << json::flat << json::object
+-                    << "id"     << r->rule - m_rules
++                    << "id"     << static_cast<size_t>(r->rule - m_rules)
+                     << "failed" << true
+                     << "input" << json::flat << json::object
+                         << "start" << objectid(dslot(&fsm.slots.segment, input_slot(fsm.slots, -r->rule->preContext)))
+@@ -480,7 +480,7 @@
+ void Pass::dumpRuleEventOutput(const FiniteStateMachine & fsm, const Rule & r, Slot * const last_slot) const
+ {

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list