diff options
author | Regina Henschel <rb.henschel@t-online.de> | 2024-03-29 22:44:45 +0100 |
---|---|---|
committer | Regina Henschel <rb.henschel@t-online.de> | 2024-03-30 21:19:25 +0100 |
commit | 9761d4239de6398d4f6ecf08356f2ce18e502a04 (patch) | |
tree | eaf040b20b68754484dbbddaa136f96759d2fec4 | |
parent | f7ccf46b13ddf4501d5952ec38b1c680398f2101 (diff) |
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 <rb.henschel@t-online.de>
-rw-r--r-- | svx/qa/unit/customshapes.cxx | 42 | ||||
-rw-r--r-- | svx/qa/unit/data/tdf160421_3D_FlipLight.odp | bin | 0 -> 23011 bytes | |||
-rw-r--r-- | svx/source/customshapes/EnhancedCustomShape3d.cxx | 8 |
3 files changed, 50 insertions, 0 deletions
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 Binary files differnew file mode 100644 index 000000000000..2decc51e3e6d --- /dev/null +++ b/svx/qa/unit/data/tdf160421_3D_FlipLight.odp 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" |