svx/qa/unit/customshapes.cxx | 42 ++++++++++++++++++++++ svx/qa/unit/data/tdf160421_3D_FlipLight.odp |binary svx/source/customshapes/EnhancedCustomShape3d.cxx | 8 ++++ 3 files changed, 50 insertions(+)
New commits: commit 9761d4239de6398d4f6ecf08356f2ce18e502a04 Author: Regina Henschel <[email protected]> AuthorDate: Fri Mar 29 22:44:45 2024 +0100 Commit: Regina Henschel <[email protected]> CommitDate: Sat Mar 30 21:19:25 2024 +0100 tdf#160421 flip lights too for flipped extruded shapes If an extruded custom shape is mirrored, the lights in the scene are also mirrored. This should not happen. MS Office keeps the light direction in relation to the camera direction for binary files and pptx files with legacy camera. We should do the same, especially since the UI does not allow the user to set the light directions at arbitrary angles. Otherwise the shape receives only ambient light. Change-Id: I091d78c581b3d247f8b0680cd57654e3df330cdd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165562 Tested-by: Jenkins Reviewed-by: Regina Henschel <[email protected]> diff --git a/svx/qa/unit/customshapes.cxx b/svx/qa/unit/customshapes.cxx index 617c97300c43..92770e9f2320 100644 --- a/svx/qa/unit/customshapes.cxx +++ b/svx/qa/unit/customshapes.cxx @@ -58,6 +58,9 @@ protected: // get shape nShapeIndex from page 0 uno::Reference<drawing::XShape> getShape(sal_uInt8 nShapeIndex); sal_uInt8 countShapes(); + // fX and fY are positions relative to the size of the bitmap of the shape + // Thus the position is indepedent from DPI + Color getColor(uno::Reference<drawing::XShape> xShape, const double& fX, const double& fY); }; uno::Reference<drawing::XShape> CustomshapesTest::getShape(sal_uInt8 nShapeIndex) @@ -84,6 +87,18 @@ sal_uInt8 CustomshapesTest::countShapes() return xDrawPage->getCount(); } +Color CustomshapesTest::getColor(uno::Reference<drawing::XShape> xShape, const double& fX, + const double& fY) +{ + GraphicHelper::SaveShapeAsGraphicToPath(mxComponent, xShape, "image/png", maTempFile.GetURL()); + SvFileStream aFileStream(maTempFile.GetURL(), StreamMode::READ); + vcl::PngImageReader aPNGReader(aFileStream); + Bitmap aBMP = aPNGReader.read().GetBitmap(); + Size aSize = aBMP.GetSizePixel(); + BitmapScopedReadAccess pRead(aBMP); + return pRead->GetColor(aSize.Height() * fY, aSize.Width() * fX); +} + CPPUNIT_TEST_FIXTURE(CustomshapesTest, testTdf150302) { loadFromFile(u"FontworkSameLetterHeights.fodg"); @@ -1376,6 +1391,33 @@ CPPUNIT_TEST_FIXTURE(CustomshapesTest, testTdf153000_MS0_SPT_25_31) CPPUNIT_ASSERT_EQUAL(aExpected[i], aCoordinates.getLength()); } } + +CPPUNIT_TEST_FIXTURE(CustomshapesTest, testTdf160421_3D_FlipLight) +{ + // The document contains (0)an extruded 'rectangle' custom shape which is illuminated with front + // light, (1) this shape vertically flipped and (2) this shape horizontally flipped. + // When the shape is flipped vertically or horizontally, the light direction should not + // change. MS Office behaves in this way for ppt and pptx and it is meaningful as flipping is + // applied to the shape, not to the scene. + + // Load document. + loadFromFile(u"tdf160421_3D_FlipLight.odp"); + + // Get color from untransformed shape (0). + uno::Reference<drawing::XShape> xShape = getShape(0); + Color aNormalColor = getColor(xShape, 0.6, 0.6); + + // Test that color from vertically flipped shape (1) is same as normal color. Without the fix + // it was only build from ambient light and thus much darker. + xShape = getShape(1); + sal_uInt16 nColorDistance = aNormalColor.GetColorError(getColor(xShape, 0.6, 0.6)); + CPPUNIT_ASSERT_LESS(sal_uInt16(6), nColorDistance); + + // Same for horizontally flipped shape (2) + xShape = getShape(2); + nColorDistance = aNormalColor.GetColorError(getColor(xShape, 0.6, 0.6)); + CPPUNIT_ASSERT_LESS(sal_uInt16(6), nColorDistance); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/qa/unit/data/tdf160421_3D_FlipLight.odp b/svx/qa/unit/data/tdf160421_3D_FlipLight.odp new file mode 100644 index 000000000000..2decc51e3e6d Binary files /dev/null and b/svx/qa/unit/data/tdf160421_3D_FlipLight.odp differ diff --git a/svx/source/customshapes/EnhancedCustomShape3d.cxx b/svx/source/customshapes/EnhancedCustomShape3d.cxx index 2763c9e47e00..d2f9de215f65 100644 --- a/svx/source/customshapes/EnhancedCustomShape3d.cxx +++ b/svx/source/customshapes/EnhancedCustomShape3d.cxx @@ -838,6 +838,14 @@ rtl::Reference<SdrObject> EnhancedCustomShape3d::Create3DObject( basegfx::B3DVector aLight2Vector(aSecondLightDirection.DirectionX, -aSecondLightDirection.DirectionY, aSecondLightDirection.DirectionZ); aLight2Vector.normalize(); + // tdf#160421 a single flip inverts the light directions currently (March 2024). So invert + // their directions here for rendering. + if (bIsMirroredX != bIsMirroredY) + { + aLight1Vector *= -1.0; + aLight2Vector *= -1.0; + } + // Light Intensity // For "FirstLight" the 3D-Scene light "1" is regularly used. In case of surface "Matte"
