summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2020-05-13 17:59:34 +0200
committerMiklos Vajna <vmiklos@collabora.com>2020-05-18 16:59:49 +0200
commit83526f667416731de462418ee12c76dfbd6385cf (patch)
treea8fcd7bb4d9023caccdd094238bd41117cae4df7
parent43c52057ae9d0a620611a3fcc484762dd06f47f5 (diff)
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. (cherry picked from commit 2abe9837deee3823c7928a76b5b2f94f1464f1a3) Conflicts: writerfilter/CppunitTest_writerfilter_dmapper.mk writerfilter/qa/cppunittests/dmapper/GraphicImport.cxx Change-Id: Iab2adaa81a33eb04e1806b17ed129ac50f5d2aa3
-rw-r--r--sw/qa/extras/ooxmlimport/data/wrap-poly-crop.docxbin0 -> 15018 bytes
-rw-r--r--sw/qa/extras/ooxmlimport/ooxmlimport.cxx41
-rw-r--r--writerfilter/source/dmapper/GraphicImport.cxx11
-rw-r--r--writerfilter/source/dmapper/WrapPolygonHandler.cxx18
-rw-r--r--writerfilter/source/dmapper/WrapPolygonHandler.hxx7
5 files changed, 69 insertions, 8 deletions
diff --git a/sw/qa/extras/ooxmlimport/data/wrap-poly-crop.docx b/sw/qa/extras/ooxmlimport/data/wrap-poly-crop.docx
new file mode 100644
index 000000000000..1835a130d740
--- /dev/null
+++ b/sw/qa/extras/ooxmlimport/data/wrap-poly-crop.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index e6f3a150b31f..513a5d64a7d4 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -898,17 +898,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")
@@ -1608,6 +1608,31 @@ DECLARE_OOXMLIMPORT_TEST(testTdf116486, "tdf116486.docx")
CPPUNIT_ASSERT_EQUAL( OUString("4006"), aTop );
}
+DECLARE_OOXMLIMPORT_TEST(testWrapPolyCrop, "wrap-poly-crop.docx")
+{
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, 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());
+}
+
DECLARE_OOXMLIMPORT_TEST(testTdf117843, "tdf117843.docx")
{
uno::Reference<container::XNameAccess> xPageStyles = getStyles("PageStyles");
diff --git a/writerfilter/source/dmapper/GraphicImport.cxx b/writerfilter/source/dmapper/GraphicImport.cxx
index 76f36045ea4e..87745f93ae16 100644
--- a/writerfilter/source/dmapper/GraphicImport.cxx
+++ b/writerfilter/source/dmapper/GraphicImport.cxx
@@ -1324,6 +1324,17 @@ uno::Reference< text::XTextContent > GraphicImport::createGraphicObject( const b
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 010cf2e195a6..e3bc6e4e2c94 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>
@@ -134,6 +135,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 3192408aa330..ae6502a13edf 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;
};