From 2abe9837deee3823c7928a76b5b2f94f1464f1a3 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 13 May 2020 17:59:34 +0200 Subject: [PATCH] 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. Change-Id: Iab2adaa81a33eb04e1806b17ed129ac50f5d2aa3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94149 Reviewed-by: Miklos Vajna Tested-by: Jenkins --- sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 16 +++++----- .../CppunitTest_writerfilter_dmapper.mk | 1 + .../qa/cppunittests/dmapper/GraphicImport.cxx | 30 ++++++++++++++++++ .../dmapper/data/wrap-poly-crop.docx | Bin 0 -> 15018 bytes writerfilter/source/dmapper/GraphicImport.cxx | 11 +++++++ .../source/dmapper/WrapPolygonHandler.cxx | 18 +++++++++++ .../source/dmapper/WrapPolygonHandler.hxx | 7 ++++ 7 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 writerfilter/qa/cppunittests/dmapper/data/wrap-poly-crop.docx diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index 14d0d2797f8b..48de70ea00b6 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -981,17 +981,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 270844557d3b..c29b3b9e1c39 100644 --- a/writerfilter/CppunitTest_writerfilter_dmapper.mk +++ b/writerfilter/CppunitTest_writerfilter_dmapper.mk @@ -25,6 +25,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 590a93273e92..7648d9e9420d 100644 --- a/writerfilter/qa/cppunittests/dmapper/GraphicImport.cxx +++ b/writerfilter/qa/cppunittests/dmapper/GraphicImport.cxx @@ -15,6 +15,9 @@ #include #include #include +#include + +#include using namespace ::com::sun::star; @@ -134,6 +137,33 @@ CPPUNIT_TEST_FIXTURE(Test, testRelfromhInsidemargin) xShape->getPropertyValue("PageToggle") >>= bPageToggle; CPPUNIT_ASSERT(bPageToggle); } + +CPPUNIT_TEST_FIXTURE(Test, testWrapPolyCrop) +{ + OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "wrap-poly-crop.docx"; + getComponent() = loadFromDesktop(aURL); + uno::Reference xDrawPageSupplier(getComponent(), uno::UNO_QUERY); + uno::Reference xDrawPage = xDrawPageSupplier->getDrawPage(); + uno::Reference 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 0000000000000000000000000000000000000000..1835a130d7402314e703ea14ea401fa02d94a613 GIT binary patch literal 15018 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

hR%Rlvz^t7M*fG+Qq6 z6Ya$?rTki#t0lLV=vCq~aSY4cEol&F#kx6W@h4am5z1WWQsvNGl~5w}=(c6T?F`8M zEa;Ulw-ACTf{d(K_W1%>z%CyejiV#JywlLWWYD6OBGvaUcV#NmpG<=nYbaf7UfT|q z)g9;_K(|Bi4#RtA(HXVO76e&GUm)v&T>U7qPlHw?t@S(<2(sQB2Sq(x(_(!p?ah>v zYSrV=$HW1HVFYf5r&+zK;F z*jeiJYtqehZjyH3OxQdlR7E-=?LAwsaV(=WX8}2CR(9^(L(=0)HIX?v*zor_4vFZb9LR*$!T$6`JAK>};@&H~uTkm6 zZne2(H0L_h(CDAxV+Y5y1__?tKd7-hJWLBX73qB4)8L%Voz0mwpIu$@){|40X6(ZC zQxa)+5NIwGmMkhrW5`+m=)J~k;$Fj{2iVG0NB@bDd~ckL$t5Aa<4WxcAhmV505LZnDH~B3~VEeEe zD)&CMcq4FeBFJGswn{yPuGG|-w`y8CK+B?J_lLG1E1j=s1Ef=YD1?orv<7YoyFs0_ zT4NFhbq5oZOq~4Slx(-TmohWYlGZt#Ze#jZF#P@ZvT}cOydq~&W3tqMz3_vicM>f8 zLgZyrQaf;-9;~00#ca-zAkWBywu|o`j*n7Ds=H*D&(0JmA`>c*V00S^V z=LP4~QN0$^0R)lA;-dJi4KNKn&Bllsd41pEzg}WXB5E>|;Na97F{hYq?E5jxmO7Y) zjoey@F$&P`hMD<@X*}(4iHb)1BTnv<3lL@bc^O`Sa$o2IcQl z93uyZ|C!-{4Cs$fj>>PlZ#u{>kd;s8ENPSqYEZ30xzCfb`j#8HB127dTcQs(n@HG^ zcES|-nyx+EY(CuC$X^GNSed8axv1>n>U>LS`N6uG=58MSCR$pHBBtrX#0}0BzMmI3 zQ?DnYw8?~2-w<%4c&`pOy0KSd0Ir$Al@?nk5jHHVt#TG^QQ=hQedJ`+PSUoyNR?9V zoiOtmW}V=yzj$hLZuhOuDL?L4CF7%5sgZZQd}f7uR)I+LDU5Kchgf$p2VgzX0QDQTfk_^GowKB_B?y%bKgi9U>O3e5v z?fIYcuzQA32;WnX?f2XV#Xu>;Y-ba>Lj=WQKx?w|*M&sF9!vF%HR~_&Q@sn1`o6Kd zkZ!j=c;&pu#e;V#UuL!&O3sAc6n*ib=#>pMhT7h9zB~C=o<4cTsY=w?LisE2C(e%m zgNM4&vMXufBfbU*$vW0Y+^2sfa)W_0fZ`~BhEo5zWA4w_^Jn=V_RlHF{*%E!_v-vf z_)-poCRTsjx$`UGKQ}P^o$v^hwe-K+&hWyC5aJ~k^q 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 7d2526c0bbaf..00b8699972bc 100644 --- a/writerfilter/source/dmapper/WrapPolygonHandler.cxx +++ b/writerfilter/source/dmapper/WrapPolygonHandler.cxx @@ -18,6 +18,7 @@ */ #include +#include #include #include @@ -135,6 +136,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 6b8b458e616c..e9e58dc0907b 100644 --- a/writerfilter/source/dmapper/WrapPolygonHandler.hxx +++ b/writerfilter/source/dmapper/WrapPolygonHandler.hxx @@ -25,6 +25,11 @@ #include #include +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; };