Kaydet (Commit) b5f6a5cf authored tarafından Jacobo Aragunde Pérez's avatar Jacobo Aragunde Pérez

ooxml: Do not repeat wdp files in artistic effects

When two pictures apply different effects to the same picture, it is
only saved once in the original document. Added a cache to DrawingML
to know if the picture has already been exported, and added a test
for it.

Change-Id: Ia25f3d8f2f46d61f18aefc22fdfdbcdc72f2d916
üst 2e68a146
...@@ -83,6 +83,7 @@ public: ...@@ -83,6 +83,7 @@ public:
private: private:
static int mnImageCounter; static int mnImageCounter;
static int mnWdpImageCounter; static int mnWdpImageCounter;
static std::map<OUString, OUString> maWdpCache;
/// To specify where write eg. the images to (like 'ppt', or 'word' - according to the OPC). /// To specify where write eg. the images to (like 'ppt', or 'word' - according to the OPC).
DocumentType meDocumentType; DocumentType meDocumentType;
...@@ -178,7 +179,7 @@ public: ...@@ -178,7 +179,7 @@ public:
void WriteShapeEffect( const OUString& sName, const css::uno::Sequence< css::beans::PropertyValue >& aEffectProps ); 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 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 ); void WriteArtisticEffect( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet );
OString WriteWdpPicture( const ::com::sun::star::uno::Sequence< sal_Int8 >& rPictureData ); OString WriteWdpPicture( const OUString& rFileId, const ::com::sun::star::uno::Sequence< sal_Int8 >& rPictureData );
static void ResetCounters(); static void ResetCounters();
......
...@@ -619,8 +619,14 @@ css::beans::PropertyValue ArtisticEffectProperties::getEffect() ...@@ -619,8 +619,14 @@ css::beans::PropertyValue ArtisticEffectProperties::getEffect()
if( mrOleObjectInfo.maEmbeddedData.hasElements() ) if( mrOleObjectInfo.maEmbeddedData.hasElements() )
{ {
css::uno::Sequence< css::beans::PropertyValue > aGraphicSeq( 2 );
aGraphicSeq[0].Name = "Id";
aGraphicSeq[0].Value = uno::makeAny( mrOleObjectInfo.maProgId );
aGraphicSeq[1].Name = "Data";
aGraphicSeq[1].Value = uno::makeAny( mrOleObjectInfo.maEmbeddedData );
aSeq[i].Name = "OriginalGraphic"; aSeq[i].Name = "OriginalGraphic";
aSeq[i].Value = uno::makeAny( mrOleObjectInfo.maEmbeddedData ); aSeq[i].Value = uno::makeAny( aGraphicSeq );
} }
pRet.Name = msName; pRet.Name = msName;
......
...@@ -339,7 +339,10 @@ ContextHandlerRef ArtisticEffectContext::onCreateContext( ...@@ -339,7 +339,10 @@ ContextHandlerRef ArtisticEffectContext::onCreateContext(
{ {
OUString aFragmentPath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( embed ), OUString() ) ); OUString aFragmentPath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( embed ), OUString() ) );
if( !aFragmentPath.isEmpty() ) if( !aFragmentPath.isEmpty() )
{
getFilter().importBinaryData( maEffect.mrOleObjectInfo.maEmbeddedData, aFragmentPath ); getFilter().importBinaryData( maEffect.mrOleObjectInfo.maEmbeddedData, aFragmentPath );
maEffect.mrOleObjectInfo.maProgId = aFragmentPath;
}
} }
return new ArtisticEffectContext( *this, maEffect ); return new ArtisticEffectContext( *this, maEffect );
} }
......
...@@ -120,11 +120,13 @@ namespace drawingml { ...@@ -120,11 +120,13 @@ namespace drawingml {
// not thread safe // not thread safe
int DrawingML::mnImageCounter = 1; int DrawingML::mnImageCounter = 1;
int DrawingML::mnWdpImageCounter = 1; int DrawingML::mnWdpImageCounter = 1;
std::map<OUString, OUString> DrawingML::maWdpCache;
void DrawingML::ResetCounters() void DrawingML::ResetCounters()
{ {
mnImageCounter = 1; mnImageCounter = 1;
mnWdpImageCounter = 1; mnWdpImageCounter = 1;
maWdpCache.clear();
} }
bool DrawingML::GetProperty( Reference< XPropertySet > rXPropSet, const OUString& aName ) bool DrawingML::GetProperty( Reference< XPropertySet > rXPropSet, const OUString& aName )
...@@ -2604,9 +2606,18 @@ void DrawingML::WriteArtisticEffect( Reference< XPropertySet > rXPropSet ) ...@@ -2604,9 +2606,18 @@ void DrawingML::WriteArtisticEffect( Reference< XPropertySet > rXPropSet )
} }
else if( aAttrs[i].Name == "OriginalGraphic" ) else if( aAttrs[i].Name == "OriginalGraphic" )
{ {
Sequence< PropertyValue > aGraphic;
aAttrs[i].Value >>= aGraphic;
Sequence< sal_Int8 > aGraphicData; Sequence< sal_Int8 > aGraphicData;
aAttrs[i].Value >>= aGraphicData; OUString sGraphicId;
sRelId = WriteWdpPicture( aGraphicData ); for( sal_Int32 j=0; j < aGraphic.getLength(); ++j )
{
if( aGraphic[j].Name == "Id" )
aGraphic[j].Value >>= sGraphicId;
else if( aGraphic[j].Name == "Data" )
aGraphic[j].Value >>= aGraphicData;
}
sRelId = WriteWdpPicture( sGraphicId, aGraphicData );
} }
} }
...@@ -2632,8 +2643,12 @@ void DrawingML::WriteArtisticEffect( Reference< XPropertySet > rXPropSet ) ...@@ -2632,8 +2643,12 @@ void DrawingML::WriteArtisticEffect( Reference< XPropertySet > rXPropSet )
mpFS->endElementNS( XML_a, XML_extLst ); mpFS->endElementNS( XML_a, XML_extLst );
} }
OString DrawingML::WriteWdpPicture( const Sequence< sal_Int8 >& rPictureData ) OString DrawingML::WriteWdpPicture( const OUString& rFileId, const Sequence< sal_Int8 >& rPictureData )
{ {
std::map<OUString, OUString>::iterator aCachedItem = maWdpCache.find( rFileId );
if( aCachedItem != maWdpCache.end() )
return OUStringToOString( aCachedItem->second, RTL_TEXTENCODING_UTF8 );
OUString sFileName = "media/hdphoto" + OUString::number( mnWdpImageCounter++ ) + ".wdp"; OUString sFileName = "media/hdphoto" + OUString::number( mnWdpImageCounter++ ) + ".wdp";
uno::Reference< io::XOutputStream > xOutStream = uno::Reference< io::XOutputStream > xOutStream =
mpFB->openFragmentStream( "word/" + sFileName, mpFB->openFragmentStream( "word/" + sFileName,
...@@ -2646,6 +2661,7 @@ OString DrawingML::WriteWdpPicture( const Sequence< sal_Int8 >& rPictureData ) ...@@ -2646,6 +2661,7 @@ OString DrawingML::WriteWdpPicture( const Sequence< sal_Int8 >& rPictureData )
"http://schemas.microsoft.com/office/2007/relationships/hdphoto", "http://schemas.microsoft.com/office/2007/relationships/hdphoto",
sFileName, false ); sFileName, false );
maWdpCache[rFileId] = sId;
return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 ); return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
} }
......
...@@ -1378,9 +1378,7 @@ DECLARE_OOXMLEXPORT_TEST(testPictureArtisticEffectPreservation, "picture-artisti ...@@ -1378,9 +1378,7 @@ DECLARE_OOXMLEXPORT_TEST(testPictureArtisticEffectPreservation, "picture-artisti
OUString sEmbedId2 = getXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent/mc:Choice/w:drawing/" 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", "wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip/a:extLst/a:ext/a14:imgProps/a14:imgLayer",
"embed"); "embed");
sXmlPath = "/rels:Relationships/rels:Relationship[@Id='" + sEmbedId2 + "']"; CPPUNIT_ASSERT_EQUAL(sEmbedId1, sEmbedId2);
sFile = getXPath(pRelsDoc, OUStringToOString( sXmlPath, RTL_TEXTENCODING_UTF8 ), "Target");
CPPUNIT_ASSERT_EQUAL(true, bool(xNameAccess->hasByName("word/" + sFile)));
// 3rd picture: pencil sketch // 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/" assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/"
...@@ -1395,9 +1393,7 @@ DECLARE_OOXMLEXPORT_TEST(testPictureArtisticEffectPreservation, "picture-artisti ...@@ -1395,9 +1393,7 @@ DECLARE_OOXMLEXPORT_TEST(testPictureArtisticEffectPreservation, "picture-artisti
OUString sEmbedId3 = getXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/" 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", "wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip/a:extLst/a:ext/a14:imgProps/a14:imgLayer",
"embed"); "embed");
sXmlPath = "/rels:Relationships/rels:Relationship[@Id='" + sEmbedId3 + "']"; CPPUNIT_ASSERT_EQUAL(sEmbedId1, sEmbedId3);
sFile = getXPath(pRelsDoc, OUStringToOString( sXmlPath, RTL_TEXTENCODING_UTF8 ), "Target");
CPPUNIT_ASSERT_EQUAL(true, bool(xNameAccess->hasByName("word/" + sFile)));
// 4th picture: light screen // 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/" assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/"
...@@ -1425,9 +1421,7 @@ DECLARE_OOXMLEXPORT_TEST(testPictureArtisticEffectPreservation, "picture-artisti ...@@ -1425,9 +1421,7 @@ DECLARE_OOXMLEXPORT_TEST(testPictureArtisticEffectPreservation, "picture-artisti
OUString sEmbedId5 = getXPath(pXmlDoc, "/w:document/w:body/w:p[5]/w:r/mc:AlternateContent/mc:Choice/w:drawing/" 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", "wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip/a:extLst/a:ext/a14:imgProps/a14:imgLayer",
"embed"); "embed");
sXmlPath = "/rels:Relationships/rels:Relationship[@Id='" + sEmbedId5 + "']"; CPPUNIT_ASSERT_EQUAL(sEmbedId1, sEmbedId5);
sFile = getXPath(pRelsDoc, OUStringToOString( sXmlPath, RTL_TEXTENCODING_UTF8 ), "Target");
CPPUNIT_ASSERT_EQUAL(true, bool(xNameAccess->hasByName("word/" + sFile)));
// 6th picture: photocopy (no attributes) // 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/" assertXPath(pXmlDoc, "/w:document/w:body/w:p[6]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/"
...@@ -1437,9 +1431,10 @@ DECLARE_OOXMLEXPORT_TEST(testPictureArtisticEffectPreservation, "picture-artisti ...@@ -1437,9 +1431,10 @@ DECLARE_OOXMLEXPORT_TEST(testPictureArtisticEffectPreservation, "picture-artisti
OUString sEmbedId6 = getXPath(pXmlDoc, "/w:document/w:body/w:p[6]/w:r/mc:AlternateContent/mc:Choice/w:drawing/" 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", "wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip/a:extLst/a:ext/a14:imgProps/a14:imgLayer",
"embed"); "embed");
sXmlPath = "/rels:Relationships/rels:Relationship[@Id='" + sEmbedId6 + "']"; CPPUNIT_ASSERT_EQUAL(sEmbedId1, sEmbedId6);
sFile = getXPath(pRelsDoc, OUStringToOString( sXmlPath, RTL_TEXTENCODING_UTF8 ), "Target");
CPPUNIT_ASSERT_EQUAL(true, bool(xNameAccess->hasByName("word/" + sFile))); // no redundant wdp files saved
CPPUNIT_ASSERT_EQUAL(false, bool(xNameAccess->hasByName("word/media/hdphoto3.wdp")));
} }
DECLARE_OOXMLEXPORT_TEST(fdo77719, "fdo77719.docx") DECLARE_OOXMLEXPORT_TEST(fdo77719, "fdo77719.docx")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment