Kaydet (Commit) a4c46cee authored tarafından Regina Henschel's avatar Regina Henschel

tdf#121761, tdf#121952 Accurate ellipsequadrant in custom shape

The current solution uses one, bad valued Bezier curve and does not
toggle direction. The patch uses the more accurate solution from
basegfx and simplifies the decision tree. In addition it extracts the
calculation in double from GetPoint, so they can be used directly
instead of double->long->double conversion.

Change-Id: I298f49415d1b7624b36ca561647f2e58af5eb5c6
Reviewed-on: https://gerrit.libreoffice.org/65203
Tested-by: Jenkins
Reviewed-by: 's avatarRegina Henschel <rb.henschel@t-online.de>
üst 721bc6da
......@@ -35,6 +35,7 @@
#include <svx/EnhancedCustomShapeFunctionParser.hxx>
#include <tools/gen.hxx>
#include <o3tl/typed_flags_set.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <memory>
#include <vector>
......@@ -132,6 +133,8 @@ class SVX_DLLPUBLIC EnhancedCustomShape2d : public SfxItemSet
sal_uInt32 nColorCount);
SAL_DLLPRIVATE Point GetPoint( const css::drawing::EnhancedCustomShapeParameterPair&,
const bool bScale = true, const bool bReplaceGeoSize = false ) const;
SAL_DLLPRIVATE basegfx::B2DPoint GetPointAsB2DPoint(const css::drawing::EnhancedCustomShapeParameterPair&,
const bool bScale = true, const bool bReplaceGeoSize = false ) const;
SAL_DLLPRIVATE void CreateSubPath(
sal_Int32& rSrcPt,
......
......@@ -48,9 +48,13 @@ public:
}
void testViewBoxLeftTop();
void testAccuracyCommandX();
void testToggleCommandXY();
CPPUNIT_TEST_SUITE(CustomshapesTest);
CPPUNIT_TEST(testViewBoxLeftTop);
CPPUNIT_TEST(testAccuracyCommandX);
CPPUNIT_TEST(testToggleCommandXY);
CPPUNIT_TEST_SUITE_END();
};
......@@ -96,6 +100,67 @@ void CustomshapesTest::testViewBoxLeftTop()
CPPUNIT_ASSERT_LESS(static_cast<long>(3), labs(aFrameRectTB.Y - aBoundRectTB.Y));
}
void CustomshapesTest::testAccuracyCommandX()
{
// 121761 Increase accuracy of quarter circles drawn by command X or Y
// The loaded document has a quarter circle with radius 10000 (unit 1/100 mm)
// which is rotated by 45deg. The test considers the segment.
OUString aURL
= 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<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;
double fHeight = static_cast<double>(aBoundRect.Height);
// The tolerance is a guess, might be smaller.
CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("segment height out of tolerance", 2942.0, fHeight, 8.0);
}
void CustomshapesTest::testToggleCommandXY()
{
// 121952 Toggle x- and y-direction if command X has several parameters
// The loaded document has a shape with command X and two parameter placed on a diagonal.
// The radius of the quarter circles are both 10000 (unit 1/100 mm).
// The shape is rotated by 45deg, so you get two segments, one up and one down.
OUString aURL
= 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<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;
double fHeight = static_cast<double>(aBoundRect.Height);
// The tolerance is a guess, might be smaller.
CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("segment height out of tolerance", 5871.0, fHeight, 16.0);
}
CPPUNIT_TEST_SUITE_REGISTRATION(CustomshapesTest);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment