[Libreoffice-commits] core.git: Branch 'private/swe/libreoffice-5-2+backports' - 7 commits - comphelper/Library_comphelper.mk comphelper/source filter/source include/comphelper include/xmloff svx/source sw/CppunitTest_sw_fodfexport.mk sw/Module_sw.mk sw/qa xmloff/source

Samuel Mehrbrodt Samuel.Mehrbrodt at cib.de
Fri Dec 1 15:11:19 UTC 2017


 comphelper/Library_comphelper.mk                    |    1 
 comphelper/source/misc/graphicmimetype.cxx          |  105 ++++++++++++++++++++
 filter/source/xslt/odf2xhtml/export/common/body.xsl |   52 +++++----
 filter/source/xslt/odf2xhtml/export/xhtml/body.xsl  |   50 +++++----
 include/comphelper/graphicmimetype.hxx              |   35 ++++++
 include/xmloff/xmlexp.hxx                           |    2 
 svx/source/svdraw/svdograf.cxx                      |    5 
 sw/CppunitTest_sw_fodfexport.mk                     |   57 ++++++++++
 sw/Module_sw.mk                                     |    1 
 sw/qa/extras/fodfexport/data/tdf113696.odt          |binary
 sw/qa/extras/fodfexport/fodfexport.cxx              |   44 ++++++++
 sw/qa/extras/inc/swmodeltestbase.hxx                |   11 ++
 sw/qa/extras/odfexport/data/image-mimetype.odt      |binary
 sw/qa/extras/odfexport/odfexport.cxx                |   10 +
 xmloff/source/core/xmlexp.cxx                       |   18 +++
 xmloff/source/draw/shapeexport.cxx                  |   26 ++++
 xmloff/source/text/txtparae.cxx                     |   10 +
 17 files changed, 378 insertions(+), 49 deletions(-)

New commits:
commit a62d4111fd8f740612f4fd4a7ffabb72776c929a
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Thu Nov 30 10:28:33 2017 +0100

    Unit test for tdf#113696
    
    Change-Id: I566cd5d38cf86547b664f0ae9a1c2f8c37edc0ca
    Reviewed-on: https://gerrit.libreoffice.org/45560
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>

diff --git a/sw/CppunitTest_sw_fodfexport.mk b/sw/CppunitTest_sw_fodfexport.mk
new file mode 100644
index 000000000000..4703b85435f7
--- /dev/null
+++ b/sw/CppunitTest_sw_fodfexport.mk
@@ -0,0 +1,57 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+#*************************************************************************
+
+$(eval $(call gb_CppunitTest_CppunitTest,sw_fodfexport))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sw_fodfexport, \
+	sw/qa/extras/fodfexport/fodfexport \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,sw_fodfexport, \
+	comphelper \
+	cppu \
+	cppuhelper \
+	sal \
+	sfx \
+	sw \
+	test \
+	tl \
+	unotest \
+	utl \
+	vcl \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,sw_fodfexport,\
+	boost_headers \
+	libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_set_include,sw_fodfexport,\
+	-I$(SRCDIR)/sw/inc \
+	-I$(SRCDIR)/sw/source/core/inc \
+	-I$(SRCDIR)/sw/qa/extras/inc \
+	$$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,sw_fodfexport))
+
+$(eval $(call gb_CppunitTest_use_ure,sw_fodfexport))
+$(eval $(call gb_CppunitTest_use_vcl,sw_fodfexport))
+
+$(eval $(call gb_CppunitTest_use_rdb,sw_fodfexport,services))
+
+$(eval $(call gb_CppunitTest_use_custom_headers,sw_fodfexport,\
+	officecfg/registry \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,sw_fodfexport))
+
+# vim: set noet sw=4 ts=4:
diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk
index f4371dfa20cf..a9de6cd82943 100644
--- a/sw/Module_sw.mk
+++ b/sw/Module_sw.mk
@@ -49,6 +49,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\
 	$(if $(and $(filter $(COM),MSC),$(MERGELIBS)),, \
 		CppunitTest_sw_uwriter) \
     CppunitTest_sw_docbookexport \
+    CppunitTest_sw_fodfexport \
     CppunitTest_sw_htmlexport \
     CppunitTest_sw_htmlimport \
     CppunitTest_sw_macros_test \
