[Libreoffice-commits] core.git: Branch 'feature/cib_contract57c' - 3 commits - basegfx/source external/breakpad external/libgpg-error vcl/qa vcl/source

nd101 (via logerrit) logerrit at kemper.freedesktop.org
Wed Mar 4 18:20:34 UTC 2020


Rebased ref, commits from common ancestor:
commit 3dfac413bf484bad334215ccf7287aca9be8563f
Author:     nd101 <Fong at nd.com.cn>
AuthorDate: Wed Jul 3 09:41:06 2019 +0800
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Mar 4 19:19:05 2020 +0100

    Fix libgpg-error compilation error with gawk5
    
    This is an adaptation of upstream patch
    https://github.com/gpg/libgpg-error/commit/7865041c77f4f7005282f10f9b6666b19072fbdf
    plus a fix to Makefile.in
    
    Change-Id: I5bf946cf93e5849b8a3428064ab86f6255be97da
    Reviewed-on: https://gerrit.libreoffice.org/75022
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    Tested-by: Mike Kaganski <mike.kaganski at collabora.com>
    (cherry picked from commit af3b993ebea2f653fabba981d4c22b9aa779b32a)
    Reviewed-on: https://gerrit.libreoffice.org/75075
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <Michael.Stahl at cib.de>
    (cherry picked from commit 87215115618de0c12d287a300fc5fde993886089)
    Reviewed-on: https://gerrit.libreoffice.org/76308
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    (cherry picked from commit 7aea534459b293d3553b7bdf0a89b8fbc6c6e0da)

