svx/qa/unit/customshapes.cxx                      |   43 ++++++++++++++++++++++
 svx/qa/unit/data/tdf145245_ExtrusionPosition.odp  |binary
 svx/source/customshapes/EnhancedCustomShape3d.cxx |    4 +-
 3 files changed, 45 insertions(+), 2 deletions(-)

New commits:
commit 264da4cc0b60e75884ff66ab25fd38952cc6020d
Author:     Regina Henschel <rb.hensc...@t-online.de>
AuthorDate: Thu Oct 21 16:09:44 2021 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Fri Oct 22 14:50:06 2021 +0200

    tdf#145245 correct relative position of extrusion
    
    ODF specifies for draw:extrusion-depth, 'The draw:extrusion-depth
    attribute specifies the depth of an extrusion. It takes two white space
    separated values. The first value specifies the depth of the extrusion
    in units, the second value specifies the fraction of the extrusion that
    lies before a shape. The second value shall be in the range [0,1].'
    
    The default for the second value is 0. Because LibreOffice has no UI to
    change the value, the error becomes only visible, if you create own
    custom shapes.
    
    On import the ODF values are put in CustomShapeGeometry>Extrusion>
    Depth. Method GetExtrusionDepth() calculates from that the length
    values rBackwardDepth and rForwardDepth so that its sum is the depth.
    
    CreateCustomShapeProperties() in escherex.cxx#2699 and
    ApplyCustomShapeGeometryAttributes() in msdffimp.cxx#1684 use them in
    the same sence.
    
    But methods Create3DObject() and CalculateNewSnapRect() in
    EnhancedCustomShape3d.cxx have used these values as if they were
    coordinates.
    
    I have keept the calculation in GetExtrusionDepth(), because it
    reflects the meaning in ODF. I have corrected the signs in
    Create3DObject() and CalculateNewSnapRect().
    
    Change-Id: If275bb263b6f3d790f5893a69f38f8433acfbe7f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123997
    Tested-by: Jenkins
    Reviewed-by: Regina Henschel <rb.hensc...@t-online.de>
    (cherry picked from commit 5ab21caf603ba0a1c95bbc94a29eebe3483d1599)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124010
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/svx/qa/unit/customshapes.cxx b/svx/qa/unit/customshapes.cxx
index 509d6204908e..fb308b7c9761 100644
--- a/svx/qa/unit/customshapes.cxx
+++ b/svx/qa/unit/customshapes.cxx
@@ -127,6 +127,49 @@ void lcl_AssertRectEqualWithTolerance(std::string_view 
sInfo, const tools::Recta
                            std::abs(rExpected.GetHeight() - 
rActual.GetHeight()) <= nTolerance);
 }
 