diff --git a/sw/qa/extras/fodfexport/data/tdf113696.odt b/sw/qa/extras/fodfexport/data/tdf113696.odt
new file mode 100644
index 000000000000..03e0612a3d14
Binary files /dev/null and b/sw/qa/extras/fodfexport/data/tdf113696.odt differ
diff --git a/sw/qa/extras/fodfexport/fodfexport.cxx b/sw/qa/extras/fodfexport/fodfexport.cxx
new file mode 100644
index 000000000000..6cd00b49ba47
--- /dev/null
+++ b/sw/qa/extras/fodfexport/fodfexport.cxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <swmodeltestbase.hxx>
+
+class Test : public SwModelTestBase
+{
+public:
+    Test()
+        : SwModelTestBase("/sw/qa/extras/fodfexport/data/", "OpenDocument Text Flat XML")
+    {
+    }
+
+    /**
+     * Blacklist handling
+     */
+    bool mustTestImportOf(const char* filename) const override
+    {
+        // Only test import of .fodt document
+        return OString(filename).endsWith(".odt") || OString(filename).endsWith(".fodt");
+    }
+};
+
+DECLARE_FODFEXPORT_TEST(testTdf113696, "tdf113696.odt")
+{
+    // Test that an image which is written in svm format (image/x-vclgraphic)
+    // is accompanied by a png fallback graphic.
+    if (xmlDocPtr pXmlDoc = parseExportedFile())
+    {
+        assertXPath(pXmlDoc, "/office:document/office:body/office:text/text:p/draw:frame/"
+                             "draw:image[@loext:mime-type='image/x-vclgraphic']");
+        assertXPath(pXmlDoc, "/office:document/office:body/office:text/text:p/draw:frame/"
+                             "draw:image[@loext:mime-type='image/png']");
+    }
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/inc/swmodeltestbase.hxx b/sw/qa/extras/inc/swmodeltestbase.hxx
index fca647b6b6d0..69578263d846 100644
--- a/sw/qa/extras/inc/swmodeltestbase.hxx
+++ b/sw/qa/extras/inc/swmodeltestbase.hxx
@@ -91,6 +91,7 @@ using namespace css;
 #define DECLARE_RTFEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test)
 #define DECLARE_ODFIMPORT_TEST(TestName, filename) DECLARE_SW_IMPORT_TEST(TestName, filename, Test)
 #define DECLARE_ODFEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test)
+#define DECLARE_FODFEXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test)
 #define DECLARE_WW8EXPORT_TEST(TestName, filename) DECLARE_SW_ROUNDTRIP_TEST(TestName, filename, Test)
 
 #define DECLARE_SW_IMPORT_TEST(TestName, filename, BaseClass) \
@@ -698,6 +699,16 @@ protected:
         return parseExportInternal( maTempFile.GetURL(), rStreamName );
     }
 
