include/oox/export/drawingml.hxx | 4 +++ include/oox/export/vmlexport.hxx | 4 +++ oox/source/export/drawingml.cxx | 33 +++++++++++++++++++++++---- oox/source/export/vmlexport.cxx | 9 ++++++- sw/qa/extras/ooxmlexport/data/tdf83227.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport4.cxx | 12 +++++++++ sw/source/filter/ww8/docxattributeoutput.cxx | 16 +++++++++++++ sw/source/filter/ww8/docxattributeoutput.hxx | 4 +++ 8 files changed, 77 insertions(+), 5 deletions(-)
New commits: commit c9a290c2a87e9af3b0cd4ccbdd751dddab3532da Author: Miklos Vajna <[email protected]> Date: Mon Sep 7 08:42:46 2015 +0200 tdf#83227 oox: reuse RelId in DML/VML export for the same graphic So that large images are written only once to the ZIP container when they are exported using both markups. This affects drawinglayer images, the Writer ones are handled directly in sw and were already deduplicated. (cherry picked from commit b484e9814c66d8d51cea974390963a6944bc9d73) Conflicts: oox/source/export/drawingml.cxx Change-Id: Iff7c769329b42939833056b727b070f6a60da5e3 Reviewed-on: https://gerrit.libreoffice.org/18581 Reviewed-by: Caolán McNamara <[email protected]> Tested-by: Caolán McNamara <[email protected]> diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx index 4bfaf3a..246960c 100644 --- a/include/oox/export/drawingml.hxx +++ b/include/oox/export/drawingml.hxx @@ -73,6 +73,10 @@ public: virtual void WriteOutliner(const OutlinerParaObject& rParaObj) = 0; /// Write the contents of the textbox that is associated to this shape. virtual void WriteTextBox(css::uno::Reference<css::drawing::XShape> xShape) = 0; + /// Look up the RelId of a graphic based on its checksum. + virtual OUString FindRelId(sal_uInt32 nChecksum) = 0; + /// Store the RelId of a graphic based on its checksum. + virtual void CacheRelId(sal_uInt32 nChecksum, const OUString& rRelId) = 0; protected: DMLTextExport() {} virtual ~DMLTextExport() {} diff --git a/include/oox/export/vmlexport.hxx b/include/oox/export/vmlexport.hxx index a87ed16..da274c1 100644 --- a/include/oox/export/vmlexport.hxx +++ b/include/oox/export/vmlexport.hxx @@ -39,6 +39,10 @@ public: virtual oox::drawingml::DrawingML& GetDrawingML() = 0; /// Write the contents of the textbox that is associated to this shape in VML format. virtual void WriteVMLTextBox(css::uno::Reference<css::drawing::XShape> xShape) = 0; + /// Look up the RelId of a graphic based on its checksum. + virtual OUString FindRelId(sal_uInt32 nChecksum) = 0; + /// Store the RelId of a graphic based on its checksum. + virtual void CacheRelId(sal_uInt32 nChecksum, const OUString& rRelId) = 0; protected: VMLTextExport() {} virtual ~VMLTextExport() {} diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index edff9b9..66dfb1f 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -762,7 +762,7 @@ void DrawingML::WriteOutline( Reference<XPropertySet> rXPropSet ) mpFS->endElementNS( XML_a, XML_ln ); } -OUString DrawingML::WriteImage( const OUString& rURL, bool bRelPathToMedia ) +bool lcl_URLToGraphic(const OUString& rURL, Graphic& rGraphic) { OString aURLBS(OUStringToOString(rURL, RTL_TEXTENCODING_UTF8)); @@ -771,9 +771,18 @@ OUString DrawingML::WriteImage( const OUString& rURL, bool bRelPathToMedia ) if ( index != -1 ) { - DBG(fprintf (stderr, "begin: %ld %s\n", long( sizeof( aURLBegin ) ), USS( rURL ) + RTL_CONSTASCII_LENGTH( aURLBegin ) )); - Graphic aGraphic = GraphicObject( aURLBS.copy(RTL_CONSTASCII_LENGTH(aURLBegin)) ).GetTransformedGraphic (); + rGraphic = GraphicObject(aURLBS.copy(RTL_CONSTASCII_LENGTH(aURLBegin))).GetTransformedGraphic(); + return true; + } + + return false; +} +OUString DrawingML::WriteImage( const OUString& rURL, bool bRelPathToMedia ) +{ + Graphic aGraphic; + if (lcl_URLToGraphic(rURL, aGraphic)) + { return WriteImage( aGraphic , bRelPathToMedia ); } else @@ -923,7 +932,23 @@ OUString DrawingML::WriteImage( const Graphic& rGraphic , bool bRelPathToMedia ) OUString DrawingML::WriteBlip( Reference< XPropertySet > rXPropSet, const OUString& rURL, bool bRelPathToMedia, const Graphic *pGraphic ) { - OUString sRelId = pGraphic ? WriteImage( *pGraphic, bRelPathToMedia ) : WriteImage( rURL, bRelPathToMedia ); + OUString sRelId; + sal_uInt32 nChecksum = 0; + if (!rURL.isEmpty() && mpTextExport) + { + Graphic aGraphic; + if (lcl_URLToGraphic(rURL, aGraphic)) + { + nChecksum = aGraphic.GetChecksum(); + sRelId = mpTextExport->FindRelId(nChecksum); + } + } + if (sRelId.isEmpty()) + { + sRelId = pGraphic ? WriteImage( *pGraphic, bRelPathToMedia ) : WriteImage( rURL, bRelPathToMedia ); + if (!rURL.isEmpty() && mpTextExport) + mpTextExport->CacheRelId(nChecksum, sRelId); + } sal_Int16 nBright = 0; sal_Int32 nContrast = 0; diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx index a0a1ac7..557bb8c 100644 --- a/oox/source/export/vmlexport.cxx +++ b/oox/source/export/vmlexport.cxx @@ -605,7 +605,14 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect aStream.Seek(0); Graphic aGraphic; GraphicConverter::Import(aStream, aGraphic); - OUString aImageId = m_pTextExport->GetDrawingML().WriteImage( aGraphic ); + + sal_uInt32 nChecksum = aGraphic.GetChecksum(); + OUString aImageId = m_pTextExport->FindRelId(nChecksum); + if (aImageId.isEmpty()) + { + aImageId = m_pTextExport->GetDrawingML().WriteImage( aGraphic ); + m_pTextExport->CacheRelId(nChecksum, aImageId); + } pAttrList->add(FSNS(XML_r, XML_id), OUStringToOString(aImageId, RTL_TEXTENCODING_UTF8)); imageData = true; } diff --git a/sw/qa/extras/ooxmlexport/data/tdf83227.docx b/sw/qa/extras/ooxmlexport/data/tdf83227.docx new file mode 100644 index 0000000..bca19a9 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf83227.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx index 9a495fd..5690507 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx @@ -798,6 +798,18 @@ DECLARE_OOXMLEXPORT_TEST(testSimpleSdts, "simple-sdts.docx") } +DECLARE_OOXMLEXPORT_TEST(testTdf83227, "tdf83227.docx") +{ + // Bug document contains a rotated image, which is handled as a draw shape (not as a Writer image) on export. + if (!mbExported) + return; + + uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), maTempFile.GetURL()); + CPPUNIT_ASSERT_EQUAL(true, bool(xNameAccess->hasByName("word/media/image1.png"))); + // This was also true, image was written twice. + CPPUNIT_ASSERT_EQUAL(false, bool(xNameAccess->hasByName("word/media/image2.png"))); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 8d37821..4cba427 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -4046,6 +4046,22 @@ void DocxAttributeOutput::WriteSrcRect(const SdrObject* pSdrObj ) void DocxAttributeOutput::ClearRelIdCache() { m_aRelIdCache.clear(); + m_aSdrRelIdCache.clear(); +} + +OUString DocxAttributeOutput::FindRelId(sal_uInt32 nChecksum) +{ + OUString aRet; + + if (m_aSdrRelIdCache.find(nChecksum) != m_aSdrRelIdCache.end()) + aRet = m_aSdrRelIdCache[nChecksum]; + + return aRet; +} + +void DocxAttributeOutput::CacheRelId(sal_uInt32 nChecksum, const OUString& rRelId) +{ + m_aSdrRelIdCache[nChecksum] = rRelId; } void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrmFmt* pOLEFrmFmt, SwOLENode* pOLENode, const SdrObject* pSdrObj ) diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index a5e13d9..f8ae626 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -901,6 +901,8 @@ private: /// RelId <-> Graphic* cache, so that in case of alternate content, the same graphic only gets written once. std::map<const Graphic*, OString> m_aRelIdCache; + /// RelId <-> sal_uInt32 (bitmap checksum) cache, similar to m_aRelIdCache, but used for non-Writer graphics, handled in oox. + std::map<sal_uInt32, OUString> m_aSdrRelIdCache; /// members to control the existence of grabbagged SDT properties in the paragraph sal_Int32 m_nParagraphSdtPrToken; @@ -958,6 +960,8 @@ public: virtual void WriteVMLTextBox(css::uno::Reference<css::drawing::XShape> xShape) SAL_OVERRIDE; /// DMLTextExport virtual void WriteTextBox(css::uno::Reference<css::drawing::XShape> xShape) SAL_OVERRIDE; + virtual OUString FindRelId(sal_uInt32 nChecksum) SAL_OVERRIDE; + virtual void CacheRelId(sal_uInt32 nChecksum, const OUString& rRelId) SAL_OVERRIDE; virtual oox::drawingml::DrawingML& GetDrawingML() SAL_OVERRIDE; void BulletDefinition(int nId, const Graphic& rGraphic, Size aSize) SAL_OVERRIDE;
_______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
