[Libreoffice-commits] core.git: Branch 'distro/nisz/libreoffice-6-4' - sw/qa writerfilter/CppunitTest_writerfilter_dmapper.mk writerfilter/qa writerfilter/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Tue Jul 28 08:05:32 UTC 2020


 sw/qa/extras/ooxmlimport/ooxmlimport.cxx                      |   16 ++---
 writerfilter/CppunitTest_writerfilter_dmapper.mk              |    1 
 writerfilter/qa/cppunittests/dmapper/GraphicImport.cxx        |   29 ++++++++++
 writerfilter/qa/cppunittests/dmapper/data/wrap-poly-crop.docx |binary
 writerfilter/source/dmapper/GraphicImport.cxx                 |   11 +++
 writerfilter/source/dmapper/WrapPolygonHandler.cxx            |   18 ++++++
 writerfilter/source/dmapper/WrapPolygonHandler.hxx            |    7 ++
 7 files changed, 74 insertions(+), 8 deletions(-)

New commits:
commit d868c41b7d35699caa502001df37c2efc12f635d
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Wed May 13 17:59:34 2020 +0200
Commit:     Gabor Kelemen <kelemen.gabor2 at nisz.hu>
CommitDate: Tue Jul 28 10:04:59 2020 +0200

    DOCX import: fix interaction between the crop and the wrap polygon of images
    
    Word first applies the crop, then applies the wrap polygon on the
    remaining visible part of the image.
    
    Writer applies the crop on the original bitmap, and even has explicit
    code to make sure the uncropped bitmap is used for the wrap polygon, see
    how SwFlyFrame::GetContour() calls SwNoTextFrame::GetGrfArea(), which
    will extend the resulting size based on cropping.
    
    Fix the problem by moving and scaling the wrap polygon, so it ends up
    where it would in Word.
    
    Also adapt testFdo76803, which had a similar crop+wrap polygon case, but
    the different there is quite small.
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94149
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit 2abe9837deee3823c7928a76b5b2f94f1464f1a3)
    
    Change-Id: Iab2adaa81a33eb04e1806b17ed129ac50f5d2aa3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99542
    Tested-by: Gabor Kelemen <kelemen.gabor2 at nisz.hu>
    Reviewed-by: Gabor Kelemen <kelemen.gabor2 at nisz.hu>

diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 0030a6ba68aa..de03b1c0ce1c 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -971,17 +971,17 @@ DECLARE_OOXMLIMPORT_TEST(testFdo76803, "fdo76803.docx")
 
     CPPUNIT_ASSERT_EQUAL(sal_uInt32(4), aPolygon.count());
 
-    CPPUNIT_ASSERT_EQUAL(double(-163), aPolygon.getB2DPoint(0).getX());
-    CPPUNIT_ASSERT_EQUAL(double(0), aPolygon.getB2DPoint(0).getY());
+    CPPUNIT_ASSERT_EQUAL(double(-162), aPolygon.getB2DPoint(0).getX());
+    CPPUNIT_ASSERT_EQUAL(double(-35), aPolygon.getB2DPoint(0).getY());
 
-    CPPUNIT_ASSERT_EQUAL(double(-163), aPolygon.getB2DPoint(1).getX());
-    CPPUNIT_ASSERT_EQUAL(double(3661), aPolygon.getB2DPoint(1).getY());
+    CPPUNIT_ASSERT_EQUAL(double(-162), aPolygon.getB2DPoint(1).getX());
+    CPPUNIT_ASSERT_EQUAL(double(3510), aPolygon.getB2DPoint(1).getY());
 
-    CPPUNIT_ASSERT_EQUAL(double(16987), aPolygon.getB2DPoint(2).getX());
-    CPPUNIT_ASSERT_EQUAL(double(3661), aPolygon.getB2DPoint(2).getY());
+    CPPUNIT_ASSERT_EQUAL(double(16892), aPolygon.getB2DPoint(2).getX());
+    CPPUNIT_ASSERT_EQUAL(double(3510), aPolygon.getB2DPoint(2).getY());
 