+    /**
+     * Returns an xml stream of a an exported file.
+     * To be used when the exporter doesn't create zip archives, but single files
+     * (like Flat ODF Export)
+     */
+    xmlDocPtr parseExportedFile()
+    {
+        return parseXmlStream(maTempFile.GetStream(StreamMode::READ));
+    }
+
     xmlDocPtr parseExportInternal( const OUString& url, const OUString& rStreamName )
     {
         // Read the XML stream we're interested in.
commit f717460c16cb558e8049f906771fe223b6eb69f9
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Fri Dec 1 09:35:41 2017 +0100

    tdf#113696 XHTML Export: Prefer fallback graphic
    
    Which is usually png and browsers can read that,
    but they can't read our internal metafile format (svm)
    
    Change-Id: Idfd82da630ead69f508b74285081e32315030825
    Reviewed-on: https://gerrit.libreoffice.org/45590
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>

diff --git a/filter/source/xslt/odf2xhtml/export/xhtml/body.xsl b/filter/source/xslt/odf2xhtml/export/xhtml/body.xsl
index 8cce4595d3ea..f594ebcd29e5 100644
--- a/filter/source/xslt/odf2xhtml/export/xhtml/body.xsl
+++ b/filter/source/xslt/odf2xhtml/export/xhtml/body.xsl
@@ -1487,27 +1487,32 @@
 	<xsl:template match="draw:image | draw:object-ole">
 		<xsl:param name="globalData"/>
 
-		<xsl:choose>
-			<xsl:when test="ancestor::text:p or parent::text:span or parent::text:h or parent::draw:a or parent::text:a or text:ruby-base">
-				<!-- XHTML does not allow the mapped elements to contain paragraphs -->
-				<xsl:call-template name="create-image-element">
-					<xsl:with-param name="globalData" select="$globalData"/>
-				</xsl:call-template>
-			</xsl:when>
-			<xsl:otherwise>
-				<!-- images are embedded in a paragraph, but are in CSS not able to express a horizontal alignment for themself.
-					A 'div' element taking over the image style would solve that problem, but is invalid as child of a paragraph -->
-				<xsl:element name="p">
-					<xsl:apply-templates select="@draw:style-name">
-						<xsl:with-param name="globalData" select="$globalData"/>
-					</xsl:apply-templates>
-
-					<xsl:call-template name="create-image-element">
-						<xsl:with-param name="globalData" select="$globalData"/>
-					</xsl:call-template>
-				</xsl:element>
-			</xsl:otherwise>
-		</xsl:choose>
+        <!-- If there is a replacement graphic, we take it.
+             It is a png which browsers are more likely able to render than the original graphic
+             which might have arbitrary formats. -->
+        <xsl:if test="not(following-sibling::draw:image)">
+            <xsl:choose>
+                <xsl:when test="ancestor::text:p or parent::text:span or parent::text:h or parent::draw:a or parent::text:a or text:ruby-base">
+                    <!-- XHTML does not allow the mapped elements to contain paragraphs -->
+                    <xsl:call-template name="create-image-element">
+                        <xsl:with-param name="globalData" select="$globalData"/>
+                    </xsl:call-template>
+                </xsl:when>
+                <xsl:otherwise>
+                    <!-- images are embedded in a paragraph, but are in CSS not able to express a horizontal alignment for themself.
+                        A 'div' element taking over the image style would solve that problem, but is invalid as child of a paragraph -->
+                    <xsl:element name="p">
+                        <xsl:apply-templates select="@draw:style-name">
+                            <xsl:with-param name="globalData" select="$globalData"/>
+                        </xsl:apply-templates>
+
+                        <xsl:call-template name="create-image-element">
+                            <xsl:with-param name="globalData" select="$globalData"/>
+                        </xsl:call-template>
+                    </xsl:element>
+                </xsl:otherwise>
+            </xsl:choose>
+        </xsl:if>
 	</xsl:template>
 
 	<xsl:template name="create-image-element">
commit bdf1f65efad90a727b51ab3cb69d0af69d7eb1cb
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Thu Nov 30 14:36:14 2017 +0100

    tdf#113696 Add mimetype also to fallback graphic
    
    Change-Id: I6eb7bb66aa688b5668d0eacd2ec7131bec2b6955
    Reviewed-on: https://gerrit.libreoffice.org/45585
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>

diff --git a/xmloff/source/draw/shapeexport.cxx b/xmloff/source/draw/shapeexport.cxx
index 0f961a95aa3e..1fe976433eae 100644
--- a/xmloff/source/draw/shapeexport.cxx
+++ b/xmloff/source/draw/shapeexport.cxx
@@ -2387,6 +2387,13 @@ void XMLShapeExport::ImpExportGraphicObjectShape(
                         mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
                     }
 
+                    uno::Reference<io::XInputStream> xInputStream(
+                        mrExport.GetEmbeddedGraphicObjectStream(aReplacementUrl));
+                    OUString aMimeType(
+                        comphelper::GraphicMimeTypeHelper::GetMimeTypeForImageStream(xInputStream));
+                    if (!aMimeType.isEmpty())
+                        GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, "mime-type", aMimeType);
+
                      SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_IMAGE, true, true);
 
                     // optional office:binary-data
commit 7d12302c671dd86a247f8b669fd31fcbe8a641bd
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Thu Nov 30 12:45:26 2017 +0100

    tdf#113696 Write replacement graphic also to flat odf
    
    Not only to zipped ODF
    
    Change-Id: Ic86656aea31c9fc20862628cdd31698b9904e999
    Reviewed-on: https://gerrit.libreoffice.org/45568
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>

diff --git a/xmloff/source/draw/shapeexport.cxx b/xmloff/source/draw/shapeexport.cxx
index 2a010f9cfd15..0f961a95aa3e 100644
--- a/xmloff/source/draw/shapeexport.cxx
+++ b/xmloff/source/draw/shapeexport.cxx
@@ -2385,13 +2385,12 @@ void XMLShapeExport::ImpExportGraphicObjectShape(
                         mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
                         mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
                         mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
+                    }
 
