summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/oox/helper/graphichelper.hxx6
-rw-r--r--include/oox/shape/ShapeFilterBase.hxx7
-rw-r--r--offapi/UnoApi_offapi.mk2
-rw-r--r--offapi/com/sun/star/graphic/GraphicMapper.idl30
-rw-r--r--offapi/com/sun/star/graphic/XGraphicMapper.idl35
-rw-r--r--offapi/com/sun/star/xml/sax/XFastShapeContextHandler.idl11
-rw-r--r--oox/source/helper/graphichelper.cxx52
-rw-r--r--oox/source/shape/ShapeContextHandler.cxx6
-rw-r--r--oox/source/shape/ShapeContextHandler.hxx2
-rw-r--r--oox/source/shape/ShapeFilterBase.cxx5
-rw-r--r--sw/qa/extras/globalfilter/data/multiple_identical_graphics.odtbin0 -> 13826 bytes
-rw-r--r--sw/qa/extras/globalfilter/globalfilter.cxx83
-rw-r--r--vcl/Library_vcl.mk1
-rw-r--r--vcl/source/graphic/UnoGraphicMapper.cxx87
-rw-r--r--vcl/vcl.common.component4
-rw-r--r--writerfilter/source/ooxml/OOXMLDocumentImpl.cxx2
-rw-r--r--writerfilter/source/ooxml/OOXMLDocumentImpl.hxx9
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.cxx5
18 files changed, 331 insertions, 16 deletions
diff --git a/include/oox/helper/graphichelper.hxx b/include/oox/helper/graphichelper.hxx
index 301bc37e27af..9a99647589b2 100644
--- a/include/oox/helper/graphichelper.hxx
+++ b/include/oox/helper/graphichelper.hxx
@@ -31,6 +31,7 @@
#include <rtl/ustring.hxx>
#include <sal/types.h>
#include <com/sun/star/graphic/XGraphicProvider2.hpp>
+#include <com/sun/star/graphic/XGraphicMapper.hpp>
struct WmfExternal;
@@ -133,9 +134,10 @@ public:
@return The original Graphic size in 100thmm */
css::awt::Size getOriginalSize( const css::uno::Reference< css::graphic::XGraphic >& rxGraphic ) const;
+ void setGraphicMapper(css::uno::Reference<css::graphic::XGraphicMapper> const & rxGraphicMapper);
+ void initializeGraphicMapperIfNeeded() const;
private:
- typedef ::std::map< OUString, css::uno::Reference< css::graphic::XGraphic > > EmbeddedGraphicMap;
css::uno::Reference< css::uno::XComponentContext > mxContext;
css::uno::Reference< css::graphic::XGraphicProvider2 > mxGraphicProvider;
@@ -143,9 +145,9 @@ private:
css::awt::DeviceInfo maDeviceInfo; ///< Current output device info.
::std::map< sal_Int32, ::Color > maSystemPalette; ///< Maps system colors (XML tokens) to RGB color values.
StorageRef mxStorage; ///< Storage containing embedded graphics.
- mutable EmbeddedGraphicMap maEmbeddedGraphics; ///< Maps all embedded graphics by their storage path.
double mfPixelPerHmmX; ///< Number of screen pixels per 1/100 mm in X direction.
double mfPixelPerHmmY; ///< Number of screen pixels per 1/100 mm in Y direction.
+ css::uno::Reference<css::graphic::XGraphicMapper> mxGraphicMapper;
};
diff --git a/include/oox/shape/ShapeFilterBase.hxx b/include/oox/shape/ShapeFilterBase.hxx
index fc4c8f7836f7..bfd5cea6d16e 100644
--- a/include/oox/shape/ShapeFilterBase.hxx
+++ b/include/oox/shape/ShapeFilterBase.hxx
@@ -25,6 +25,7 @@
#include <oox/vml/vmldrawing.hxx>
#include <oox/core/xmlfilterbase.hxx>
#include <oox/drawingml/drawingmltypes.hxx>
+#include <com/sun/star/graphic/XGraphicMapper.hpp>
namespace oox::drawingml::table {
@@ -66,6 +67,11 @@ public:
void importTheme();
+ void setGraphicMapper(css::uno::Reference<css::graphic::XGraphicMapper> const & rxGraphicMapper)
+ {
+ mxGraphicMapper = rxGraphicMapper;
+ }
+
private:
virtual ::oox::ole::VbaProject* implCreateVbaProject() const override;
virtual OUString SAL_CALL getImplementationName() override;
@@ -73,6 +79,7 @@ private:
std::shared_ptr< ::oox::drawingml::chart::ChartConverter > mxChartConv;
::oox::drawingml::ThemePtr mpTheme;
+ css::uno::Reference<css::graphic::XGraphicMapper> mxGraphicMapper;
};
} // namespace oox::shape
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index 23138250b9d4..0eaefbcca348 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -210,6 +210,7 @@ $(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,com/sun/star/frame,\
$(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,com/sun/star/graphic,\
GraphicObject \
GraphicProvider \
+ GraphicMapper \
Primitive2DTools \
SvgTools \
EmfTools \
@@ -2719,6 +2720,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/graphic,\
XGraphicRasterizer \
XGraphicRenderer \
XGraphicTransformer \
+ XGraphicMapper \
XPrimitive2D \
XPrimitive2DRenderer \
XPrimitive3D \
diff --git a/offapi/com/sun/star/graphic/GraphicMapper.idl b/offapi/com/sun/star/graphic/GraphicMapper.idl
new file mode 100644
index 000000000000..f74abd45ff62
--- /dev/null
+++ b/offapi/com/sun/star/graphic/GraphicMapper.idl
@@ -0,0 +1,30 @@
+/* -*- 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 com_sun_star_graphic_GraphicMapper_idl
+#define com_sun_star_graphic_GraphicMapper_idl
+
+#include <com/sun/star/graphic/XGraphicMapper.idl>
+
+module com { module sun { module star { module graphic
+{
+
+/** implementation of the XGraphicMapper interface
+
+ @see XGraphicMapper
+ @since LibreOffice 7.1
+*/
+service GraphicMapper : XGraphicMapper;
+
+} ; } ; } ; } ;
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/offapi/com/sun/star/graphic/XGraphicMapper.idl b/offapi/com/sun/star/graphic/XGraphicMapper.idl
new file mode 100644
index 000000000000..f1c933b12e38
--- /dev/null
+++ b/offapi/com/sun/star/graphic/XGraphicMapper.idl
@@ -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 com_sun_star_graphic_XGraphicCache_idl
+#define com_sun_star_graphic_XGraphicCache_idl
+
+#include <com/sun/star/graphic/XGraphic.idl>
+
+module com { module sun { module star { module graphic
+{
+
+/** This interface allows mapping of XGraphics for a certain string key
+
+ @since LibreOffice 7.1
+ */
+interface XGraphicMapper
+{
+ /** Find if we have the XGraphic for the certain key */
+ com::sun::star::graphic::XGraphic findGraphic([in] string Id);
+
+ /** Insert a new entry to map an id/key to the XGraphic */
+ void putGraphic([in] string Id, [in] com::sun::star::graphic::XGraphic Graphic);
+};
+
+}; }; }; };
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/offapi/com/sun/star/xml/sax/XFastShapeContextHandler.idl b/offapi/com/sun/star/xml/sax/XFastShapeContextHandler.idl
index 301971a2141d..1475db6479b1 100644
--- a/offapi/com/sun/star/xml/sax/XFastShapeContextHandler.idl
+++ b/offapi/com/sun/star/xml/sax/XFastShapeContextHandler.idl
@@ -1,4 +1,4 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
@@ -25,7 +25,7 @@
#include <com/sun/star/frame/XModel.idl>
#include <com/sun/star/io/XInputStream.idl>
#include <com/sun/star/document/XDocumentProperties.idl>
-
+#include <com/sun/star/graphic/XGraphicMapper.idl>
module com { module sun { module star { module xml { module sax {
@@ -45,6 +45,13 @@ interface XFastShapeContextHandler: com::sun::star::xml::sax::XFastContextHandle
[attribute] com::sun::star::awt::Point Position;
[attribute] com::sun::star::document::XDocumentProperties DocumentProperties;
[attribute] sequence< com::sun::star::beans::PropertyValue > MediaDescriptor;
+
+ /** Graphic mapper to map a key/id string to a XGraphic. This is needed to
+ remember for XGraphics for a path in the document storage
+
+ @since LibreOffice 7.1
+ */
+ void setGraphicMapper([in] com::sun::star::graphic::XGraphicMapper xGraphicMapper);
};
diff --git a/oox/source/helper/graphichelper.cxx b/oox/source/helper/graphichelper.cxx
index 85490fb43a8e..e8a1c94326a7 100644
--- a/oox/source/helper/graphichelper.cxx
+++ b/oox/source/helper/graphichelper.cxx
@@ -27,6 +27,7 @@
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/graphic/GraphicProvider.hpp>
#include <com/sun/star/util/MeasureUnit.hpp>
+#include <com/sun/star/graphic/GraphicMapper.hpp>
#include <osl/diagnose.h>
#include <sal/log.hxx>
#include <comphelper/seqstream.hxx>
@@ -316,16 +317,24 @@ void GraphicHelper::importEmbeddedGraphics(const std::vector<OUString>& rStreamN
std::vector<OUString> aMissingStreamNames;
std::vector< uno::Reference<io::XInputStream> > aMissingStreams;
+ initializeGraphicMapperIfNeeded();
+
+ SAL_WARN_IF(!mxGraphicMapper.is(), "oox", "GraphicHelper::importEmbeddedGraphic - graphic mapper not available");
+
for (const auto& rStreamName : rStreamNames)
{
- if(rStreamName.isEmpty())
+
+ if (rStreamName.isEmpty())
{
SAL_WARN("oox", "GraphicHelper::importEmbeddedGraphics - empty stream name");
continue;
}
- EmbeddedGraphicMap::const_iterator aIt = maEmbeddedGraphics.find(rStreamName);
- if (aIt == maEmbeddedGraphics.end())
+ Reference<XGraphic> xGraphic;
+
+ xGraphic = mxGraphicMapper->findGraphic(rStreamName);
+
+ if (!xGraphic.is())
{
aMissingStreamNames.push_back(rStreamName);
aMissingStreams.push_back(mxStorage->openInputStream(rStreamName));
@@ -334,11 +343,14 @@ void GraphicHelper::importEmbeddedGraphics(const std::vector<OUString>& rStreamN
std::vector< uno::Reference<graphic::XGraphic> > aGraphics = importGraphics(aMissingStreams);
+
assert(aGraphics.size() == aMissingStreamNames.size());
for (size_t i = 0; i < aGraphics.size(); ++i)
{
if (aGraphics[i].is())
- maEmbeddedGraphics[aMissingStreamNames[i]] = aGraphics[i];
+ {
+ mxGraphicMapper->putGraphic(aMissingStreamNames[i], aGraphics[i]);
+ }
}
}
@@ -346,22 +358,26 @@ Reference< XGraphic > GraphicHelper::importEmbeddedGraphic( const OUString& rStr
{
Reference< XGraphic > xGraphic;
OSL_ENSURE( !rStreamName.isEmpty(), "GraphicHelper::importEmbeddedGraphic - empty stream name" );
+
if( !rStreamName.isEmpty() )
{
- EmbeddedGraphicMap::const_iterator aIt = maEmbeddedGraphics.find( rStreamName );
- if( aIt == maEmbeddedGraphics.end() )
+ initializeGraphicMapperIfNeeded();
+
+ SAL_WARN_IF(!mxGraphicMapper.is(), "oox", "GraphicHelper::importEmbeddedGraphic - graphic mapper not available");
+
+ xGraphic = mxGraphicMapper->findGraphic(rStreamName);
+ if (!xGraphic.is())
{
// Lazy-loading doesn't work with TIFF or WMF at the moment.
WmfExternal aHeader;
if ( (rStreamName.endsWith(".tiff") || rStreamName.endsWith(".wmf") ) && !pExtHeader)
pExtHeader = &aHeader;
- xGraphic = importGraphic(mxStorage->openInputStream(rStreamName), pExtHeader);
- if( xGraphic.is() )
- maEmbeddedGraphics[ rStreamName ] = xGraphic;
+ auto xStream = mxStorage->openInputStream(rStreamName);
+ xGraphic = importGraphic(xStream, pExtHeader);
+ if (xGraphic.is())
+ mxGraphicMapper->putGraphic(rStreamName, xGraphic);
}
- else
- xGraphic = aIt->second;
}
return xGraphic;
}
@@ -379,6 +395,20 @@ awt::Size GraphicHelper::getOriginalSize( const Reference< XGraphic >& xGraphic
return aSizeHmm;
}
+void GraphicHelper::setGraphicMapper(css::uno::Reference<css::graphic::XGraphicMapper> const & rGraphicMapper)
+{
+ mxGraphicMapper = rGraphicMapper;
+}
+
+void GraphicHelper::initializeGraphicMapperIfNeeded() const
+{
+ if (!mxGraphicMapper.is())
+ {
+ auto* pNonConstThis = const_cast<GraphicHelper*>(this);
+ pNonConstThis->mxGraphicMapper = graphic::GraphicMapper::create(mxContext);
+ }
+}
+
} // namespace oox
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/shape/ShapeContextHandler.cxx b/oox/source/shape/ShapeContextHandler.cxx
index 0684814bc7cc..c1cc28129eb0 100644
--- a/oox/source/shape/ShapeContextHandler.cxx
+++ b/oox/source/shape/ShapeContextHandler.cxx
@@ -593,6 +593,12 @@ void SAL_CALL ShapeContextHandler::setMediaDescriptor(const uno::Sequence<beans:
maMediaDescriptor = rMediaDescriptor;
}
+void SAL_CALL ShapeContextHandler::setGraphicMapper(css::uno::Reference<css::graphic::XGraphicMapper> const & rxGraphicMapper)
+{
+ auto pShapeFilterBase = static_cast<ShapeFilterBase*>(mxFilterBase.get());
+ pShapeFilterBase->setGraphicMapper(rxGraphicMapper);
+}
+
OUString ShapeContextHandler::getImplementationName()
{
return "com.sun.star.comp.oox.ShapeContextHandler";
diff --git a/oox/source/shape/ShapeContextHandler.hxx b/oox/source/shape/ShapeContextHandler.hxx
index abda9c94a913..a633fac2f028 100644
--- a/oox/source/shape/ShapeContextHandler.hxx
+++ b/oox/source/shape/ShapeContextHandler.hxx
@@ -119,6 +119,8 @@ public:
virtual css::uno::Sequence<css::beans::PropertyValue> SAL_CALL getMediaDescriptor() override;
virtual void SAL_CALL setMediaDescriptor(const css::uno::Sequence<css::beans::PropertyValue>& rMediaDescriptor) override;
+ void SAL_CALL setGraphicMapper(css::uno::Reference<css::graphic::XGraphicMapper> const & rGraphicMapper) override;
+
private:
ShapeContextHandler(ShapeContextHandler const &) = delete;
void operator =(ShapeContextHandler const &) = delete;
diff --git a/oox/source/shape/ShapeFilterBase.cxx b/oox/source/shape/ShapeFilterBase.cxx
index 6505b91a16e5..33c9da8bb0ed 100644
--- a/oox/source/shape/ShapeFilterBase.cxx
+++ b/oox/source/shape/ShapeFilterBase.cxx
@@ -104,7 +104,10 @@ ShapeGraphicHelper::ShapeGraphicHelper( const ShapeFilterBase& rFilter ) :
GraphicHelper* ShapeFilterBase::implCreateGraphicHelper() const
{
- return new ShapeGraphicHelper( *this );
+ GraphicHelper* pGraphicHelper = new ShapeGraphicHelper(*this);
+ if (mxGraphicMapper.is())
+ pGraphicHelper->setGraphicMapper(mxGraphicMapper);
+ return pGraphicHelper;
}
::Color ShapeFilterBase::getSchemeColor( sal_Int32 nToken ) const
diff --git a/sw/qa/extras/globalfilter/data/multiple_identical_graphics.odt b/sw/qa/extras/globalfilter/data/multiple_identical_graphics.odt
new file mode 100644
index 000000000000..20f40798edfe
--- /dev/null
+++ b/sw/qa/extras/globalfilter/data/multiple_identical_graphics.odt
Binary files differ
diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx
index ed20dd790e1b..c0c72c5b7dfa 100644
--- a/sw/qa/extras/globalfilter/globalfilter.cxx
+++ b/sw/qa/extras/globalfilter/globalfilter.cxx
@@ -44,6 +44,7 @@ public:
void testLinkedGraphicRT();
void testImageWithSpecialID();
void testGraphicShape();
+ void testMultipleIdenticalGraphics();
void testCharHighlight();
void testCharHighlightODF();
void testCharHighlightBody();
@@ -68,6 +69,7 @@ public:
CPPUNIT_TEST(testLinkedGraphicRT);
CPPUNIT_TEST(testImageWithSpecialID);
CPPUNIT_TEST(testGraphicShape);
+ CPPUNIT_TEST(testMultipleIdenticalGraphics);
CPPUNIT_TEST(testCharHighlight);
CPPUNIT_TEST(testCharHighlightODF);
CPPUNIT_TEST(testMSCharBackgroundEditing);
@@ -394,6 +396,87 @@ void Test::testGraphicShape()
}
}
+namespace
+{
+
+std::vector<uno::Reference<graphic::XGraphic>>
+ lcl_getGraphics(const uno::Reference<lang::XComponent>& xComponent)
+{
+ std::vector<uno::Reference<graphic::XGraphic>> aGraphics;
+ uno::Reference<drawing::XShape> xShape;
+
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ for (sal_Int32 i = 0; i < xDrawPage->getCount(); ++i)
+ {
+ uno::Reference<beans::XPropertySet> xShapeProperties(xDrawPage->getByIndex(i), uno::UNO_QUERY);
+ uno::Reference<graphic::XGraphic> xGraphic;
+ xShapeProperties->getPropertyValue("Graphic") >>= xGraphic;
+ if (xGraphic.is())
+ {
+ aGraphics.push_back(xGraphic);
+ }
+ }
+
+ return aGraphics;
+}
+
+}
+
+void Test::testMultipleIdenticalGraphics()
+{
+ // We have multiple identical graphics. When we save them we want
+ // them to be saved de-duplicated and the same should still be true
+ // after loading them again. This test check that the de-duplication
+ // works as expected.
+
+ const OUString aFilterNames[] {
+ "writer8",
+ //"Rich Text Format", // doesn't work correctly for now
+ "MS Word 97",
+ "Office Open XML Text",
+ };
+
+ for (OUString const & rFilterName : aFilterNames)
+ {
+ if (mxComponent.is())
+ mxComponent->dispose();
+
+ mxComponent = loadFromDesktop(m_directories.getURLFromSrc("/sw/qa/extras/globalfilter/data/multiple_identical_graphics.odt"), "com.sun.star.text.TextDocument");
+
+ // Export the document and import again for a check
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= rFilterName;
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+ mxComponent->dispose();
+
+ mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument");
+
+ // Check whether graphic exported well
+ const OString sFailedMessage = OStringLiteral("Failed on filter: ") + rFilterName.toUtf8();
+ auto aGraphics = lcl_getGraphics(mxComponent);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), size_t(5), aGraphics.size());
+
+ // Get all GfxLink addresses, we expect all of them to be the same
+ // indicating we use the same graphic instance for all shapes
+ std::vector<sal_Int64> aGfxLinkAddresses;
+ for (auto const & rxGraphic : aGraphics)
+ {
+ GfxLink* pLink = Graphic(rxGraphic).GetSharedGfxLink().get();
+ aGfxLinkAddresses.emplace_back(reinterpret_cast<sal_Int64>(pLink));
+ }
+
+ // Check all addresses are the same
+ bool bResult = std::equal(aGfxLinkAddresses.begin() + 1, aGfxLinkAddresses.end(), aGfxLinkAddresses.begin());
+ const OString sGraphicNotTheSameFailedMessage = OStringLiteral("Graphics not the same for filter: '") + rFilterName.toUtf8() + OStringLiteral("'");
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sGraphicNotTheSameFailedMessage.getStr(), true, bResult);
+ }
+}
+
void Test::testCharHighlightBody()
{
// MS Word has two kind of character backgrounds called character shading and highlighting
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index ac63bb3606b7..ee68260fbd50 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -330,6 +330,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/graphic/grfattr \
vcl/source/graphic/Manager \
vcl/source/graphic/UnoGraphic \
+ vcl/source/graphic/UnoGraphicMapper \
vcl/source/graphic/UnoGraphicDescriptor \
vcl/source/graphic/UnoGraphicObject \
vcl/source/graphic/UnoGraphicProvider \
diff --git a/vcl/source/graphic/UnoGraphicMapper.cxx b/vcl/source/graphic/UnoGraphicMapper.cxx
new file mode 100644
index 000000000000..6bde78097681
--- /dev/null
+++ b/vcl/source/graphic/UnoGraphicMapper.cxx
@@ -0,0 +1,87 @@
+/* -*- 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 <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/graphic/XGraphicMapper.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <cppuhelper/implbase.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <comphelper/unique_disposing_ptr.hxx>
+
+#include <memory>
+#include <unordered_map>
+
+using namespace css;
+
+namespace
+{
+class GraphicMapper : public cppu::WeakImplHelper<graphic::XGraphicMapper, lang::XServiceInfo>
+{
+private:
+ std::unordered_map<OUString, uno::Reference<graphic::XGraphic>> maGraphicMap;
+
+public:
+ GraphicMapper() = default;
+
+protected:
+ // XServiceInfo
+ OUString SAL_CALL getImplementationName() override
+ {
+ return "com.sun.star.comp.graphic.GraphicMapper";
+ }
+ sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override
+ {
+ return cppu::supportsService(this, ServiceName);
+ }
+ css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
+ {
+ return { "com.sun.star.graphic.GraphicMapper" };
+ }
+
+ // XTypeProvider
+ css::uno::Sequence<css::uno::Type> SAL_CALL getTypes() override
+ {
+ static const uno::Sequence<uno::Type> aTypes{
+ cppu::UnoType<lang::XServiceInfo>::get(), cppu::UnoType<lang::XTypeProvider>::get(),
+ cppu::UnoType<graphic::XGraphicMapper>::get()
+ };
+ return aTypes;
+ }
+ css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() override
+ {
+ return css::uno::Sequence<sal_Int8>();
+ }
+
+ // XGraphicMapper
+ css::uno::Reference<css::graphic::XGraphic> SAL_CALL findGraphic(const OUString& rId) override
+ {
+ auto aIterator = maGraphicMap.find(rId);
+
+ if (aIterator == maGraphicMap.end())
+ return css::uno::Reference<css::graphic::XGraphic>();
+
+ return aIterator->second;
+ }
+ void SAL_CALL putGraphic(const OUString& rId,
+ css::uno::Reference<css::graphic::XGraphic> const& rGraphic) override
+ {
+ maGraphicMap.emplace(rId, rGraphic);
+ }
+};
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+com_sun_star_comp_graphic_GraphicMapper_get_implementation(css::uno::XComponentContext*,
+ css::uno::Sequence<css::uno::Any> const&)
+{
+ return cppu::acquire(new GraphicMapper);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/vcl.common.component b/vcl/vcl.common.component
index a884f6bd8c2e..2665a136afcc 100644
--- a/vcl/vcl.common.component
+++ b/vcl/vcl.common.component
@@ -27,6 +27,10 @@
constructor="com_sun_star_graphic_GraphicObject_get_implementation">
<service name="com.sun.star.graphic.GraphicObject"/>
</implementation>
+ <implementation name="com.sun.star.comp.graphic.GraphicMapper"
+ constructor="com_sun_star_comp_graphic_GraphicMapper_get_implementation">
+ <service name="com.sun.star.graphic.GraphicMapper"/>
+ </implementation>
<implementation name="com.sun.star.datatransfer.MimeCntTypeFactory"
constructor="dtrans_CMimeContentTypeFactory_get_implementation">
<service name="com.sun.star.datatransfer.MimeContentTypeFactory"/>
diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
index db4990cc6497..fba694b5b77b 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
@@ -23,6 +23,7 @@
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/xml/sax/SAXException.hpp>
#include <com/sun/star/xml/dom/DocumentBuilder.hpp>
+#include <com/sun/star/graphic/GraphicMapper.hpp>
#include <ooxml/resourceids.hxx>
#include "OOXMLStreamImpl.hxx"
#include "OOXMLDocumentImpl.hxx"
@@ -60,6 +61,7 @@ OOXMLDocumentImpl::OOXMLDocumentImpl(OOXMLStream::Pointer_t const & pStream, con
, mnProgressEndPos(0)
, m_rBaseURL(utl::MediaDescriptor(rDescriptor).getUnpackedValueOrDefault("DocumentBaseURL", OUString()))
, maMediaDescriptor(rDescriptor)
+ , mxGraphicMapper(graphic::GraphicMapper::create(mpStream->getContext()))
{
pushShapeContext();
}
diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
index efaefd5f7d2a..1848f8971766 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
@@ -22,6 +22,7 @@
#include <ooxml/OOXMLDocument.hxx>
#include <com/sun/star/xml/dom/XDocument.hpp>
+#include <com/sun/star/graphic/XGraphicMapper.hpp>
#include "OOXMLPropertySet.hxx"
@@ -63,6 +64,8 @@ class OOXMLDocumentImpl : public OOXMLDocument
/// DocumentBaseURL
OUString m_rBaseURL;
css::uno::Sequence<css::beans::PropertyValue> maMediaDescriptor;
+ /// Graphic mapper
+ css::uno::Reference<css::graphic::XGraphicMapper> mxGraphicMapper;
private:
void resolveFastSubStream(Stream & rStream,
@@ -134,7 +137,13 @@ public:
bool IsSkipImages() const { return mbSkipImages; };
OUString const& GetDocumentBaseURL() const { return m_rBaseURL; };
const css::uno::Sequence<css::beans::PropertyValue>& getMediaDescriptor() const;
+
+ const css::uno::Reference<css::graphic::XGraphicMapper>& getGraphicMapper() const
+ {
+ return mxGraphicMapper;
+ }
};
+
}
#endif // OOXML_DOCUMENT_IMPL_HXX
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index 938cbdf88812..104d3ad6a660 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -1670,6 +1670,11 @@ void OOXMLFastContextHandlerShape::setToken(Token_t nToken)
mrShapeContext->setRelationFragmentPath(mpParserState->getTarget());
+ auto xGraphicMapper = getDocument()->getGraphicMapper();
+
+ if (xGraphicMapper.is())
+ mrShapeContext->setGraphicMapper(xGraphicMapper);
+
OOXMLFastContextHandler::setToken(nToken);
if (mrShapeContext.is())