+CPPUNIT_TEST_FIXTURE(CustomshapesTest, testTdf145245_ExtrusionPosition)
+{
+    // The second parameter of the extrusion-depth property specifies how much 
of the extrusion
+    // lies before the shape. The file contains three shapes which have the 
values 0, 0.5 and 1.
+    // They are rotated around the x-axis so that the extrusion becomes 
visible. The extrusion
+    // depth itself is 5cm. Y-coordinate of shape is 6cm.
+
+    // Load document
+    OUString aURL = m_directories.getURLFromSrc(sDataDirectory) + 
"tdf145245_ExtrusionPosition.odp";
+    mxComponent = loadFromDesktop(aURL, 
"com.sun.star.comp.presentation.PresentationDocument");
+
+    // The tolerance 40 is estimated and can be adjusted if required for HiDPI.
+    {
+        // First shape has extrusion behind the shape.
+        uno::Reference<drawing::XShape> xShape0(getShape(0));
+        SdrObjCustomShape& rSdrCustomShape(
+            
static_cast<SdrObjCustomShape&>(*SdrObject::getSdrObjectFromXShape(xShape0)));
+        tools::Rectangle aBoundRect(rSdrCustomShape.GetCurrentBoundRect());
+        tools::Rectangle aExpected(Point(1000, 1000), Size(6002, 5001));
+        lcl_AssertRectEqualWithTolerance("Pos 0.0 extrusion", aExpected, 
aBoundRect, 40);
+    }
+    {
+        // Second shape has half of extrusion behind the shape.
+        uno::Reference<drawing::XShape> xShape(getShape(1));
+        SdrObjCustomShape& rSdrCustomShape(
+            
static_cast<SdrObjCustomShape&>(*SdrObject::getSdrObjectFromXShape(xShape)));
+        // Without the fix the height was 1 instead of 5001.
+        tools::Rectangle aBoundRect(rSdrCustomShape.GetCurrentBoundRect());
+        tools::Rectangle aExpected(Point(9000, 3500), Size(6002, 5001));
+        lcl_AssertRectEqualWithTolerance("Pos 0.5 extrusion", aExpected, 
aBoundRect, 40);
+    }
+    {
+        // Third shape has extrusion before the shape.
+        uno::Reference<drawing::XShape> xShape(getShape(2));
+        SdrObjCustomShape& rSdrCustomShape(
+            
static_cast<SdrObjCustomShape&>(*SdrObject::getSdrObjectFromXShape(xShape)));
+        // Without the fix the y-coordinate was 1000 instead of 6000.
+        tools::Rectangle aBoundRect(rSdrCustomShape.GetCurrentBoundRect());
+        tools::Rectangle aExpected(Point(18000, 6000), Size(6002, 5001));
+        lcl_AssertRectEqualWithTolerance("Pos 1.0 extrusion", aExpected, 
aBoundRect, 40);
+    }
+}
+
 CPPUNIT_TEST_FIXTURE(CustomshapesTest, 
testTdf145111_Fontwork_rendering_font_size)
 {
     // The tested position and height depend on dpi.
diff --git a/svx/qa/unit/data/tdf145245_ExtrusionPosition.odp 
b/svx/qa/unit/data/tdf145245_ExtrusionPosition.odp
new file mode 100644
index 000000000000..a356cf9ed396
Binary files /dev/null and b/svx/qa/unit/data/tdf145245_ExtrusionPosition.odp 
differ
diff --git a/svx/source/customshapes/EnhancedCustomShape3d.cxx 
b/svx/source/customshapes/EnhancedCustomShape3d.cxx
index 9c933ef9313e..d52d9c5d4b60 100644
--- a/svx/source/customshapes/EnhancedCustomShape3d.cxx
+++ b/svx/source/customshapes/EnhancedCustomShape3d.cxx
@@ -304,7 +304,7 @@ SdrObject* EnhancedCustomShape3d::Create3DObject(
 
         double fExtrusionBackward, fExtrusionForward;
         GetExtrusionDepth( rGeometryItem, pMap, fExtrusionBackward, 
fExtrusionForward );
-        double fDepth = fExtrusionBackward - fExtrusionForward;
+        double fDepth = fExtrusionBackward + fExtrusionForward;
         if ( fDepth < 1.0 )
             fDepth = 1.0;
 
@@ -768,7 +768,7 @@ tools::Rectangle 
EnhancedCustomShape3d::CalculateNewSnapRect(
 
     for ( i = 0; i < 4; i++ )
     {
-        aBoundVolume.append(basegfx::B3DPoint(aPolygon[ 
static_cast<sal_uInt16>(i) ].X() - aCenter.X(), aPolygon[ 
static_cast<sal_uInt16>(i) ].Y() - aCenter.Y(), fExtrusionForward));
+        aBoundVolume.append(basegfx::B3DPoint(aPolygon[ 
static_cast<sal_uInt16>(i) ].X() - aCenter.X(), aPolygon[ 
static_cast<sal_uInt16>(i) ].Y() - aCenter.Y(), -fExtrusionForward));
     }
 
     for ( i = 0; i < 4; i++ )

Reply via email to