-                        // xlink:href for replacement, only written for Svg content
-                        SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_IMAGE, true, true);
+                     SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_IMAGE, true, true);
 
-                        // optional office:binary-data
-                        mrExport.AddEmbeddedGraphicObjectAsBase64(aReplacementUrl);
-                    }
+                    // optional office:binary-data
+                    mrExport.AddEmbeddedGraphicObjectAsBase64(aReplacementUrl);
                 }
             }
         }
commit b12d18575b2a92bf3ed707a14378bb65f56ae423
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Thu Nov 30 12:42:10 2017 +0100

    Related tdf#72966 Provide replacement graphic also for metafiles
    
    With this, SVM files are still written to ODF, but accompanied
    by a replacement png graphic.
    
    Change-Id: I2c949f100dd5197a10c741baa42ea740f3a1415a
    Reviewed-on: https://gerrit.libreoffice.org/45567
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Armin Le Grand <Armin.Le.Grand at cib.de>
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/svx/source/svdraw/svdograf.cxx b/svx/source/svdraw/svdograf.cxx
index ad51e4a6af38..656b3f8c61cb 100644
--- a/svx/source/svdraw/svdograf.cxx
+++ b/svx/source/svdraw/svdograf.cxx
@@ -446,6 +446,11 @@ const GraphicObject* SdrGrafObj::GetReplacementGraphicObject() const
         {
             const_cast< SdrGrafObj* >(this)->mpReplacementGraphic = new GraphicObject(rSvgDataPtr->getReplacement());
         }
+        else if (pGraphic->GetGraphic().GetType() == GRAPHIC_GDIMETAFILE)
+        {
+            // Replacement graphic for PDF and metafiles is just the bitmap.
+            const_cast<SdrGrafObj*>(this)->mpReplacementGraphic = new GraphicObject(pGraphic->GetGraphic().GetBitmapEx());
+        }
     }
 
     return mpReplacementGraphic;
commit ee28a7908f42775d135bd87d83c27671b27c110e
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Wed Nov 29 21:12:32 2017 +0100

    tdf#113696 Add mimetype to image element
    
    Otherwise browsers don't recognize base64 encoded svg files.
    
    Change-Id: I54d0b87c52a1ca9da1d820751ae32159b88ed28f

