From c7c2b9273cfe4b080fbfd30179c7ae673f3cd066 Mon Sep 17 00:00:00 2001 From: Vasily Melenchuk Date: Mon, 15 May 2017 13:41:14 +0300 Subject: tdf#100072 zero height of shape's path was causing geometry errors DOCX custom geometry shape's path width and height are now used independently for scaling calculations. Reviewed-on: https://gerrit.libreoffice.org/37639 Tested-by: Jenkins Reviewed-by: Thorsten Behrens (cherry picked from commit 5477f7274e4df1210298c0f503a54eabc0f06bfc) plus: tdf#100072 extra test for DOCX shape import with zero height Corresponding bug is already fixed in tdf#107104. However created tests do care only for width, but not for height, like we have in this testcase. Reviewed-on: https://gerrit.libreoffice.org/37538 Tested-by: Jenkins Reviewed-by: Miklos Vajna (cherry picked from commit cffc5a04661fc0a84dff9fa5da954236d88a8b38) Change-Id: If5d5499f402379df125b0f31dd071ca51b2553f1 Reviewed-on: https://gerrit.libreoffice.org/38224 Tested-by: Jenkins Reviewed-by: Thorsten Behrens (cherry picked from commit 9c3100a4b9f258a7dc0aff93bc01fa39f7501d2c) --- svx/source/customshapes/EnhancedCustomShape2d.cxx | 17 ++++++++- sw/qa/extras/ooxmlimport/data/tdf100072.docx | Bin 0 -> 7034 bytes sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 44 ++++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 sw/qa/extras/ooxmlimport/data/tdf100072.docx diff --git a/svx/source/customshapes/EnhancedCustomShape2d.cxx b/svx/source/customshapes/EnhancedCustomShape2d.cxx index 6a5e9e9c87e9..85886b22ec3e 100644 --- a/svx/source/customshapes/EnhancedCustomShape2d.cxx +++ b/svx/source/customshapes/EnhancedCustomShape2d.cxx @@ -651,10 +651,23 @@ void EnhancedCustomShape2d::SetPathSize( sal_Int32 nIndex ) "svx", "ooxml shape, path width: " << nCoordWidth << " height: " << nCoordHeight); + + // Try to set up scale separately, if given only width or height + // This is possible case in OOXML when only width or height is non-zero if ( nCoordWidth == 0 ) - fXScale = 1.0; + { + if ( nWidth ) + fXScale = (double)aLogicRect.GetWidth() / (double)nWidth; + else + fXScale = 1.0; + } if ( nCoordHeight == 0 ) - fYScale = 1.0; + { + if ( nHeight ) + fYScale = (double)aLogicRect.GetHeight() / (double)nHeight; + else + fYScale = 1.0; + } } if ( (sal_uInt32)nXRef != 0x80000000 && aLogicRect.GetHeight() ) { diff --git a/sw/qa/extras/ooxmlimport/data/tdf100072.docx b/sw/qa/extras/ooxmlimport/data/tdf100072.docx new file mode 100644 index 000000000000..02b885b9aafa Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/tdf100072.docx differ diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index 70713a4abe49..1ce389416b2d 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -59,6 +60,7 @@ #include #include #include +#include class Test : public SwModelTestBase { @@ -1347,6 +1349,48 @@ DECLARE_OOXMLIMPORT_TEST(testTdf96218, "tdf96218.docx") CPPUNIT_ASSERT(!getProperty(getShape(1), "IsFollowingTextFlow")); } +DECLARE_OOXMLIMPORT_TEST(testTdf100072, "tdf100072.docx") +{ + uno::Reference xShape = getShape(1); + + // Ensure that shape has non-zero height + CPPUNIT_ASSERT(xShape->getSize().Height > 0); + + // Ensure that shape left corner is within page (positive) + CPPUNIT_ASSERT(xShape->getPosition().X > 0); + + // Save the first shape to a metafile. + uno::Reference xGraphicExporter = drawing::GraphicExportFilter::create(comphelper::getProcessComponentContext()); + uno::Reference xSourceDoc(xShape, uno::UNO_QUERY); + xGraphicExporter->setSourceDocument(xSourceDoc); + + SvMemoryStream aStream; + uno::Reference xOutputStream(new utl::OStreamWrapper(aStream)); + uno::Sequence aDescriptor = + { + beans::PropertyValue("OutputStream", sal_Int32(0), uno::makeAny(xOutputStream), beans::PropertyState_DIRECT_VALUE), + beans::PropertyValue("FilterName", sal_Int32(0), uno::makeAny(OUString("SVM")), beans::PropertyState_DIRECT_VALUE) + }; + xGraphicExporter->filter(aDescriptor); + aStream.Seek(STREAM_SEEK_TO_BEGIN); + + // Read it back and dump it as an XML file. + Graphic aGraphic; + ReadGraphic(aStream, aGraphic); + const GDIMetaFile& rMetaFile = aGraphic.GetGDIMetaFile(); + MetafileXmlDump dumper; + xmlDocPtr pXmlDoc = dumper.dumpAndParse(rMetaFile); + + // Get first polyline rightside x coordinate + sal_Int32 nFirstEnd = getXPath(pXmlDoc, "/metafile/polyline[1]/point[2]", "x").toInt32(); + + // Get last stroke x coordinate + sal_Int32 nSecondEnd = getXPath(pXmlDoc, "/metafile/polyline[last()]/point[2]", "x").toInt32(); + + // Assert that the difference is less than half point. + CPPUNIT_ASSERT_MESSAGE("Shape line width does not match", abs(nFirstEnd - nSecondEnd) < 10); +} + // tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT CPPUNIT_PLUGIN_IMPLEMENT(); -- cgit