diff options
author | Jacobo Aragunde Pérez <jaragunde@igalia.com> | 2014-05-05 17:24:59 +0200 |
---|---|---|
committer | Jacobo Aragunde Pérez <jaragunde@igalia.com> | 2014-05-06 16:32:28 +0200 |
commit | 1b7773cb071c7bbf60ea023551f35375b6120d4a (patch) | |
tree | 01caeb4b93ffd64c3865c551691d3adc1b698f3d /oox | |
parent | 8d2a5c16c7e487b407aced891da17e5c2486f2ff (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.cxx | 9 | ||||
-rw-r--r-- | oox/source/drawingml/shape.cxx | 5 | ||||
-rw-r--r-- | oox/source/drawingml/shape3dproperties.cxx | 97 | ||||
-rw-r--r-- | oox/source/drawingml/shapepropertiescontext.cxx | 2 | ||||
-rw-r--r-- | oox/source/export/drawingml.cxx | 53 | ||||
-rw-r--r-- | oox/source/export/shapes.cxx | 1 |
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 ); |