diff options
author | Jacobo Aragunde Pérez <jaragunde@igalia.com> | 2014-05-22 13:54:42 +0200 |
---|---|---|
committer | Jacobo Aragunde Pérez <jaragunde@igalia.com> | 2014-05-23 10:04:00 +0200 |
commit | 2e68a1468c035fc3bb4d02ad0b3187872fe1e67b (patch) | |
tree | 0bd5ccdee8253233ca7f919a70c5bd337b3b5a37 /oox | |
parent | 642a252cf1a2f1d08c4bbfcae15527bb82c7664d (diff) |
ooxml: Preserve the original picture in artistic effects
When Word applies an artistic effect, it creates two embedded files;
one contains the bitmap with the effect and the other one contains the
original bitmap to be able to undo the effect.
This patch reads the original bitmap, stores it in the shape grab bag
and saves it back to the docx file. Added unit tests too.
TODO: right now, if two effects point to the same original bitmap it
is stored twice, we should improve this.
Change-Id: Ia72034a257739abe4ffafa0f42b2a912e4bf9436
Diffstat (limited to 'oox')
-rw-r--r-- | oox/source/drawingml/fillproperties.cxx | 8 | ||||
-rw-r--r-- | oox/source/drawingml/fillpropertiesgroupcontext.cxx | 13 | ||||
-rw-r--r-- | oox/source/export/drawingml.cxx | 30 |
3 files changed, 47 insertions, 4 deletions
diff --git a/oox/source/drawingml/fillproperties.cxx b/oox/source/drawingml/fillproperties.cxx index a9ca0db37546..7d816758f459 100644 --- a/oox/source/drawingml/fillproperties.cxx +++ b/oox/source/drawingml/fillproperties.cxx @@ -608,7 +608,7 @@ css::beans::PropertyValue ArtisticEffectProperties::getEffect() if( msName.isEmpty() ) return pRet; - css::uno::Sequence< css::beans::PropertyValue > aSeq( maAttribs.size() ); + css::uno::Sequence< css::beans::PropertyValue > aSeq( maAttribs.size() + 1 ); sal_uInt32 i = 0; for( std::map< OUString, css::uno::Any >::iterator it = maAttribs.begin(); it != maAttribs.end(); ++it ) { @@ -617,6 +617,12 @@ css::beans::PropertyValue ArtisticEffectProperties::getEffect() i++; } + if( mrOleObjectInfo.maEmbeddedData.hasElements() ) + { + aSeq[i].Name = "OriginalGraphic"; + aSeq[i].Value = uno::makeAny( mrOleObjectInfo.maEmbeddedData ); + } + pRet.Name = msName; pRet.Value = css::uno::Any( aSeq ); diff --git a/oox/source/drawingml/fillpropertiesgroupcontext.cxx b/oox/source/drawingml/fillpropertiesgroupcontext.cxx index e7e414277906..ac8f215a9d03 100644 --- a/oox/source/drawingml/fillpropertiesgroupcontext.cxx +++ b/oox/source/drawingml/fillpropertiesgroupcontext.cxx @@ -333,9 +333,18 @@ ContextHandlerRef ArtisticEffectContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) { // containers - if( nElement == OOX_TOKEN( a14, imgLayer ) || nElement == OOX_TOKEN( a14, imgEffect ) ) + if( nElement == OOX_TOKEN( a14, imgLayer ) ) + { + if( rAttribs.hasAttribute( R_TOKEN( embed ) ) ) + { + OUString aFragmentPath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( embed ), OUString() ) ); + if( !aFragmentPath.isEmpty() ) + getFilter().importBinaryData( maEffect.mrOleObjectInfo.maEmbeddedData, aFragmentPath ); + } + return new ArtisticEffectContext( *this, maEffect ); + } + if( nElement == OOX_TOKEN( a14, imgEffect ) ) return new ArtisticEffectContext( *this, maEffect ); - // TODO: manage r:embed attribute in a14:imgLayer // effects maEffect.msName = ArtisticEffectProperties::getEffectString( nElement ); diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 0364764f1d3d..141455452809 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -119,10 +119,12 @@ namespace drawingml { // not thread safe int DrawingML::mnImageCounter = 1; +int DrawingML::mnWdpImageCounter = 1; void DrawingML::ResetCounters() { mnImageCounter = 1; + mnWdpImageCounter = 1; } bool DrawingML::GetProperty( Reference< XPropertySet > rXPropSet, const OUString& aName ) @@ -2590,6 +2592,7 @@ void DrawingML::WriteArtisticEffect( Reference< XPropertySet > rXPropSet ) Sequence< PropertyValue > aAttrs; aEffect.Value >>= aAttrs; sax_fastparser::FastAttributeList *aAttrList = mpFS->createAttrList(); + OString sRelId; for( sal_Int32 i=0; i < aAttrs.getLength(); ++i ) { sal_Int32 nToken = ArtisticEffectProperties::getEffectToken( aAttrs[i].Name ); @@ -2599,6 +2602,12 @@ void DrawingML::WriteArtisticEffect( Reference< XPropertySet > rXPropSet ) aAttrs[i].Value >>= nVal; aAttrList->add( nToken, OString::number( nVal ).getStr() ); } + else if( aAttrs[i].Name == "OriginalGraphic" ) + { + Sequence< sal_Int8 > aGraphicData; + aAttrs[i].Value >>= aGraphicData; + sRelId = WriteWdpPicture( aGraphicData ); + } } mpFS->startElementNS( XML_a, XML_extLst, FSEND ); @@ -2608,7 +2617,9 @@ void DrawingML::WriteArtisticEffect( Reference< XPropertySet > rXPropSet ) 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_imgLayer, + FSNS( XML_r, XML_embed), sRelId.getStr(), + FSEND ); mpFS->startElementNS( XML_a14, XML_imgEffect, FSEND ); sax_fastparser::XFastAttributeListRef xAttrList( aAttrList ); @@ -2621,6 +2632,23 @@ void DrawingML::WriteArtisticEffect( Reference< XPropertySet > rXPropSet ) mpFS->endElementNS( XML_a, XML_extLst ); } +OString DrawingML::WriteWdpPicture( const Sequence< sal_Int8 >& rPictureData ) +{ + OUString sFileName = "media/hdphoto" + OUString::number( mnWdpImageCounter++ ) + ".wdp"; + uno::Reference< io::XOutputStream > xOutStream = + mpFB->openFragmentStream( "word/" + sFileName, + "image/vnd.ms-photo" ); + OUString sId; + xOutStream->writeBytes( rPictureData ); + xOutStream->closeOutput(); + + sId = mpFB->addRelation( mpFS->getOutputStream(), + "http://schemas.microsoft.com/office/2007/relationships/hdphoto", + sFileName, false ); + + return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 ); +} + } } |