summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRegina Henschel <rb.henschel@t-online.de>2024-03-29 22:44:45 +0100
committerRegina Henschel <rb.henschel@t-online.de>2024-03-30 21:19:25 +0100
commit9761d4239de6398d4f6ecf08356f2ce18e502a04 (patch)
treeeaf040b20b68754484dbbddaa136f96759d2fec4
parentf7ccf46b13ddf4501d5952ec38b1c680398f2101 (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.cxx42
-rw-r--r--svx/qa/unit/data/tdf160421_3D_FlipLight.odpbin0 -> 23011 bytes
-rw-r--r--svx/source/customshapes/EnhancedCustomShape3d.cxx8
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
new file mode 100644
index 000000000000..2decc51e3e6d
--- /dev/null
+++ b/svx/qa/unit/data/tdf160421_3D_FlipLight.odp
Binary files 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"