summaryrefslogtreecommitdiff
path: root/svx/qa/unit/customshapes.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svx/qa/unit/customshapes.cxx')
-rw-r--r--svx/qa/unit/customshapes.cxx160
1 files changed, 121 insertions, 39 deletions
diff --git a/svx/qa/unit/customshapes.cxx b/svx/qa/unit/customshapes.cxx
index a0c256b5d6e0..23d3fb676770 100644
--- a/svx/qa/unit/customshapes.cxx
+++ b/svx/qa/unit/customshapes.cxx
@@ -11,6 +11,11 @@
#include <unotest/macros_test.hxx>
#include <rtl/ustring.hxx>
#include <editeng/unoprnms.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <svx/EnhancedCustomShape2d.hxx>
+#include <svx/svdoashp.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/unoapi.hxx>
#include <cppunit/TestAssert.h>
@@ -24,13 +29,17 @@ using namespace ::com::sun::star;
namespace
{
-const OUString sDataDirectory("/svx/qa/unit/data/");
+const OUString sDataDirectory("svx/qa/unit/data/");
/// Tests for svx/source/customshapes/ code.
class CustomshapesTest : public test::BootstrapFixture, public unotest::MacrosTest
{
uno::Reference<lang::XComponent> mxComponent;
+private:
+ // get shape nShapeIndex from page 0
+ uno::Reference<drawing::XShape> getShape(sal_uInt8 nShapeIndex);
+
public:
virtual void setUp() override
{
@@ -51,15 +60,36 @@ public:
void testAccuracyCommandX();
void testToggleCommandXY();
void testMultipleMoveTo();
+ void testWidthOrientationCommandU();
+ void testHalfEllipseVML();
+ void testLargeSwingAngleVML();
+ void testTdf121845_two_commands_U();
CPPUNIT_TEST_SUITE(CustomshapesTest);
CPPUNIT_TEST(testViewBoxLeftTop);
CPPUNIT_TEST(testAccuracyCommandX);
CPPUNIT_TEST(testToggleCommandXY);
CPPUNIT_TEST(testMultipleMoveTo);
+ CPPUNIT_TEST(testWidthOrientationCommandU);
+ CPPUNIT_TEST(testHalfEllipseVML);
+ CPPUNIT_TEST(testLargeSwingAngleVML);
+ CPPUNIT_TEST(testTdf121845_two_commands_U);
CPPUNIT_TEST_SUITE_END();
};
+uno::Reference<drawing::XShape> CustomshapesTest::getShape(sal_uInt8 nShapeIndex)
+{
+ 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);
+ CPPUNIT_ASSERT_MESSAGE("Could not get xDrawPage", xDrawPage.is());
+ uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(nShapeIndex), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_MESSAGE("Could not get xShape", xShape.is());
+ return xShape;
+}
+
void CustomshapesTest::testViewBoxLeftTop()
{
// tdf#121890 formula values "left" and "top" are wrongly calculated
@@ -68,17 +98,9 @@ void CustomshapesTest::testViewBoxLeftTop()
= m_directories.getURLFromSrc(sDataDirectory) + "viewBox_positive_twolines_strict.odp";
mxComponent = loadFromDesktop(aURL, "com.sun.star.comp.presentation.PresentationDocument");
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);
-
// Get the shape "leftright". Error was, that the identifier "left" was always set to zero, thus
// the path was outside the frame rectangle for a viewBox having a positive "left" value.
- uno::Reference<drawing::XShape> xShapeLR(xDrawPage->getByIndex(0), uno::UNO_QUERY);
- CPPUNIT_ASSERT_MESSAGE("Could not get the shape 'leftright'", xShapeLR.is());
+ uno::Reference<drawing::XShape> xShapeLR(getShape(0));
uno::Reference<beans::XPropertySet> xShapeLRProps(xShapeLR, uno::UNO_QUERY);
CPPUNIT_ASSERT_MESSAGE("Could not get the shape 'leftright' properties", xShapeLRProps.is());
awt::Rectangle aFrameRectLR;
@@ -90,8 +112,7 @@ void CustomshapesTest::testViewBoxLeftTop()
// Get the shape "topbottom". Error was, that the identifier "top" was always set to zero, thus
// the path was outside the frame rectangle for a viewBox having a positive "top" value.
- uno::Reference<drawing::XShape> xShapeTB(xDrawPage->getByIndex(1), uno::UNO_QUERY);
- CPPUNIT_ASSERT_MESSAGE("Could not get the shape 'topbottom'", xShapeTB.is());
+ uno::Reference<drawing::XShape> xShapeTB(getShape(1));
uno::Reference<beans::XPropertySet> xShapeTBProps(xShapeTB, uno::UNO_QUERY);
CPPUNIT_ASSERT_MESSAGE("Could not get the shape 'topbottom' properties", xShapeTBProps.is());
awt::Rectangle aFrameRectTB;
@@ -111,18 +132,10 @@ void CustomshapesTest::testAccuracyCommandX()
= m_directories.getURLFromSrc(sDataDirectory) + "tdf121761_Accuracy_command_X.odp";
mxComponent = loadFromDesktop(aURL, "com.sun.star.comp.presentation.PresentationDocument");
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);
-
// Get the shape "arc_45deg_rotated". Error was, that a Bezier curve with bad parameters
// was used, thus the segment height was obviously smaller than for a true circle.
// Math: segment height approx 10000 * ( 1 - sqrt(0.5)) + line width
- uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
- CPPUNIT_ASSERT_MESSAGE("Could not get the shape", xShape.is());
+ uno::Reference<drawing::XShape> xShape(getShape(0));
uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
CPPUNIT_ASSERT_MESSAGE("Could not get the shape properties", xShapeProps.is());
awt::Rectangle aBoundRect;
@@ -142,18 +155,10 @@ void CustomshapesTest::testToggleCommandXY()
= m_directories.getURLFromSrc(sDataDirectory) + "tdf121952_Toggle_direction_command_X.odp";
mxComponent = loadFromDesktop(aURL, "com.sun.star.comp.presentation.PresentationDocument");
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 segment was drawn with same direction as first one. If drawn
// correctly, the bounding box height of the segments together is about twice the single
// segment height. Math: segment height approx 10000 * ( 1 - sqrt(0.5)) + line width
- uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
- CPPUNIT_ASSERT_MESSAGE("Could not get the shape", xShape.is());
+ uno::Reference<drawing::XShape> xShape(getShape(0));
uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
CPPUNIT_ASSERT_MESSAGE("Could not get the shape properties", xShapeProps.is());
awt::Rectangle aBoundRect;
@@ -170,18 +175,10 @@ void CustomshapesTest::testMultipleMoveTo()
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<drawing::XShape> xShape(getShape(0));
uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
CPPUNIT_ASSERT_MESSAGE("Could not get the shape properties", xShapeProps.is());
awt::Rectangle aBoundRect;
@@ -190,6 +187,91 @@ void CustomshapesTest::testMultipleMoveTo()
CPPUNIT_ASSERT_MESSAGE("Path is empty", !bIsZero);
}
+void CustomshapesTest::testWidthOrientationCommandU()
+{
+ // tdf121845 custom shape with command U (angleellipse) is wrongly drawn
+ // Load a document with path "M 750 0 L 750 500 250 500 250 0 U 500 0 500 500 0 180 N"
+ // in viewBox="0 0 1000 500" and width="10cm", height="5cm".
+ const OUString sFileName("tdf121845_WidthOrientation_command_U.odg");
+ const OUString sURL = m_directories.getURLFromSrc(sDataDirectory) + sFileName;
+ mxComponent = loadFromDesktop(sURL, "com.sun.star.comp.drawing.DrawingDocument");
+ CPPUNIT_ASSERT_MESSAGE("Could not load document", mxComponent.is());
+ // Error was, that the width and height of the ellipse was halved and that the ellipse
+ // was not drawn clockwise but counter clockwise.
+ uno::Reference<drawing::XShape> xShape(getShape(0));
+ 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;
+ const double fWidth = static_cast<double>(aBoundRect.Width);
+ // Need some tolerance for line width
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("wrong width", 10000.0, fWidth, 40.0);
+ const double fHeight = static_cast<double>(aBoundRect.Height);
+ // Wrong orientation draws segment above the top of the viewBox and so increases 'Height'.
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("wrong orientation", 5000.0, fHeight, 40.0);
+}
+
+void CustomshapesTest::testHalfEllipseVML()
+{
+ // tdf121845 custom shape with command U (angleellipse) is wrongly drawn
+ // Load a document which was converted from VML to doc by Word. It had a VML
+ // path="m750,al500,,500,500,,-11796480e" resulting in a lower half circle.
+ const OUString sFileName("tdf121845_HalfEllipseVML.doc");
+ const OUString sURL = m_directories.getURLFromSrc(sDataDirectory) + sFileName;
+ mxComponent = loadFromDesktop(sURL, "com.sun.star.comp.text.TextDocument");
+ CPPUNIT_ASSERT_MESSAGE("Could not load document", mxComponent.is());
+ // Error was, that a full circle instead of the half circle was draw.
+ uno::Reference<drawing::XShape> xShape(getShape(0));
+ 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;
+ const double fDiff2HmW = static_cast<double>(2 * aBoundRect.Height - aBoundRect.Width);
+ // Need some tolerance for line width
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("not a half circle", 0.0, fDiff2HmW, 40.0);
+}
+
+void CustomshapesTest::testLargeSwingAngleVML()
+{
+ // tdf121845 custom shape with command U (angleellipse) is wrongly drawn
+ // Load a document which was converted from VML to doc by Word. It had a VML
+ // path="al50,50,45,45,2621440,31457280e" resulting in a full circle plus 120 deg segment.
+ const OUString sFileName("tdf121845_start40_swing480.doc");
+ const OUString sURL = m_directories.getURLFromSrc(sDataDirectory) + sFileName;
+ mxComponent = loadFromDesktop(sURL, "com.sun.star.comp.text.TextDocument");
+ CPPUNIT_ASSERT_MESSAGE("Could not load document", mxComponent.is());
+ // Error was, that only the 120 deg segment was drawn.
+ uno::Reference<drawing::XShape> xShape(getShape(0));
+ 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;
+ const double fDiffWmH = static_cast<double>(aBoundRect.Width - aBoundRect.Height);
+ // Need some tolerance for line width
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Full circle plus segment expected", 0.0, fDiffWmH, 10.0);
+}
+void CustomshapesTest::testTdf121845_two_commands_U()
+{
+ // tdf121845 custom shape with command U (angleellipse) is wrongly drawn
+ // Load a document with path "U 950 250 200 200 90 180 250 250 200 200 180 270 N"
+ // Error was, that the second ellipse segment was interpreted as command T and
+ // thus a line from first to second segment was drawn.
+ const OUString sFileName("tdf121845_Two_commands_U.odg");
+ OUString sURL = m_directories.getURLFromSrc(sDataDirectory) + sFileName;
+ mxComponent = loadFromDesktop(sURL, "com.sun.star.comp.drawing.DrawingDocument");
+ CPPUNIT_ASSERT_MESSAGE("Could not load document", mxComponent.is());
+ uno::Reference<drawing::XShape> xShape(getShape(0));
+ // In case no line is drawn, two polygons are generated; with line only one polygon
+ SdrObjCustomShape& rSdrObjCustomShape(
+ static_cast<SdrObjCustomShape&>(*GetSdrObjectFromXShape(xShape)));
+ EnhancedCustomShape2d aCustomShape2d(rSdrObjCustomShape);
+ SdrPathObj* pPathObj = static_cast<SdrPathObj*>(aCustomShape2d.CreateLineGeometry());
+ CPPUNIT_ASSERT_MESSAGE("Could not convert to SdrPathObj", pPathObj);
+ const basegfx::B2DPolyPolygon aPolyPolygon(pPathObj->GetPathPoly());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("count polygons", static_cast<sal_uInt32>(2),
+ aPolyPolygon.count());
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(CustomshapesTest);
}