tdf#70039 partly enable 3D-image from pptx

This enables 3D for those images, that have been cropped to a shape.
Those images are imported as custom shapes anyway and thus can use the
now possible rendering as 3D-scene.

The patch does not change the import of pure images with 3D properties.
(Such is possible in OOXML.) Using a custom shape here too, would
restrict the user. Exchange of the image or using color corrections
and filters on the image, for example, would be no longer possible.

It also fixes the error, that a z-rotation of a pure image was no
longer considered.

Change-Id: I626b1687c5aed1cac6f35388a3b25941673b5513
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165194
Tested-by: Jenkins
Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
This commit is contained in:
Regina Henschel
2024-03-23 10:20:25 +01:00
parent c845b7db95
commit 15e43d9679
5 changed files with 85 additions and 11 deletions
Binary file not shown.
Binary file not shown.
+68
View File
@@ -555,6 +555,74 @@ CPPUNIT_TEST_FIXTURE(TestScene3d, test_material_wireframe)
"shade-mode"_ostr, "draft");
}
CPPUNIT_TEST_FIXTURE(TestScene3d, test_cropped_image)
{
// The file contains an image that has been cropped to shape in PowerPoint. The image is in 3D
// mode with perspective camera perspectiveContrastingRightFacing and perspective angle 120°. The
// extrusion is 76200 EMU deep with extrusion color #00B050. As a cropped image, it was imported
// in earlier LO versions as custom shape with bitmap fill, but without any 3D.
loadFromFile(u"Scene3d_cropped_image.pptx");
uno::Reference<drawing::XShape> xShape(getShape(0, 0)); // shape 0 on page 0
// Prepare property maps
uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
uno::Sequence<beans::PropertyValue> aGeoPropSeq;
xShapeProps->getPropertyValue(u"CustomShapeGeometry"_ustr) >>= aGeoPropSeq;
comphelper::SequenceAsHashMap aGeoPropMap(aGeoPropSeq);
uno::Sequence<beans::PropertyValue> aExtrusionSeq;
aGeoPropMap.getValue(u"Extrusion"_ustr) >>= aExtrusionSeq;
comphelper::SequenceAsHashMap aExtrusionPropMap(aExtrusionSeq);
// Check that extrusion is on and has the correct geometry.
bool bIsExtruded(false);
aExtrusionPropMap.getValue(u"Extrusion"_ustr) >>= bIsExtruded;
CPPUNIT_ASSERT_MESSAGE("error: Extrusion is disabled", bIsExtruded);
drawing::ProjectionMode eProjectionMode = drawing::ProjectionMode_PARALLEL;
aExtrusionPropMap.getValue(u"ProjectionMode"_ustr) >>= eProjectionMode;
CPPUNIT_ASSERT_EQUAL(drawing::ProjectionMode_PERSPECTIVE, eProjectionMode);
drawing::Position3D aViewPoint;
aExtrusionPropMap.getValue(u"ViewPoint"_ustr) >>= aViewPoint;
CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, aViewPoint.PositionX, 1E-12);
CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, aViewPoint.PositionY, 1E-12);
CPPUNIT_ASSERT_DOUBLES_EQUAL(9223.7479, aViewPoint.PositionZ, 1E-5);
// Check shape rotation angles
drawing::EnhancedCustomShapeParameterPair aParaPair;
aExtrusionPropMap.getValue(UNO_NAME_MISC_OBJ_ROTATEANGLE) >>= aParaPair;
CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.94093344831102, aParaPair.First.Value.get<double>(), 1E-12);
CPPUNIT_ASSERT_DOUBLES_EQUAL(-44.4431265782766, aParaPair.Second.Value.get<double>(), 1E-12);
sal_Int32 nZRotate; // unit 1/100 degree
xShapeProps->getPropertyValue(UNO_NAME_MISC_OBJ_ROTATEANGLE) >>= nZRotate;
CPPUNIT_ASSERT_EQUAL(sal_Int32(496), nZRotate);
// Check extrusion depth and color
aExtrusionPropMap.getValue(u"Depth"_ustr) >>= aParaPair;
CPPUNIT_ASSERT_DOUBLES_EQUAL(212.0, aParaPair.First.Value.get<double>(), 1E-12);
Color nColor;
xShapeProps->getPropertyValue(UNO_NAME_FILLCOLOR_2) >>= nColor;
CPPUNIT_ASSERT_EQUAL(Color(0x00b050), nColor);
}
CPPUNIT_TEST_FIXTURE(TestScene3d, test_pureImage)
{
// Given a document with a scene3d element on an image. Because it would lose image properties
// it is currently (March 2024) not imported as custom shape. But the z-rotation is evaluated
// as users might have used this instead of shape rotation, for example.
loadFromFile(u"Scene3d_pureImage.pptx");
uno::Reference<drawing::XShape> xShape(getShape(0, 0)); // shape 0 on page 0
// Make sure it is an image.
CPPUNIT_ASSERT_EQUAL(u"com.sun.star.drawing.GraphicObjectShape"_ustr, xShape->getShapeType());
// Make sure the image is rotated.
uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
sal_Int32 nZRotate; // unit 1/100 degree
xShapeProps->getPropertyValue(UNO_NAME_MISC_OBJ_ROTATEANGLE) >>= nZRotate;
CPPUNIT_ASSERT_EQUAL(sal_Int32(27000), nZRotate);
}
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+14 -6
View File
@@ -398,6 +398,18 @@ bool Scene3DHelper::setExtrusionProperties(const oox::drawingml::Shape3DProperti
return false; // error in document. OOXML specifies a fixed set of preset camera types.
mnPrstCameraIndex = nPrstCameraIndex;
// Extrusion color is not handled as extrusion property but as shape property. Thus deliver it
// in any case, so that Shape::createAndInsert() knows about it.
rExtrusionColor = (*p3DProperties).maExtrusionColor;
// Even if we do not extrude an image, we still want to get the z-Rotation.
if (bBlockExtrusion)
{
rRotZ = basegfx::deg2rad<60000>((*p3DProperties).maCameraRotation.mnRevolution.value_or(0)
- rnMSOShapeRotation);
return false;
}
// We use extrusion, if there is a rotation around x-axis or y-axis,
// or if there is no such rotation but we have a perspective projection with true depth,
// or we have a parallel projection other than a 'front' type.
@@ -413,18 +425,14 @@ bool Scene3DHelper::setExtrusionProperties(const oox::drawingml::Shape3DProperti
|| (!bIsParallel && nDepthAmount > 0)
|| (bIsParallel && !bIsParallelFrontType);
// Extrusion color is not handled as extrusion property but as shape property. Thus deliver it
// in any case, so that Shape::createAndInsert() knows about it.
rExtrusionColor = (*p3DProperties).maExtrusionColor;
if (!bCreateExtrusion || bBlockExtrusion)
if (!bCreateExtrusion)
return false;
// Create the extrusion properties in rPropertyMap so that they can be directly used.
// Turn extrusion on
rPropertyMap.setProperty(oox::PROP_Extrusion, true);
// Dummy value. Will be changed from evaluating the material properties, when implemented.
// Dummy value. Will be changed from evaluating the material properties.
rPropertyMap.setProperty(oox::PROP_Diffusion, 100.0);
// Camera properties
+3 -5
View File
@@ -975,11 +975,9 @@ Reference< XShape > const & Shape::createAndInsert(
bool bIsCustomShape = (aServiceName == "com.sun.star.drawing.CustomShape" || bIsCroppedGraphic);
bool bIsConnectorShape = (aServiceName == "com.sun.star.drawing.ConnectorShape");
// Look for 3D. Its z-rotation and extrusion color become shape properties. Do it early as
// graphics might use 3D too and in that case should be imported as custom shape as well.
// FixMe. tdf#159515. We currently do not use extrusion, if an image has a 3D-scene.
bool bBlockExtrusion = aServiceName == "com.sun.star.drawing.GraphicObjectShape" &&
mp3DPropertiesPtr->mnPreset.has_value();
// Look for 3D. Its z-rotation and extrusion color become shape properties. We consider a
// z-rotation of an image even we currently do not extrude an image to 3D-scene.
bool bBlockExtrusion = !bIsCustomShape && mp3DPropertiesPtr->mnPreset.has_value();
double fShapeRotateInclCamera = 0.0; // unit rad; same orientation as shape property RotateAngle
Color aExtrusionColor;
Scene3DHelper aScene3DHelper;