[Libreoffice-commits] core.git: Branch 'libreoffice-5-0' - include/oox oox/source sw/qa sw/source

Miklos Vajna vmiklos at collabora.co.uk
Fri Sep 11 02:36:43 PDT 2015


 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 1b381370b026f62397dc2d41ddcecf9d6523e044
Author: Miklos Vajna <vmiklos at collabora.co.uk>
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/18491
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index 3b9d847..fff1e2c 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -74,6 +74,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(BitmapChecksum nChecksum) = 0;
+    /// Store the RelId of a graphic based on its checksum.
+    virtual void CacheRelId(BitmapChecksum 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..922b019 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(BitmapChecksum nChecksum) = 0;
+    /// Store the RelId of a graphic based on its checksum.
+    virtual void CacheRelId(BitmapChecksum nChecksum, const OUString& rRelId) = 0;
 protected:
     VMLTextExport() {}
     virtual ~VMLTextExport() {}
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index da38474..878276a 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -769,7 +769,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));
 
@@ -778,9 +778,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
@@ -930,7 +939,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;
+    BitmapChecksum 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 7161a2f..d90ff82 100644
--- a/oox/source/export/vmlexport.cxx
+++ b/oox/source/export/vmlexport.cxx
@@ -583,7 +583,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 );
+
+                        BitmapChecksum 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 3727353..3a273f3 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx
@@ -803,6 +803,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 022ee0b..00aeb75 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -4074,6 +4074,22 @@ void DocxAttributeOutput::WriteSrcRect(const SdrObject* pSdrObj )
 void DocxAttributeOutput::ClearRelIdCache()
 {
     m_aRelIdCache.clear();
+    m_aSdrRelIdCache.clear();
+}
+
+OUString DocxAttributeOutput::FindRelId(BitmapChecksum nChecksum)
+{
+    OUString aRet;
+
+    if (m_aSdrRelIdCache.find(nChecksum) != m_aSdrRelIdCache.end())
+        aRet = m_aSdrRelIdCache[nChecksum];
+
+    return aRet;
+}
+
+void DocxAttributeOutput::CacheRelId(BitmapChecksum nChecksum, const OUString& rRelId)
+{
+     m_aSdrRelIdCache[nChecksum] = rRelId;
 }
 
 void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrameFormat* pOLEFrameFormat, SwOLENode* pOLENode, const SdrObject* pSdrObj )
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index b7ce59d..4dbc29f 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -906,6 +906,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 <-> BitmapChecksum cache, similar to m_aRelIdCache, but used for non-Writer graphics, handled in oox.
+    std::map<BitmapChecksum, OUString> m_aSdrRelIdCache;
 
     /// members to control the existence of grabbagged SDT properties in the paragraph
     sal_Int32 m_nParagraphSdtPrToken;
@@ -963,6 +965,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(BitmapChecksum nChecksum) SAL_OVERRIDE;
+    virtual void CacheRelId(BitmapChecksum nChecksum, const OUString& rRelId) SAL_OVERRIDE;
     virtual oox::drawingml::DrawingML& GetDrawingML() SAL_OVERRIDE;
 
     void BulletDefinition(int nId, const Graphic& rGraphic, Size aSize) SAL_OVERRIDE;


More information about the Libreoffice-commits mailing list