[Libreoffice-commits] core.git: 3 commits - include/oox oox/source sw/qa
Jacobo Aragunde Pérez
jaragunde at igalia.com
Fri May 9 05:12:24 PDT 2014
include/oox/drawingml/scene3dcontext.hxx | 11
include/oox/drawingml/shape3dproperties.hxx | 21 +
oox/source/drawingml/scene3dcontext.cxx | 43 ++
oox/source/drawingml/shape.cxx | 12
oox/source/drawingml/shape3dproperties.cxx | 176 ++++++++++
oox/source/drawingml/shapepropertiescontext.cxx | 3
oox/source/export/drawingml.cxx | 159 ++++++++-
sw/qa/extras/ooxmlexport/data/shape-3d-effect-preservation.docx |binary
sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx | 60 +++
9 files changed, 467 insertions(+), 18 deletions(-)
New commits:
commit f6422b3dfcb00e451ef103127aace1856dc752a9
Author: Jacobo Aragunde Pérez <jaragunde at igalia.com>
Date: Fri May 9 12:01:46 2014 +0200
ooxml: Preserve shape 3d effects: top and bottom bevel
Shapes 3D effects can specify top and bottom bevels like in the
following example:
<a:sp3d z="488950" extrusionH="63500" contourW="50800">
<a:bevelT w="139700" h="88900" prst="cross"/>
<a:bevelB h="88900" prst="relaxedInset"/>
</a:sp3d>
This patch preserves the a:bevel* tags and their attributes using the
shape grab bag and modifies an existing unit test to add this check.
Change-Id: I4762111e4d2f75ba2fd3721a126aa324a28a853c
diff --git a/include/oox/drawingml/scene3dcontext.hxx b/include/oox/drawingml/scene3dcontext.hxx
index e4b7a62..d016445 100644
--- a/include/oox/drawingml/scene3dcontext.hxx
+++ b/include/oox/drawingml/scene3dcontext.hxx
@@ -54,6 +54,8 @@ class Shape3DPropertiesContext : public ::oox::core::ContextHandler2
public:
Shape3DPropertiesContext( ::oox::core::ContextHandler2Helper& rParent, const ::oox::AttributeList& rAttribs, Shape3DProperties& r3DProperties ) throw();
+ ::oox::core::ContextHandlerRef onCreateContext( ::sal_Int32 Element, const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE;
+
private:
Shape3DProperties& mr3DProperties;
};
diff --git a/include/oox/drawingml/shape3dproperties.hxx b/include/oox/drawingml/shape3dproperties.hxx
index a66d46c..32e0f27 100644
--- a/include/oox/drawingml/shape3dproperties.hxx
+++ b/include/oox/drawingml/shape3dproperties.hxx
@@ -43,6 +43,13 @@ struct RotationProperties
OptValue< sal_Int32 > mnRevolution;
};
+struct BevelProperties
+{
+ OptValue< sal_Int32 > mnPreset;
+ OptValue< sal_Int32 > mnWidth;
+ OptValue< sal_Int32 > mnHeight;
+};
+
struct Shape3DProperties
{
OptValue< sal_Int32 > mnPreset;
@@ -57,16 +64,21 @@ struct Shape3DProperties
OptValue< sal_Int32 > mnContourW;
OptValue< sal_Int32 > mnShapeZ;
+ OptValue< BevelProperties > maTopBevelProperties;
+ OptValue< BevelProperties > maBottomBevelProperties;
+
/** Overwrites all members that are explicitly set in rSourceProps. */
void assignUsed( const Shape3DProperties& rSourceProps );
OUString getCameraPrstName( sal_Int32 nElement );
OUString getLightRigName( sal_Int32 nElement );
OUString getLightRigDirName( sal_Int32 nElement );
+ OUString getBevelPresetTypeString( sal_Int32 nType );
css::uno::Sequence< css::beans::PropertyValue > getCameraAttributes();
css::uno::Sequence< css::beans::PropertyValue > getLightRigAttributes();
css::uno::Sequence< css::beans::PropertyValue > getShape3DAttributes();
+ css::uno::Sequence< css::beans::PropertyValue > getBevelAttributes( BevelProperties rProps );
};
diff --git a/oox/source/drawingml/scene3dcontext.cxx b/oox/source/drawingml/scene3dcontext.cxx
index bbae7ab..124a741 100644
--- a/oox/source/drawingml/scene3dcontext.cxx
+++ b/oox/source/drawingml/scene3dcontext.cxx
@@ -80,6 +80,32 @@ Shape3DPropertiesContext::Shape3DPropertiesContext( ContextHandler2Helper& rPare
mr3DProperties.mnShapeZ = rAttribs.getInteger( XML_z, 0 );
}
+ContextHandlerRef Shape3DPropertiesContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+{
+ switch( aElementToken )
+ {
+ case A_TOKEN( bevelT ):
+ case A_TOKEN( bevelB ):
+ {
+ BevelProperties aProps;
+ if( rAttribs.hasAttribute( XML_w ) )
+ aProps.mnWidth = rAttribs.getInteger( XML_w, 0 );
+ if( rAttribs.hasAttribute( XML_h ) )
+ aProps.mnHeight = rAttribs.getInteger( XML_h, 0 );
+ if( rAttribs.hasAttribute( XML_prst ) )
+ aProps.mnPreset = rAttribs.getToken( XML_prst, XML_none );
+
+ if( aElementToken == A_TOKEN( bevelT ) )
+ mr3DProperties.maTopBevelProperties.set( aProps );
+ else
+ mr3DProperties.maBottomBevelProperties.set( aProps );
+
+ break;
+ }
+ }
+ return 0;
+}
+
Scene3DRotationPropertiesContext::Scene3DRotationPropertiesContext( ContextHandler2Helper& rParent, RotationProperties& rRotationProperties ) throw()
: ContextHandler2( rParent )
, mrRotationProperties( rRotationProperties )
diff --git a/oox/source/drawingml/shape3dproperties.cxx b/oox/source/drawingml/shape3dproperties.cxx
index 7da8a0b..28d9079 100644
--- a/oox/source/drawingml/shape3dproperties.cxx
+++ b/oox/source/drawingml/shape3dproperties.cxx
@@ -171,6 +171,27 @@ OUString Shape3DProperties::getLightRigDirName( sal_Int32 nElement )
return OUString();
}
+OUString Shape3DProperties::getBevelPresetTypeString( sal_Int32 nType )
+{
+ switch (nType)
+ {
+ case XML_relaxedInset: return OUString("relaxedInset");
+ case XML_circle: return OUString("circle");
+ case XML_slope: return OUString("slope");
+ case XML_cross: return OUString("cross");
+ case XML_angle: return OUString("angle");
+ case XML_softRound: return OUString("softRound");
+ case XML_convex: return OUString("convex");
+ case XML_coolSlant: return OUString("coolSlant");
+ case XML_divot: return OUString("divot");
+ case XML_riblet: return OUString("riblet");
+ case XML_hardEdge: return OUString("hardEdge");
+ case XML_artDeco: return OUString("artDeco");
+ }
+ SAL_WARN( "oox.drawingml", "Shape3DProperties::getBevelPresetTypeString - unexpected token" );
+ return OUString();
+}
+
css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getCameraAttributes()
{
css::uno::Sequence<css::beans::PropertyValue> aSeq(6);
@@ -253,10 +274,36 @@ css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getLightRigAt
return aSeq;
}
-css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getShape3DAttributes()
+css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getBevelAttributes( BevelProperties rProps )
{
css::uno::Sequence<css::beans::PropertyValue> aSeq(3);
sal_Int32 nSize = 0;
+ if( rProps.mnPreset.has() )
+ {
+ aSeq[nSize].Name = "prst";
+ aSeq[nSize].Value = css::uno::Any( getBevelPresetTypeString( rProps.mnPreset.use() ) );
+ nSize++;
+ }
+ if( rProps.mnWidth.has() )
+ {
+ aSeq[nSize].Name = "w";
+ aSeq[nSize].Value = css::uno::Any( rProps.mnWidth.use() );
+ nSize++;
+ }
+ if( rProps.mnHeight.has() )
+ {
+ aSeq[nSize].Name = "h";
+ aSeq[nSize].Value = css::uno::Any( rProps.mnHeight.use() );
+ nSize++;
+ }
+ aSeq.realloc( nSize );
+ return aSeq;
+}
+
+css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getShape3DAttributes()
+{
+ css::uno::Sequence<css::beans::PropertyValue> aSeq(5);
+ sal_Int32 nSize = 0;
if( mnExtrusionH.has() )
{
aSeq[nSize].Name = "extrusionH";
@@ -275,6 +322,18 @@ css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getShape3DAtt
aSeq[nSize].Value = css::uno::Any( mnShapeZ.use() );
nSize++;
}
+ if( maTopBevelProperties.has() )
+ {
+ aSeq[nSize].Name = "bevelT";
+ aSeq[nSize].Value = css::uno::Any( getBevelAttributes( maTopBevelProperties.use() ) );
+ nSize++;
+ }
+ if( maBottomBevelProperties.has() )
+ {
+ aSeq[nSize].Name = "bevelB";
+ aSeq[nSize].Value = css::uno::Any( getBevelAttributes( maBottomBevelProperties.use() ) );
+ nSize++;
+ }
aSeq.realloc( nSize );
return aSeq;
}
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 0b437db..90000a1 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -2408,6 +2408,9 @@ void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet )
if( aShape3DProps.getLength() == 0 )
return;
+ bool bBevelTPresent = false, bBevelBPresent = false;
+ sax_fastparser::FastAttributeList *aBevelTAttrList = mpFS->createAttrList();
+ sax_fastparser::FastAttributeList *aBevelBAttrList = mpFS->createAttrList();
sax_fastparser::FastAttributeList *aShape3DAttrList = mpFS->createAttrList();
for( sal_Int32 i=0; i < aShape3DProps.getLength(); ++i )
{
@@ -2423,10 +2426,59 @@ void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet )
nToken = XML_z;
aShape3DAttrList->add( nToken, OString::number( nVal ).getStr() );
}
+ if( aShape3DProps[i].Name == "bevelT" || aShape3DProps[i].Name == "bevelB" )
+ {
+ Sequence< PropertyValue > aBevelProps;
+ aShape3DProps[i].Value >>= aBevelProps;
+ if ( aBevelProps.getLength() == 0 )
+ continue;
+
+ sax_fastparser::FastAttributeList *aBevelAttrList = NULL;
+ if( aShape3DProps[i].Name == "bevelT" )
+ {
+ bBevelTPresent = true;
+ aBevelAttrList = aBevelTAttrList;
+ }
+ else
+ {
+ bBevelBPresent = true;
+ aBevelAttrList = aBevelBAttrList;
+ }
+ for( sal_Int32 j=0; j < aBevelProps.getLength(); ++j )
+ {
+ if( aBevelProps[j].Name == "w" || aBevelProps[j].Name == "h" )
+ {
+ sal_Int32 nVal = 0, nToken = XML_none;
+ aBevelProps[j].Value >>= nVal;
+ if( aBevelProps[j].Name == "w" )
+ nToken = XML_w;
+ else if( aBevelProps[j].Name == "h" )
+ nToken = XML_h;
+ aBevelAttrList->add( nToken, OString::number( nVal ).getStr() );
+ }
+ else if( aBevelProps[j].Name == "prst" )
+ {
+ OUString sVal;
+ aBevelProps[j].Value >>= sVal;
+ aBevelAttrList->add( XML_prst, OUStringToOString( sVal, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+
+ }
}
sax_fastparser::XFastAttributeListRef xAttrList( aShape3DAttrList );
mpFS->startElementNS( XML_a, XML_sp3d, xAttrList );
+ if( bBevelTPresent )
+ {
+ sax_fastparser::XFastAttributeListRef xBevelAttrList( aBevelTAttrList );
+ mpFS->singleElementNS( XML_a, XML_bevelT, xBevelAttrList );
+ }
+ if( bBevelBPresent )
+ {
+ sax_fastparser::XFastAttributeListRef xBevelAttrList( aBevelBAttrList );
+ mpFS->singleElementNS( XML_a, XML_bevelB, xBevelAttrList );
+ }
mpFS->endElementNS( XML_a, XML_sp3d );
}
diff --git a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx
index d7bcf07..1bee43ea 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx
@@ -1216,6 +1216,21 @@ DECLARE_OOXMLEXPORT_TEST(testShape3DEffectPreservation, "shape-3d-effect-preserv
assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:sp3d",
"contourW", "50800");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
+ "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:sp3d/a:bevelT",
+ "w", "139700");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
+ "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:sp3d/a:bevelT",
+ "h", "88900");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
+ "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:sp3d/a:bevelT",
+ "prst", "cross");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
+ "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:sp3d/a:bevelB",
+ "h", "88900");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
+ "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:sp3d/a:bevelB",
+ "prst", "relaxedInset");
}
DECLARE_OOXMLEXPORT_TEST(fdo77719, "fdo77719.docx")
commit 6566c218afec3cd8c4d36094777bc30b1970e9e4
Author: Jacobo Aragunde Pérez <jaragunde at igalia.com>
Date: Thu May 8 14:25:10 2014 +0200
ooxml: Preserve shape 3d effects: z, contour and extrusion
Shapes can contain 3D effects like in the following example:
<a:sp3d z="488950" extrusionH="63500" contourW="50800"/>
This patch preserves the a:sp3d tag and its attributes using the shape
grab bag and modifies an existing unit test to add this check.
Change-Id: Ice3cae39c71784be0f6c7f2700b07c21a5e1fb6e
diff --git a/include/oox/drawingml/scene3dcontext.hxx b/include/oox/drawingml/scene3dcontext.hxx
index 82af76e..e4b7a62 100644
--- a/include/oox/drawingml/scene3dcontext.hxx
+++ b/include/oox/drawingml/scene3dcontext.hxx
@@ -49,6 +49,15 @@ private:
Shape3DProperties& mr3DProperties;
};
+class Shape3DPropertiesContext : public ::oox::core::ContextHandler2
+{
+public:
+ Shape3DPropertiesContext( ::oox::core::ContextHandler2Helper& rParent, const ::oox::AttributeList& rAttribs, Shape3DProperties& r3DProperties ) throw();
+
+private:
+ Shape3DProperties& mr3DProperties;
+};
+
} }
#endif // INCLUDED_OOX_DRAWINGML_SCENE3DCONTEXT_HXX
diff --git a/include/oox/drawingml/shape3dproperties.hxx b/include/oox/drawingml/shape3dproperties.hxx
index 2577e3f..a66d46c 100644
--- a/include/oox/drawingml/shape3dproperties.hxx
+++ b/include/oox/drawingml/shape3dproperties.hxx
@@ -53,6 +53,10 @@ struct Shape3DProperties
RotationProperties maCameraRotation;
RotationProperties maLightRigRotation;
+ OptValue< sal_Int32 > mnExtrusionH;
+ OptValue< sal_Int32 > mnContourW;
+ OptValue< sal_Int32 > mnShapeZ;
+
/** Overwrites all members that are explicitly set in rSourceProps. */
void assignUsed( const Shape3DProperties& rSourceProps );
@@ -62,6 +66,7 @@ struct Shape3DProperties
css::uno::Sequence< css::beans::PropertyValue > getCameraAttributes();
css::uno::Sequence< css::beans::PropertyValue > getLightRigAttributes();
+ css::uno::Sequence< css::beans::PropertyValue > getShape3DAttributes();
};
diff --git a/oox/source/drawingml/scene3dcontext.cxx b/oox/source/drawingml/scene3dcontext.cxx
index 7d95b73..bbae7ab 100644
--- a/oox/source/drawingml/scene3dcontext.cxx
+++ b/oox/source/drawingml/scene3dcontext.cxx
@@ -68,6 +68,18 @@ ContextHandlerRef Scene3DPropertiesContext::onCreateContext( sal_Int32 aElementT
return 0;
}
+Shape3DPropertiesContext::Shape3DPropertiesContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, Shape3DProperties& r3DProperties ) throw()
+: ContextHandler2( rParent )
+, mr3DProperties( r3DProperties )
+{
+ if( rAttribs.hasAttribute( XML_extrusionH ) )
+ mr3DProperties.mnExtrusionH = rAttribs.getInteger( XML_extrusionH, 0 );
+ if( rAttribs.hasAttribute( XML_contourW ) )
+ mr3DProperties.mnContourW = rAttribs.getInteger( XML_contourW, 0 );
+ if( rAttribs.hasAttribute( XML_z ) )
+ mr3DProperties.mnShapeZ = rAttribs.getInteger( XML_z, 0 );
+}
+
Scene3DRotationPropertiesContext::Scene3DRotationPropertiesContext( ContextHandler2Helper& rParent, RotationProperties& rRotationProperties ) throw()
: ContextHandler2( rParent )
, mrRotationProperties( rRotationProperties )
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 564f51b..da125cf 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -940,11 +940,13 @@ Reference< XShape > Shape::createAndInsert(
// add 3D effects if any
Sequence< PropertyValue > aCamera3DEffects = get3DProperties().getCameraAttributes();
Sequence< PropertyValue > aLightRig3DEffects = get3DProperties().getLightRigAttributes();
+ Sequence< PropertyValue > aShape3DEffects = get3DProperties().getShape3DAttributes();
if( aCamera3DEffects.getLength() > 0 || aLightRig3DEffects.getLength() > 0 )
{
- Sequence< PropertyValue > a3DEffectsGrabBag( 2 );
+ Sequence< PropertyValue > a3DEffectsGrabBag( 3 );
PUT_PROP( a3DEffectsGrabBag, 0, "Camera", Any( aCamera3DEffects ) );
PUT_PROP( a3DEffectsGrabBag, 1, "LightRig", Any( aLightRig3DEffects ) );
+ PUT_PROP( a3DEffectsGrabBag, 2, "Shape3D", Any( aShape3DEffects ) );
putPropertyToGrabBag( "3DEffectProperties", Any( a3DEffectsGrabBag ) );
}
}
diff --git a/oox/source/drawingml/shape3dproperties.cxx b/oox/source/drawingml/shape3dproperties.cxx
index 47346a9..7da8a0b 100644
--- a/oox/source/drawingml/shape3dproperties.cxx
+++ b/oox/source/drawingml/shape3dproperties.cxx
@@ -253,6 +253,32 @@ css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getLightRigAt
return aSeq;
}
+css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getShape3DAttributes()
+{
+ css::uno::Sequence<css::beans::PropertyValue> aSeq(3);
+ sal_Int32 nSize = 0;
+ if( mnExtrusionH.has() )
+ {
+ aSeq[nSize].Name = "extrusionH";
+ aSeq[nSize].Value = css::uno::Any( mnExtrusionH.use() );
+ nSize++;
+ }
+ if( mnContourW.has() )
+ {
+ aSeq[nSize].Name = "contourW";
+ aSeq[nSize].Value = css::uno::Any( mnContourW.use() );
+ nSize++;
+ }
+ if( mnShapeZ.has() )
+ {
+ aSeq[nSize].Name = "z";
+ aSeq[nSize].Value = css::uno::Any( mnShapeZ.use() );
+ nSize++;
+ }
+ aSeq.realloc( nSize );
+ return aSeq;
+}
+
} // namespace drawingml
diff --git a/oox/source/drawingml/shapepropertiescontext.cxx b/oox/source/drawingml/shapepropertiescontext.cxx
index 0823e67..daf8731 100644
--- a/oox/source/drawingml/shapepropertiescontext.cxx
+++ b/oox/source/drawingml/shapepropertiescontext.cxx
@@ -99,8 +99,9 @@ ContextHandlerRef ShapePropertiesContext::onCreateContext( sal_Int32 aElementTok
return new Scene3DPropertiesContext( *this, mrShape.get3DProperties() );
break;
- // todo
+ // todo not supported by core, only for preservation via grab bags
case A_TOKEN( sp3d ): // CT_Shape3D
+ return new Shape3DPropertiesContext( *this, rAttribs, mrShape.get3DProperties() );
break;
}
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index abe338b..0b437db 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -2277,7 +2277,7 @@ void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet )
return;
// extract the relevant properties from the grab bag
- Sequence< PropertyValue > aGrabBag, aEffectProps, aLightRigProps;
+ Sequence< PropertyValue > aGrabBag, aEffectProps, aLightRigProps, aShape3DProps;
mAny >>= aGrabBag;
for( sal_Int32 i=0; i < aGrabBag.getLength(); ++i )
if( aGrabBag[i].Name == "3DEffectProperties" )
@@ -2290,10 +2290,12 @@ void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet )
a3DEffectProps[j].Value >>= aEffectProps;
else if( a3DEffectProps[j].Name == "LightRig" )
a3DEffectProps[j].Value >>= aLightRigProps;
+ else if( a3DEffectProps[j].Name == "Shape3D" )
+ a3DEffectProps[j].Value >>= aShape3DProps;
}
break;
}
- if( aEffectProps.getLength() == 0 && aLightRigProps.getLength() == 0 )
+ if( aEffectProps.getLength() == 0 && aLightRigProps.getLength() == 0 && aShape3DProps.getLength() == 0 )
return;
bool bCameraRotationPresent = false;
@@ -2402,6 +2404,30 @@ void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet )
mpFS->singleElementNS( XML_a, XML_lightRig, XML_rig, "threePt", XML_dir, "t", FSEND );
mpFS->endElementNS( XML_a, XML_scene3d );
+
+ if( aShape3DProps.getLength() == 0 )
+ return;
+
+ sax_fastparser::FastAttributeList *aShape3DAttrList = mpFS->createAttrList();
+ for( sal_Int32 i=0; i < aShape3DProps.getLength(); ++i )
+ {
+ if( aShape3DProps[i].Name == "extrusionH" || aShape3DProps[i].Name == "contourW" || aShape3DProps[i].Name == "z" )
+ {
+ sal_Int32 nVal = 0, nToken = XML_none;
+ aShape3DProps[i].Value >>= nVal;
+ if( aShape3DProps[i].Name == "extrusionH" )
+ nToken = XML_extrusionH;
+ else if( aShape3DProps[i].Name == "contourW" )
+ nToken = XML_contourW;
+ else if( aShape3DProps[i].Name == "z" )
+ nToken = XML_z;
+ aShape3DAttrList->add( nToken, OString::number( nVal ).getStr() );
+ }
+ }
+
+ sax_fastparser::XFastAttributeListRef xAttrList( aShape3DAttrList );
+ mpFS->startElementNS( XML_a, XML_sp3d, xAttrList );
+ mpFS->endElementNS( XML_a, XML_sp3d );
}
}
diff --git a/sw/qa/extras/ooxmlexport/data/shape-3d-effect-preservation.docx b/sw/qa/extras/ooxmlexport/data/shape-3d-effect-preservation.docx
index ed41483..dd4a522 100644
Binary files a/sw/qa/extras/ooxmlexport/data/shape-3d-effect-preservation.docx and b/sw/qa/extras/ooxmlexport/data/shape-3d-effect-preservation.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx
index 727aef9..d7bcf07 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx
@@ -1151,7 +1151,7 @@ DECLARE_OOXMLEXPORT_TEST(testShape3DEffectPreservation, "shape-3d-effect-preserv
if (!pXmlDoc)
return;
- // first shape
+ // first shape: extrusion and shift on z, rotated camera with zoom, rotated light rig
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",
"prst", "perspectiveRelaxedModerately");
@@ -1184,7 +1184,14 @@ DECLARE_OOXMLEXPORT_TEST(testShape3DEffectPreservation, "shape-3d-effect-preserv
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:scene3d/a:lightRig/a:rot",
"rev", "4800000");
- // second shape
+ 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:sp3d",
+ "extrusionH", "63500");
+ 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:sp3d",
+ "z", "488950");
+
+ // second shape: extrusion with theme color, no camera or light rotation
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",
"prst", "isometricLeftDown");
@@ -1200,6 +1207,15 @@ DECLARE_OOXMLEXPORT_TEST(testShape3DEffectPreservation, "shape-3d-effect-preserv
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:lightRig/a:rot",
0);
+
+ 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:sp3d",
+ "extrusionH", "25400");
+
+ // third shape: colored countour and top and bottom bevel
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
+ "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:sp3d",
+ "contourW", "50800");
}
DECLARE_OOXMLEXPORT_TEST(fdo77719, "fdo77719.docx")
commit 0df9ec782efeb24c02f7c5baef53bf2fa75a4bc5
Author: Jacobo Aragunde Pérez <jaragunde at igalia.com>
Date: Tue May 6 16:40:27 2014 +0200
oox: preserve scene3d/lightRig 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:rot lat="0" lon="0" rev="4800000"/>
</a:lightRig>
</a:scene3d>
This patch preserves the a:lightRig tag, its attributes and the child
element a:rot using the shape grab bag. It also adds a unit test for
this case.
Change-Id: I66b6de3c2b5ef89223b10da54006e28113b8ba5f
diff --git a/include/oox/drawingml/shape3dproperties.hxx b/include/oox/drawingml/shape3dproperties.hxx
index efce9e0..2577e3f 100644
--- a/include/oox/drawingml/shape3dproperties.hxx
+++ b/include/oox/drawingml/shape3dproperties.hxx
@@ -51,13 +51,17 @@ struct Shape3DProperties
OptValue< sal_Int32 > mnLightRigDirection;
OptValue< sal_Int32 > mnLightRigType;
RotationProperties maCameraRotation;
+ RotationProperties maLightRigRotation;
/** Overwrites all members that are explicitly set in rSourceProps. */
void assignUsed( const Shape3DProperties& rSourceProps );
OUString getCameraPrstName( sal_Int32 nElement );
+ OUString getLightRigName( sal_Int32 nElement );
+ OUString getLightRigDirName( sal_Int32 nElement );
css::uno::Sequence< css::beans::PropertyValue > getCameraAttributes();
+ css::uno::Sequence< css::beans::PropertyValue > getLightRigAttributes();
};
diff --git a/oox/source/drawingml/scene3dcontext.cxx b/oox/source/drawingml/scene3dcontext.cxx
index 21c564c..7d95b73 100644
--- a/oox/source/drawingml/scene3dcontext.cxx
+++ b/oox/source/drawingml/scene3dcontext.cxx
@@ -58,8 +58,9 @@ ContextHandlerRef Scene3DPropertiesContext::onCreateContext( sal_Int32 aElementT
case A_TOKEN( lightRig ):
mr3DProperties.mnLightRigDirection = rAttribs.getToken( XML_dir, XML_none );
mr3DProperties.mnLightRigType = rAttribs.getToken( XML_rig, XML_none );
- // TODO: nested element XML_rot
- break;
+
+ return new Scene3DRotationPropertiesContext( *this, mr3DProperties.maLightRigRotation );
+
case A_TOKEN( backdrop ):
case A_TOKEN( extLst ):
return 0; // TODO: later (backdrop is not supported by core anyway)
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index a83fe49..564f51b 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -939,8 +939,14 @@ Reference< XShape > Shape::createAndInsert(
// add 3D effects if any
Sequence< PropertyValue > aCamera3DEffects = get3DProperties().getCameraAttributes();
- if( aCamera3DEffects.getLength() > 0 )
- putPropertyToGrabBag( "3DEffectProperties", Any( aCamera3DEffects ) );
+ Sequence< PropertyValue > aLightRig3DEffects = get3DProperties().getLightRigAttributes();
+ if( aCamera3DEffects.getLength() > 0 || aLightRig3DEffects.getLength() > 0 )
+ {
+ Sequence< PropertyValue > a3DEffectsGrabBag( 2 );
+ PUT_PROP( a3DEffectsGrabBag, 0, "Camera", Any( aCamera3DEffects ) );
+ PUT_PROP( a3DEffectsGrabBag, 1, "LightRig", Any( aLightRig3DEffects ) );
+ putPropertyToGrabBag( "3DEffectProperties", Any( a3DEffectsGrabBag ) );
+ }
}
// 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 853ed46..47346a9 100644
--- a/oox/source/drawingml/shape3dproperties.cxx
+++ b/oox/source/drawingml/shape3dproperties.cxx
@@ -118,6 +118,59 @@ OUString Shape3DProperties::getCameraPrstName( sal_Int32 nElement )
return OUString();
}
+OUString Shape3DProperties::getLightRigName( sal_Int32 nElement )
+{
+ switch( nElement )
+ {
+ case XML_legacyFlat1: return OUString( "legacyFlat1" );
+ case XML_legacyFlat2: return OUString( "legacyFlat2" );
+ case XML_legacyFlat3: return OUString( "legacyFlat3" );
+ case XML_legacyFlat4: return OUString( "legacyFlat4" );
+ case XML_legacyNormal1: return OUString( "legacyNormal1" );
+ case XML_legacyNormal2: return OUString( "legacyNormal2" );
+ case XML_legacyNormal3: return OUString( "legacyNormal3" );
+ case XML_legacyNormal4: return OUString( "legacyNormal4" );
+ case XML_legacyHarsh1: return OUString( "legacyHarsh1" );
+ case XML_legacyHarsh2: return OUString( "legacyHarsh2" );
+ case XML_legacyHarsh3: return OUString( "legacyHarsh3" );
+ case XML_legacyHarsh4: return OUString( "legacyHarsh4" );
+ case XML_threePt: return OUString( "threePt" );
+ case XML_balanced: return OUString( "balanced" );
+ case XML_soft: return OUString( "soft" );
+ case XML_harsh: return OUString( "harsh" );
+ case XML_flood: return OUString( "flood" );
+ case XML_contrasting: return OUString( "contrasting" );
+ case XML_morning: return OUString( "morning" );
+ case XML_sunrise: return OUString( "sunrise" );
+ case XML_sunset: return OUString( "sunset" );
+ case XML_chilly: return OUString( "chilly" );
+ case XML_freezing: return OUString( "freezing" );
+ case XML_flat: return OUString( "flat" );
+ case XML_twoPt: return OUString( "twoPt" );
+ case XML_glow: return OUString( "glow" );
+ case XML_brightRoom: return OUString( "brightRoom" );
+ }
+ SAL_WARN( "oox.drawingml", "Shape3DProperties::getLightRigName - unexpected token" );
+ return OUString();
+}
+
+OUString Shape3DProperties::getLightRigDirName( sal_Int32 nElement )
+{
+ switch( nElement )
+ {
+ case XML_tl: return OUString( "tl" );
+ case XML_t: return OUString( "t" );
+ case XML_tr: return OUString( "tr" );
+ case XML_l: return OUString( "l" );
+ case XML_r: return OUString( "r" );
+ case XML_bl: return OUString( "bl" );
+ case XML_b: return OUString( "b" );
+ case XML_br: return OUString( "br" );
+ }
+ SAL_WARN( "oox.drawingml", "Shape3DProperties::getLightRigDirName - unexpected token" );
+ return OUString();
+}
+
css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getCameraAttributes()
{
css::uno::Sequence<css::beans::PropertyValue> aSeq(6);
@@ -162,6 +215,44 @@ css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getCameraAttr
return aSeq;
}
+css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getLightRigAttributes()
+{
+ css::uno::Sequence<css::beans::PropertyValue> aSeq(5);
+ sal_Int32 nSize = 0;
+ if( mnLightRigDirection.has() )
+ {
+ aSeq[nSize].Name = "dir";
+ aSeq[nSize].Value = css::uno::Any( getLightRigDirName( mnLightRigDirection.use() ) );
+ nSize++;
+ }
+ if( mnLightRigType.has() )
+ {
+ aSeq[nSize].Name = "rig";
+ aSeq[nSize].Value = css::uno::Any( getLightRigName( mnLightRigType.use() ) );
+ nSize++;
+ }
+ if( maLightRigRotation.mnLatitude.has() )
+ {
+ aSeq[nSize].Name = "rotLat";
+ aSeq[nSize].Value = css::uno::Any( maLightRigRotation.mnLatitude.use() );
+ nSize++;
+ }
+ if( maLightRigRotation.mnLongitude.has() )
+ {
+ aSeq[nSize].Name = "rotLon";
+ aSeq[nSize].Value = css::uno::Any( maLightRigRotation.mnLongitude.use() );
+ nSize++;
+ }
+ if( maLightRigRotation.mnRevolution.has() )
+ {
+ aSeq[nSize].Name = "rotRev";
+ aSeq[nSize].Value = css::uno::Any( maLightRigRotation.mnRevolution.use() );
+ nSize++;
+ }
+ aSeq.realloc( nSize );
+ return aSeq;
+}
+
} // namespace drawingml
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 5d08216..abe338b 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -2277,15 +2277,23 @@ void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet )
return;
// extract the relevant properties from the grab bag
- Sequence< PropertyValue > aGrabBag, aEffectProps;
+ Sequence< PropertyValue > aGrabBag, aEffectProps, aLightRigProps;
mAny >>= aGrabBag;
for( sal_Int32 i=0; i < aGrabBag.getLength(); ++i )
if( aGrabBag[i].Name == "3DEffectProperties" )
{
- aGrabBag[i].Value >>= aEffectProps;
+ Sequence< PropertyValue > a3DEffectProps;
+ aGrabBag[i].Value >>= a3DEffectProps;
+ for( sal_Int32 j=0; j < a3DEffectProps.getLength(); ++j )
+ {
+ if( a3DEffectProps[j].Name == "Camera" )
+ a3DEffectProps[j].Value >>= aEffectProps;
+ else if( a3DEffectProps[j].Name == "LightRig" )
+ a3DEffectProps[j].Value >>= aLightRigProps;
+ }
break;
}
- if( aEffectProps.getLength() == 0 )
+ if( aEffectProps.getLength() == 0 && aLightRigProps.getLength() == 0 )
return;
bool bCameraRotationPresent = false;
@@ -2328,19 +2336,70 @@ void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet )
}
}
+ bool bLightRigRotationPresent = false;
+ sax_fastparser::FastAttributeList *aLightRigAttrList = mpFS->createAttrList();
+ sax_fastparser::FastAttributeList *aLightRigRotationAttrList = mpFS->createAttrList();
+ for( sal_Int32 i=0; i < aLightRigProps.getLength(); ++i )
+ {
+ if( aLightRigProps[i].Name == "rig" || aLightRigProps[i].Name == "dir" )
+ {
+ OUString sVal;
+ sal_Int32 nToken = XML_none;
+ aLightRigProps[i].Value >>= sVal;
+ if( aLightRigProps[i].Name == "rig" )
+ nToken = XML_rig;
+ else if( aLightRigProps[i].Name == "dir" )
+ nToken = XML_dir;
+ aLightRigAttrList->add( nToken, OUStringToOString( sVal, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ else if( aLightRigProps[i].Name == "rotLat" ||
+ aLightRigProps[i].Name == "rotLon" ||
+ aLightRigProps[i].Name == "rotRev" )
+ {
+ sal_Int32 nVal = 0, nToken = XML_none;
+ aLightRigProps[i].Value >>= nVal;
+ if( aLightRigProps[i].Name == "rotLat" )
+ nToken = XML_lat;
+ else if( aLightRigProps[i].Name == "rotLon" )
+ nToken = XML_lon;
+ else if( aLightRigProps[i].Name == "rotRev" )
+ nToken = XML_rev;
+ aLightRigRotationAttrList->add( nToken, OString::number( nVal ).getStr() );
+ bLightRigRotationPresent = true;
+ }
+ }
+
mpFS->startElementNS( XML_a, XML_scene3d, FSEND );
- sax_fastparser::XFastAttributeListRef xAttrList( aCameraAttrList );
- mpFS->startElementNS( XML_a, XML_camera, xAttrList );
- if( bCameraRotationPresent )
+ if( aEffectProps.getLength() > 0 )
{
- sax_fastparser::XFastAttributeListRef xRotAttrList( aCameraRotationAttrList );
- mpFS->singleElementNS( XML_a, XML_rot, xRotAttrList );
+ sax_fastparser::XFastAttributeListRef xAttrList( aCameraAttrList );
+ 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 );
+ else
+ // a:camera with Word default values - Word won't open the document if this is not present
+ mpFS->singleElementNS( XML_a, XML_camera, XML_prst, "orthographicFront", FSEND );
- // 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 );
+ if( aEffectProps.getLength() > 0 )
+ {
+ sax_fastparser::XFastAttributeListRef xAttrList( aLightRigAttrList );
+ mpFS->startElementNS( XML_a, XML_lightRig, xAttrList );
+ if( bLightRigRotationPresent )
+ {
+ sax_fastparser::XFastAttributeListRef xRotAttrList( aLightRigRotationAttrList );
+ mpFS->singleElementNS( XML_a, XML_rot, xRotAttrList );
+ }
+ mpFS->endElementNS( XML_a, XML_lightRig );
+ }
+ else
+ // 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/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx
index e88d320..727aef9 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx
@@ -1168,6 +1168,22 @@ DECLARE_OOXMLEXPORT_TEST(testShape3DEffectPreservation, "shape-3d-effect-preserv
"wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:scene3d/a:camera/a:rot",
"rev", "12900001");
+ 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:lightRig",
+ "rig", "threePt");
+ 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:lightRig",
+ "dir", "t");
+ 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:lightRig/a:rot",
+ "lat", "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:lightRig/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:lightRig/a:rot",
+ "rev", "4800000");
+
// second shape
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",
@@ -1175,6 +1191,15 @@ DECLARE_OOXMLEXPORT_TEST(testShape3DEffectPreservation, "shape-3d-effect-preserv
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);
+ 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:lightRig",
+ "rig", "threePt");
+ 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:lightRig",
+ "dir", "t");
+ 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:lightRig/a:rot",
+ 0);
}
DECLARE_OOXMLEXPORT_TEST(fdo77719, "fdo77719.docx")
More information about the Libreoffice-commits
mailing list