diff options
author | Daniel Arato (NISZ) <arato.daniel@nisz.hu> | 2020-09-29 16:37:41 +0200 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2020-10-09 10:12:35 +0200 |
commit | a9c5c0d814a266096483572b84c72875ef8efd77 (patch) | |
tree | 88e3ccb249e188f10050addc1a7cfdf173dc8e71 /oox/source | |
parent | 20da1a5dd37c7edac620566c992d5a53b23a5f12 (diff) |
tdf#133037 OOXML shape import: camera rotation along Z
Instead of implementing proper OOXML 3D rotation (which would be
an entirely new feature if I understand correctly), I merely
interpret attribute "rev" of the rotation element a:camera/a:rot
as a directive to rotate the entire shape the usual 2D way. That
is already implemented and works well. This isn't the same thing
Word does, but it might be good enough for now. This is kind of a
mock solution, but it will be very easy to revert if it turns out
to cause problems.
Note: the export worked well previously, too (moreover, reloading
the first LO export fixed the import).
Change-Id: I2a99c119880bbed1c5b6430c4638cfbd10b7ac06
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103627
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
Diffstat (limited to 'oox/source')
-rw-r--r-- | oox/source/drawingml/shape.cxx | 7 | ||||
-rw-r--r-- | oox/source/export/drawingml.cxx | 32 |
2 files changed, 35 insertions, 4 deletions
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index c9ade16f7a1d..95b608eadcc6 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -1461,11 +1461,14 @@ Reference< XShape > const & Shape::createAndInsert( else if( getTextBody() ) getTextBody()->getTextProperties().pushVertSimulation(); + // tdf#133037: a bit hackish: force Shape to rotate in the opposite direction the camera would rotate + const sal_Int32 nCameraRotation = get3DProperties().maCameraRotation.mnRevolution.get(0); + PropertySet aPropertySet(mxShape); - if ( !bUseRotationTransform && mnRotation != 0 ) + if ( !bUseRotationTransform && (mnRotation != 0 || nCameraRotation != 0) ) { // use the same logic for rotation from VML exporter (SimpleShape::implConvertAndInsert at vmlshape.cxx) - aPropertySet.setAnyProperty( PROP_RotateAngle, makeAny( sal_Int32( NormAngle36000( mnRotation / -600 ) ) ) ); + aPropertySet.setAnyProperty( PROP_RotateAngle, makeAny( sal_Int32( NormAngle36000( (mnRotation - nCameraRotation) / -600 ) ) ) ); aPropertySet.setAnyProperty( PROP_HoriOrientPosition, makeAny( maPosition.X ) ); aPropertySet.setAnyProperty( PROP_VertOrientPosition, makeAny( maPosition.Y ) ); } diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 4a9ac9f69014..c19b030ad642 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -1708,7 +1708,8 @@ void DrawingML::WriteShapeTransformation( const Reference< XShape >& rXShape, sa { SAL_INFO("oox.shape", "write shape transformation"); - sal_Int32 nRotation=0; + sal_Int32 nRotation = 0; + sal_Int32 nCameraRotation = 0; awt::Point aPos = rXShape->getPosition(); awt::Size aSize = rXShape->getSize(); @@ -1745,6 +1746,33 @@ void DrawingML::WriteShapeTransformation( const Reference< XShape >& rXShape, sa uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo(); if (xPropertySetInfo->hasPropertyByName("RotateAngle")) xPropertySet->getPropertyValue("RotateAngle") >>= nRotation; + // tdf#133037: restore original rotate angle before output + if (xPropertySetInfo->hasPropertyByName(UNO_NAME_MISC_OBJ_INTEROPGRABBAG)) + { + uno::Sequence<beans::PropertyValue> aGrabBagProps; + xPropertySet->getPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG) >>= aGrabBagProps; + auto p3DEffectProps = std::find_if(std::cbegin(aGrabBagProps), std::cend(aGrabBagProps), + [](const PropertyValue& rProp) { return rProp.Name == "3DEffectProperties"; }); + if (p3DEffectProps != std::cend(aGrabBagProps)) + { + uno::Sequence<beans::PropertyValue> a3DEffectProps; + p3DEffectProps->Value >>= a3DEffectProps; + auto pCameraProps = std::find_if(std::cbegin(a3DEffectProps), std::cend(a3DEffectProps), + [](const PropertyValue& rProp) { return rProp.Name == "Camera"; }); + if (pCameraProps != std::cend(a3DEffectProps)) + { + uno::Sequence<beans::PropertyValue> aCameraProps; + pCameraProps->Value >>= aCameraProps; + auto pZRotationProp = std::find_if(std::cbegin(aCameraProps), std::cend(aCameraProps), + [](const PropertyValue& rProp) { return rProp.Name == "rotRev"; }); + if (pZRotationProp != std::cend(aCameraProps)) + { + pZRotationProp->Value >>= nCameraRotation; + nCameraRotation = NormAngle36000(nCameraRotation / -600); + } + } + } + } } // OOXML flips shapes before rotating them. @@ -1752,7 +1780,7 @@ void DrawingML::WriteShapeTransformation( const Reference< XShape >& rXShape, sa nRotation = nRotation * -1 + 36000; WriteTransformation(tools::Rectangle(Point(aPos.X, aPos.Y), Size(aSize.Width, aSize.Height)), nXmlNamespace, - bFlipHWrite, bFlipVWrite, ExportRotateClockwisify(nRotation), IsGroupShape( rXShape )); + bFlipHWrite, bFlipVWrite, ExportRotateClockwisify(nRotation + nCameraRotation), IsGroupShape( rXShape )); } void DrawingML::WriteRunProperties( const Reference< XPropertySet >& rRun, bool bIsField, sal_Int32 nElement, |