From 25f059a423d42b546e319d0860df0de9c1580101 Mon Sep 17 00:00:00 2001 From: Regina Henschel Date: Thu, 6 Dec 2018 12:27:25 +0100 Subject: tdf#121890 ODF custom shapes use left and top from viewBox MS custom shapes use always zero for identifier left and top in the formulas of the shape geometry. But custom shapes in ODF use the left and top value from the svg:viewBox attribute, see table 11 in section 19.171 draw:formula; part 1 of the spec. Change-Id: Ief4b9d9b8797e165a494d049f32c5a46880044c2 Reviewed-on: https://gerrit.libreoffice.org/64704 Tested-by: Jenkins Reviewed-by: Regina Henschel --- svx/CppunitTest_svx_unit.mk | 1 + svx/qa/unit/customshapes.cxx | 102 +++++++++++++++++++++ .../unit/data/viewBox_positive_twolines_strict.odp | Bin 0 -> 12107 bytes svx/source/customshapes/EnhancedCustomShape2d.cxx | 8 +- 4 files changed, 107 insertions(+), 4 deletions(-) create mode 100755 svx/qa/unit/customshapes.cxx create mode 100644 svx/qa/unit/data/viewBox_positive_twolines_strict.odp (limited to 'svx') diff --git a/svx/CppunitTest_svx_unit.mk b/svx/CppunitTest_svx_unit.mk index f48f2c1a5560..4ae8fecf2762 100644 --- a/svx/CppunitTest_svx_unit.mk +++ b/svx/CppunitTest_svx_unit.mk @@ -21,6 +21,7 @@ $(eval $(call gb_CppunitTest_set_include,svx_unit,\ $(eval $(call gb_CppunitTest_add_exception_objects,svx_unit, \ svx/qa/unit/svdraw/test_SdrTextObject \ + svx/qa/unit/customshapes \ svx/qa/unit/unodraw \ svx/qa/unit/xoutdev \ svx/qa/unit/XTableImportExportTest \ diff --git a/svx/qa/unit/customshapes.cxx b/svx/qa/unit/customshapes.cxx new file mode 100755 index 000000000000..b5aeea670ae2 --- /dev/null +++ b/svx/qa/unit/customshapes.cxx @@ -0,0 +1,102 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +using namespace ::com::sun::star; + +namespace +{ +const OUString sDataDirectory("/svx/qa/unit/data/"); + +/// Tests for svx/source/customshapes/ code. +class CustomshapesTest : public test::BootstrapFixture, public unotest::MacrosTest +{ + uno::Reference mxComponent; + +public: + virtual void setUp() override + { + test::BootstrapFixture::setUp(); + mxDesktop.set(frame::Desktop::create(m_xContext)); + } + + virtual void tearDown() override + { + if (mxComponent.is()) + { + mxComponent->dispose(); + } + test::BootstrapFixture::tearDown(); + } + + void testViewBoxLeftTop(); + + CPPUNIT_TEST_SUITE(CustomshapesTest); + CPPUNIT_TEST(testViewBoxLeftTop); + CPPUNIT_TEST_SUITE_END(); +}; + +void CustomshapesTest::testViewBoxLeftTop() +{ + // tdf#121890 formula values "left" and "top" are wrongly calculated + // Load a document with two custom shapes of type "non-primitive" + OUString aURL + = 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 xDrawPagesSupplier(mxComponent, + uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_MESSAGE("Could not get XDrawPagesSupplier", xDrawPagesSupplier.is()); + uno::Reference xDrawPages(xDrawPagesSupplier->getDrawPages()); + uno::Reference 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 xShapeLR(xDrawPage->getByIndex(0), uno::UNO_QUERY); + CPPUNIT_ASSERT_MESSAGE("Could not get the shape 'leftright'", xShapeLR.is()); + uno::Reference xShapeLRProps(xShapeLR, uno::UNO_QUERY); + CPPUNIT_ASSERT_MESSAGE("Could not get the shape 'leftright' properties", xShapeLRProps.is()); + awt::Rectangle aFrameRectLR; + xShapeLRProps->getPropertyValue(UNO_NAME_MISC_OBJ_FRAMERECT) >>= aFrameRectLR; + awt::Rectangle aBoundRectLR; + xShapeLRProps->getPropertyValue(UNO_NAME_MISC_OBJ_BOUNDRECT) >>= aBoundRectLR; + // difference should be zero, but allow some rounding errors + CPPUNIT_ASSERT_LESS(static_cast(3), labs(aFrameRectLR.X - aBoundRectLR.X)); + + // 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 xShapeTB(xDrawPage->getByIndex(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_MESSAGE("Could not get the shape 'topbottom'", xShapeTB.is()); + uno::Reference xShapeTBProps(xShapeTB, uno::UNO_QUERY); + CPPUNIT_ASSERT_MESSAGE("Could not get the shape 'topbottom' properties", xShapeTBProps.is()); + awt::Rectangle aFrameRectTB; + xShapeTBProps->getPropertyValue(UNO_NAME_MISC_OBJ_FRAMERECT) >>= aFrameRectTB; + awt::Rectangle aBoundRectTB; + xShapeTBProps->getPropertyValue(UNO_NAME_MISC_OBJ_BOUNDRECT) >>= aBoundRectTB; + // difference should be zero, but allow some rounding errors + CPPUNIT_ASSERT_LESS(static_cast(3), labs(aFrameRectTB.Y - aBoundRectTB.Y)); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(CustomshapesTest); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/qa/unit/data/viewBox_positive_twolines_strict.odp b/svx/qa/unit/data/viewBox_positive_twolines_strict.odp new file mode 100644 index 000000000000..3425582b82ba Binary files /dev/null and b/svx/qa/unit/data/viewBox_positive_twolines_strict.odp differ diff --git a/svx/source/customshapes/EnhancedCustomShape2d.cxx b/svx/source/customshapes/EnhancedCustomShape2d.cxx index 1b1312aff615..12448ca95054 100644 --- a/svx/source/customshapes/EnhancedCustomShape2d.cxx +++ b/svx/source/customshapes/EnhancedCustomShape2d.cxx @@ -831,10 +831,10 @@ double EnhancedCustomShape2d::GetEnumFunc( const ExpressionFunct eFunc ) const switch( eFunc ) { case ExpressionFunct::EnumPi : fRet = F_PI; break; - case ExpressionFunct::EnumLeft : fRet = 0.0; break; - case ExpressionFunct::EnumTop : fRet = 0.0; break; - case ExpressionFunct::EnumRight : fRet = static_cast(nCoordWidth) * fXRatio; break; - case ExpressionFunct::EnumBottom : fRet = static_cast(nCoordHeight) * fYRatio; break; + case ExpressionFunct::EnumLeft : fRet = static_cast(nCoordLeft); break; + case ExpressionFunct::EnumTop : fRet = static_cast(nCoordTop); break; + case ExpressionFunct::EnumRight : fRet = static_cast(nCoordLeft + nCoordWidth) * fXRatio; break; + case ExpressionFunct::EnumBottom : fRet = static_cast(nCoordTop + nCoordHeight) * fYRatio; break; case ExpressionFunct::EnumXStretch : fRet = nXRef; break; case ExpressionFunct::EnumYStretch : fRet = nYRef; break; case ExpressionFunct::EnumHasStroke : fRet = bStroked ? 1.0 : 0.0; break; -- cgit