diff --git a/external/libgpg-error/UnpackedTarball_libgpg-error.mk b/external/libgpg-error/UnpackedTarball_libgpg-error.mk
index ad2145a96aa7..ea99c3c3c076 100644
--- a/external/libgpg-error/UnpackedTarball_libgpg-error.mk
+++ b/external/libgpg-error/UnpackedTarball_libgpg-error.mk
@@ -14,6 +14,7 @@ $(eval $(call gb_UnpackedTarball_set_tarball,libgpg-error,$(LIBGPGERROR_TARBALL)
 $(eval $(call gb_UnpackedTarball_set_patchlevel,libgpg-error,0))
 
 $(eval $(call gb_UnpackedTarball_add_patches,libgpg-error, \
+	external/libgpg-error/libgpg-error_gawk5.patch \
 	$(if $(filter MSC,$(COM)),external/libgpg-error/w32-build-fixes.patch) \
 	$(if $(filter MSC,$(COM)),external/libgpg-error/w32-build-fixes-2.patch.1) \
 	$(if $(filter MSC,$(COM)),external/libgpg-error/w32-build-fixes-3.patch.1) \
diff --git a/external/libgpg-error/libgpg-error_gawk5.patch b/external/libgpg-error/libgpg-error_gawk5.patch
new file mode 100644
index 000000000000..3be76a4538a8
--- /dev/null
+++ b/external/libgpg-error/libgpg-error_gawk5.patch
@@ -0,0 +1,114 @@
+--- src/Makefile.am
++++ src/Makefile.am~
+@@ -266,7 +266,7 @@
+ 
+ errnos-sym.h: Makefile mkstrtable.awk errnos.in
+ 	$(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=2 -v nogettext=1 \
+-		-v prefix=GPG_ERR_ -v namespace=errnos_ \
++		-v prefix=GPG_ERR_ -v pkg_namespace=errnos_ \
+ 		$(srcdir)/errnos.in >$@
+ 
+ 
+--- src/mkerrcodes.awk
++++ src/mkerrcodes.awk~
+@@ -81,7 +81,7 @@
+ }
+ 
+ !header {
+-  sub (/\#.+/, "");
++  sub (/#.+/, "");
+   sub (/[ 	]+$/, ""); # Strip trailing space and tab characters.
+ 
+   if (/^$/)
+--- src/mkerrcodes1.awk
++++ src/mkerrcodes1.awk~
+@@ -81,7 +81,7 @@
+ }
+ 
+ !header {
+-  sub (/\#.+/, "");
++  sub (/#.+/, "");
+   sub (/[ 	]+$/, ""); # Strip trailing space and tab characters.
+ 
+   if (/^$/)
+--- src/mkerrcodes2.awk
++++ src/mkerrcodes2.awk~
+@@ -91,7 +91,7 @@
+ }
+ 
+ !header {
+-  sub (/\#.+/, "");
++  sub (/#.+/, "");
+   sub (/[ 	]+$/, ""); # Strip trailing space and tab characters.
+ 
+   if (/^$/)
+--- src/mkerrnos.awk
++++ src/mkerrnos.awk~
+@@ -83,7 +83,7 @@
+ }
+ 
+ !header {
+-  sub (/\#.+/, "");
++  sub (/#.+/, "");
+   sub (/[ 	]+$/, ""); # Strip trailing space and tab characters.
+ 
+   if (/^$/)
+--- src/mkstrtable.awk
++++ src/mkstrtable.awk~
+@@ -77,7 +77,7 @@
+ #
+ # The variable prefix can be used to prepend a string to each message.
+ #
+-# The variable namespace can be used to prepend a string to each
++# The variable pkg_namespace can be used to prepend a string to each
+ # variable and macro name.
+ 
+ BEGIN {
+@@ -102,7 +102,7 @@
+       print "/* The purpose of this complex string table is to produce";
+       print "   optimal code with a minimum of relocations.  */";
+       print "";
+-      print "static const char " namespace "msgstr[] = ";
++      print "static const char " pkg_namespace "msgstr[] = ";
+       header = 0;
+     }
+   else
+@@ -110,7 +110,7 @@
+ }
+ 
+ !header {
+-  sub (/\#.+/, "");
++  sub (/#.+/, "");
+   sub (/[ 	]+$/, ""); # Strip trailing space and tab characters.
+ 
+   if (/^$/)
+@@ -150,7 +150,7 @@
+   else
+     print "  gettext_noop (\"" last_msgstr "\");";
+   print "";
+-  print "static const int " namespace "msgidx[] =";
++  print "static const int " pkg_namespace "msgidx[] =";
+   print "  {";
+   for (i = 0; i < coded_msgs; i++)
+     print "    " pos[i] ",";
+@@ -158,7 +158,7 @@
+   print "  };";
+   print "";
+   print "static GPG_ERR_INLINE int";
+-  print namespace "msgidxof (int code)";
++  print pkg_namespace "msgidxof (int code)";
+   print "{";
+   print "  return (0 ? 0";
+ 
+--- src/Makefile.in
++++ src/Makefile.in~
+@@ -1321,7 +1321,7 @@
+ 
+ errnos-sym.h: Makefile mkstrtable.awk errnos.in
+ 	$(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=2 -v nogettext=1 \
+-		-v prefix=GPG_ERR_ -v namespace=errnos_ \
++		-v prefix=GPG_ERR_ -v pkg_namespace=errnos_ \
+ 		$(srcdir)/errnos.in >$@
+ 
+ mkheader: mkheader.c Makefile
+ 
diff --git a/external/libgpg-error/w32-build-fixes.patch b/external/libgpg-error/w32-build-fixes.patch
index e8a6b6145d46..96a62e32042c 100644
--- a/external/libgpg-error/w32-build-fixes.patch
+++ b/external/libgpg-error/w32-build-fixes.patch
@@ -136,7 +136,7 @@ diff -ru libgpg-error.orig/src/Makefile.in libgpg-error/src/Makefile.in
  
  errnos-sym.h: Makefile mkstrtable.awk errnos.in
 @@ -1325,7 +1325,7 @@
- 		-v prefix=GPG_ERR_ -v namespace=errnos_ \
+ 		-v prefix=GPG_ERR_ -v pkg_namespace=errnos_ \
  		$(srcdir)/errnos.in >$@
  
 -mkheader: mkheader.c Makefile
commit 1a0d2fb7ee7da66c5202922d901c702071fff340
Author:     Stephan Bergmann <sbergman at redhat.com>
AuthorDate: Thu Sep 26 22:09:56 2019 +0200
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Mar 4 19:19:05 2020 +0100

    external/breakpad: glibc 2.30 declares tgkill
    
    ...so building against glibc-headers-2.30-4.fc31.x86_64 fails with
    
    > src/client/linux/handler/exception_handler.cc:109:12: error: static declaration of 'tgkill' follows non-static declaration
    > static int tgkill(pid_t tgid, pid_t tid, int sig) {
    >            ^
    > /usr/include/bits/signal_ext.h:29:12: note: previous declaration is here
    > extern int tgkill (__pid_t __tgid, __pid_t __tid, int __signal);
    >            ^
    > 1 error generated.
    
    Upstream commit <https://chromium.googlesource.com/breakpad/breakpad/+/
    7e3c165000d44fa153a3270870ed500bc8bbb461%5E%21/> "Fix double declaration of
    tgkill when using Android NDK Headers" looks like the perfect fit.
    
    Reviewed-on: https://gerrit.libreoffice.org/79661
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sbergman at redhat.com>
    
    Conflicts:
            external/breakpad/UnpackedTarball_breakpad.mk
    
    Change-Id: I1b4805886fb7c770cf9733f34a31296e6b859d92

diff --git a/external/breakpad/0001-Fix-double-declaration-of-tgkill-when-using-Android-.patch.1 b/external/breakpad/0001-Fix-double-declaration-of-tgkill-when-using-Android-.patch.1
new file mode 100644
index 000000000000..7c8a68c2451a
--- /dev/null
+++ b/external/breakpad/0001-Fix-double-declaration-of-tgkill-when-using-Android-.patch.1
@@ -0,0 +1,49 @@
+From 7e3c165000d44fa153a3270870ed500bc8bbb461 Mon Sep 17 00:00:00 2001
+From: Nicholas Baldwin <baldwinn at google.com>
+Date: Fri, 27 Oct 2017 11:44:36 -0700
+Subject: [PATCH] Fix double declaration of tgkill when using Android NDK
+ Headers.
+
+As of Android API level 16 tgkill is declared in the NDK version of
+signal.h, which conflicts with the static definition found in
+src/client/linux/handler/exception_handler.cc. This change removes
+the static tgkill definition and replaces its use with sys_tgkill
+from the linux syscall support library.
+
+Bug:
+Change-Id: Ic70addd8a064cfa36345d86b7e36409e2089e909
+Reviewed-on: https://chromium-review.googlesource.com/738912
+Reviewed-by: Mike Frysinger <vapier at chromium.org>
+---
+ src/client/linux/handler/exception_handler.cc | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc
+index 95005209..cd94e3b5 100644
+--- a/src/client/linux/handler/exception_handler.cc
++++ b/src/client/linux/handler/exception_handler.cc
+@@ -105,12 +105,6 @@
+ #define PR_SET_PTRACER 0x59616d61
+ #endif
+ 
+-// A wrapper for the tgkill syscall: send a signal to a specific thread.
+-static int tgkill(pid_t tgid, pid_t tid, int sig) {
+-  return syscall(__NR_tgkill, tgid, tid, sig);
+-  return 0;
+-}
+-
+ namespace google_breakpad {
+ 
+ namespace {
+@@ -400,7 +394,7 @@ void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) {
+     // In order to retrigger it, we have to queue a new signal by calling
+     // kill() ourselves.  The special case (si_pid == 0 && sig == SIGABRT) is
+     // due to the kernel sending a SIGABRT from a user request via SysRQ.
+-    if (tgkill(getpid(), syscall(__NR_gettid), sig) < 0) {
++    if (sys_tgkill(getpid(), syscall(__NR_gettid), sig) < 0) {
+       // If we failed to kill ourselves (e.g. because a sandbox disallows us
+       // to do so), we instead resort to terminating our process. This will
+       // result in an incorrect exit code.
+-- 
+2.23.0
+
diff --git a/external/breakpad/UnpackedTarball_breakpad.mk b/external/breakpad/UnpackedTarball_breakpad.mk
index e970bd5ad3f3..b4e778482c12 100644
--- a/external/breakpad/UnpackedTarball_breakpad.mk
+++ b/external/breakpad/UnpackedTarball_breakpad.mk
@@ -19,6 +19,7 @@ $(eval $(call gb_UnpackedTarball_add_patches,breakpad,\
 	external/breakpad/breakpad-wshadow2.patch.1 \
 	external/breakpad/breakpad-stackwalk.patch.1 \
 	external/breakpad/ucontext.patch \
+	external/breakpad/0001-Fix-double-declaration-of-tgkill-when-using-Android-.patch.1 \
 ))
 
 ifeq ($(COM_IS_CLANG),TRUE)
commit 05b7e773e4c0d1a210ebb19b8f0da07a026c6417
Author:     Armin.Le.Grand (CIB) <Armin.Le.Grand at me.com>
AuthorDate: Tue Mar 3 11:34:45 2020 +0100
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Mar 4 19:19:05 2020 +0100

    tdf#130150 Improve clipping in PDF export
    
    For more info and discusson please have a look
    at the task. It reverts the change from tdf#99680
    which did a wrong paradigm change in how clip in
    Region(s) is defined and tries to fix the
    underlying error in a more correct way.
    This includes problems noted in tdf#44388 and
    tdf#113449.
    This is a decent improvement, but - due to dealing
    with numerical problems - not yet the whole healing.
    Still thinking about how to solve this for good.
    Adapted PdfExportTest::testTdf99680() and
    PdfExportTest::testTdf99680_2() as needed, empty
    clip regions are allowed again. Added comments, too.
    Had to change solvePolygonOperationAnd to work
    on ranges if both inputs *are* ranges. The AND-case
    is then completely solvable. Also increased geometry
    for transformations of clip geometries - may help
    later.
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89874
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    
    Conflicts:
            vcl/source/gdi/pdfwriter_impl.cxx
    
    Change-Id: I2370447597faa6efb81d58ee31c63654e304262e

diff --git a/basegfx/source/polygon/b2dpolygontools.cxx b/basegfx/source/polygon/b2dpolygontools.cxx
index db3365eee313..766a7cd4d361 100644
--- a/basegfx/source/polygon/b2dpolygontools.cxx
+++ b/basegfx/source/polygon/b2dpolygontools.cxx
@@ -343,15 +343,15 @@ namespace basegfx
                         const B2DPoint aPreviousPoint(aCurrentPoint);
                         aCurrentPoint = aCandidate.getB2DPoint(a);
 
-                        // cross-over in Y?
-                        const bool bCompYA(fTools::more(aPreviousPoint.getY(), rPoint.getY()));
-                        const bool bCompYB(fTools::more(aCurrentPoint.getY(), rPoint.getY()));
+                        // cross-over in Y? tdf#130150 use full precision, no need for epsilon
+                        const bool bCompYA(aPreviousPoint.getY() > rPoint.getY());
+                        const bool bCompYB(aCurrentPoint.getY() > rPoint.getY());
 
                         if(bCompYA != bCompYB)
                         {
-                            // cross-over in X?
-                            const bool bCompXA(fTools::more(aPreviousPoint.getX(), rPoint.getX()));
-                            const bool bCompXB(fTools::more(aCurrentPoint.getX(), rPoint.getX()));
+                            // cross-over in X? tdf#130150 use full precision, no need for epsilon
+                            const bool bCompXA(aPreviousPoint.getX() > rPoint.getX());
+                            const bool bCompXB(aCurrentPoint.getX() > rPoint.getX());
 
                             if(bCompXA == bCompXB)
                             {
@@ -367,7 +367,8 @@ namespace basegfx
                                     (aPreviousPoint.getX() - aCurrentPoint.getX()) /
                                     (aPreviousPoint.getY() - aCurrentPoint.getY()));
 
-                                if(fTools::more(fCompare, rPoint.getX()))
+                                // tdf#130150 use full precision, no need for epsilon
+                                if(fCompare > rPoint.getX())
                                 {
                                     bRetval = !bRetval;
                                 }
diff --git a/basegfx/source/polygon/b2dpolypolygoncutter.cxx b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
index 4fd7bf369d85..1d2b3efb7363 100644
--- a/basegfx/source/polygon/b2dpolypolygoncutter.cxx
+++ b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
@@ -986,6 +986,42 @@ namespace basegfx
             }
             else
             {
+                // tdf#130150 shortcut & precision: If both are simple ranges,
+                // solve based on ranges
+                if(basegfx::utils::isRectangle(rCandidateA) && basegfx::utils::isRectangle(rCandidateB))
+                {
+                    // *if* both are ranges, AND always can be solved
+                    const basegfx::B2DRange aRangeA(rCandidateA.getB2DRange());
+                    const basegfx::B2DRange aRangeB(rCandidateB.getB2DRange());
+
+                    if(aRangeA.isInside(aRangeB))
+                    {
+                        // 2nd completely inside 1st -> 2nd is result of AND
+                        return rCandidateB;
+                    }
+
+                    if(aRangeB.isInside(aRangeA))
+                    {
+                        // 2nd completely inside 1st -> 2nd is result of AND
+                        return rCandidateA;
+                    }
+
+                    // solve by intersection
+                    basegfx::B2DRange aIntersect(aRangeA);
+                    aIntersect.intersect(aRangeB);
+
+                    if(aIntersect.isEmpty())
+                    {
+                        // no overlap -> empty polygon as result of AND
+                        return B2DPolyPolygon();
+                    }
+
+                    // create polygon result
+                    return B2DPolyPolygon(
+                        basegfx::utils::createPolygonFromRect(
+                            aIntersect));
+                }
+
                 // concatenate polygons, solve crossovers and throw away all sub-polygons
                 // with a depth of < 1. This means to keep all polygons where at least two
                 // polygons do overlap.
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index 5c4b4a8c7141..57c6e8b1445c 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -714,15 +714,17 @@ void PdfExportTest::testTdf99680()
     aZCodec.Decompress(rObjectStream, aUncompressed);
     CPPUNIT_ASSERT(aZCodec.EndCompression());
 
-    // Make sure there are no empty clipping regions.
-    OString aEmptyRegion("0 0 m h W* n");
-    auto pStart = static_cast<const char*>(aUncompressed.GetData());
-    const char* pEnd = pStart + aUncompressed.GetSize();
-    auto it = std::search(pStart, pEnd, aEmptyRegion.getStr(), aEmptyRegion.getStr() + aEmptyRegion.getLength());
-    CPPUNIT_ASSERT_EQUAL_MESSAGE("Empty clipping region detected!", it, pEnd);
+    // tdf#130150 See infos in task - short: tdf#99680 was not the
+    // correct fix, so empty clip regions are valid - allow again in tests
+    //      Make sure there are no empty clipping regions.
+    //      OString aEmptyRegion("0 0 m h W* n");
+    //      auto it = std::search(pStart, pEnd, aEmptyRegion.getStr(), aEmptyRegion.getStr() + aEmptyRegion.getLength());
+    //      CPPUNIT_ASSERT_EQUAL_MESSAGE("Empty clipping region detected!", it, pEnd);
 
     // Count save graphic state (q) and restore (Q) operators
     // and ensure their amount is equal
+    auto pStart = static_cast<const char*>(aUncompressed.GetData());
+    const char* pEnd = pStart + aUncompressed.GetSize();
     size_t nSaveCount = std::count(pStart, pEnd, 'q');
     size_t nRestoreCount = std::count(pStart, pEnd, 'Q');
     CPPUNIT_ASSERT_EQUAL_MESSAGE("Save/restore graphic state operators count mismatch!", nSaveCount, nRestoreCount);
@@ -753,15 +755,17 @@ void PdfExportTest::testTdf99680_2()
         aZCodec.Decompress(rObjectStream, aUncompressed);
         CPPUNIT_ASSERT(aZCodec.EndCompression());
 
-        // Make sure there are no empty clipping regions.
-        OString aEmptyRegion("0 0 m h W* n");
-        auto pStart = static_cast<const char*>(aUncompressed.GetData());
-        const char* pEnd = pStart + aUncompressed.GetSize();
-        auto it = std::search(pStart, pEnd, aEmptyRegion.getStr(), aEmptyRegion.getStr() + aEmptyRegion.getLength());
-        CPPUNIT_ASSERT_EQUAL_MESSAGE("Empty clipping region detected!", it, pEnd);
+        // tdf#130150 See infos in task - short: tdf#99680 was not the
+        // correct fix, so empty clip regions are valid - allow again in tests
+        //      Make sure there are no empty clipping regions.
+        //      OString aEmptyRegion("0 0 m h W* n");
+        //      auto it = std::search(pStart, pEnd, aEmptyRegion.getStr(), aEmptyRegion.getStr() + aEmptyRegion.getLength());
+        //      CPPUNIT_ASSERT_EQUAL_MESSAGE("Empty clipping region detected!", it, pEnd);
 
         // Count save graphic state (q) and restore (Q) operators
         // and ensure their amount is equal
+        auto pStart = static_cast<const char*>(aUncompressed.GetData());
+        const char* pEnd = pStart + aUncompressed.GetSize();
         size_t nSaveCount = std::count(pStart, pEnd, 'q');
         size_t nRestoreCount = std::count(pStart, pEnd, 'Q');
         CPPUNIT_ASSERT_EQUAL_MESSAGE("Save/restore graphic state operators count mismatch!", nSaveCount, nRestoreCount);
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index a14f64d54ed5..3e538cc2fec7 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -10318,8 +10318,15 @@ void PDFWriterImpl::updateGraphicsState(Mode const mode)
                 if ( rNewState.m_aClipRegion.count() )
                 {
                     m_aPages.back().appendPolyPolygon( rNewState.m_aClipRegion, aLine );
-                    aLine.append( "W* n\n" );
                 }
+                else
+                {
+                    // tdf#130150 Need to revert tdf#99680, that breaks the
+                    // rule that an set but empty clip-region clips everything
+                    // aka draws nothing -> nothing is in an empty clip-region
+                    aLine.append( "0 0 m h " ); // NULL clip, i.e. nothing visible
+                }
+                aLine.append( "W* n\n" );
 
                 rNewState.m_aMapMode = aNewMapMode;
                 getReferenceDevice()->SetMapMode( rNewState.m_aMapMode );
@@ -10465,8 +10472,13 @@ void PDFWriterImpl::setMapMode( const MapMode& rMapMode )
 
 void PDFWriterImpl::setClipRegion( const basegfx::B2DPolyPolygon& rRegion )
 {
-    basegfx::B2DPolyPolygon aRegion = getReferenceDevice()->LogicToPixel( rRegion, m_aGraphicsStack.front().m_aMapMode );
-    aRegion = getReferenceDevice()->PixelToLogic( aRegion, m_aMapMode );
+    // tdf#130150 improve coordinate manipulations to double precision transformations
+    const basegfx::B2DHomMatrix aCurrentTransform(
+        getReferenceDevice()->GetInverseViewTransformation(m_aMapMode) *
+        getReferenceDevice()->GetViewTransformation(m_aGraphicsStack.front().m_aMapMode));
+    basegfx::B2DPolyPolygon aRegion(rRegion);
+
+    aRegion.transform(aCurrentTransform);
     m_aGraphicsStack.front().m_aClipRegion = aRegion;
     m_aGraphicsStack.front().m_bClipRegion = true;
     m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsStateUpdateFlags::ClipRegion;
@@ -10476,16 +10488,26 @@ void PDFWriterImpl::moveClipRegion( sal_Int32 nX, sal_Int32 nY )
 {
     if( m_aGraphicsStack.front().m_bClipRegion && m_aGraphicsStack.front().m_aClipRegion.count() )
     {
-        Point aPoint( lcl_convert( m_aGraphicsStack.front().m_aMapMode,
-                                   m_aMapMode,
-                                   getReferenceDevice(),
-                                   Point( nX, nY ) ) );
-        aPoint -= lcl_convert( m_aGraphicsStack.front().m_aMapMode,
-                               m_aMapMode,
-                               getReferenceDevice(),
-                               Point() );
+        // tdf#130150 improve coordinate manipulations to double precision transformations
+        basegfx::B2DHomMatrix aConvertA;
+
+        if(MapUnit::MapPixel == m_aGraphicsStack.front().m_aMapMode.GetMapUnit())
+        {
+            aConvertA = getReferenceDevice()->GetInverseViewTransformation(m_aMapMode);
+        }
+        else
+        {
+            aConvertA = getReferenceDevice()->LogicToLogic(m_aGraphicsStack.front().m_aMapMode, m_aMapMode);
+        }
+
+        basegfx::B2DPoint aB2DPointA(nX, nY);
+        basegfx::B2DPoint aB2DPointB(0.0, 0.0);
+        aB2DPointA *= aConvertA;
+        aB2DPointB *= aConvertA;
+        aB2DPointA -= aB2DPointB;
         basegfx::B2DHomMatrix aMat;
-        aMat.translate( aPoint.X(), aPoint.Y() );
+
+        aMat.translate(aB2DPointA.getX(), aB2DPointA.getY());
         m_aGraphicsStack.front().m_aClipRegion.transform( aMat );
         m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsStateUpdateFlags::ClipRegion;
     }
@@ -10500,9 +10522,15 @@ void PDFWriterImpl::intersectClipRegion( const tools::Rectangle& rRect )
 
 void PDFWriterImpl::intersectClipRegion( const basegfx::B2DPolyPolygon& rRegion )
 {
-    basegfx::B2DPolyPolygon aRegion( getReferenceDevice()->LogicToPixel( rRegion, m_aGraphicsStack.front().m_aMapMode ) );
-    aRegion = getReferenceDevice()->PixelToLogic( aRegion, m_aMapMode );
+    // tdf#130150 improve coordinate manipulations to double precision transformations
+    const basegfx::B2DHomMatrix aCurrentTransform(
+        getReferenceDevice()->GetInverseViewTransformation(m_aMapMode) *
+        getReferenceDevice()->GetViewTransformation(m_aGraphicsStack.front().m_aMapMode));
+    basegfx::B2DPolyPolygon aRegion(rRegion);
+
+    aRegion.transform(aCurrentTransform);
     m_aGraphicsStack.front().m_nUpdateFlags |= GraphicsStateUpdateFlags::ClipRegion;
+
     if( m_aGraphicsStack.front().m_bClipRegion )
     {
         basegfx::B2DPolyPolygon aOld( basegfx::utils::prepareForPolygonOperation( m_aGraphicsStack.front().m_aClipRegion ) );


More information about the Libreoffice-commits mailing list