diff options
author | Regina Henschel <rb.henschel@t-online.de> | 2019-01-25 00:30:57 +0100 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2019-01-29 01:16:51 +0100 |
commit | 76c7a6c39d769cb9bdb9b951d9f95507c0139372 (patch) | |
tree | e718b89423f52c71d3f94afa12a738edfff21639 | |
parent | ecc855aa1c86d88a99c3be06c70ed382180be688 (diff) |
Improve ODF enhanced-path command moveTo to follow spec
ODF 1.2 section 19.145 says 'If a moveto is followed by multiple
pairs of coordinates, they are treated as lineto.' The patch does
this on import.
Change-Id: Ib493ca49288cdb2d34b7ee801bd052281617d2e8
Reviewed-on: https://gerrit.libreoffice.org/66888
Tested-by: Jenkins
Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
-rwxr-xr-x[-rw-r--r--] | svx/qa/unit/customshapes.cxx | 29 | ||||
-rw-r--r-- | svx/qa/unit/data/tdf122964_MultipleMoveTo.odg | bin | 0 -> 9666 bytes | |||
-rw-r--r-- | xmloff/source/draw/ximpcustomshape.cxx | 29 |
3 files changed, 52 insertions, 6 deletions
diff --git a/svx/qa/unit/customshapes.cxx b/svx/qa/unit/customshapes.cxx index d3f63dffe2a9..a0c256b5d6e0 100644..100755 --- a/svx/qa/unit/customshapes.cxx +++ b/svx/qa/unit/customshapes.cxx @@ -50,11 +50,13 @@ public: void testViewBoxLeftTop(); void testAccuracyCommandX(); void testToggleCommandXY(); + void testMultipleMoveTo(); CPPUNIT_TEST_SUITE(CustomshapesTest); CPPUNIT_TEST(testViewBoxLeftTop); CPPUNIT_TEST(testAccuracyCommandX); CPPUNIT_TEST(testToggleCommandXY); + CPPUNIT_TEST(testMultipleMoveTo); CPPUNIT_TEST_SUITE_END(); }; @@ -161,6 +163,33 @@ void CustomshapesTest::testToggleCommandXY() CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("segment height out of tolerance", 5871.0, fHeight, 16.0); } +void CustomshapesTest::testMultipleMoveTo() +{ + // tdf122964 Multiple moveTo has to be treated as lineTo in draw:enhanced-path + // Load a document with path "M 0 0 5 10 10 0 N" + OUString aURL = m_directories.getURLFromSrc(sDataDirectory) + "tdf122964_MultipleMoveTo.odg"; + mxComponent = loadFromDesktop(aURL, "com.sun.star.comp.drawing.DrawingDocument"); + CPPUNIT_ASSERT_MESSAGE("Could not load document", mxComponent.is()); + + uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent, + uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_MESSAGE("Could not get XDrawPagesSupplier", xDrawPagesSupplier.is()); + uno::Reference<drawing::XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages()); + uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(0), uno::UNO_QUERY_THROW); + + // Error was, that the second and further parameter pairs were treated as moveTo, + // and so the generated path was empty, resulting in zero width and height of the + // bounding box. It has to be treated same as "M 0 0 L 5 10 10 0 N". + uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); + CPPUNIT_ASSERT_MESSAGE("Could not get the shape", xShape.is()); + uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY); + CPPUNIT_ASSERT_MESSAGE("Could not get the shape properties", xShapeProps.is()); + awt::Rectangle aBoundRect; + xShapeProps->getPropertyValue(UNO_NAME_MISC_OBJ_BOUNDRECT) >>= aBoundRect; + bool bIsZero(aBoundRect.Height == 0 && aBoundRect.Width == 0); + CPPUNIT_ASSERT_MESSAGE("Path is empty", !bIsZero); +} + CPPUNIT_TEST_SUITE_REGISTRATION(CustomshapesTest); } diff --git a/svx/qa/unit/data/tdf122964_MultipleMoveTo.odg b/svx/qa/unit/data/tdf122964_MultipleMoveTo.odg Binary files differnew file mode 100644 index 000000000000..63d80fd06736 --- /dev/null +++ b/svx/qa/unit/data/tdf122964_MultipleMoveTo.odg diff --git a/xmloff/source/draw/ximpcustomshape.cxx b/xmloff/source/draw/ximpcustomshape.cxx index da15e3458cbb..35de24ba2562 100644 --- a/xmloff/source/draw/ximpcustomshape.cxx +++ b/xmloff/source/draw/ximpcustomshape.cxx @@ -792,16 +792,33 @@ static void GetEnhancedPath( std::vector< css::beans::PropertyValue >& rDest, } else if ( nParameterCount >= nParametersNeeded ) { - // check if the last command is identical, - // if so, we just need to increment the count - if ( !vSegments.empty() && ( vSegments[ vSegments.size() - 1 ].Command == nLatestSegmentCommand ) ) - vSegments[ vSegments.size() -1 ].Count++; - else + // Special rule for moveto in ODF 1.2 section 19.145 + // "If a moveto is followed by multiple pairs of coordinates, they are treated as lineto." + if ( nLatestSegmentCommand == css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO ) { css::drawing::EnhancedCustomShapeSegment aSegment; - aSegment.Command = nLatestSegmentCommand; + aSegment.Command = css::drawing::EnhancedCustomShapeSegmentCommand::MOVETO; aSegment.Count = 1; vSegments.push_back( aSegment ); + nIndex--; + nLatestSegmentCommand = css::drawing::EnhancedCustomShapeSegmentCommand::LINETO; + nParametersNeeded = 1; + } + else + { + // General rule in ODF 1.2. section 19.145 + // "If a command is repeated multiple times, all repeated command characters + // except the first one may be omitted." Thus check if the last command is identical, + // if so, we just need to increment the count + if ( !vSegments.empty() && ( vSegments[ vSegments.size() - 1 ].Command == nLatestSegmentCommand ) ) + vSegments[ vSegments.size() -1 ].Count++; + else + { + css::drawing::EnhancedCustomShapeSegment aSegment; + aSegment.Command = nLatestSegmentCommand; + aSegment.Count = 1; + vSegments.push_back( aSegment ); + } } nParameterCount = 0; } |