summaryrefslogtreecommitdiff
path: root/oox/source/drawingml
diff options
context:
space:
mode:
authorJacobo Aragunde Pérez <jaragunde@igalia.com>2014-05-20 21:05:10 +0200
committerJacobo Aragunde Pérez <jaragunde@igalia.com>2014-05-23 10:03:59 +0200
commit642a252cf1a2f1d08c4bbfcae15527bb82c7664d (patch)
tree605b6c546b61972a9c6dd6b1fd1b3a89d3b9f0e0 /oox/source/drawingml
parent21d4cfe19e2796ebf89c408e292c4473924b2bc4 (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
Diffstat (limited to 'oox/source/drawingml')
-rw-r--r--oox/source/drawingml/fillproperties.cxx193
-rw-r--r--oox/source/drawingml/fillpropertiesgroupcontext.cxx70
-rw-r--r--oox/source/drawingml/shape.cxx5
3 files changed, 268 insertions, 0 deletions
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 )