[Libreoffice-commits] core.git: drawinglayer/source svx/CppunitTest_svx_unit.mk svx/qa svx/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Mon May 11 16:47:53 UTC 2020


 drawinglayer/source/tools/primitive2dxmldump.cxx     |   20 +++
 svx/CppunitTest_svx_unit.mk                          |    1 
 svx/qa/unit/data/shadow-scale-origin.pptx            |binary
 svx/qa/unit/sdr.cxx                                  |   96 +++++++++++++++++++
 svx/source/sdr/primitive2d/sdrdecompositiontools.cxx |   14 ++
 5 files changed, 128 insertions(+), 3 deletions(-)

New commits:
commit e21d522dddce2590ed435890ae8d5fe39658a71a
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon May 11 16:38:12 2020 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon May 11 18:47:20 2020 +0200

    tdf#129916 svx: fix origin of scaled shadow
    
    We assumed that the top left corner is the origin for scaling, but that
    is not necessarily the case. The intention is that the shadow direction
    can be determined from its x and y offset, and the origin is the
    opposite corner of the shape.
    
    Change-Id: I6759302767d20739b6e2be79d379740dd06f70f5
    (cherry picked from commit a1dde1a85a8d1c54521a0ac6310571ffcdd4bb5a)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93974
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/drawinglayer/source/tools/primitive2dxmldump.cxx b/drawinglayer/source/tools/primitive2dxmldump.cxx
index 5ba531d1b1de..7fd249697ac2 100644
--- a/drawinglayer/source/tools/primitive2dxmldump.cxx
+++ b/drawinglayer/source/tools/primitive2dxmldump.cxx
@@ -423,9 +423,27 @@ void Primitive2dXmlDump::decomposeAndWrite(
                 break;
             }
 
+            case PRIMITIVE2D_ID_SHADOWPRIMITIVE2D:
+            {
+                // ShadowPrimitive2D.
+                rWriter.startElement("shadow");
+                drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer;
+                pBasePrimitive->get2DDecomposition(aPrimitiveContainer,
+                                                   drawinglayer::geometry::ViewInformation2D());
+                decomposeAndWrite(aPrimitiveContainer, rWriter);
+                rWriter.endElement();
+                break;
+            }
+
             default:
             {
-                rWriter.element(OUStringToOString(sCurrentElementTag, RTL_TEXTENCODING_UTF8));
+                rWriter.startElement("unhandled");
+                rWriter.attribute("id", OUStringToOString(sCurrentElementTag, RTL_TEXTENCODING_UTF8));
+                drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer;
+                pBasePrimitive->get2DDecomposition(aPrimitiveContainer,
+                                                   drawinglayer::geometry::ViewInformation2D());
+                decomposeAndWrite(aPrimitiveContainer, rWriter);
+                rWriter.endElement();
             }
             break;
         }
