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 <[email protected]> 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 <[email protected]> Date: Thu Jun 15 16:02:48 2017 +0200 upload graphite 1.3.10 Reviewed-on: https://gerrit.libreoffice.org/38837 Tested-by: Jenkins <[email protected]> Reviewed-by: Michael Stahl <[email protected]> also includes patch edit from: new release of Graphite lib: 1.3.9 Reviewed-on: https://gerrit.libreoffice.org/30771 Tested-by: Jenkins <[email protected]> Reviewed-by: Andras Timar <[email protected]> (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 <[email protected]> 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 <[email protected]> Reviewed-by: Martin Hosken <[email protected]> (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 <[email protected]> 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 <[email protected]> Tested-by: Michael Stahl <[email protected]> (cherry picked from commit 817192b3f55be0b0a4a6e877a3c1ab95d3a4b4cb) Reviewed-on: https://gerrit.libreoffice.org/22845 Tested-by: Christian Lohmaier <[email protected]> Tested-by: Jenkins <[email protected]> Reviewed-by: Christian Lohmaier <[email protected]> (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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> Tested-by: Miklos Vajna <[email protected]> (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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> Reviewed-by: Michael Stahl <[email protected]> (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 _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
