From cbc6e67d3c88fb6ae39c304604a98eaa504f19cc Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Mon, 29 Aug 2022 09:23:22 +0200 Subject: [PATCH] avmedia: implement video crop support in the ODP filter And also import/export the video preview as well. The naming follows the style used for table shape previews. The preview is important, since the cropping is relative to the bitmap's preferred logic size. Change-Id: I6115284c1f4cf342b3296cd0ac3beb70a809fd1b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138959 Reviewed-by: Miklos Vajna Tested-by: Jenkins --- include/svx/unoshape.hxx | 2 + svx/source/unodraw/unoshap4.cxx | 25 ++++++++++++ xmloff/CppunitTest_xmloff_draw.mk | 3 ++ xmloff/qa/unit/data/video-snapshot.odp | Bin 0 -> 17605 bytes xmloff/qa/unit/draw.cxx | 50 +++++++++++++++++++++++ xmloff/source/draw/shapeexport.cxx | 54 ++++++++++++++++++++++++- xmloff/source/draw/ximpshap.cxx | 14 ++++++- 7 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 xmloff/qa/unit/data/video-snapshot.odp diff --git a/include/svx/unoshape.hxx b/include/svx/unoshape.hxx index 923636d3b9c7..51b65e23ade9 100644 --- a/include/svx/unoshape.hxx +++ b/include/svx/unoshape.hxx @@ -858,6 +858,8 @@ private: // override these for special property handling in subcasses. Return true if property is handled virtual bool setPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, const css::uno::Any& rValue ) override; virtual bool getPropertyValueImpl( const OUString& rName, const SfxItemPropertyMapEntry* pProperty, css::uno::Any& rValue ) override; + bool getPropertyStateImpl(const SfxItemPropertyMapEntry* pProperty, + css::beans::PropertyState& rState) override; OUString referer_; }; diff --git a/svx/source/unodraw/unoshap4.cxx b/svx/source/unodraw/unoshap4.cxx index 482efb826117..ae26aaabeca6 100644 --- a/svx/source/unodraw/unoshap4.cxx +++ b/svx/source/unodraw/unoshap4.cxx @@ -1071,4 +1071,29 @@ bool SvxMediaShape::getPropertyValueImpl( const OUString& rName, const SfxItemPr } } +bool SvxMediaShape::getPropertyStateImpl(const SfxItemPropertyMapEntry* pProperty, + css::beans::PropertyState& rState) +{ +#if HAVE_FEATURE_AVMEDIA + if (pProperty->nWID == SDRATTR_GRAFCROP) + { + auto pMedia = static_cast(GetSdrObject()); + const avmedia::MediaItem& rItem = pMedia->getMediaProperties(); + const text::GraphicCrop& rCrop = rItem.getCrop(); + if (rCrop.Bottom > 0 || rCrop.Left > 0 || rCrop.Right > 0 || rCrop.Top > 0) + { + // The media has a crop, expose it to UNO-based export filters. + rState = beans::PropertyState_DIRECT_VALUE; + } + else + { + rState = beans::PropertyState_AMBIGUOUS_VALUE; + } + return true; + } +#endif + + return SvxShape::getPropertyStateImpl(pProperty, rState); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/CppunitTest_xmloff_draw.mk b/xmloff/CppunitTest_xmloff_draw.mk index 42c7a9526661..a503cc9f2c1d 100644 --- a/xmloff/CppunitTest_xmloff_draw.mk +++ b/xmloff/CppunitTest_xmloff_draw.mk @@ -28,6 +28,9 @@ $(eval $(call gb_CppunitTest_use_libraries,xmloff_draw, \ test \ unotest \ utl \ + avmedia \ + svxcore \ + vcl \ )) $(eval $(call gb_CppunitTest_use_sdk_api,xmloff_draw)) diff --git a/xmloff/qa/unit/data/video-snapshot.odp b/xmloff/qa/unit/data/video-snapshot.odp new file mode 100644 index 0000000000000000000000000000000000000000..ca3b7f21dc6c3b355cb6931fd7fdfbda9428127e GIT binary patch literal 17605 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 literal 0 HcmV?d00001 diff --git a/xmloff/qa/unit/draw.cxx b/xmloff/qa/unit/draw.cxx index e8462ccc6181..6aab4c12a46f 100644 --- a/xmloff/qa/unit/draw.cxx +++ b/xmloff/qa/unit/draw.cxx @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,9 @@ #include #include #include +#include +#include +#include using namespace ::com::sun::star; @@ -173,6 +177,52 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testThemeExport) assertXPath(pXmlDoc, "//style:master-page/loext:theme/loext:color-table/loext:color", 12); } +CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testVideoSnapshot) +{ + // Execute ODP import: + OUString aURL = m_directories.getURLFromSrc(u"xmloff/qa/unit/data/video-snapshot.odp"); + getComponent() = loadFromDesktop(aURL, "com.sun.star.presentation.PresentationDocument"); + uno::Reference xDrawPagesSupplier(getComponent(), + uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT(xDrawPagesSupplier.is()); + uno::Reference xDrawPages(xDrawPagesSupplier->getDrawPages()); + uno::Reference xDrawPage(xDrawPages->getByIndex(0), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT(xDrawPage.is()); + auto pUnoPage = dynamic_cast(xDrawPage.get()); + SdrPage* pSdrPage = pUnoPage->GetSdrPage(); + auto pMedia = dynamic_cast(pSdrPage->GetObj(0)); + + // Check that the preview was imported: + const avmedia::MediaItem& rItem = pMedia->getMediaProperties(); + const Graphic& rGraphic = rItem.getGraphic(); + CPPUNIT_ASSERT(!rGraphic.IsNone()); + + // Check that the crop was imported: + const text::GraphicCrop& rCrop = rItem.getCrop(); + CPPUNIT_ASSERT_EQUAL(static_cast(0), rCrop.Top); + CPPUNIT_ASSERT_EQUAL(static_cast(0), rCrop.Bottom); + CPPUNIT_ASSERT_EQUAL(static_cast(1356), rCrop.Left); + CPPUNIT_ASSERT_EQUAL(static_cast(1356), rCrop.Right); + + // Execute ODP export: + utl::TempFile aTempFile; + save("impress8", aTempFile); + + std::unique_ptr pStream = parseExportStream(aTempFile, "content.xml"); + xmlDocUniquePtr pXmlDoc = parseXmlStream(pStream.get()); + // Check that the preview was exported: + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 1 + // - Actual : 0 + // - XPath '//draw:frame[@draw:style-name='gr1']/draw:image' number of nodes is incorrect + // i.e. the preview wasn't exported to ODP. + assertXPath(pXmlDoc, "//draw:frame[@draw:style-name='gr1']/draw:image", "href", + "Pictures/MediaPreview1.png"); + // Check that the crop was exported: + assertXPath(pXmlDoc, "//style:style[@style:name='gr1']/style:graphic-properties", "clip", + "rect(0cm, 1.356cm, 0cm, 1.356cm)"); +} + CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testThemeImport) { // Given a document that has a master page with a theme associated: diff --git a/xmloff/source/draw/shapeexport.cxx b/xmloff/source/draw/shapeexport.cxx index cd9c90efad24..6931c5684642 100644 --- a/xmloff/source/draw/shapeexport.cxx +++ b/xmloff/source/draw/shapeexport.cxx @@ -103,6 +103,7 @@ #include #include #include +#include #include #include @@ -3400,7 +3401,7 @@ void XMLShapeExport::ImpExportMediaShape( mrExport.AddAttribute( XML_NAMESPACE_DRAW, XML_MIME_TYPE, sMimeType ); // write plugin - SvXMLElementExport aPluginOBJ(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, !( nFeatures & XMLShapeExportFlags::NO_WS ), true); + auto pPluginOBJ = std::make_unique(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, !( nFeatures & XMLShapeExportFlags::NO_WS ), true); // export parameters const OUString aFalseStr( "false" ), aTrueStr( "true" ); @@ -3450,6 +3451,57 @@ void XMLShapeExport::ImpExportMediaShape( delete new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true ); } + pPluginOBJ.reset(); + + uno::Reference xGraphic; + xPropSet->getPropertyValue("Graphic") >>= xGraphic; + Graphic aGraphic(xGraphic); + if (!aGraphic.IsNone()) + { + // The media has a preview, export it. + uno::Reference xPictureStorage; + uno::Reference xStorage; + uno::Reference xPictureStream; + OUString sPictureName; + xStorage.set(GetExport().GetTargetStorage(), uno::UNO_SET_THROW); + xPictureStorage.set( + xStorage->openStorageElement("Pictures", embed::ElementModes::READWRITE), + uno::UNO_SET_THROW); + sal_Int32 nIndex = 0; + while (true) + { + sPictureName = "MediaPreview" + OUString::number(++nIndex) + ".png"; + if (!xPictureStorage->hasByName(sPictureName)) + { + break; + } + } + + xPictureStream.set( + xPictureStorage->openStreamElement(sPictureName, ::embed::ElementModes::READWRITE), + uno::UNO_SET_THROW); + + uno::Reference xContext = GetExport().getComponentContext(); + uno::Reference xProvider( + graphic::GraphicProvider::create(xContext)); + uno::Sequence aArgs{ + comphelper::makePropertyValue("MimeType", OUString("image/png")), + comphelper::makePropertyValue("OutputStream", xPictureStream->getOutputStream()) + }; + xProvider->storeGraphic(xGraphic, aArgs); + if (xPictureStorage.is()) + { + uno::Reference xTrans(xPictureStorage, uno::UNO_QUERY); + if (xTrans.is()) + xTrans->commit(); + } + OUString sURL = "Pictures/" + sPictureName; + mrExport.AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, sURL); + 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); + SvXMLElementExport aImageElem(GetExport(), XML_NAMESPACE_DRAW, XML_IMAGE, false, true); + } } void XMLShapeExport::ImpExport3DSceneShape( const uno::Reference< drawing::XShape >& xShape, XMLShapeExportFlags nFeatures, awt::Point* pRefPoint) diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx index 1971c9b9f022..af0bfc1a7ef0 100644 --- a/xmloff/source/draw/ximpshap.cxx +++ b/xmloff/source/draw/ximpshap.cxx @@ -2918,6 +2918,12 @@ void SdXMLPluginShapeContext::startFastElement (sal_Int32 /*nElement*/, if( !mxShape.is() ) return; + if (mbMedia) + { + // The media may have a crop, apply it. + SetStyle(/*bSupportsStyle=*/false); + } + SetLayer(); if(bIsPresShape) @@ -3312,6 +3318,7 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLFrameShapeContext pShapeContext->setHyperlink( msHyperlink ); auto nToken = nElement & TOKEN_MASK; + bool bMedia = false; // Ignore gltf model if necessary and so the fallback image will be imported if( nToken == XML_PLUGIN ) { @@ -3321,10 +3328,15 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > SdXMLFrameShapeContext mxImplContext = nullptr; return new SvXMLImportContext(GetImport()); } + else if (pPluginContext && pPluginContext->getMimeType() == "application/vnd.sun.star.media") + { + // The media may have a preview, import it. + bMedia = true; + } } mxImplContext = xContext; - mbSupportsReplacement = (nToken == XML_OBJECT ) || (nToken == XML_OBJECT_OLE); + mbSupportsReplacement = (nToken == XML_OBJECT ) || (nToken == XML_OBJECT_OLE) || bMedia; setSupportsMultipleContents(nToken == XML_IMAGE); if(getSupportsMultipleContents() && dynamic_cast< SdXMLGraphicObjectShapeContext* >(xContext.get()))