summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorJacobo Aragunde Pérez <jaragunde@igalia.com>2014-05-05 17:24:59 +0200
committerJacobo Aragunde Pérez <jaragunde@igalia.com>2014-05-06 16:32:28 +0200
commit1b7773cb071c7bbf60ea023551f35375b6120d4a (patch)
tree01caeb4b93ffd64c3865c551691d3adc1b698f3d /oox
parent8d2a5c16c7e487b407aced891da17e5c2486f2ff (diff)
oox: preserve scene3d/camera effects on shapes.
Shapes can contain 3D effects like in the following example: <a:scene3d> <a:camera prst="isometricLeftDown" zoom="150000"/> <a:lightRig rig="threePt" dir="t"/> </a:scene3d> This patch preserves the a:camera tag and its attributes using the shape grab bag. It also adds a unit test for this case. Change-Id: Ic6a78031d2e1fb84a2bacd97b5cc9c55d9dbaa95
Diffstat (limited to 'oox')
-rw-r--r--oox/source/drawingml/scene3dcontext.cxx9
-rw-r--r--oox/source/drawingml/shape.cxx5
-rw-r--r--oox/source/drawingml/shape3dproperties.cxx97
-rw-r--r--oox/source/drawingml/shapepropertiescontext.cxx2
-rw-r--r--oox/source/export/drawingml.cxx53
-rw-r--r--oox/source/export/shapes.cxx1
6 files changed, 163 insertions, 4 deletions
diff --git a/oox/source/drawingml/scene3dcontext.cxx b/oox/source/drawingml/scene3dcontext.cxx
index bc0c1b96e27e..c9855e116f7e 100644
--- a/oox/source/drawingml/scene3dcontext.cxx
+++ b/oox/source/drawingml/scene3dcontext.cxx
@@ -46,9 +46,12 @@ ContextHandlerRef Scene3DPropertiesContext::onCreateContext( sal_Int32 aElementT
switch( aElementToken )
{
case A_TOKEN( camera ):
- mr3DProperties.mfFieldOfVision = rAttribs.getInteger( XML_fov, 0 ) / 60000.0; // 60000ths of degree
- mr3DProperties.mfZoom = rAttribs.getInteger( XML_zoom, 100000 ) / 100000.0;
- mr3DProperties.mnPreset = rAttribs.getToken( XML_prst, XML_none );
+ if( rAttribs.hasAttribute( XML_fov ) )
+ mr3DProperties.mfFieldOfVision = rAttribs.getInteger( XML_fov, 0 ) / 60000.0; // 60000ths of degree
+ if( rAttribs.hasAttribute( XML_zoom ) )
+ mr3DProperties.mfZoom = rAttribs.getInteger( XML_zoom, 100000 ) / 100000.0;
+ if( rAttribs.hasAttribute( XML_prst ) )
+ mr3DProperties.mnPreset = rAttribs.getToken( XML_prst, XML_none );
// TODO: nested element XML_rot
break;
case A_TOKEN( lightRig ):
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 4e06de08b21c..72a7920d26e4 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -924,6 +924,11 @@ Reference< XShape > Shape::createAndInsert(
putPropertyToGrabBag( "EffectProperties", Any( aEffectsGrabBag ) );
}
+
+ // add 3D effects if any
+ Sequence< PropertyValue > aCamera3DEffects = get3DProperties().getCameraAttributes();
+ if( aCamera3DEffects.getLength() > 0 )
+ putPropertyToGrabBag( "3DEffectProperties", Any( aCamera3DEffects ) );
}
// These can have a custom geometry, so position should be set here,
diff --git a/oox/source/drawingml/shape3dproperties.cxx b/oox/source/drawingml/shape3dproperties.cxx
index 1ef3f5dbae8c..86498aa3507e 100644
--- a/oox/source/drawingml/shape3dproperties.cxx
+++ b/oox/source/drawingml/shape3dproperties.cxx
@@ -31,6 +31,7 @@
#include <com/sun/star/graphic/XGraphicTransformer.hpp>
#include "oox/helper/propertymap.hxx"
#include "oox/helper/propertyset.hxx"
+#include "oox/token/tokens.hxx"
using namespace ::com::sun::star;
using namespace ::com::sun::star::drawing;
@@ -46,6 +47,102 @@ namespace oox {
namespace drawingml {
+OUString Shape3DProperties::getCameraPrstName( sal_Int32 nElement )
+{
+ switch( nElement )
+ {
+ case XML_legacyObliqueTopLeft: return OUString( "legacyObliqueTopLeft" );
+ case XML_legacyObliqueTop: return OUString( "legacyObliqueTop" );
+ case XML_legacyObliqueTopRight: return OUString( "legacyObliqueTopRight" );
+ case XML_legacyObliqueLeft: return OUString( "legacyObliqueLeft" );
+ case XML_legacyObliqueFront: return OUString( "legacyObliqueFront" );
+ case XML_legacyObliqueRight: return OUString( "legacyObliqueRight" );
+ case XML_legacyObliqueBottomLeft: return OUString( "legacyObliqueBottomLeft" );
+ case XML_legacyObliqueBottom: return OUString( "legacyObliqueBottom" );
+ case XML_legacyObliqueBottomRight: return OUString( "legacyObliqueBottomRight" );
+ case XML_legacyPerspectiveTopLeft: return OUString( "legacyPerspectiveTopLeft" );
+ case XML_legacyPerspectiveTop: return OUString( "legacyPerspectiveTop" );
+ case XML_legacyPerspectiveTopRight: return OUString( "legacyPerspectiveTopRight" );
+ case XML_legacyPerspectiveLeft: return OUString( "legacyPerspectiveLeft" );
+ case XML_legacyPerspectiveFront: return OUString( "legacyPerspectiveFront" );
+ case XML_legacyPerspectiveRight: return OUString( "legacyPerspectiveRight" );
+ case XML_legacyPerspectiveBottomLeft: return OUString( "legacyPerspectiveBottomLeft" );
+ case XML_legacyPerspectiveBottom: return OUString( "legacyPerspectiveBottom" );
+ case XML_legacyPerspectiveBottomRight: return OUString( "legacyPerspectiveBottomRight" );
+ case XML_orthographicFront: return OUString( "orthographicFront" );
+ case XML_isometricTopUp: return OUString( "isometricTopUp" );
+ case XML_isometricTopDown: return OUString( "isometricTopDown" );
+ case XML_isometricBottomUp: return OUString( "isometricBottomUp" );
+ case XML_isometricBottomDown: return OUString( "isometricBottomDown" );
+ case XML_isometricLeftUp: return OUString( "isometricLeftUp" );
+ case XML_isometricLeftDown: return OUString( "isometricLeftDown" );
+ case XML_isometricRightUp: return OUString( "isometricRightUp" );
+ case XML_isometricRightDown: return OUString( "isometricRightDown" );
+ case XML_isometricOffAxis1Left: return OUString( "isometricOffAxis1Left" );
+ case XML_isometricOffAxis1Right: return OUString( "isometricOffAxis1Right" );
+ case XML_isometricOffAxis1Top: return OUString( "isometricOffAxis1Top" );
+ case XML_isometricOffAxis2Left: return OUString( "isometricOffAxis2Left" );
+ case XML_isometricOffAxis2Right: return OUString( "isometricOffAxis2Right" );
+ case XML_isometricOffAxis2Top: return OUString( "isometricOffAxis2Top" );
+ case XML_isometricOffAxis3Left: return OUString( "isometricOffAxis3Left" );
+ case XML_isometricOffAxis3Right: return OUString( "isometricOffAxis3Right" );
+ case XML_isometricOffAxis3Bottom: return OUString( "isometricOffAxis3Bottom" );
+ case XML_isometricOffAxis4Left: return OUString( "isometricOffAxis4Left" );
+ case XML_isometricOffAxis4Right: return OUString( "isometricOffAxis4Right" );
+ case XML_isometricOffAxis4Bottom: return OUString( "isometricOffAxis4Bottom" );
+ case XML_obliqueTopLeft: return OUString( "obliqueTopLeft" );
+ case XML_obliqueTop: return OUString( "obliqueTop" );
+ case XML_obliqueTopRight: return OUString( "obliqueTopRight" );
+ case XML_obliqueLeft: return OUString( "obliqueLeft" );
+ case XML_obliqueRight: return OUString( "obliqueRight" );
+ case XML_obliqueBottomLeft: return OUString( "obliqueBottomLeft" );
+ case XML_obliqueBottom: return OUString( "obliqueBottom" );
+ case XML_obliqueBottomRight: return OUString( "obliqueBottomRight" );
+ case XML_perspectiveFront: return OUString( "perspectiveFront" );
+ case XML_perspectiveLeft: return OUString( "perspectiveLeft" );
+ case XML_perspectiveRight: return OUString( "perspectiveRight" );
+ case XML_perspectiveAbove: return OUString( "perspectiveAbove" );
+ case XML_perspectiveBelow: return OUString( "perspectiveBelow" );
+ case XML_perspectiveAboveLeftFacing: return OUString( "perspectiveAboveLeftFacing" );
+ case XML_perspectiveAboveRightFacing: return OUString( "perspectiveAboveRightFacing" );
+ case XML_perspectiveContrastingLeftFacing: return OUString( "perspectiveContrastingLeftFacing" );
+ case XML_perspectiveContrastingRightFacing: return OUString( "perspectiveContrastingRightFacing" );
+ case XML_perspectiveHeroicLeftFacing: return OUString( "perspectiveHeroicLeftFacing" );
+ case XML_perspectiveHeroicRightFacing: return OUString( "perspectiveHeroicRightFacing" );
+ case XML_perspectiveHeroicExtremeLeftFacing: return OUString( "perspectiveHeroicExtremeLeftFacing" );
+ case XML_perspectiveHeroicExtremeRightFacing: return OUString( "perspectiveHeroicExtremeRightFacing" );
+ case XML_perspectiveRelaxed: return OUString( "perspectiveRelaxed" );
+ case XML_perspectiveRelaxedModerately: return OUString( "perspectiveRelaxedModerately" );
+ }
+ SAL_WARN( "oox.drawingml", "Shape3DProperties::getCameraPrstName - unexpected prst type" );
+ return OUString();
+}
+
+css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getCameraAttributes()
+{
+ css::uno::Sequence<css::beans::PropertyValue> aSeq(3);
+ sal_Int32 nSize = 0;
+ if( mfFieldOfVision.has() )
+ {
+ aSeq[nSize].Name = "fov";
+ aSeq[nSize].Value = css::uno::Any( mfFieldOfVision.use() );
+ nSize++;
+ }
+ if( mfZoom.has() )
+ {
+ aSeq[nSize].Name = "zoom";
+ aSeq[nSize].Value = css::uno::Any( mfZoom.use() );
+ nSize++;
+ }
+ if( mnPreset.has() )
+ {
+ aSeq[nSize].Name = "prst";
+ aSeq[nSize].Value = css::uno::Any( getCameraPrstName( mnPreset.use() ) );
+ nSize++;
+ }
+ aSeq.realloc( nSize );
+ return aSeq;
+}
diff --git a/oox/source/drawingml/shapepropertiescontext.cxx b/oox/source/drawingml/shapepropertiescontext.cxx
index 10130d3e5eef..0823e67240c7 100644
--- a/oox/source/drawingml/shapepropertiescontext.cxx
+++ b/oox/source/drawingml/shapepropertiescontext.cxx
@@ -94,7 +94,7 @@ ContextHandlerRef ShapePropertiesContext::onCreateContext( sal_Int32 aElementTok
case A_TOKEN( effectDag ): // CT_EffectContainer
return new EffectPropertiesContext( *this, mrShape.getEffectProperties() );
- // todo
+ // todo not supported by core, only for preservation via grab bags
case A_TOKEN( scene3d ): // CT_Scene3D
return new Scene3DPropertiesContext( *this, mrShape.get3DProperties() );
break;
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 1fde44a0f713..6f61016bc387 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -2270,6 +2270,59 @@ void DrawingML::WriteShapeEffects( Reference< XPropertySet > rXPropSet )
}
}
+void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet )
+{
+ // check existence of the grab bag
+ if( !GetProperty( xPropSet, "InteropGrabBag" ) )
+ return;
+
+ // extract the relevant properties from the grab bag
+ Sequence< PropertyValue > aGrabBag, aEffectProps;
+ mAny >>= aGrabBag;
+ for( sal_Int32 i=0; i < aGrabBag.getLength(); ++i )
+ if( aGrabBag[i].Name == "3DEffectProperties" )
+ {
+ aGrabBag[i].Value >>= aEffectProps;
+ break;
+ }
+ if( aEffectProps.getLength() == 0 )
+ return;
+
+ sax_fastparser::FastAttributeList *aCameraAttrList = mpFS->createAttrList();
+ for( sal_Int32 i=0; i < aEffectProps.getLength(); ++i )
+ {
+ if( aEffectProps[i].Name == "prst" )
+ {
+ OUString sVal;
+ aEffectProps[i].Value >>= sVal;
+ aCameraAttrList->add( XML_prst, OUStringToOString( sVal, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ else if( aEffectProps[i].Name == "fov" )
+ {
+ float fVal = 0;
+ aEffectProps[i].Value >>= fVal;
+ aCameraAttrList->add( XML_fov, OString::number( fVal * 60000 ).getStr() );
+ }
+ else if( aEffectProps[i].Name == "zoom" )
+ {
+ float fVal = 1;
+ aEffectProps[i].Value >>= fVal;
+ aCameraAttrList->add( XML_zoom, OString::number( fVal * 100000 ).getStr() );
+ }
+ }
+
+ mpFS->startElementNS( XML_a, XML_scene3d, FSEND );
+
+ sax_fastparser::XFastAttributeListRef xAttrList( aCameraAttrList );
+ mpFS->startElementNS( XML_a, XML_camera, xAttrList );
+ mpFS->endElementNS( XML_a, XML_camera );
+
+ // a:lightRig with Word default values - Word won't open the document if this is not present
+ mpFS->singleElementNS( XML_a, XML_lightRig, XML_rig, "threePt", XML_dir, "t", FSEND );
+
+ mpFS->endElementNS( XML_a, XML_scene3d );
+}
+
}
}
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index 49d1a4bf31e4..c9eaa6fa384d 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -374,6 +374,7 @@ ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape )
WriteFill( rXPropSet );
WriteOutline( rXPropSet );
WriteShapeEffects( rXPropSet );
+ WriteShape3DEffects( rXPropSet );
}
pFS->endElementNS( mnXmlNamespace, XML_spPr );