diff --git a/comphelper/Library_comphelper.mk b/comphelper/Library_comphelper.mk
index 4d4e7345298d..c267711126da 100644
--- a/comphelper/Library_comphelper.mk
+++ b/comphelper/Library_comphelper.mk
@@ -91,6 +91,7 @@ $(eval $(call gb_Library_add_exception_objects,comphelper,\
     comphelper/source/misc/evtmethodhelper \
     comphelper/source/misc/fileurl \
     comphelper/source/misc/getexpandeduri \
+    comphelper/source/misc/graphicmimetype \
     comphelper/source/misc/instancelocker \
     comphelper/source/misc/interaction \
     comphelper/source/misc/listenernotification \
diff --git a/comphelper/source/misc/graphicmimetype.cxx b/comphelper/source/misc/graphicmimetype.cxx
new file mode 100644
index 000000000000..bf88312304b1
--- /dev/null
+++ b/comphelper/source/misc/graphicmimetype.cxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <comphelper/graphicmimetype.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/graphic/GraphicProvider.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <comphelper/processfactory.hxx>
+
+using namespace css;
+using namespace css::beans;
+using namespace css::graphic;
+using namespace css::io;
+using namespace css::uno;
+
+namespace comphelper
+{
+OUString GraphicMimeTypeHelper::GetMimeTypeForExtension(const OString& rExt)
+{
+    struct XMLGraphicMimeTypeMapper
+    {
+        const char* pExt;
+        const char* pMimeType;
+    };
+
+    static const XMLGraphicMimeTypeMapper aMapper[]
+        = { { "gif", "image/gif" },   { "png", "image/png" },     { "jpg", "image/jpeg" },
+            { "tif", "image/tiff" },  { "svg", "image/svg+xml" }, { "pdf", "application/pdf" },
+            { "wmf", "image/x-wmf" }, { "eps", "image/x-eps" },   { "bmp", "image/bmp" },
+            { "pct", "image/x-pict" } };
+
+    OUString aMimeType;
+
+    long const nCount = SAL_N_ELEMENTS(aMapper);
+    for (long i = 0; (i < nCount) && aMimeType.isEmpty(); ++i)
+    {
+        if (rExt == aMapper[i].pExt)
+            aMimeType = OUString(aMapper[i].pMimeType, strlen(aMapper[i].pMimeType),
+                                 RTL_TEXTENCODING_ASCII_US);
+    }
+
+    return aMimeType;
+}
+
+OUString GraphicMimeTypeHelper::GetMimeTypeForXGraphic(Reference<XGraphic> xGraphic)
+{
+    OUString aSourceMimeType;
+    Reference<XPropertySet> const xGraphicPropertySet(xGraphic, UNO_QUERY);
+    if (xGraphicPropertySet.is() && // it's null if it's an external link
+        (xGraphicPropertySet->getPropertyValue("MimeType") >>= aSourceMimeType))
+    {
+        return aSourceMimeType;
+    }
+    return OUString("");
+}
+
+OUString GraphicMimeTypeHelper::GetMimeTypeForImageUrl(const OUString& rImageUrl)
+{
+    // Create the graphic to retrieve the mimetype from it
+    Reference<XGraphicProvider> xProvider
+        = css::graphic::GraphicProvider::create(comphelper::getProcessComponentContext());
+    Sequence<PropertyValue> aMediaProperties(1);
+    aMediaProperties[0].Name = "URL";
+    aMediaProperties[0].Value <<= rImageUrl;
+    Reference<XGraphic> xGraphic(xProvider->queryGraphic(aMediaProperties));
+
+    return GetMimeTypeForXGraphic(xGraphic);
+}
+
+OUString GraphicMimeTypeHelper::GetMimeTypeForImageStream(Reference<XInputStream> xInputStream)
+{
+    // Create the graphic to retrieve the mimetype from it
+    Reference<XGraphicProvider> xProvider
+        = css::graphic::GraphicProvider::create(comphelper::getProcessComponentContext());
+    Sequence<PropertyValue> aMediaProperties(1);
+    aMediaProperties[0].Name = "InputStream";
+    aMediaProperties[0].Value <<= xInputStream;
+    Reference<XGraphic> xGraphic(xProvider->queryGraphic(aMediaProperties));
+
+    return GetMimeTypeForXGraphic(xGraphic);
+}
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/comphelper/graphicmimetype.hxx b/include/comphelper/graphicmimetype.hxx
new file mode 100644
index 000000000000..970342f2e5f5
--- /dev/null
+++ b/include/comphelper/graphicmimetype.hxx
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_COMPHELPER_GMH_HXX
+#define INCLUDED_COMPHELPER_GMH_HXX
+
+#include <comphelper/comphelperdllapi.h>
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+namespace comphelper
+{
+class COMPHELPER_DLLPUBLIC GraphicMimeTypeHelper
+{
+public:
+    static OUString GetMimeTypeForExtension(const OString& rExt);
+    static OUString GetMimeTypeForXGraphic(css::uno::Reference<css::graphic::XGraphic> xGraphic);
+    static OUString GetMimeTypeForImageUrl(const OUString& rImageUrl);
+    static OUString
+    GetMimeTypeForImageStream(css::uno::Reference<css::io::XInputStream> xInputStream);
+};
+}
+
+#endif // INCLUDED_COMPHELPER_GMH_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/xmloff/xmlexp.hxx b/include/xmloff/xmlexp.hxx
index 41e8ddd8d417..f95e71d86a38 100644
--- a/include/xmloff/xmlexp.hxx
+++ b/include/xmloff/xmlexp.hxx
@@ -468,6 +468,8 @@ public:
 
     OUString AddEmbeddedGraphicObject(
                             const OUString& rGraphicObjectURL );
+    css::uno::Reference<css::io::XInputStream> GetEmbeddedGraphicObjectStream(
+        const OUString& rGraphicObjectURL);
     bool AddEmbeddedGraphicObjectAsBase64(
                             const OUString& rGraphicObjectURL );
 
diff --git a/xmloff/source/core/xmlexp.cxx b/xmloff/source/core/xmlexp.cxx
index 8ed21181dff9..484216087e0d 100644
--- a/xmloff/source/core/xmlexp.cxx
+++ b/xmloff/source/core/xmlexp.cxx
@@ -1901,6 +1901,24 @@ OUString SvXMLExport::AddEmbeddedGraphicObject( const OUString& rGraphicObjectUR
     return sRet;
 }
 
+Reference< XInputStream > SvXMLExport::GetEmbeddedGraphicObjectStream( const OUString& rGraphicObjectURL )
+{
+    if( (getExportFlags() & SvXMLExportFlags::EMBEDDED) &&
+        rGraphicObjectURL.startsWith( msGraphicObjectProtocol ) &&
+        mxGraphicResolver.is() )
+    {
+        Reference< XBinaryStreamResolver > xStmResolver( mxGraphicResolver, UNO_QUERY );
+
+        if( xStmResolver.is() )
+        {
+            Reference< XInputStream > xIn( xStmResolver->getInputStream( rGraphicObjectURL ) );
+            return xIn;
+        }
+    }
+
+    return nullptr;
+}
+
 bool SvXMLExport::AddEmbeddedGraphicObjectAsBase64( const OUString& rGraphicObjectURL )
 {
     bool bRet = false;
diff --git a/xmloff/source/draw/shapeexport.cxx b/xmloff/source/draw/shapeexport.cxx
index 04fb1772064f..2a010f9cfd15 100644
--- a/xmloff/source/draw/shapeexport.cxx
+++ b/xmloff/source/draw/shapeexport.cxx
@@ -82,6 +82,7 @@
 #include <com/sun/star/document/XStorageBasedDocument.hpp>
 
 #include <comphelper/classids.hxx>
+#include <comphelper/graphicmimetype.hxx>
 #include <comphelper/processfactory.hxx>
 #include <comphelper/storagehelper.hxx>
 
@@ -2346,6 +2347,15 @@ void XMLShapeExport::ImpExportGraphicObjectShape(
             }
 
             {
+                // We can't guess the mimetype from sImageURL because the image type might be changed
+                // while creating the stream (by SvXMLGraphicInputStream). So we first need to create
+                // the stream, get the mime type and then write the stream.
+                uno::Reference<io::XInputStream> xInputStream(
+                    mrExport.GetEmbeddedGraphicObjectStream(sImageURL));
+                OUString aMimeType(
+                    comphelper::GraphicMimeTypeHelper::GetMimeTypeForImageStream(xInputStream));
+                GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, "mime-type", aMimeType);
+
                 SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DRAW, XML_IMAGE, true, true);
 
                 if( !sImageURL.isEmpty() )
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index 12355f2a254a..462f655d642f 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -113,7 +113,7 @@
 #include <vector>
 #include <algorithm>
 #include <iterator>
-#include <comphelper/processfactory.hxx>
+#include <comphelper/graphicmimetype.hxx>
 
 using namespace ::std;
 using namespace ::com::sun::star;
@@ -3046,22 +3046,6 @@ void XMLTextParagraphExport::exportContour(
                               true, true );
 }
 
-static OUString getMimeType(const OUString& sImageUrl)
-{
-    // Create the graphic to retrieve the mimetype from it
-    Reference< XGraphicProvider > xProvider = css::graphic::GraphicProvider::create(comphelper::getProcessComponentContext());
-    Sequence< PropertyValue > aMediaProperties( 1 );
-    aMediaProperties[0].Name = "URL";
-    aMediaProperties[0].Value <<= sImageUrl;
-    Reference< XGraphic > xGraphic( xProvider->queryGraphic( aMediaProperties ) );
-
-    OUString aSourceMimeType;
-    Reference< XPropertySet > xGraphicPropertySet( xGraphic, UNO_QUERY_THROW );
-    if ( xGraphicPropertySet->getPropertyValue( "MimeType" ) >>= aSourceMimeType )
-        return aSourceMimeType;
-    return OUString("");
-}
-
 void XMLTextParagraphExport::_exportTextGraphic(
         const Reference < XPropertySet > & rPropSet,
         const Reference < XPropertySetInfo > & rPropSetInfo )
@@ -3124,7 +3108,7 @@ void XMLTextParagraphExport::_exportTextGraphic(
                                   sGrfFilter );
 
     // Add mimetype to make it easier for readers to get the base64 image type right, tdf#109202
-    OUString aSourceMimeType = getMimeType(sOrigURL);
+    OUString aSourceMimeType = comphelper::GraphicMimeTypeHelper::GetMimeTypeForImageUrl(sOrigURL);
     if ( !aSourceMimeType.isEmpty() )
         GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, "mime-type", aSourceMimeType);
 
commit a3523631dbc46a80b77696a1ed53530e70b76374
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Mon Jul 24 15:46:06 2017 +0200

    tdf#109202 Add mimetype to image element
    
    Browsers don't recognize base64 svg if the mimetype is missing.
    So we add the image mimetype to our flat odf export, which the xhtml
    export uses and transforms it into an xhtml document.
    
    Change-Id: I21aafdb97b4104e14e2d40abda73a526bb37041a
    Reviewed-on: https://gerrit.libreoffice.org/40371
    Reviewed-by: Michael Stahl <mstahl at redhat.com>
    Tested-by: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>

diff --git a/filter/source/xslt/odf2xhtml/export/common/body.xsl b/filter/source/xslt/odf2xhtml/export/common/body.xsl
index 3196facc8092..05b78a5ed43e 100644
--- a/filter/source/xslt/odf2xhtml/export/common/body.xsl
+++ b/filter/source/xslt/odf2xhtml/export/common/body.xsl
@@ -1,21 +1,21 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!--
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- -->
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ -->
 <!--
 	For further documentation and updates visit http://xml.openoffice.org/odf2xhtml
 -->
@@ -317,6 +317,7 @@
 
 	<xsl:template name="create-href">
 		<xsl:param name="href"/>
+		<xsl:param name="mimetype"/>
 
 		<xsl:choose>
 			<!-- internal OOo URL used in content tables -->
@@ -332,7 +333,14 @@
 				<xsl:value-of select="concat('a_', translate(normalize-space($title), '.,;: %()[]/\+', '_____________'))"/>
 			</xsl:when>
 			<xsl:when test="self::draw:image[office:binary-data]">
-				<xsl:text>data:image/*;base64,</xsl:text><xsl:value-of select="office:binary-data"/>
+                <xsl:choose>
+                    <xsl:when test="$mimetype">
+                        <xsl:text>data:</xsl:text><xsl:value-of select="$mimetype"/><xsl:text>;base64,</xsl:text><xsl:value-of select="office:binary-data"/>
+                    </xsl:when>
+                    <xsl:otherwise>
+                        <xsl:text>data:image/*;base64,</xsl:text><xsl:value-of select="office:binary-data"/>
+                    </xsl:otherwise>
+                </xsl:choose>
 			</xsl:when>
 			<xsl:otherwise>
 				<xsl:choose>
@@ -361,10 +369,10 @@
 								<xsl:value-of select="concat($href, $optionalURLSuffix)"/>
 							</xsl:when>
 							 <!-- for relative URLs -->
-							 <xsl:when test="starts-with($href, '#')">
-							   <!-- intra document ref -->
-							   <xsl:value-of select="$href"/>
-							 </xsl:when>
+							 <xsl:when test="starts-with($href, '#')">
+							   <!-- intra document ref -->
+							   <xsl:value-of select="$href"/>
+							 </xsl:when>
 							<xsl:otherwise>
 								<xsl:value-of select="concat($sourceBaseURL, $href, $optionalURLSuffix)"/>
 							</xsl:otherwise>
diff --git a/filter/source/xslt/odf2xhtml/export/xhtml/body.xsl b/filter/source/xslt/odf2xhtml/export/xhtml/body.xsl
index baee18241128..8cce4595d3ea 100644
--- a/filter/source/xslt/odf2xhtml/export/xhtml/body.xsl
+++ b/filter/source/xslt/odf2xhtml/export/xhtml/body.xsl
@@ -19,7 +19,7 @@
 <!--
 	For further documentation and updates visit http://xml.openoffice.org/odf2xhtml
 -->
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:s
 tyle="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xt="http://www.jclark.com/xt" xmlns:common="http://exslt.org/common" xmlns:xalan="http://xml.apache.org/xalan" exclude-result-prefixes="chart config dc dom dr3d draw fo form math meta number office ooo oooc ooow script style svg table text xforms xlink xsd xsi xt common xalan" xmlns="http://www.w3.org/1999/xhtml">
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:s
 tyle="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xt="http://www.jclark.com/xt" xmlns:common="http://exslt.org/common" xmlns:xalan="http://xml.apache.org/xalan" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" exclude-result-prefixes="chart config dc dom dr3d draw fo form math meta number office ooo oooc ooow script style svg table text xforms xlink xsd xsi xt common xalan" xmlns="http://www.w3.org/1999/xhtml">
 
 
 	<!--+++++ INCLUDED XSL MODULES +++++-->
@@ -1551,6 +1551,7 @@
 			<xsl:attribute name="src">
 				<xsl:call-template name="create-href">
 					<xsl:with-param name="href" select="@xlink:href"/>
+					<xsl:with-param name="mimetype" select="@loext:mime-type"/>
 				</xsl:call-template>
 			</xsl:attribute>
 
diff --git a/sw/qa/extras/odfexport/data/image-mimetype.odt b/sw/qa/extras/odfexport/data/image-mimetype.odt
new file mode 100644
index 000000000000..4c4924a1b254
Binary files /dev/null and b/sw/qa/extras/odfexport/data/image-mimetype.odt differ
diff --git a/sw/qa/extras/odfexport/odfexport.cxx b/sw/qa/extras/odfexport/odfexport.cxx
index 8c827404769f..83848a81a124 100644
--- a/sw/qa/extras/odfexport/odfexport.cxx
+++ b/sw/qa/extras/odfexport/odfexport.cxx
@@ -846,6 +846,16 @@ DECLARE_ODFEXPORT_TEST(testCellUserDefineAttr, "userdefattr-tablecell.odt")
     getUserDefineAttribute(uno::makeAny(xCellC1), "proName", "v3");
 }
 
+DECLARE_ODFEXPORT_TEST(testImageMimetype, "image-mimetype.odt")
+{
+    // Test that the loext:mimetype attribute is written for exported images, tdf#109202
+    if (xmlDocPtr pXmlDoc = parseExport("content.xml"))
+    {
+        // Original image (svg)
+        assertXPath(pXmlDoc, "/office:document-content/office:body/office:text/text:p/draw:frame/draw:image[@loext:mime-type='image/svg+xml']");
+    }
+}
+
 #endif
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index a809bf0b758c..12355f2a254a 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -28,6 +28,9 @@
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/beans/XMultiPropertySet.hpp>
 #include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/graphic/GraphicProvider.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
 #include <com/sun/star/text/XTextDocument.hpp>
 #include <com/sun/star/text/XTextSectionsSupplier.hpp>
 #include <com/sun/star/text/XTextTablesSupplier.hpp>
@@ -110,6 +113,7 @@
 #include <vector>
 #include <algorithm>
 #include <iterator>
+#include <comphelper/processfactory.hxx>
 
 using namespace ::std;
 using namespace ::com::sun::star;
@@ -123,6 +127,7 @@ using namespace ::com::sun::star::util;
 using namespace ::com::sun::star::drawing;
 using namespace ::com::sun::star::document;
 using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::graphic;
 using namespace ::xmloff;
 using namespace ::xmloff::token;
 
@@ -3041,6 +3046,22 @@ void XMLTextParagraphExport::exportContour(
                               true, true );
 }
 
+static OUString getMimeType(const OUString& sImageUrl)
+{
+    // Create the graphic to retrieve the mimetype from it
+    Reference< XGraphicProvider > xProvider = css::graphic::GraphicProvider::create(comphelper::getProcessComponentContext());
+    Sequence< PropertyValue > aMediaProperties( 1 );
+    aMediaProperties[0].Name = "URL";
+    aMediaProperties[0].Value <<= sImageUrl;
+    Reference< XGraphic > xGraphic( xProvider->queryGraphic( aMediaProperties ) );
+
+    OUString aSourceMimeType;
+    Reference< XPropertySet > xGraphicPropertySet( xGraphic, UNO_QUERY_THROW );
+    if ( xGraphicPropertySet->getPropertyValue( "MimeType" ) >>= aSourceMimeType )
+        return aSourceMimeType;
+    return OUString("");
+}
+
 void XMLTextParagraphExport::_exportTextGraphic(
         const Reference < XPropertySet > & rPropSet,
         const Reference < XPropertySetInfo > & rPropSetInfo )
@@ -3102,6 +3123,11 @@ void XMLTextParagraphExport::_exportTextGraphic(
         GetExport().AddAttribute( XML_NAMESPACE_DRAW, XML_FILTER_NAME,
                                   sGrfFilter );
 
+    // Add mimetype to make it easier for readers to get the base64 image type right, tdf#109202
+    OUString aSourceMimeType = getMimeType(sOrigURL);
+    if ( !aSourceMimeType.isEmpty() )
+        GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, "mime-type", aSourceMimeType);
+
     {
         SvXMLElementExport aElement( GetExport(), XML_NAMESPACE_DRAW,
                                   XML_IMAGE, false, true );


More information about the Libreoffice-commits mailing list