diff --git a/svx/CppunitTest_svx_unit.mk b/svx/CppunitTest_svx_unit.mk
index 92feb45d6578..ac9f3e4531ad 100644
--- a/svx/CppunitTest_svx_unit.mk
+++ b/svx/CppunitTest_svx_unit.mk
@@ -26,6 +26,7 @@ $(eval $(call gb_CppunitTest_add_exception_objects,svx_unit, \
 	svx/qa/unit/svdraw/test_SdrTextObject \
 	svx/qa/unit/customshapes \
     svx/qa/unit/classicshapes \
+	svx/qa/unit/sdr \
 	svx/qa/unit/svdraw \
 	svx/qa/unit/unodraw \
 	svx/qa/unit/xoutdev \
diff --git a/svx/qa/unit/data/shadow-scale-origin.pptx b/svx/qa/unit/data/shadow-scale-origin.pptx
new file mode 100644
index 000000000000..a0a164a3cddf
Binary files /dev/null and b/svx/qa/unit/data/shadow-scale-origin.pptx differ
diff --git a/svx/qa/unit/sdr.cxx b/svx/qa/unit/sdr.cxx
new file mode 100644
index 000000000000..a83ad564f33f
--- /dev/null
+++ b/svx/qa/unit/sdr.cxx
@@ -0,0 +1,96 @@
+/* -*- 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 <test/bootstrapfixture.hxx>
+#include <unotest/macros_test.hxx>
+#include <test/xmltesttools.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+
+#include <drawinglayer/tools/primitive2dxmldump.hxx>
+#include <rtl/ustring.hxx>
+#include <svx/sdr/contact/displayinfo.hxx>
+#include <svx/sdr/contact/viewcontact.hxx>
+#include <svx/sdr/contact/viewobjectcontact.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/unopage.hxx>
+#include <vcl/virdev.hxx>
+#include <sdr/contact/objectcontactofobjlistpainter.hxx>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for svx/source/sdr/ code.
+class SdrTest : public test::BootstrapFixture, public unotest::MacrosTest, public XmlTestTools
+{
+protected:
+    uno::Reference<lang::XComponent> 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();
+    }
+    uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
+};
+
+CPPUNIT_TEST_FIXTURE(SdrTest, testShadowScaleOrigin)
+{
+    // Load a document containing a custom shape.
+    test::Directories aDirectories;
+    OUString aURL = aDirectories.getURLFromSrc("svx/qa/unit/data/shadow-scale-origin.pptx");
+    getComponent() = loadFromDesktop(aURL);
+    uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(getComponent(), uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+                                                 uno::UNO_QUERY);
+
+    // Render it.
+    auto pDrawPage = dynamic_cast<SvxDrawPage*>(xDrawPage.get());
+    CPPUNIT_ASSERT(pDrawPage);
+    SdrPage* pSdrPage = pDrawPage->GetSdrPage();
+    ScopedVclPtrInstance<VirtualDevice> aVirtualDevice;
+    sdr::contact::ObjectContactOfObjListPainter aObjectContact(*aVirtualDevice,
+                                                               { pSdrPage->GetObj(0) }, nullptr);
+    const sdr::contact::ViewObjectContact& rDrawPageVOContact
+        = pSdrPage->GetViewContact().GetViewObjectContact(aObjectContact);
+    sdr::contact::DisplayInfo aDisplayInfo;
+    drawinglayer::primitive2d::Primitive2DContainer xPrimitiveSequence
+        = rDrawPageVOContact.getPrimitive2DSequenceHierarchy(aDisplayInfo);
+
+    // Examine the created primitives.
+    drawinglayer::tools::Primitive2dXmlDump aDumper;
+    xmlDocUniquePtr pDocument = aDumper.dumpAndParse(xPrimitiveSequence);
+    double fShadowX = getXPath(pDocument, "//shadow/transform", "xy13").toDouble();
+    double fShadowY = getXPath(pDocument, "//shadow/transform", "xy23").toDouble();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: -705
+    // - Actual  : -158
+    // i.e. the shadow origin was not the top right corner for scaling (larger x position, so it was
+    // visible on the right of the shape as well).
+    CPPUNIT_ASSERT_EQUAL(-705., std::round(fShadowX));
+    CPPUNIT_ASSERT_EQUAL(-685., std::round(fShadowY));
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
index ca26a45f826b..c191e8724aaf 100644
--- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
+++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
@@ -500,9 +500,19 @@ namespace drawinglayer::primitive2d
                         double fShearX = 0;
                         rObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
                         // Scale the shadow
-                        aShadowOffset.translate(-aTranslate.getX(), -aTranslate.getY());
+                        double nTranslateX = aTranslate.getX();
+                        double nTranslateY = aTranslate.getY();
+
+                        // The origin for scaling is the top left corner by default. A negative
+                        // shadow offset changes the origin.
+                        if (rShadow.getOffset().getX() < 0)
+                            nTranslateX += aScale.getX();
+                        if (rShadow.getOffset().getY() < 0)
+                            nTranslateY += aScale.getY();
+
+                        aShadowOffset.translate(-nTranslateX, -nTranslateY);
                         aShadowOffset.scale(rShadow.getSize().getX() * 0.00001, rShadow.getSize().getY() * 0.00001);
-                        aShadowOffset.translate(aTranslate.getX(), aTranslate.getY());
+                        aShadowOffset.translate(nTranslateX, nTranslateY);
                     }
 
                     aShadowOffset.translate(rShadow.getOffset().getX(), rShadow.getOffset().getY());


More information about the Libreoffice-commits mailing list