Kaydet (Commit) 36e22e83 authored tarafından Jacobo Aragunde Pérez's avatar Jacobo Aragunde Pérez

oox: preserve camera rotation on shape 3D effects.

Camera options in shape 3D effects can have rotation settings like in
the following example:

  <a:camera prst="perspectiveRelaxedModerately" zoom="150000">
     <a:rot lat="19490639" lon="0" rev="12900001"/>
  </a:camera>

This patch preserves the a:rot tag and its attributes using the
shape grab bag. We created the class Scene3DRotationPropertiesContext
to be piled on top of a Scene3DPropertiesContext and process the
contents of the child item. It also adds a unit test for this case.

Change-Id: Id6bf58ad05fe5b49061619b6750ed0658badc9af
üst 1b7773cb
...@@ -27,6 +27,17 @@ namespace oox { namespace drawingml { ...@@ -27,6 +27,17 @@ namespace oox { namespace drawingml {
struct Shape3DProperties; struct Shape3DProperties;
class Scene3DRotationPropertiesContext : public ::oox::core::ContextHandler2
{
public:
Scene3DRotationPropertiesContext( ::oox::core::ContextHandler2Helper& rParent, RotationProperties& rRotationProperties ) throw();
::oox::core::ContextHandlerRef onCreateContext( ::sal_Int32 Element, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
private:
RotationProperties& mrRotationProperties;
};
class Scene3DPropertiesContext : public ::oox::core::ContextHandler2 class Scene3DPropertiesContext : public ::oox::core::ContextHandler2
{ {
public: public:
......
...@@ -36,6 +36,13 @@ namespace drawingml { ...@@ -36,6 +36,13 @@ namespace drawingml {
struct RotationProperties
{
OptValue< sal_Int32 > mnLatitude;
OptValue< sal_Int32 > mnLongitude;
OptValue< sal_Int32 > mnRevolution;
};
struct Shape3DProperties struct Shape3DProperties
{ {
OptValue< sal_Int32 > mnPreset; OptValue< sal_Int32 > mnPreset;
...@@ -43,6 +50,7 @@ struct Shape3DProperties ...@@ -43,6 +50,7 @@ struct Shape3DProperties
OptValue< float > mfZoom; OptValue< float > mfZoom;
OptValue< sal_Int32 > mnLightRigDirection; OptValue< sal_Int32 > mnLightRigDirection;
OptValue< sal_Int32 > mnLightRigType; OptValue< sal_Int32 > mnLightRigType;
RotationProperties maCameraRotation;
/** Overwrites all members that are explicitly set in rSourceProps. */ /** Overwrites all members that are explicitly set in rSourceProps. */
void assignUsed( const Shape3DProperties& rSourceProps ); void assignUsed( const Shape3DProperties& rSourceProps );
......
...@@ -52,8 +52,9 @@ ContextHandlerRef Scene3DPropertiesContext::onCreateContext( sal_Int32 aElementT ...@@ -52,8 +52,9 @@ ContextHandlerRef Scene3DPropertiesContext::onCreateContext( sal_Int32 aElementT
mr3DProperties.mfZoom = rAttribs.getInteger( XML_zoom, 100000 ) / 100000.0; mr3DProperties.mfZoom = rAttribs.getInteger( XML_zoom, 100000 ) / 100000.0;
if( rAttribs.hasAttribute( XML_prst ) ) if( rAttribs.hasAttribute( XML_prst ) )
mr3DProperties.mnPreset = rAttribs.getToken( XML_prst, XML_none ); mr3DProperties.mnPreset = rAttribs.getToken( XML_prst, XML_none );
// TODO: nested element XML_rot
break; return new Scene3DRotationPropertiesContext( *this, mr3DProperties.maCameraRotation );
case A_TOKEN( lightRig ): case A_TOKEN( lightRig ):
mr3DProperties.mnLightRigDirection = rAttribs.getToken( XML_dir, XML_none ); mr3DProperties.mnLightRigDirection = rAttribs.getToken( XML_dir, XML_none );
mr3DProperties.mnLightRigType = rAttribs.getToken( XML_rig, XML_none ); mr3DProperties.mnLightRigType = rAttribs.getToken( XML_rig, XML_none );
...@@ -66,6 +67,25 @@ ContextHandlerRef Scene3DPropertiesContext::onCreateContext( sal_Int32 aElementT ...@@ -66,6 +67,25 @@ ContextHandlerRef Scene3DPropertiesContext::onCreateContext( sal_Int32 aElementT
return 0; return 0;
} }
Scene3DRotationPropertiesContext::Scene3DRotationPropertiesContext( ContextHandler2Helper& rParent, RotationProperties& rRotationProperties ) throw()
: ContextHandler2( rParent )
, mrRotationProperties( rRotationProperties )
{
}
ContextHandlerRef Scene3DRotationPropertiesContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
{
switch( aElementToken )
{
case A_TOKEN( rot ):
mrRotationProperties.mnLatitude = rAttribs.getInteger( XML_lat, 0 );
mrRotationProperties.mnLongitude = rAttribs.getInteger( XML_lon, 0 );
mrRotationProperties.mnRevolution = rAttribs.getInteger( XML_rev, 0 );
break;
}
return 0;
}
} } } }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -120,7 +120,7 @@ OUString Shape3DProperties::getCameraPrstName( sal_Int32 nElement ) ...@@ -120,7 +120,7 @@ OUString Shape3DProperties::getCameraPrstName( sal_Int32 nElement )
css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getCameraAttributes() css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getCameraAttributes()
{ {
css::uno::Sequence<css::beans::PropertyValue> aSeq(3); css::uno::Sequence<css::beans::PropertyValue> aSeq(6);
sal_Int32 nSize = 0; sal_Int32 nSize = 0;
if( mfFieldOfVision.has() ) if( mfFieldOfVision.has() )
{ {
...@@ -140,6 +140,24 @@ css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getCameraAttr ...@@ -140,6 +140,24 @@ css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getCameraAttr
aSeq[nSize].Value = css::uno::Any( getCameraPrstName( mnPreset.use() ) ); aSeq[nSize].Value = css::uno::Any( getCameraPrstName( mnPreset.use() ) );
nSize++; nSize++;
} }
if( maCameraRotation.mnLatitude.has() )
{
aSeq[nSize].Name = "rotLat";
aSeq[nSize].Value = css::uno::Any( maCameraRotation.mnLatitude.use() );
nSize++;
}
if( maCameraRotation.mnLongitude.has() )
{
aSeq[nSize].Name = "rotLon";
aSeq[nSize].Value = css::uno::Any( maCameraRotation.mnLongitude.use() );
nSize++;
}
if( maCameraRotation.mnRevolution.has() )
{
aSeq[nSize].Name = "rotRev";
aSeq[nSize].Value = css::uno::Any( maCameraRotation.mnRevolution.use() );
nSize++;
}
aSeq.realloc( nSize ); aSeq.realloc( nSize );
return aSeq; return aSeq;
} }
......
...@@ -2288,7 +2288,9 @@ void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet ) ...@@ -2288,7 +2288,9 @@ void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet )
if( aEffectProps.getLength() == 0 ) if( aEffectProps.getLength() == 0 )
return; return;
bool bCameraRotationPresent = false;
sax_fastparser::FastAttributeList *aCameraAttrList = mpFS->createAttrList(); sax_fastparser::FastAttributeList *aCameraAttrList = mpFS->createAttrList();
sax_fastparser::FastAttributeList *aCameraRotationAttrList = mpFS->createAttrList();
for( sal_Int32 i=0; i < aEffectProps.getLength(); ++i ) for( sal_Int32 i=0; i < aEffectProps.getLength(); ++i )
{ {
if( aEffectProps[i].Name == "prst" ) if( aEffectProps[i].Name == "prst" )
...@@ -2309,12 +2311,32 @@ void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet ) ...@@ -2309,12 +2311,32 @@ void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet )
aEffectProps[i].Value >>= fVal; aEffectProps[i].Value >>= fVal;
aCameraAttrList->add( XML_zoom, OString::number( fVal * 100000 ).getStr() ); aCameraAttrList->add( XML_zoom, OString::number( fVal * 100000 ).getStr() );
} }
else if( aEffectProps[i].Name == "rotLat" ||
aEffectProps[i].Name == "rotLon" ||
aEffectProps[i].Name == "rotRev" )
{
sal_Int32 nVal = 0, nToken = XML_none;
aEffectProps[i].Value >>= nVal;
if( aEffectProps[i].Name == "rotLat" )
nToken = XML_lat;
else if( aEffectProps[i].Name == "rotLon" )
nToken = XML_lon;
else if( aEffectProps[i].Name == "rotRev" )
nToken = XML_rev;
aCameraRotationAttrList->add( nToken, OString::number( nVal ).getStr() );
bCameraRotationPresent = true;
}
} }
mpFS->startElementNS( XML_a, XML_scene3d, FSEND ); mpFS->startElementNS( XML_a, XML_scene3d, FSEND );
sax_fastparser::XFastAttributeListRef xAttrList( aCameraAttrList ); sax_fastparser::XFastAttributeListRef xAttrList( aCameraAttrList );
mpFS->startElementNS( XML_a, XML_camera, xAttrList ); mpFS->startElementNS( XML_a, XML_camera, xAttrList );
if( bCameraRotationPresent )
{
sax_fastparser::XFastAttributeListRef xRotAttrList( aCameraRotationAttrList );
mpFS->singleElementNS( XML_a, XML_rot, xRotAttrList );
}
mpFS->endElementNS( XML_a, XML_camera ); mpFS->endElementNS( XML_a, XML_camera );
// a:lightRig with Word default values - Word won't open the document if this is not present // a:lightRig with Word default values - Word won't open the document if this is not present
......
...@@ -1158,11 +1158,23 @@ DECLARE_OOXMLEXPORT_TEST(testShape3DEffectPreservation, "shape-3d-effect-preserv ...@@ -1158,11 +1158,23 @@ DECLARE_OOXMLEXPORT_TEST(testShape3DEffectPreservation, "shape-3d-effect-preserv
assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/" assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:scene3d/a:camera", "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:scene3d/a:camera",
"zoom", "150000"); "zoom", "150000");
assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:scene3d/a:camera/a:rot",
"lat", "19490639");
assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:scene3d/a:camera/a:rot",
"lon", "0");
assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:scene3d/a:camera/a:rot",
"rev", "12900001");
// second shape // second shape
assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent/mc:Choice/w:drawing/" assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:scene3d/a:camera", "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:scene3d/a:camera",
"prst", "isometricLeftDown"); "prst", "isometricLeftDown");
assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:scene3d/a:camera/a:rot",
0);
} }
DECLARE_OOXMLEXPORT_TEST(fdo77719, "fdo77719.docx") DECLARE_OOXMLEXPORT_TEST(fdo77719, "fdo77719.docx")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment