From 8484e52675052848d2d3ffe07378ce2ad29fd288 Mon Sep 17 00:00:00 2001 From: Tomaž Vajngerl Date: Fri, 11 May 2018 00:22:06 +0900 Subject: tdf#117427 missing API for determining and loading linked graphic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds 2 properties to GraphicDescriptor: "Linked" - to indicate if the graphic is a linked one "OriginURL" - the URL of the location from where the graphic was or will be loaded (and is linked to) Additionally GraphicProvider was extended with a "LoadAsLink" (media)property, which can be passed using queryGraphic method. If "LoadAsLink" is set to true, then the Graphic will be created as a linked one. In addition the tests for this API was added to VCL (home of this API implementors). Change-Id: Ibdabe5e7780d1b372d1e66c3e19b18779fee2c9a Reviewed-on: https://gerrit.libreoffice.org/54090 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl --- offapi/com/sun/star/graphic/GraphicDescriptor.idl | 12 ++ vcl/CppunitTest_vcl_apitests.mk | 64 ++++++ vcl/Module_vcl.mk | 1 + vcl/qa/api/XGraphicTest.cxx | 246 ++++++++++++++++++++++ vcl/qa/api/data/TestGraphic.png | Bin 0 -> 81 bytes vcl/source/gdi/impgraph.cxx | 3 + vcl/source/graphic/UnoGraphicDescriptor.cxx | 24 ++- vcl/source/graphic/UnoGraphicProvider.cxx | 13 +- 8 files changed, 360 insertions(+), 3 deletions(-) create mode 100644 vcl/CppunitTest_vcl_apitests.mk create mode 100644 vcl/qa/api/XGraphicTest.cxx create mode 100644 vcl/qa/api/data/TestGraphic.png diff --git a/offapi/com/sun/star/graphic/GraphicDescriptor.idl b/offapi/com/sun/star/graphic/GraphicDescriptor.idl index 183519c8a708..daf3c88f9e3e 100644 --- a/offapi/com/sun/star/graphic/GraphicDescriptor.idl +++ b/offapi/com/sun/star/graphic/GraphicDescriptor.idl @@ -136,6 +136,18 @@ published service GraphicDescriptor querying for the GraphicDescriptor

*/ [optional, property] boolean Animated; + + /** Indicates that the graphic is an external linked graphic + + @since LibreOffice 6.1 + */ + [optional, property] boolean Linked; + + /** The URL of the location from where the graphic was loaded from + + @since LibreOffice 6.1 + */ + [optional, property] string OriginURL; }; } ; } ; } ; } ; diff --git a/vcl/CppunitTest_vcl_apitests.mk b/vcl/CppunitTest_vcl_apitests.mk new file mode 100644 index 000000000000..83c618b06184 --- /dev/null +++ b/vcl/CppunitTest_vcl_apitests.mk @@ -0,0 +1,64 @@ +# -*- 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,vcl_apitests)) + +$(eval $(call gb_CppunitTest_set_include,vcl_apitests,\ + $$(INCLUDE) \ +)) + +$(eval $(call gb_CppunitTest_add_exception_objects,vcl_apitests, \ + vcl/qa/api/XGraphicTest \ +)) + +$(eval $(call gb_CppunitTest_use_externals,vcl_apitests,boost_headers)) + +$(eval $(call gb_CppunitTest_use_libraries,vcl_apitests, \ + comphelper \ + cppu \ + cppuhelper \ + sal \ + svt \ + test \ + tl \ + unotest \ + vcl \ +)) + +$(eval $(call gb_CppunitTest_use_api,vcl_apitests,\ + offapi \ + udkapi \ +)) + +$(eval $(call gb_CppunitTest_use_ure,vcl_apitests)) +$(eval $(call gb_CppunitTest_use_vcl,vcl_apitests)) +$(eval $(call gb_CppunitTest_use_configuration,vcl_apitests)) + +$(eval $(call gb_CppunitTest_use_components,vcl_apitests,\ + comphelper/util/comphelp \ + configmgr/source/configmgr \ + filter/source/config/cache/filterconfig1 \ + filter/source/storagefilterdetect/storagefd \ + i18npool/util/i18npool \ + package/source/xstor/xstor \ + package/util/package2 \ + sfx2/util/sfx \ + sot/util/sot \ + svl/source/fsstor/fsstorage \ + svtools/util/svt \ + ucb/source/core/ucb1 \ + ucb/source/ucp/file/ucpfile1 \ + ucb/source/ucp/tdoc/ucptdoc1 \ + unotools/util/utl \ + uui/util/uui \ + vcl/vcl.common \ +)) + + +# vim: set noet sw=4 ts=4: diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk index 3005538a966c..a3db18b5413d 100644 --- a/vcl/Module_vcl.mk +++ b/vcl/Module_vcl.mk @@ -203,6 +203,7 @@ $(eval $(call gb_Module_add_check_targets,vcl,\ CppunitTest_vcl_pdfexport \ CppunitTest_vcl_errorhandler \ CppunitTest_vcl_bitmap_render_test \ + CppunitTest_vcl_apitests \ )) diff --git a/vcl/qa/api/XGraphicTest.cxx b/vcl/qa/api/XGraphicTest.cxx new file mode 100644 index 000000000000..1dc9a1c1fe65 --- /dev/null +++ b/vcl/qa/api/XGraphicTest.cxx @@ -0,0 +1,246 @@ +/* -*- 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 + +#include + +namespace +{ +using namespace css; + +class XGraphicTest : public test::BootstrapFixture +{ +public: + OUString maDataUrl; + + XGraphicTest() + : BootstrapFixture(true, false) + , maDataUrl("/vcl/qa/api/data/") + { + } + + OUString getFullUrl(const OUString& sFileName) + { + return m_directories.getURLFromSrc(maDataUrl) + sFileName; + } + + void testGraphic(); + void testGraphicDescriptor(); + void testGraphicProvider(); + + CPPUNIT_TEST_SUITE(XGraphicTest); + CPPUNIT_TEST(testGraphic); + CPPUNIT_TEST(testGraphicDescriptor); + CPPUNIT_TEST(testGraphicProvider); + CPPUNIT_TEST_SUITE_END(); +}; + +BitmapEx createBitmap() +{ + Bitmap aBitmap(Size(100, 50), 24); + aBitmap.Erase(COL_LIGHTRED); + + return BitmapEx(aBitmap); +} + +void XGraphicTest::testGraphic() +{ + Graphic aGraphic; + uno::Reference xGraphic = aGraphic.GetXGraphic(); +} + +void XGraphicTest::testGraphicDescriptor() +{ + Graphic aGraphic(createBitmap()); + uno::Reference xGraphic = aGraphic.GetXGraphic(); + uno::Reference xGraphicDescriptor(xGraphic, uno::UNO_QUERY_THROW); + + //[property] byte GraphicType; + sal_Int8 nType; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("GraphicType") >>= nType); + CPPUNIT_ASSERT_EQUAL(graphic::GraphicType::PIXEL, nType); + + //[property] string MimeType; + OUString sMimeType; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("MimeType") >>= sMimeType); + CPPUNIT_ASSERT_EQUAL(OUString("image/x-vclgraphic"), sMimeType); + + //[optional, property] ::com::sun::star::awt::Size SizePixel; + awt::Size aSizePixel; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("SizePixel") >>= aSizePixel); + CPPUNIT_ASSERT_EQUAL(sal_Int32(100), aSizePixel.Width); + CPPUNIT_ASSERT_EQUAL(sal_Int32(50), aSizePixel.Height); + + //[optional, property] ::com::sun::star::awt::Size Size100thMM; + awt::Size aSize100thMM; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("Size100thMM") >>= aSize100thMM); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aSize100thMM.Width); + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aSize100thMM.Height); + + //[optional, property] byte BitsPerPixel; + sal_Int8 nBitsPerPixel; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("BitsPerPixel") >>= nBitsPerPixel); + CPPUNIT_ASSERT_EQUAL(sal_Int8(24), nBitsPerPixel); + + //[optional, property] boolean Transparent; + bool bTransparent; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("Transparent") >>= bTransparent); + CPPUNIT_ASSERT_EQUAL(false, bTransparent); + + //[optional, property] boolean Alpha; + bool bAlpha; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("Alpha") >>= bAlpha); + CPPUNIT_ASSERT_EQUAL(false, bAlpha); + + //[optional, property] boolean Animated; + bool bAnimated; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("Animated") >>= bAnimated); + CPPUNIT_ASSERT_EQUAL(false, bAnimated); +} + +void XGraphicTest::testGraphicProvider() +{ + OUString aGraphicURL = getFullUrl("TestGraphic.png"); + + { // Load lazy + uno::Reference xContext(comphelper::getProcessComponentContext()); + uno::Reference xGraphicProvider; + xGraphicProvider.set(graphic::GraphicProvider::create(xContext), uno::UNO_QUERY_THROW); + + auto aMediaProperties(comphelper::InitPropertySequence({ + { "URL", uno::makeAny(aGraphicURL) }, + { "LazyRead", uno::makeAny(true) }, + { "LoadAsLink", uno::makeAny(false) }, + })); + + uno::Reference xGraphic( + xGraphicProvider->queryGraphic(aMediaProperties)); + CPPUNIT_ASSERT(xGraphic.is()); + Graphic aGraphic(xGraphic); + CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); + + uno::Reference xGraphicDescriptor(xGraphic, uno::UNO_QUERY_THROW); + + sal_Int8 nType; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("GraphicType") >>= nType); + CPPUNIT_ASSERT_EQUAL(graphic::GraphicType::PIXEL, nType); + + awt::Size aSizePixel; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("SizePixel") >>= aSizePixel); + CPPUNIT_ASSERT_EQUAL(sal_Int32(8), aSizePixel.Width); + CPPUNIT_ASSERT_EQUAL(sal_Int32(8), aSizePixel.Height); + + bool bLinked; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("Linked") >>= bLinked); + CPPUNIT_ASSERT_EQUAL(false, bLinked); + + OUString sOriginURL; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("OriginURL") >>= sOriginURL); + CPPUNIT_ASSERT_EQUAL(OUString(), sOriginURL); + + CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); + } + + { // Load as link + uno::Reference xContext(comphelper::getProcessComponentContext()); + uno::Reference xGraphicProvider; + xGraphicProvider.set(graphic::GraphicProvider::create(xContext), uno::UNO_QUERY_THROW); + + auto aMediaProperties(comphelper::InitPropertySequence({ + { "URL", uno::makeAny(aGraphicURL) }, + { "LazyRead", uno::makeAny(false) }, + { "LoadAsLink", uno::makeAny(true) }, + })); + + uno::Reference xGraphic( + xGraphicProvider->queryGraphic(aMediaProperties)); + CPPUNIT_ASSERT(xGraphic.is()); + Graphic aGraphic(xGraphic); + CPPUNIT_ASSERT_EQUAL(true, aGraphic.isAvailable()); + + uno::Reference xGraphicDescriptor(xGraphic, uno::UNO_QUERY_THROW); + + sal_Int8 nType; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("GraphicType") >>= nType); + CPPUNIT_ASSERT_EQUAL(graphic::GraphicType::PIXEL, nType); + + awt::Size aSizePixel; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("SizePixel") >>= aSizePixel); + CPPUNIT_ASSERT_EQUAL(sal_Int32(8), aSizePixel.Width); + CPPUNIT_ASSERT_EQUAL(sal_Int32(8), aSizePixel.Height); + + bool bLinked; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("Linked") >>= bLinked); + CPPUNIT_ASSERT_EQUAL(true, bLinked); + + OUString sOriginURL; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("OriginURL") >>= sOriginURL); + CPPUNIT_ASSERT_EQUAL(aGraphicURL, sOriginURL); + } + + { // Load lazy and as link + uno::Reference xContext(comphelper::getProcessComponentContext()); + uno::Reference xGraphicProvider; + xGraphicProvider.set(graphic::GraphicProvider::create(xContext), uno::UNO_QUERY_THROW); + + auto aMediaProperties(comphelper::InitPropertySequence({ + { "URL", uno::makeAny(aGraphicURL) }, + { "LazyRead", uno::makeAny(true) }, + { "LoadAsLink", uno::makeAny(true) }, + })); + + uno::Reference xGraphic( + xGraphicProvider->queryGraphic(aMediaProperties)); + CPPUNIT_ASSERT(xGraphic.is()); + Graphic aGraphic(xGraphic); + + CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); + + uno::Reference xGraphicDescriptor(xGraphic, uno::UNO_QUERY_THROW); + + sal_Int8 nType; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("GraphicType") >>= nType); + CPPUNIT_ASSERT_EQUAL(graphic::GraphicType::PIXEL, nType); + + awt::Size aSizePixel; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("SizePixel") >>= aSizePixel); + CPPUNIT_ASSERT_EQUAL(sal_Int32(8), aSizePixel.Width); + CPPUNIT_ASSERT_EQUAL(sal_Int32(8), aSizePixel.Height); + + bool bLinked; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("Linked") >>= bLinked); + CPPUNIT_ASSERT_EQUAL(true, bLinked); + + OUString sOriginURL; + CPPUNIT_ASSERT(xGraphicDescriptor->getPropertyValue("OriginURL") >>= sOriginURL); + CPPUNIT_ASSERT_EQUAL(aGraphicURL, sOriginURL); + + CPPUNIT_ASSERT_EQUAL(false, aGraphic.isAvailable()); + } +} + +} // namespace + +CPPUNIT_TEST_SUITE_REGISTRATION(XGraphicTest); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/qa/api/data/TestGraphic.png b/vcl/qa/api/data/TestGraphic.png new file mode 100644 index 000000000000..fe0c3c8ae437 Binary files /dev/null and b/vcl/qa/api/data/TestGraphic.png differ diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index 2b263bcab354..61e062a43467 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -1535,7 +1535,10 @@ bool ImpGraphic::loadPrepared() Graphic aGraphic; if (mpGfxLink->LoadNative(aGraphic)) { + GraphicExternalLink aLink = maGraphicExternalLink; *this = *aGraphic.ImplGetImpGraphic(); + maGraphicExternalLink = aLink; + return true; } return false; diff --git a/vcl/source/graphic/UnoGraphicDescriptor.cxx b/vcl/source/graphic/UnoGraphicDescriptor.cxx index 49e1c01769cd..6f4a37af2c17 100644 --- a/vcl/source/graphic/UnoGraphicDescriptor.cxx +++ b/vcl/source/graphic/UnoGraphicDescriptor.cxx @@ -34,7 +34,6 @@ #include #include - enum class UnoGraphicProperty { GraphicType = 1 @@ -45,6 +44,8 @@ enum class UnoGraphicProperty , Transparent = 6 , Alpha = 7 , Animated = 8 + , Linked = 9 + , OriginURL = 10 }; @@ -241,6 +242,9 @@ rtl::Reference<::comphelper::PropertySetInfo> GraphicDescriptor::createPropertyS { OUString( "Transparent" ), static_cast< sal_Int32 >( UnoGraphicProperty::Transparent ), cppu::UnoType< sal_Bool >::get(), beans::PropertyAttribute::READONLY, 0 }, { OUString( "Alpha" ), static_cast< sal_Int32 >( UnoGraphicProperty::Alpha ), cppu::UnoType< sal_Bool >::get(), beans::PropertyAttribute::READONLY, 0 }, { OUString( "Animated" ), static_cast< sal_Int32 >( UnoGraphicProperty::Animated ), cppu::UnoType< sal_Bool >::get(), beans::PropertyAttribute::READONLY, 0 }, + { OUString("Linked"), sal_Int32(UnoGraphicProperty::Linked), cppu::UnoType::get(), beans::PropertyAttribute::READONLY, 0 }, + { OUString("OriginURL"), sal_Int32(UnoGraphicProperty::OriginURL), cppu::UnoType::get(), beans::PropertyAttribute::READONLY, 0 }, + { OUString(), 0, css::uno::Type(), 0, 0 } }; @@ -327,7 +331,7 @@ void GraphicDescriptor::_getPropertyValues( const comphelper::PropertyMapEntry** { if( mpGraphic->GetType() == GraphicType::Bitmap ) { - const Size aSizePix( mpGraphic->GetBitmapEx().GetSizePixel() ); + const Size aSizePix( mpGraphic->GetSizePixel() ); aAWTSize = awt::Size( aSizePix.Width(), aSizePix.Height() ); } } @@ -393,6 +397,22 @@ void GraphicDescriptor::_getPropertyValues( const comphelper::PropertyMapEntry** *pValues <<= mpGraphic && mpGraphic->IsAnimated(); } break; + + case UnoGraphicProperty::Linked: + { + *pValues <<= mpGraphic && !mpGraphic->getOriginURL().isEmpty(); + } + break; + + case UnoGraphicProperty::OriginURL: + { + OUString aOriginURL; + if (mpGraphic) + aOriginURL = mpGraphic->getOriginURL(); + + *pValues <<= aOriginURL; + } + break; } ++ppEntries; diff --git a/vcl/source/graphic/UnoGraphicProvider.cxx b/vcl/source/graphic/UnoGraphicProvider.cxx index 7adb183f5aa8..3576213fd9b2 100644 --- a/vcl/source/graphic/UnoGraphicProvider.cxx +++ b/vcl/source/graphic/UnoGraphicProvider.cxx @@ -305,6 +305,8 @@ uno::Reference< ::graphic::XGraphic > SAL_CALL GraphicProvider::queryGraphic( co uno::Sequence< ::beans::PropertyValue > aFilterData; bool bLazyRead = false; + bool bLoadAsLink = false; + for( sal_Int32 i = 0; ( i < rMediaProperties.getLength() ) && !pIStm && !xRet.is(); ++i ) { const OUString aName( rMediaProperties[ i ].Name ); @@ -329,7 +331,13 @@ uno::Reference< ::graphic::XGraphic > SAL_CALL GraphicProvider::queryGraphic( co aValue >>= aFilterData; } else if (aName == "LazyRead") + { aValue >>= bLazyRead; + } + else if (aName == "LoadAsLink") + { + aValue >>= bLoadAsLink; + } } // Check for the goal width and height if they are defined @@ -384,7 +392,7 @@ uno::Reference< ::graphic::XGraphic > SAL_CALL GraphicProvider::queryGraphic( co ::GraphicFilter& rFilter = ::GraphicFilter::GetGraphicFilter(); { - ::Graphic aVCLGraphic; + Graphic aVCLGraphic; // Define APM Header if goal height and width are defined WmfExternal aExtHeader; @@ -412,6 +420,9 @@ uno::Reference< ::graphic::XGraphic > SAL_CALL GraphicProvider::queryGraphic( co if( (error == ERRCODE_NONE ) && ( aVCLGraphic.GetType() != GraphicType::NONE ) ) { + if (!aPath.isEmpty() && bLoadAsLink) + aVCLGraphic.setOriginURL(aPath); + ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic; pUnoGraphic->init( aVCLGraphic ); -- cgit