diff options
-rw-r--r-- | include/oox/helper/graphichelper.hxx | 6 | ||||
-rw-r--r-- | include/oox/shape/ShapeFilterBase.hxx | 7 | ||||
-rw-r--r-- | offapi/UnoApi_offapi.mk | 2 | ||||
-rw-r--r-- | offapi/com/sun/star/graphic/GraphicMapper.idl | 30 | ||||
-rw-r--r-- | offapi/com/sun/star/graphic/XGraphicMapper.idl | 35 | ||||
-rw-r--r-- | offapi/com/sun/star/xml/sax/XFastShapeContextHandler.idl | 11 | ||||
-rw-r--r-- | oox/source/helper/graphichelper.cxx | 52 | ||||
-rw-r--r-- | oox/source/shape/ShapeContextHandler.cxx | 6 | ||||
-rw-r--r-- | oox/source/shape/ShapeContextHandler.hxx | 2 | ||||
-rw-r--r-- | oox/source/shape/ShapeFilterBase.cxx | 5 | ||||
-rw-r--r-- | sw/qa/extras/globalfilter/data/multiple_identical_graphics.odt | bin | 0 -> 13826 bytes | |||
-rw-r--r-- | sw/qa/extras/globalfilter/globalfilter.cxx | 83 | ||||
-rw-r--r-- | vcl/Library_vcl.mk | 1 | ||||
-rw-r--r-- | vcl/source/graphic/UnoGraphicMapper.cxx | 87 | ||||
-rw-r--r-- | vcl/vcl.common.component | 4 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLDocumentImpl.cxx | 2 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLDocumentImpl.hxx | 8 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLFastContextHandler.cxx | 5 |
18 files changed, 330 insertions, 16 deletions
diff --git a/include/oox/helper/graphichelper.hxx b/include/oox/helper/graphichelper.hxx index 4854985d1014..d9d274b70377 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 b5b90ddafa37..35118a15d35c 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 { namespace drawingml { namespace table { @@ -67,6 +68,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; @@ -74,6 +80,7 @@ private: std::shared_ptr< ::oox::drawingml::chart::ChartConverter > mxChartConv; ::oox::drawingml::ThemePtr mpTheme; + css::uno::Reference<css::graphic::XGraphicMapper> mxGraphicMapper; }; } // namespace shape diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index 3cbd23756281..2f9f6e266f24 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 8e56f58ccabb..e43f7ee655fa 100644 --- a/oox/source/helper/graphichelper.cxx +++ b/oox/source/helper/graphichelper.cxx @@ -30,6 +30,7 @@ #include <com/sun/star/graphic/GraphicProvider.hpp> #include <com/sun/star/graphic/XGraphicProvider.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> @@ -320,16 +321,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)); @@ -338,11 +347,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]); + } } } @@ -350,22 +362,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; } @@ -383,6 +399,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 1a1aafa5cf38..82f30c84ff09 100644 --- a/oox/source/shape/ShapeContextHandler.cxx +++ b/oox/source/shape/ShapeContextHandler.cxx @@ -595,6 +595,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 2de45f533637..b1204470346e 100644 --- a/oox/source/shape/ShapeContextHandler.hxx +++ b/oox/source/shape/ShapeContextHandler.hxx @@ -122,6 +122,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 562504090f76..255dd65a7b94 100644 --- a/oox/source/shape/ShapeFilterBase.cxx +++ b/oox/source/shape/ShapeFilterBase.cxx @@ -100,7 +100,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 Binary files differnew file mode 100644 index 000000000000..20f40798edfe --- /dev/null +++ b/sw/qa/extras/globalfilter/data/multiple_identical_graphics.odt diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx index f0d61355ea86..fe9b58e16413 100644 --- a/sw/qa/extras/globalfilter/globalfilter.cxx +++ b/sw/qa/extras/globalfilter/globalfilter.cxx @@ -40,6 +40,7 @@ public: void testLinkedGraphicRT(); void testImageWithSpecialID(); void testGraphicShape(); + void testMultipleIdenticalGraphics(); void testCharHighlight(); void testCharHighlightODF(); void testCharHighlightBody(); @@ -62,6 +63,7 @@ public: CPPUNIT_TEST(testLinkedGraphicRT); CPPUNIT_TEST(testImageWithSpecialID); CPPUNIT_TEST(testGraphicShape); + CPPUNIT_TEST(testMultipleIdenticalGraphics); CPPUNIT_TEST(testCharHighlight); CPPUNIT_TEST(testCharHighlightODF); CPPUNIT_TEST(testMSCharBackgroundEditing); @@ -396,6 +398,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 94707b6ee6b8..e9d820806870 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -327,6 +327,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 77fbf38a1973..de33114bd264 100644 --- a/vcl/vcl.common.component +++ b/vcl/vcl.common.component @@ -27,4 +27,8 @@ 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> </component> diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx index bec04a949ac7..b5ef23464f8f 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx @@ -26,6 +26,7 @@ #include <com/sun/star/xml/sax/SAXException.hpp> #include <com/sun/star/xml/dom/DocumentBuilder.hpp> #include <com/sun/star/embed/XHierarchicalStorageAccess.hpp> +#include <com/sun/star/graphic/GraphicMapper.hpp> #include <ooxml/resourceids.hxx> #include "OOXMLStreamImpl.hxx" #include "OOXMLDocumentImpl.hxx" @@ -67,6 +68,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 2bcc1e746ab0..6b290bc489d9 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx @@ -23,6 +23,7 @@ #include <com/sun/star/xml/sax/XFastTokenHandler.hpp> #include <com/sun/star/xml/dom/XDocument.hpp> +#include <com/sun/star/graphic/XGraphicMapper.hpp> #include "OOXMLPropertySet.hxx" @@ -65,6 +66,8 @@ class OOXMLDocumentImpl : public OOXMLDocument /// DocumentBaseURL OUString const m_rBaseURL; css::uno::Sequence<css::beans::PropertyValue> const maMediaDescriptor; + /// Graphic mapper + css::uno::Reference<css::graphic::XGraphicMapper> mxGraphicMapper; private: void resolveFastSubStream(Stream & rStream, @@ -136,6 +139,11 @@ 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 6359cb3b044d..7d3c081b2676 100644 --- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx +++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx @@ -1646,6 +1646,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()) |