From 8fc1b60f62c213a0476f3acc9f89cd5eccbf335d Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Thu, 27 Feb 2020 09:34:30 +0100 Subject: [PATCH] sw SVG export: try to reuse original bitmap data for JPG and PNG bitmaps Writer shapes are implemented using SwXShape, Impress shapes use SdrGrafObj. So switch to working with the XShape interface, which is supported by both. Also, don't work with the transformed graphic if it has the same checksum as the original graphic: the transformed graphic is not linked to the original JPG/PNG data. Now selecting an image in Writer Online has the same speedup that Impress Online already had. Change-Id: Iab2791c5f5c7a2754e3de0ebb2d6ea664f6c77e4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89540 Reviewed-by: Miklos Vajna Tested-by: Jenkins --- filter/CppunitTest_filter_svg.mk | 47 +++++++++++++ filter/Module_filter.mk | 1 + filter/qa/unit/data/preserve-jpg.odt | Bin 0 -> 10052 bytes filter/qa/unit/svg.cxx | 100 +++++++++++++++++++++++++++ filter/source/svg/svgexport.cxx | 17 +++-- filter/source/svg/svgwriter.cxx | 52 +++++++------- 6 files changed, 185 insertions(+), 32 deletions(-) create mode 100644 filter/CppunitTest_filter_svg.mk create mode 100644 filter/qa/unit/data/preserve-jpg.odt create mode 100644 filter/qa/unit/svg.cxx diff --git a/filter/CppunitTest_filter_svg.mk b/filter/CppunitTest_filter_svg.mk new file mode 100644 index 000000000000..ec0841929f3f --- /dev/null +++ b/filter/CppunitTest_filter_svg.mk @@ -0,0 +1,47 @@ +# -*- 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,filter_svg)) + +$(eval $(call gb_CppunitTest_use_externals,filter_svg,\ + boost_headers \ + libxml2 \ +)) + +$(eval $(call gb_CppunitTest_add_exception_objects,filter_svg, \ + filter/qa/unit/svg \ +)) + +$(eval $(call gb_CppunitTest_use_libraries,filter_svg, \ + comphelper \ + cppu \ + cppuhelper \ + sal \ + test \ + unotest \ + utl \ + tl \ +)) + +$(eval $(call gb_CppunitTest_use_sdk_api,filter_svg)) + +$(eval $(call gb_CppunitTest_use_ure,filter_svg)) +$(eval $(call gb_CppunitTest_use_vcl,filter_svg)) + +$(eval $(call gb_CppunitTest_use_rdb,filter_svg,services)) + +$(eval $(call gb_CppunitTest_use_custom_headers,filter_svg,\ + officecfg/registry \ +)) + +$(eval $(call gb_CppunitTest_use_configuration,filter_svg)) + +# vim: set noet sw=4 ts=4: diff --git a/filter/Module_filter.mk b/filter/Module_filter.mk index 2d380fbd91ac..a01baa0b48a7 100644 --- a/filter/Module_filter.mk +++ b/filter/Module_filter.mk @@ -67,6 +67,7 @@ $(eval $(call gb_Module_add_check_targets,filter,\ CppunitTest_filter_ras_test \ CppunitTest_filter_tiff_test \ CppunitTest_filter_tga_test \ + CppunitTest_filter_svg \ )) endif diff --git a/filter/qa/unit/data/preserve-jpg.odt b/filter/qa/unit/data/preserve-jpg.odt new file mode 100644 index 0000000000000000000000000000000000000000..83768bd47afbda979c3db655d77954c0099c9e94 GIT binary patch literal 10052 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 literal 0 HcmV?d00001 diff --git a/filter/qa/unit/svg.cxx b/filter/qa/unit/svg.cxx new file mode 100644 index 000000000000..49e22e0ebd16 --- /dev/null +++ b/filter/qa/unit/svg.cxx @@ -0,0 +1,100 @@ +/* -*- 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace ::com::sun::star; + +char const DATA_DIRECTORY[] = "/filter/qa/unit/data/"; + +/// SVG filter tests. +class SvgFilterTest : public test::BootstrapFixture, public unotest::MacrosTest, public XmlTestTools +{ +private: + uno::Reference mxComponent; + +public: + void setUp() override; + void tearDown() override; + void registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx) override; + uno::Reference& getComponent() { return mxComponent; } + void load(const OUString& rURL); +}; + +void SvgFilterTest::setUp() +{ + test::BootstrapFixture::setUp(); + + mxDesktop.set(frame::Desktop::create(mxComponentContext)); +} + +void SvgFilterTest::tearDown() +{ + if (mxComponent.is()) + mxComponent->dispose(); + + test::BootstrapFixture::tearDown(); +} + +void SvgFilterTest::load(const OUString& rFileName) +{ + OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + rFileName; + mxComponent = loadFromDesktop(aURL); +} + +void SvgFilterTest::registerNamespaces(xmlXPathContextPtr& pXmlXpathCtx) +{ + xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("svg"), BAD_CAST("http://www.w3.org/2000/svg")); +} + +CPPUNIT_TEST_FIXTURE(SvgFilterTest, testPreserveJpg) +{ +#if !defined(MACOSX) + // Load a document with a jpeg image in it. + load("preserve-jpg.odt"); + + // Select the image. + dispatchCommand(getComponent(), ".uno:JumpToNextFrame", {}); + + // Export the selection to SVG. + uno::Reference xStorable(getComponent(), uno::UNO_QUERY_THROW); + SvMemoryStream aStream; + uno::Reference xOut = new utl::OOutputStreamWrapper(aStream); + utl::MediaDescriptor aMediaDescriptor; + aMediaDescriptor["FilterName"] <<= OUString("writer_svg_Export"); + aMediaDescriptor["SelectionOnly"] <<= true; + aMediaDescriptor["OutputStream"] <<= xOut; + xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList()); + aStream.Seek(STREAM_SEEK_TO_BEGIN); + + // Make sure the the original JPG data is reused and we don't perform a PNG re-compress. + xmlDocPtr pXmlDoc = parseXmlStream(&aStream); + OUString aAttributeValue = getXPath(pXmlDoc, "//svg:image", "href"); + + // Without the accompanying fix in place, this test would have failed with: + // - Expression: aAttributeValue.startsWith("data:image/jpeg") + // i.e. the SVG export result re-compressed the image as PNG, even if the original and the + // transformed image is the same, so there is no need for that. + CPPUNIT_ASSERT(aAttributeValue.startsWith("data:image/jpeg")); +#endif +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx index c717d00596ef..aa071ca37f50 100644 --- a/filter/source/svg/svgexport.cxx +++ b/filter/source/svg/svgexport.cxx @@ -693,13 +693,20 @@ bool SVGFilter::implExportWriterTextGraphic( const Reference< view::XSelectionSu if (xSelection.is() && xSelection->supportsService("com.sun.star.text.TextGraphicObject")) { uno::Reference xPropertySet(xSelection, uno::UNO_QUERY); - uno::Reference xGraphic; - xPropertySet->getPropertyValue("TransformedGraphic") >>= xGraphic; - if (!xGraphic.is()) + uno::Reference xOriginalGraphic; + xPropertySet->getPropertyValue("Graphic") >>= xOriginalGraphic; + const Graphic aOriginalGraphic(xOriginalGraphic); + + uno::Reference xTransformedGraphic; + xPropertySet->getPropertyValue("TransformedGraphic") >>= xTransformedGraphic; + + if (!xTransformedGraphic.is()) return false; - - const Graphic aGraphic(xGraphic); + const Graphic aTransformedGraphic(xTransformedGraphic); + bool bChecksumMatches = aOriginalGraphic.GetChecksum() == aTransformedGraphic.GetChecksum(); + const Graphic aGraphic = bChecksumMatches ? aOriginalGraphic : aTransformedGraphic; + uno::Reference xGraphic = bChecksumMatches ? xOriginalGraphic : xTransformedGraphic; // Calculate size from Graphic Point aPos( OutputDevice::LogicToLogic(aGraphic.GetPrefMapMode().GetOrigin(), aGraphic.GetPrefMapMode(), MapMode(MapUnit::Map100thMM)) ); diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx index 9ccd18eaafee..8d491d122d0b 100644 --- a/filter/source/svg/svgwriter.cxx +++ b/filter/source/svg/svgwriter.cxx @@ -2688,20 +2688,22 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, const OUString& rText, namespace { -SdrGrafObj* GetSdrGrafObjFromXShape(const css::uno::Reference* pShape) +void GetGraphicFromXShape(const css::uno::Reference* pShape, Graphic& rGraphic) { if (!pShape) { - return nullptr; + return; } - auto pObject = dynamic_cast(pShape->get()); - if (!pObject) + uno::Reference xPropertySet(*pShape, uno::UNO_QUERY); + if (!xPropertySet.is()) { - return nullptr; + return; } - return dynamic_cast(pObject->GetSdrObject()); + uno::Reference xGraphic; + xPropertySet->getPropertyValue("Graphic") >>= xGraphic; + rGraphic= Graphic(xGraphic); } } @@ -2724,34 +2726,30 @@ void SVGActionWriter::ImplWriteBmp( const BitmapEx& rBmpEx, SvMemoryStream aOStm( 65535, 65535 ); bool bCached = false; - SdrGrafObj* pGrafObj = nullptr; + Graphic aGraphic; bool bPNG = false; bool bJPG = false; if (pShape) { - pGrafObj = GetSdrGrafObjFromXShape(pShape); - if (pGrafObj) + GetGraphicFromXShape(pShape, aGraphic); + if (aGraphic.GetType() == GraphicType::Bitmap) { - const Graphic& rGraphic = pGrafObj->GetGraphic(); - if (rGraphic.GetType() == GraphicType::Bitmap) + const BitmapEx& rGraphicBitmap = aGraphic.GetBitmapExRef(); + if (rGraphicBitmap.GetChecksum() == rBmpEx.GetChecksum()) { - const BitmapEx& rGraphicBitmap = rGraphic.GetBitmapExRef(); - if (rGraphicBitmap.GetChecksum() == rBmpEx.GetChecksum()) + GfxLink aGfxLink = aGraphic.GetGfxLink(); + if (aGfxLink.GetType() == GfxLinkType::NativePng) { - GfxLink aGfxLink = rGraphic.GetGfxLink(); - if (aGfxLink.GetType() == GfxLinkType::NativePng) - { - bPNG = true; - } - else if (aGfxLink.GetType() == GfxLinkType::NativeJpg) - { - bJPG = true; - } - if (bPNG || bJPG) - { - aOStm.WriteBytes(aGfxLink.GetData(), aGfxLink.GetDataSize()); - bCached = true; - } + bPNG = true; + } + else if (aGfxLink.GetType() == GfxLinkType::NativeJpg) + { + bJPG = true; + } + if (bPNG || bJPG) + { + aOStm.WriteBytes(aGfxLink.GetData(), aGfxLink.GetDataSize()); + bCached = true; } } }