diff options
author | Jacobo Aragunde Pérez <jaragunde@igalia.com> | 2014-05-20 21:05:10 +0200 |
---|---|---|
committer | Jacobo Aragunde Pérez <jaragunde@igalia.com> | 2014-05-23 10:03:59 +0200 |
commit | 642a252cf1a2f1d08c4bbfcae15527bb82c7664d (patch) | |
tree | 605b6c546b61972a9c6dd6b1fd1b3a89d3b9f0e0 | |
parent | 21d4cfe19e2796ebf89c408e292c4473924b2bc4 (diff) |
ooxml: preserve artistic effects on shapes.
Bitmaps can define artistic effects like in the following example:
<a:blip r:embed="rId5">
<a:extLst>
<a:ext uri="{BEBA8EAE-BF5A-486C-A8C5-ECC9F3942E4B}">
<a14:imgProps
xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main">
<a14:imgLayer r:embed="rId6">
<a14:imgEffect>
<a14:artisticMarker trans="14000" size="80" />
</a14:imgEffect>
</a14:imgLayer>
</a14:imgProps>
</a:ext>
</a:extLst>
</a:blip>
LO core doesn't support them, but I'm preserving them using the shape
grab bag. Bitmaps must not be transformed to a SwXTextGraphicObject
so the grab bag of the XShape is not discarded.
Added several Context and Properties objects on the import side to
traverse and save the relevant tags, and added the corresponding code
on the export side to extract the grab bag and output the effect back.
Also added a unit test for a selection of artistic effects.
TODO: Word saves the original bitmap as an embedded wdp file so the
effect can be undone. We must preserve it too and add the reference to
the a14:imgLayer tag.
Change-Id: I61d427f83e4c8f353eb073da0114cd73ba50ba4b
-rw-r--r-- | include/oox/drawingml/fillproperties.hxx | 24 | ||||
-rw-r--r-- | include/oox/drawingml/fillpropertiesgroupcontext.hxx | 42 | ||||
-rw-r--r-- | include/oox/export/drawingml.hxx | 1 | ||||
-rw-r--r-- | oox/source/drawingml/fillproperties.cxx | 193 | ||||
-rw-r--r-- | oox/source/drawingml/fillpropertiesgroupcontext.cxx | 70 | ||||
-rw-r--r-- | oox/source/drawingml/shape.cxx | 5 | ||||
-rw-r--r-- | oox/source/export/drawingml.cxx | 56 | ||||
-rw-r--r-- | sw/qa/extras/inc/swmodeltestbase.hxx | 1 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/picture-artistic-effects-preservation.docx | bin | 0 -> 17272 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx | 58 | ||||
-rw-r--r-- | writerfilter/source/dmapper/GraphicImport.cxx | 3 |
11 files changed, 452 insertions, 1 deletions
diff --git a/include/oox/drawingml/fillproperties.hxx b/include/oox/drawingml/fillproperties.hxx index 447cba2fa76c..c588deec8faa 100644 --- a/include/oox/drawingml/fillproperties.hxx +++ b/include/oox/drawingml/fillproperties.hxx @@ -65,6 +65,28 @@ struct PatternFillProperties void assignUsed( const PatternFillProperties& rSourceProps ); }; +struct ArtisticEffectProperties +{ + OUString msName; + std::map< OUString, css::uno::Any > + maAttribs; + + bool isEmpty() const; + + /** Returns the struct as a PropertyValue with Name = msName and + * Value = maAttribs as a Sequence< PropertyValue >. */ + css::beans::PropertyValue getEffect(); + + /** Overwrites all members that are explicitly set in rSourceProps. */ + void assignUsed( const ArtisticEffectProperties& rSourceProps ); + + /** Translate effect tokens to strings. */ + static OUString getEffectString( sal_Int32 nToken ); + + /** Translate effect strings to tokens. */ + static sal_Int32 getEffectToken( OUString sName ); +}; + struct BlipFillProperties { ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > @@ -89,6 +111,8 @@ struct BlipFillProperties Color maColorChangeTo; /// Destination color of color transformation. Color maDuotoneColors[2]; /// Duotone Colors + ArtisticEffectProperties maEffect; /// Artistic effect, not supported by core. + /** Overwrites all members that are explicitly set in rSourceProps. */ void assignUsed( const BlipFillProperties& rSourceProps ); }; diff --git a/include/oox/drawingml/fillpropertiesgroupcontext.hxx b/include/oox/drawingml/fillpropertiesgroupcontext.hxx index bbeed0837903..aae88df408be 100644 --- a/include/oox/drawingml/fillpropertiesgroupcontext.hxx +++ b/include/oox/drawingml/fillpropertiesgroupcontext.hxx @@ -78,6 +78,48 @@ private: +/** Context handler that imports a14:imgProps, a14:imgLayer, a14:imgEffect containers + and the a14:artistic* effect tags defined in the MS-ODRAWXML extension. */ +class ArtisticEffectContext : public ::oox::core::ContextHandler2 +{ +public: + explicit ArtisticEffectContext( + ::oox::core::ContextHandler2Helper& rParent, + ArtisticEffectProperties& rEffect ); + virtual ~ArtisticEffectContext(); + + virtual ::oox::core::ContextHandlerRef + onCreateContext( + sal_Int32 nElement, + const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE; + +private: + ArtisticEffectProperties& maEffect; +}; + + + +/** Context handler that imports the a:extLst element inside a:blip and its + children a:ext, which can contain transformations to the bitmap. */ +class BlipExtensionContext : public ::oox::core::ContextHandler2 +{ +public: + explicit BlipExtensionContext( + ::oox::core::ContextHandler2Helper& rParent, + BlipFillProperties& rBlipProps ); + virtual ~BlipExtensionContext(); + + virtual ::oox::core::ContextHandlerRef + onCreateContext( + sal_Int32 nElement, + const ::oox::AttributeList& rAttribs ) SAL_OVERRIDE; + +private: + BlipFillProperties& mrBlipProps; +}; + + + /** Context handler that imports the a:duotone element containing the colors of a bitmap duotone transformation. */ class DuotoneContext : public ::oox::core::ContextHandler2 diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx index 86e3d0769449..98cc0dfb38a0 100644 --- a/include/oox/export/drawingml.hxx +++ b/include/oox/export/drawingml.hxx @@ -176,6 +176,7 @@ public: void WriteShapeEffects( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet ); void WriteShapeEffect( const OUString& sName, const css::uno::Sequence< css::beans::PropertyValue >& aEffectProps ); void WriteShape3DEffects( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet ); + void WriteArtisticEffect( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet ); static void ResetCounters(); diff --git a/oox/source/drawingml/fillproperties.cxx b/oox/source/drawingml/fillproperties.cxx index 6ae078a46465..a9ca0db37546 100644 --- a/oox/source/drawingml/fillproperties.cxx +++ b/oox/source/drawingml/fillproperties.cxx @@ -205,6 +205,7 @@ void BlipFillProperties::assignUsed( const BlipFillProperties& rSourceProps ) maColorChangeTo.assignIfUsed( rSourceProps.maColorChangeTo ); maDuotoneColors[0].assignIfUsed( rSourceProps.maDuotoneColors[0] ); maDuotoneColors[1].assignIfUsed( rSourceProps.maDuotoneColors[1] ); + maEffect.assignUsed( rSourceProps.maEffect ); } @@ -596,6 +597,198 @@ void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const GraphicHelpe rPropMap.setProperty(PROP_MediaURL, maAudio.msEmbed); } +bool ArtisticEffectProperties::isEmpty() const +{ + return msName.isEmpty(); +} + +css::beans::PropertyValue ArtisticEffectProperties::getEffect() +{ + css::beans::PropertyValue pRet; + if( msName.isEmpty() ) + return pRet; + + css::uno::Sequence< css::beans::PropertyValue > aSeq( maAttribs.size() ); + sal_uInt32 i = 0; + for( std::map< OUString, css::uno::Any >::iterator it = maAttribs.begin(); it != maAttribs.end(); ++it ) + { + aSeq[i].Name = it->first; + aSeq[i].Value = it->second; + i++; + } + + pRet.Name = msName; + pRet.Value = css::uno::Any( aSeq ); + + return pRet; +} + +void ArtisticEffectProperties::assignUsed( const ArtisticEffectProperties& rSourceProps ) +{ + if( !rSourceProps.isEmpty() ) + { + msName = rSourceProps.msName; + maAttribs = rSourceProps.maAttribs; + } +} + +OUString ArtisticEffectProperties::getEffectString( sal_Int32 nToken ) +{ + switch( nToken ) + { + // effects + case OOX_TOKEN( a14, artisticBlur ): return OUString( "artisticBlur" ); + case OOX_TOKEN( a14, artisticCement ): return OUString( "artisticCement" ); + case OOX_TOKEN( a14, artisticChalkSketch ): return OUString( "artisticChalkSketch" ); + case OOX_TOKEN( a14, artisticCrisscrossEtching ): return OUString( "artisticCrisscrossEtching" ); + case OOX_TOKEN( a14, artisticCutout ): return OUString( "artisticCutout" ); + case OOX_TOKEN( a14, artisticFilmGrain ): return OUString( "artisticFilmGrain" ); + case OOX_TOKEN( a14, artisticGlass ): return OUString( "artisticGlass" ); + case OOX_TOKEN( a14, artisticGlowDiffused ): return OUString( "artisticGlowDiffused" ); + case OOX_TOKEN( a14, artisticGlowEdges ): return OUString( "artisticGlowEdges" ); + case OOX_TOKEN( a14, artisticLightScreen ): return OUString( "artisticLightScreen" ); + case OOX_TOKEN( a14, artisticLineDrawing ): return OUString( "artisticLineDrawing" ); + case OOX_TOKEN( a14, artisticMarker ): return OUString( "artisticMarker" ); + case OOX_TOKEN( a14, artisticMosiaicBubbles ): return OUString( "artisticMosiaicBubbles" ); + case OOX_TOKEN( a14, artisticPaintStrokes ): return OUString( "artisticPaintStrokes" ); + case OOX_TOKEN( a14, artisticPaintBrush ): return OUString( "artisticPaintBrush" ); + case OOX_TOKEN( a14, artisticPastelsSmooth ): return OUString( "artisticPastelsSmooth" ); + case OOX_TOKEN( a14, artisticPencilGrayscale ): return OUString( "artisticPencilGrayscale" ); + case OOX_TOKEN( a14, artisticPencilSketch ): return OUString( "artisticPencilSketch" ); + case OOX_TOKEN( a14, artisticPhotocopy ): return OUString( "artisticPhotocopy" ); + case OOX_TOKEN( a14, artisticPlasticWrap ): return OUString( "artisticPlasticWrap" ); + case OOX_TOKEN( a14, artisticTexturizer ): return OUString( "artisticTexturizer" ); + case OOX_TOKEN( a14, artisticWatercolorSponge ): return OUString( "artisticWatercolorSponge" ); + case OOX_TOKEN( a14, artisticBrightnessContrast ): return OUString( "artisticBrightnessContrast" ); + case OOX_TOKEN( a14, artisticColorTemperature ): return OUString( "artisticColorTemperature" ); + case OOX_TOKEN( a14, artisticSaturation ): return OUString( "artisticSaturation" ); + case OOX_TOKEN( a14, artisticSharpenSoften ): return OUString( "artisticSharpenSoften" ); + + // attributes + case XML_visible: return OUString( "visible" ); + case XML_trans: return OUString( "trans" ); + case XML_crackSpacing: return OUString( "crackSpacing" ); + case XML_pressure: return OUString( "pressure" ); + case XML_numberOfShades: return OUString( "numberOfShades" ); + case XML_grainSize: return OUString( "grainSize" ); + case XML_intensity: return OUString( "intensity" ); + case XML_smoothness: return OUString( "smoothness" ); + case XML_gridSize: return OUString( "gridSize" ); + case XML_pencilSize: return OUString( "pencilSize" ); + case XML_size: return OUString( "size" ); + case XML_brushSize: return OUString( "brushSize" ); + case XML_scaling: return OUString( "scaling" ); + case XML_detail: return OUString( "detail" ); + case XML_bright: return OUString( "bright" ); + case XML_contrast: return OUString( "contrast" ); + case XML_colorTemp: return OUString( "colorTemp" ); + case XML_sat: return OUString( "sat" ); + case XML_amount: return OUString( "amount" ); + } + SAL_WARN( "oox.drawingml", "ArtisticEffectProperties::getEffectString - unexpected token" ); + return OUString(); +} + +sal_Int32 ArtisticEffectProperties::getEffectToken( OUString sName ) +{ + // effects + if( sName == "artisticBlur" ) + return XML_artisticBlur; + else if( sName == "artisticCement" ) + return XML_artisticCement; + else if( sName == "artisticChalkSketch" ) + return XML_artisticChalkSketch; + else if( sName == "artisticCrisscrossEtching" ) + return XML_artisticCrisscrossEtching; + else if( sName == "artisticCutout" ) + return XML_artisticCutout; + else if( sName == "artisticFilmGrain" ) + return XML_artisticFilmGrain; + else if( sName == "artisticGlass" ) + return XML_artisticGlass; + else if( sName == "artisticGlowDiffused" ) + return XML_artisticGlowDiffused; + else if( sName == "artisticGlowEdges" ) + return XML_artisticGlowEdges; + else if( sName == "artisticLightScreen" ) + return XML_artisticLightScreen; + else if( sName == "artisticLineDrawing" ) + return XML_artisticLineDrawing; + else if( sName == "artisticMarker" ) + return XML_artisticMarker; + else if( sName == "artisticMosiaicBubbles" ) + return XML_artisticMosiaicBubbles; + else if( sName == "artisticPaintStrokes" ) + return XML_artisticPaintStrokes; + else if( sName == "artisticPaintBrush" ) + return XML_artisticPaintBrush; + else if( sName == "artisticPastelsSmooth" ) + return XML_artisticPastelsSmooth; + else if( sName == "artisticPencilGrayscale" ) + return XML_artisticPencilGrayscale; + else if( sName == "artisticPencilSketch" ) + return XML_artisticPencilSketch; + else if( sName == "artisticPhotocopy" ) + return XML_artisticPhotocopy; + else if( sName == "artisticPlasticWrap" ) + return XML_artisticPlasticWrap; + else if( sName == "artisticTexturizer" ) + return XML_artisticTexturizer; + else if( sName == "artisticWatercolorSponge" ) + return XML_artisticWatercolorSponge; + else if( sName == "artisticBrightnessContrast" ) + return XML_artisticBrightnessContrast; + else if( sName == "artisticColorTemperature" ) + return XML_artisticColorTemperature; + else if( sName == "artisticSaturation" ) + return XML_artisticSaturation; + else if( sName == "artisticSharpenSoften" ) + return XML_artisticSharpenSoften; + + // attributes + else if( sName == "visible" ) + return XML_visible; + else if( sName == "trans" ) + return XML_trans; + else if( sName == "crackSpacing" ) + return XML_crackSpacing; + else if( sName == "pressure" ) + return XML_pressure; + else if( sName == "numberOfShades" ) + return XML_numberOfShades; + else if( sName == "grainSize" ) + return XML_grainSize; + else if( sName == "intensity" ) + return XML_intensity; + else if( sName == "smoothness" ) + return XML_smoothness; + else if( sName == "gridSize" ) + return XML_gridSize; + else if( sName == "pencilSize" ) + return XML_pencilSize; + else if( sName == "size" ) + return XML_size; + else if( sName == "brushSize" ) + return XML_brushSize; + else if( sName == "scaling" ) + return XML_scaling; + else if( sName == "detail" ) + return XML_detail; + else if( sName == "bright" ) + return XML_bright; + else if( sName == "contrast" ) + return XML_contrast; + else if( sName == "colorTemp" ) + return XML_colorTemp; + else if( sName == "sat" ) + return XML_sat; + else if( sName == "amount" ) + return XML_amount; + + SAL_WARN( "oox.drawingml", "ArtisticEffectProperties::getEffectToken - unexpected token name" ); + return XML_none; +} + } // namespace drawingml diff --git a/oox/source/drawingml/fillpropertiesgroupcontext.cxx b/oox/source/drawingml/fillpropertiesgroupcontext.cxx index 89fdb26f7b74..e7e414277906 100644 --- a/oox/source/drawingml/fillpropertiesgroupcontext.cxx +++ b/oox/source/drawingml/fillpropertiesgroupcontext.cxx @@ -182,6 +182,9 @@ ContextHandlerRef BlipContext::onCreateContext( case A_TOKEN( duotone ): return new DuotoneContext( *this, rAttribs, mrBlipProps ); + case A_TOKEN( extLst ): + return new BlipExtensionContext( *this, mrBlipProps ); + case A_TOKEN( lum ): mrBlipProps.moBrightness = rAttribs.getInteger( XML_bright ); mrBlipProps.moContrast = rAttribs.getInteger( XML_contrast ); @@ -292,6 +295,73 @@ SimpleFillPropertiesContext::~SimpleFillPropertiesContext() mrColor = getBestSolidColor(); } +BlipExtensionContext::BlipExtensionContext( ContextHandler2Helper& rParent, BlipFillProperties& rBlipProps ) : + ContextHandler2( rParent ), + mrBlipProps( rBlipProps ) +{ +} + +BlipExtensionContext::~BlipExtensionContext() +{ +} + +ContextHandlerRef BlipExtensionContext::onCreateContext( + sal_Int32 nElement, const AttributeList& ) +{ + switch( nElement ) + { + case A_TOKEN( ext ): + return new BlipExtensionContext( *this, mrBlipProps ); + + case OOX_TOKEN( a14, imgProps ): + return new ArtisticEffectContext( *this, mrBlipProps.maEffect ); + } + return 0; +} + +ArtisticEffectContext::ArtisticEffectContext( ContextHandler2Helper& rParent, ArtisticEffectProperties& rEffect ) : + ContextHandler2( rParent ), + maEffect( rEffect ) +{ +} + +ArtisticEffectContext::~ArtisticEffectContext() +{ +} + +ContextHandlerRef ArtisticEffectContext::onCreateContext( + sal_Int32 nElement, const AttributeList& rAttribs ) +{ + // containers + if( nElement == OOX_TOKEN( a14, imgLayer ) || nElement == OOX_TOKEN( a14, imgEffect ) ) + return new ArtisticEffectContext( *this, maEffect ); + // TODO: manage r:embed attribute in a14:imgLayer + + // effects + maEffect.msName = ArtisticEffectProperties::getEffectString( nElement ); + if( maEffect.isEmpty() ) + return 0; + + // effect attributes + sal_Int32 aAttribs[19] = { + XML_visible, XML_trans, XML_crackSpacing, XML_pressure, XML_numberOfShades, + XML_grainSize, XML_intensity, XML_smoothness, XML_gridSize, XML_pencilSize, + XML_size, XML_brushSize, XML_scaling, XML_detail, XML_bright, XML_contrast, + XML_colorTemp, XML_sat, XML_amount + }; + for( sal_Int32 i=0; i<19; ++i ) + { + if( rAttribs.hasAttribute( aAttribs[i] ) ) + { + OUString sName = ArtisticEffectProperties::getEffectString( aAttribs[i] ); + if( !sName.isEmpty() ) + maEffect.maAttribs[sName] = uno::makeAny( rAttribs.getInteger( aAttribs[i], 0 ) ); + } + } + + return 0; +} + } // namespace drawingml } // namespace oox diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index ca42d4a5d9f1..8c97b8781473 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -960,6 +960,11 @@ Reference< XShape > Shape::createAndInsert( PUT_PROP( a3DEffectsGrabBag, 2, "Shape3D", Any( aShape3DEffects ) ); putPropertyToGrabBag( "3DEffectProperties", Any( a3DEffectsGrabBag ) ); } + + // store bitmap artistic effects in the grab bag + if( !mpGraphicPropertiesPtr->maBlipProps.maEffect.isEmpty() ) + putPropertyToGrabBag( "ArtisticEffectProperties", + Any( mpGraphicPropertiesPtr->maBlipProps.maEffect.getEffect() ) ); } else if( mbLockedCanvas ) diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 037466ad9eaf..0364764f1d3d 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -23,6 +23,7 @@ #include "oox/export/drawingml.hxx" #include "oox/export/utils.hxx" #include <oox/drawingml/color.hxx> +#include <oox/drawingml/fillproperties.hxx> #include <oox/token/tokens.hxx> #include <oox/drawingml/drawingmltypes.hxx> @@ -836,6 +837,7 @@ OUString DrawingML::WriteBlip( Reference< XPropertySet > rXPropSet, const OUStri XML_bright, nBright ? I32S( nBright*1000 ) : NULL, XML_contrast, nContrast ? I32S( nContrast*1000 ) : NULL, FSEND ); + WriteArtisticEffect( rXPropSet ); mpFS->endElementNS( XML_a, XML_blip ); @@ -2565,6 +2567,60 @@ void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet ) mpFS->endElementNS( XML_a, XML_sp3d ); } +void DrawingML::WriteArtisticEffect( Reference< XPropertySet > rXPropSet ) +{ + if( !GetProperty( rXPropSet, "InteropGrabBag" ) ) + return; + + PropertyValue aEffect; + Sequence< PropertyValue > aGrabBag; + mAny >>= aGrabBag; + for( sal_Int32 i=0; i < aGrabBag.getLength(); ++i ) + { + if( aGrabBag[i].Name == "ArtisticEffectProperties" ) + { + aGrabBag[i].Value >>= aEffect; + break; + } + } + sal_Int32 nEffectToken = ArtisticEffectProperties::getEffectToken( aEffect.Name ); + if( nEffectToken == XML_none ) + return; + + Sequence< PropertyValue > aAttrs; + aEffect.Value >>= aAttrs; + sax_fastparser::FastAttributeList *aAttrList = mpFS->createAttrList(); + for( sal_Int32 i=0; i < aAttrs.getLength(); ++i ) + { + sal_Int32 nToken = ArtisticEffectProperties::getEffectToken( aAttrs[i].Name ); + if( nToken != XML_none ) + { + sal_Int32 nVal = 0; + aAttrs[i].Value >>= nVal; + aAttrList->add( nToken, OString::number( nVal ).getStr() ); + } + } + + mpFS->startElementNS( XML_a, XML_extLst, FSEND ); + mpFS->startElementNS( XML_a, XML_ext, + XML_uri, "{BEBA8EAE-BF5A-486C-A8C5-ECC9F3942E4B}", + FSEND ); + mpFS->startElementNS( XML_a14, XML_imgProps, + FSNS( XML_xmlns, XML_a14 ), "http://schemas.microsoft.com/office/drawing/2010/main", + FSEND ); + mpFS->startElementNS( XML_a14, XML_imgLayer, FSEND ); + mpFS->startElementNS( XML_a14, XML_imgEffect, FSEND ); + + sax_fastparser::XFastAttributeListRef xAttrList( aAttrList ); + mpFS->singleElementNS( XML_a14, nEffectToken, xAttrList ); + + mpFS->endElementNS( XML_a14, XML_imgEffect ); + mpFS->endElementNS( XML_a14, XML_imgLayer ); + mpFS->endElementNS( XML_a14, XML_imgProps ); + mpFS->endElementNS( XML_a, XML_ext ); + mpFS->endElementNS( XML_a, XML_extLst ); +} + } } diff --git a/sw/qa/extras/inc/swmodeltestbase.hxx b/sw/qa/extras/inc/swmodeltestbase.hxx index 2c688fdfbb23..da802cff0216 100644 --- a/sw/qa/extras/inc/swmodeltestbase.hxx +++ b/sw/qa/extras/inc/swmodeltestbase.hxx @@ -613,6 +613,7 @@ protected: xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("ContentType"), BAD_CAST("http://schemas.openxmlformats.org/package/2006/content-types")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("lc"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("extended-properties"), BAD_CAST("http://schemas.openxmlformats.org/officeDocument/2006/extended-properties")); + xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("a14"), BAD_CAST("http://schemas.microsoft.com/office/drawing/2010/main")); } }; diff --git a/sw/qa/extras/ooxmlexport/data/picture-artistic-effects-preservation.docx b/sw/qa/extras/ooxmlexport/data/picture-artistic-effects-preservation.docx Binary files differnew file mode 100644 index 000000000000..85f31d8c3211 --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/picture-artistic-effects-preservation.docx diff --git a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx index 9c492162068b..43f5b6e7751d 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx @@ -1338,6 +1338,64 @@ DECLARE_OOXMLEXPORT_TEST(testPictureEffectPreservation, "picture-effects-preserv "rad", "63500"); } +DECLARE_OOXMLEXPORT_TEST(testPictureArtisticEffectPreservation, "picture-artistic-effects-preservation.docx") +{ + xmlDocPtr pXmlDoc = parseExport("word/document.xml"); + if (!pXmlDoc) + return; + + // 1st picture: marker effect + assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/" + "a:graphicData/pic:pic/pic:blipFill/a:blip/a:extLst/a:ext/a14:imgProps/a14:imgLayer/a14:imgEffect/" + "a14:artisticMarker", + "trans", "14000"); + assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/" + "a:graphicData/pic:pic/pic:blipFill/a:blip/a:extLst/a:ext/a14:imgProps/a14:imgLayer/a14:imgEffect/" + "a14:artisticMarker", + "size", "80"); + + // 2nd picture: pencil grayscale + assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/" + "a:graphicData/pic:pic/pic:blipFill/a:blip/a:extLst/a:ext/a14:imgProps/a14:imgLayer/a14:imgEffect/" + "a14:artisticPencilGrayscale", + "trans", "15000"); + assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/" + "a:graphicData/pic:pic/pic:blipFill/a:blip/a:extLst/a:ext/a14:imgProps/a14:imgLayer/a14:imgEffect/" + "a14:artisticPencilGrayscale", + "pencilSize", "66"); + + // 3rd picture: pencil sketch + assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/" + "a:graphicData/pic:pic/pic:blipFill/a:blip/a:extLst/a:ext/a14:imgProps/a14:imgLayer/a14:imgEffect/" + "a14:artisticPencilSketch", + "trans", "7000"); + assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/" + "a:graphicData/pic:pic/pic:blipFill/a:blip/a:extLst/a:ext/a14:imgProps/a14:imgLayer/a14:imgEffect/" + "a14:artisticPencilSketch", + "pressure", "17"); + + // 4th picture: light screen + assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/" + "a:graphicData/pic:pic/pic:blipFill/a:blip/a:extLst/a:ext/a14:imgProps/a14:imgLayer/a14:imgEffect/" + "a14:artisticLightScreen", + "trans", "13000"); + assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/" + "a:graphicData/pic:pic/pic:blipFill/a:blip/a:extLst/a:ext/a14:imgProps/a14:imgLayer/a14:imgEffect/" + "a14:artisticLightScreen", + "gridSize", "1"); + + // 5th picture: watercolor sponge + assertXPath(pXmlDoc, "/w:document/w:body/w:p[5]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/" + "a:graphicData/pic:pic/pic:blipFill/a:blip/a:extLst/a:ext/a14:imgProps/a14:imgLayer/a14:imgEffect/" + "a14:artisticWatercolorSponge", + "brushSize", "4"); + + // 6th picture: photocopy (no attributes) + assertXPath(pXmlDoc, "/w:document/w:body/w:p[6]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/" + "a:graphicData/pic:pic/pic:blipFill/a:blip/a:extLst/a:ext/a14:imgProps/a14:imgLayer/a14:imgEffect/" + "a14:artisticPhotocopy", 1); +} + DECLARE_OOXMLEXPORT_TEST(fdo77719, "fdo77719.docx") { xmlDocPtr pXmlDoc = parseExport("word/document.xml"); diff --git a/writerfilter/source/dmapper/GraphicImport.cxx b/writerfilter/source/dmapper/GraphicImport.cxx index 1d19df08de5b..11f5a73345c2 100644 --- a/writerfilter/source/dmapper/GraphicImport.cxx +++ b/writerfilter/source/dmapper/GraphicImport.cxx @@ -650,7 +650,8 @@ void GraphicImport::lcl_attribute(Id nName, Value& rValue) { // if the shape contains effects in the grab bag, we should not transform it // in a XTextContent so those effects can be preserved - if( aGrabBag[i].Name == "EffectProperties" || aGrabBag[i].Name == "3DEffectProperties" ) + if( aGrabBag[i].Name == "EffectProperties" || aGrabBag[i].Name == "3DEffectProperties" || + aGrabBag[i].Name == "ArtisticEffectProperties" ) bContainsEffects = true; } |