diff options
-rw-r--r-- | include/oox/drawingml/fillproperties.hxx | 2 | ||||
-rw-r--r-- | include/oox/export/drawingml.hxx | 2 | ||||
-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 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx | 48 |
6 files changed, 98 insertions, 5 deletions
diff --git a/include/oox/drawingml/fillproperties.hxx b/include/oox/drawingml/fillproperties.hxx index c588deec8faa..dcf3afbfd230 100644 --- a/include/oox/drawingml/fillproperties.hxx +++ b/include/oox/drawingml/fillproperties.hxx @@ -26,6 +26,7 @@ #include <oox/drawingml/color.hxx> #include <oox/helper/helper.hxx> #include <oox/drawingml/embeddedwavaudiofile.hxx> +#include <oox/ole/oleobjecthelper.hxx> namespace oox { class GraphicHelper; @@ -70,6 +71,7 @@ struct ArtisticEffectProperties OUString msName; std::map< OUString, css::uno::Any > maAttribs; + ::oox::ole::OleObjectInfo mrOleObjectInfo; /// The original graphic as embedded object. bool isEmpty() const; diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx index 98cc0dfb38a0..77d54b48b014 100644 --- a/include/oox/export/drawingml.hxx +++ b/include/oox/export/drawingml.hxx @@ -82,6 +82,7 @@ public: private: static int mnImageCounter; + static int mnWdpImageCounter; /// To specify where write eg. the images to (like 'ppt', or 'word' - according to the OPC). DocumentType meDocumentType; @@ -177,6 +178,7 @@ public: 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 ); + OString WriteWdpPicture( const ::com::sun::star::uno::Sequence< sal_Int8 >& rPictureData ); static void ResetCounters(); 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 ); +} + } } diff --git a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx index 43f5b6e7751d..0284347daa86 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx @@ -1341,9 +1341,13 @@ DECLARE_OOXMLEXPORT_TEST(testPictureEffectPreservation, "picture-effects-preserv DECLARE_OOXMLEXPORT_TEST(testPictureArtisticEffectPreservation, "picture-artistic-effects-preservation.docx") { xmlDocPtr pXmlDoc = parseExport("word/document.xml"); - if (!pXmlDoc) + xmlDocPtr pRelsDoc = parseExport("word/_rels/document.xml.rels"); + if (!pXmlDoc || !pRelsDoc) return; + uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL( + comphelper::getComponentContext(m_xSFactory), maTempFile.GetURL()); + // 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/" @@ -1354,6 +1358,13 @@ DECLARE_OOXMLEXPORT_TEST(testPictureArtisticEffectPreservation, "picture-artisti "a14:artisticMarker", "size", "80"); + OUString sEmbedId1 = getXPath(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", + "embed"); + OUString sXmlPath = "/rels:Relationships/rels:Relationship[@Id='" + sEmbedId1 + "']"; + OUString sFile = getXPath(pRelsDoc, OUStringToOString( sXmlPath, RTL_TEXTENCODING_UTF8 ), "Target"); + CPPUNIT_ASSERT_EQUAL(true, bool(xNameAccess->hasByName("word/" + sFile))); + // 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/" @@ -1364,6 +1375,13 @@ DECLARE_OOXMLEXPORT_TEST(testPictureArtisticEffectPreservation, "picture-artisti "a14:artisticPencilGrayscale", "pencilSize", "66"); + OUString sEmbedId2 = getXPath(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", + "embed"); + sXmlPath = "/rels:Relationships/rels:Relationship[@Id='" + sEmbedId2 + "']"; + sFile = getXPath(pRelsDoc, OUStringToOString( sXmlPath, RTL_TEXTENCODING_UTF8 ), "Target"); + CPPUNIT_ASSERT_EQUAL(true, bool(xNameAccess->hasByName("word/" + sFile))); + // 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/" @@ -1374,6 +1392,13 @@ DECLARE_OOXMLEXPORT_TEST(testPictureArtisticEffectPreservation, "picture-artisti "a14:artisticPencilSketch", "pressure", "17"); + OUString sEmbedId3 = getXPath(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", + "embed"); + sXmlPath = "/rels:Relationships/rels:Relationship[@Id='" + sEmbedId3 + "']"; + sFile = getXPath(pRelsDoc, OUStringToOString( sXmlPath, RTL_TEXTENCODING_UTF8 ), "Target"); + CPPUNIT_ASSERT_EQUAL(true, bool(xNameAccess->hasByName("word/" + sFile))); + // 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/" @@ -1384,16 +1409,37 @@ DECLARE_OOXMLEXPORT_TEST(testPictureArtisticEffectPreservation, "picture-artisti "a14:artisticLightScreen", "gridSize", "1"); + OUString sEmbedId4 = getXPath(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", + "embed"); + sXmlPath = "/rels:Relationships/rels:Relationship[@Id='" + sEmbedId4 + "']"; + sFile = getXPath(pRelsDoc, OUStringToOString( sXmlPath, RTL_TEXTENCODING_UTF8 ), "Target"); + CPPUNIT_ASSERT_EQUAL(true, bool(xNameAccess->hasByName("word/" + sFile))); + // 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"); + OUString sEmbedId5 = getXPath(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", + "embed"); + sXmlPath = "/rels:Relationships/rels:Relationship[@Id='" + sEmbedId5 + "']"; + sFile = getXPath(pRelsDoc, OUStringToOString( sXmlPath, RTL_TEXTENCODING_UTF8 ), "Target"); + CPPUNIT_ASSERT_EQUAL(true, bool(xNameAccess->hasByName("word/" + sFile))); + // 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); + + OUString sEmbedId6 = getXPath(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", + "embed"); + sXmlPath = "/rels:Relationships/rels:Relationship[@Id='" + sEmbedId6 + "']"; + sFile = getXPath(pRelsDoc, OUStringToOString( sXmlPath, RTL_TEXTENCODING_UTF8 ), "Target"); + CPPUNIT_ASSERT_EQUAL(true, bool(xNameAccess->hasByName("word/" + sFile))); } DECLARE_OOXMLEXPORT_TEST(fdo77719, "fdo77719.docx") |