-    CPPUNIT_ASSERT_EQUAL(double(16987), aPolygon.getB2DPoint(3).getX());
-    CPPUNIT_ASSERT_EQUAL(double(0), aPolygon.getB2DPoint(3).getY());
+    CPPUNIT_ASSERT_EQUAL(double(16892), aPolygon.getB2DPoint(3).getX());
+    CPPUNIT_ASSERT_EQUAL(double(-35), aPolygon.getB2DPoint(3).getY());
 }
 
 DECLARE_OOXMLIMPORT_TEST(testUnbalancedColumnsCompat, "unbalanced-columns-compat.docx")
diff --git a/writerfilter/CppunitTest_writerfilter_dmapper.mk b/writerfilter/CppunitTest_writerfilter_dmapper.mk
index 8678bb92da10..fe0a2b21be5f 100644
--- a/writerfilter/CppunitTest_writerfilter_dmapper.mk
+++ b/writerfilter/CppunitTest_writerfilter_dmapper.mk
@@ -24,6 +24,7 @@ $(eval $(call gb_CppunitTest_add_exception_objects,writerfilter_dmapper, \
 ))
 
 $(eval $(call gb_CppunitTest_use_libraries,writerfilter_dmapper, \
+    basegfx \
     comphelper \
     cppu \
     oox \
diff --git a/writerfilter/qa/cppunittests/dmapper/GraphicImport.cxx b/writerfilter/qa/cppunittests/dmapper/GraphicImport.cxx
index a22304d256ac..aa0f63d143de 100644
--- a/writerfilter/qa/cppunittests/dmapper/GraphicImport.cxx
+++ b/writerfilter/qa/cppunittests/dmapper/GraphicImport.cxx
@@ -18,8 +18,10 @@
 #include <com/sun/star/text/XTextTablesSupplier.hpp>
 #include <com/sun/star/text/RelOrientation.hpp>
 #include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/drawing/PointSequenceSequence.hpp>
 
 #include <comphelper/processfactory.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
 
 using namespace ::com::sun::star;
 
@@ -107,6 +109,33 @@ CPPUNIT_TEST_FIXTURE(Test, testInlineAnchoredZOrder)
     // i.e. the rectangle (with no name) was on top of the oval one, not the other way around.
     CPPUNIT_ASSERT_EQUAL(OUString("Oval 2"), xOval->getName());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testWrapPolyCrop)
+{
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "wrap-poly-crop.docx";
+    getComponent() = loadFromDesktop(aURL);
+    uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(getComponent(), uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+    uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+    drawing::PointSequenceSequence aContour;
+    xShape->getPropertyValue("ContourPolyPolygon") >>= aContour;
+    auto aPolyPolygon = basegfx::utils::UnoPointSequenceSequenceToB2DPolyPolygon(aContour);
+    CPPUNIT_ASSERT_EQUAL(sal_uInt32(1), aPolyPolygon.count());
+    auto aPolygon = aPolyPolygon.getB2DPolygon(0);
+    CPPUNIT_ASSERT_EQUAL(sal_uInt32(4), aPolygon.count());
+
+    // Ideally this would be 2352, because the graphic size in mm100, using the graphic's DPI is
+    // 10582, the lower 33% of the graphic is cropped, and the wrap polygon covers the middle third
+    // of the area vertically. Which means 10582*2/3 = 7054.67 is the cropped height, and the top of
+    // the middle third is 2351.55.
+    //
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 2361
+    // - Actual  : 3542
+    // i.e. the wrap polygon covered a larger-than-correct area, which end the end means 3 lines
+    // were wrapping around the image, not only 2 as Word does it.
+    CPPUNIT_ASSERT_EQUAL(2361., aPolygon.getB2DPoint(0).getY());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/qa/cppunittests/dmapper/data/wrap-poly-crop.docx b/writerfilter/qa/cppunittests/dmapper/data/wrap-poly-crop.docx
new file mode 100644
index 000000000000..1835a130d740
Binary files /dev/null and b/writerfilter/qa/cppunittests/dmapper/data/wrap-poly-crop.docx differ
diff --git a/writerfilter/source/dmapper/GraphicImport.cxx b/writerfilter/source/dmapper/GraphicImport.cxx
index db01a5f65562..8ebc0cdc3a43 100644
--- a/writerfilter/source/dmapper/GraphicImport.cxx
+++ b/writerfilter/source/dmapper/GraphicImport.cxx
@@ -1418,6 +1418,17 @@ uno::Reference<text::XTextContent> GraphicImport::createGraphicObject(uno::Refer
                         pCorrected = m_pImpl->mpWrapPolygon->correctWordWrapPolygonPixel(aGraphicSize);
                     }
                 }
+
+                text::GraphicCrop aGraphicCrop;
+                xShapeProps->getPropertyValue("GraphicCrop") >>= aGraphicCrop;
+                if (aGraphicCrop.Top != 0 || aGraphicCrop.Bottom != 0 || aGraphicCrop.Left != 0
+                    || aGraphicCrop.Right != 0)
+                {
+                    // Word's wrap polygon deals with a canvas which has the size of the already
+                    // cropped graphic, correct our polygon to have the same render result.
+                    pCorrected = pCorrected->correctCrop(aGraphicSize, aGraphicCrop);
+                }
+
                 if (pCorrected)
                 {
                     aContourPolyPolygon <<= pCorrected->getPointSequenceSequence();
diff --git a/writerfilter/source/dmapper/WrapPolygonHandler.cxx b/writerfilter/source/dmapper/WrapPolygonHandler.cxx
index 862dae53e2e2..14c1d6a0c5bf 100644
--- a/writerfilter/source/dmapper/WrapPolygonHandler.cxx
+++ b/writerfilter/source/dmapper/WrapPolygonHandler.cxx
@@ -18,6 +18,7 @@
  */
 
 #include <com/sun/star/drawing/PointSequence.hpp>
+#include <com/sun/star/text/GraphicCrop.hpp>
 #include <comphelper/sequence.hxx>
 
 #include <ooxml/resourceids.hxx>
@@ -136,6 +137,23 @@ WrapPolygon::Pointer_t WrapPolygon::correctWordWrapPolygonPixel(const awt::Size
     return pResult;
 }
 
+WrapPolygon::Pointer_t WrapPolygon::correctCrop(const awt::Size& rGraphicSize,
+                                                const text::GraphicCrop& rGraphicCrop)
+{
+    WrapPolygon::Pointer_t pResult;
+
+    Fraction aScaleX(rGraphicSize.Width - rGraphicCrop.Left - rGraphicCrop.Right,
+                     rGraphicSize.Width);
+    Fraction aScaleY(rGraphicSize.Height - rGraphicCrop.Top - rGraphicCrop.Bottom,
+                     rGraphicSize.Height);
+    pResult = scale(aScaleX, aScaleY);
+
+    awt::Point aMove(rGraphicCrop.Left, rGraphicCrop.Top);
+    pResult = pResult->move(aMove);
+
+    return pResult;
+}
+
 drawing::PointSequenceSequence WrapPolygon::getPointSequenceSequence() const
 {
     drawing::PointSequenceSequence aPolyPolygon(1);
diff --git a/writerfilter/source/dmapper/WrapPolygonHandler.hxx b/writerfilter/source/dmapper/WrapPolygonHandler.hxx
index 807e78362924..d5dfd3487d84 100644
--- a/writerfilter/source/dmapper/WrapPolygonHandler.hxx
+++ b/writerfilter/source/dmapper/WrapPolygonHandler.hxx
@@ -26,6 +26,11 @@
 #include <tools/fract.hxx>
 #include <vector>
 
+namespace com::sun::star::text
+{
+struct GraphicCrop;
+}
+
 namespace writerfilter {
 namespace dmapper {
 
@@ -51,6 +56,8 @@ public:
     WrapPolygon::Pointer_t scale(const Fraction & rFractionX, const Fraction & rFractionY);
     WrapPolygon::Pointer_t correctWordWrapPolygon(const css::awt::Size & rSrcSize);
     WrapPolygon::Pointer_t correctWordWrapPolygonPixel(const css::awt::Size & rSrcSize);
+    WrapPolygon::Pointer_t correctCrop(const css::awt::Size& rGraphicSize,
+                                       const css::text::GraphicCrop& rGraphicCrop);
     css::drawing::PointSequenceSequence getPointSequenceSequence() const;
 };
 


More information about the Libreoffice-commits mailing list