Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.4:ARM
libreoffice
bsc1202114.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File bsc1202114.patch of Package libreoffice
From 91653df0bf9abad5d67635db6576a559f742576c Mon Sep 17 00:00:00 2001 From: Miklos Vajna <vmiklos@collabora.com> Date: Wed, 24 Aug 2022 13:53:38 +0200 Subject: [PATCH] Related: tdf#149971 svx: support explicitly provided snapshots for media shapes Snapshots / previews for media objects are used when the shape's video is not playing. This is generated by seeking to the 3rd second in the video, probably to avoid initial black frames. The trouble is that PowerPoint takes the initial frame (at least in case of the bugdoc), so our snapshot doesn't match the reference. We already import a bitmap snapshot from PPTX files since commit e2d46da076f43a7c0d56fc486b9f15339243f7c9 (avmedia: add doc model for bitmap fill of slide narrations, 2021-01-21), fix the problem by changing the snapshot generation to prefer this bitmap over generating one from the video. The crop properties of this bitmap / the video are still not yet handled from PPTX. (cherry picked from commit 8fa1d453c94cdbb03dac646fb8db2ebd1a0e84bd) Change-Id: Id985eaaaad5e4222d9a98203d054e08a0f97a0f7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138967 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com> --- svx/source/svdraw/svdomedia.cxx | 9 +++++++++ 3 files changed, 32 insertions(+) create mode 100644 svx/qa/unit/data/video-snapshot.pptx diff --git a/svx/source/svdraw/svdomedia.cxx b/svx/source/svdraw/svdomedia.cxx index bc030c7d6d3f..96d12027a060 100644 --- a/svx/source/svdraw/svdomedia.cxx +++ b/svx/source/svdraw/svdomedia.cxx @@ -143,6 +143,15 @@ uno::Reference< graphic::XGraphic > const & SdrMediaObj::getSnapshot() const #if HAVE_FEATURE_AVMEDIA if( !m_xImpl->m_xCachedSnapshot.is() ) { + Graphic aGraphic = m_xImpl->m_MediaProperties.getGraphic(); + if (!aGraphic.IsNone()) + { + // We have an explicit graphic for this media object, then go with that instead of + // generating our own one. + m_xImpl->m_xCachedSnapshot = aGraphic.GetXGraphic(); + return m_xImpl->m_xCachedSnapshot; + } + OUString aRealURL = m_xImpl->m_MediaProperties.getTempURL(); if( aRealURL.isEmpty() ) aRealURL = m_xImpl->m_MediaProperties.getURL(); -- 2.35.3 From 2a0c3f70aca0493f334d2af59a2dc23727e571ff Mon Sep 17 00:00:00 2001 From: Miklos Vajna <vmiklos@collabora.com> Date: Thu, 25 Aug 2022 14:01:43 +0200 Subject: [PATCH] Related: tdf#149971 avmedia: add doc model and render for crop of media objects It is possible to provide an explicit preview of media objects since commit 8fa1d453c94cdbb03dac646fb8db2ebd1a0e84bd (Related: tdf#149971 svx: support explicitly provided snapshots for media shapes, 2022-08-24), however they can't be cropped. This means that media shapes from PPTX with cropping show unexpected content and can also have a buggy aspect ratio. Extend avmedia::MediaItem to store cropping and take it into account when returning the preview bitmap in SdrMediaObj::getSnapshot(). PPTX import works out of the box, as oox/ already tried to set a cropping property on the media shape. This is just the preview, the cropping of the video itself is not yet implemented. (cherry picked from commit b6f0fd6a2f459ead2268e07bfd86db7e303b323f) Conflicts: svx/source/unodraw/unoprov.cxx Change-Id: I8db3e0dcf252613d56eb0e6139adf097e53b15cc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138968 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com> --- avmedia/source/framework/mediaitem.cxx | 17 +++++++++++++++ include/avmedia/mediaitem.hxx | 8 +++++-- svx/source/svdraw/svdomedia.cxx | 21 +++++++++++++++++++ svx/source/unodraw/unoprov.cxx | 1 + svx/source/unodraw/unoshap4.cxx | 28 +++++++++++++++++++++++-- 7 files changed, 77 insertions(+), 4 deletions(-) diff --git a/avmedia/source/framework/mediaitem.cxx b/avmedia/source/framework/mediaitem.cxx index 0a53cf5d4d39..ac8c09b79871 100644 --- a/avmedia/source/framework/mediaitem.cxx +++ b/avmedia/source/framework/mediaitem.cxx @@ -30,6 +30,7 @@ #include <com/sun/star/uri/UriReferenceFactory.hpp> #include <com/sun/star/uri/XUriReference.hpp> #include <com/sun/star/uri/XUriReferenceFactory.hpp> +#include <com/sun/star/text/GraphicCrop.hpp> #include <sal/log.hxx> @@ -64,6 +65,7 @@ struct MediaItem::Impl bool m_bMute; css::media::ZoomLevel m_eZoom; Graphic m_aGraphic; + text::GraphicCrop m_aCrop; explicit Impl(AVMediaSetMask nMaskSet) : m_nMaskSet( nMaskSet ) @@ -107,6 +109,7 @@ bool MediaItem::operator==( const SfxPoolItem& rItem ) const && m_pImpl->m_Referer == rOther.m_pImpl->m_Referer && m_pImpl->m_sMimeType == rOther.m_pImpl->m_sMimeType && m_pImpl->m_aGraphic == rOther.m_pImpl->m_aGraphic + && m_pImpl->m_aCrop == rOther.m_pImpl->m_aCrop && m_pImpl->m_eState == rOther.m_pImpl->m_eState && m_pImpl->m_fDuration == rOther.m_pImpl->m_fDuration && m_pImpl->m_fTime == rOther.m_pImpl->m_fTime @@ -193,6 +196,9 @@ bool MediaItem::merge(const MediaItem& rMediaItem) if (nMaskSet & AVMediaSetMask::GRAPHIC) bChanged |= setGraphic(rMediaItem.getGraphic()); + if (nMaskSet & AVMediaSetMask::CROP) + bChanged |= setCrop(rMediaItem.getCrop()); + if( AVMediaSetMask::STATE & nMaskSet ) bChanged |= setState( rMediaItem.getState() ); @@ -275,6 +281,17 @@ bool MediaItem::setGraphic(const Graphic& rGraphic) const Graphic & MediaItem::getGraphic() const { return m_pImpl->m_aGraphic; } +bool MediaItem::setCrop(const text::GraphicCrop& rCrop) +{ + m_pImpl->m_nMaskSet |= AVMediaSetMask::CROP; + bool bChanged = rCrop != m_pImpl->m_aCrop; + if (bChanged) + m_pImpl->m_aCrop = rCrop; + return bChanged; +} + +const text::GraphicCrop& MediaItem::getCrop() const { return m_pImpl->m_aCrop; } + bool MediaItem::setState(MediaState eState) { m_pImpl->m_nMaskSet |= AVMediaSetMask::STATE; diff --git a/include/avmedia/mediaitem.hxx b/include/avmedia/mediaitem.hxx index ab9418607cb7..9578974aaa99 100644 --- a/include/avmedia/mediaitem.hxx +++ b/include/avmedia/mediaitem.hxx @@ -32,6 +32,7 @@ namespace com::sun::star::embed { class XStorage; } namespace com::sun::star::frame { class XModel; } namespace com::sun::star::io { class XInputStream; } namespace com::sun::star::io { class XStream; } +namespace com::sun::star::text { struct GraphicCrop; } class Graphic; enum class AVMediaSetMask @@ -47,11 +48,12 @@ enum class AVMediaSetMask URL = 0x080, MIME_TYPE = 0x100, GRAPHIC = 0x200, - ALL = 0x3ff, + CROP = 0x400, + ALL = 0x7ff, }; namespace o3tl { - template<> struct typed_flags<AVMediaSetMask> : is_typed_flags<AVMediaSetMask, 0x3ff> {}; + template<> struct typed_flags<AVMediaSetMask> : is_typed_flags<AVMediaSetMask, 0x7ff> {}; } @@ -119,6 +121,8 @@ public: OUString getMimeType() const; bool setGraphic(const Graphic& rGraphic); const Graphic & getGraphic() const; + bool setCrop(const css::text::GraphicCrop& rCrop); + const css::text::GraphicCrop& getCrop() const; const OUString& getTempURL() const; const OUString& getReferer() const; diff --git a/svx/source/svdraw/svdomedia.cxx b/svx/source/svdraw/svdomedia.cxx index 96d12027a060..cb78eee47766 100644 --- a/svx/source/svdraw/svdomedia.cxx +++ b/svx/source/svdraw/svdomedia.cxx @@ -21,6 +21,8 @@ #include <svx/svdomedia.hxx> +#include <com/sun/star/text/GraphicCrop.hpp> + #include <rtl/ustring.hxx> #include <rtl/ustrbuf.hxx> #include <sal/log.hxx> @@ -146,6 +148,20 @@ uno::Reference< graphic::XGraphic > const & SdrMediaObj::getSnapshot() const Graphic aGraphic = m_xImpl->m_MediaProperties.getGraphic(); if (!aGraphic.IsNone()) { + Size aPref = aGraphic.GetPrefSize(); + Size aPixel = aGraphic.GetSizePixel(); + const text::GraphicCrop& rCrop = m_xImpl->m_MediaProperties.getCrop(); + if (rCrop.Bottom > 0 || rCrop.Left > 0 || rCrop.Right > 0 || rCrop.Top > 0) + { + tools::Long nLeft = aPixel.getWidth() * rCrop.Left / aPref.getWidth(); + tools::Long nTop = aPixel.getHeight() * rCrop.Top / aPref.getHeight(); + tools::Long nRight = aPixel.getWidth() * rCrop.Right / aPref.getWidth(); + tools::Long nBottom = aPixel.getHeight() * rCrop.Bottom / aPref.getHeight(); + BitmapEx aBitmapEx = aGraphic.GetBitmapEx(); + aBitmapEx.Crop({nLeft, nTop, aPixel.getWidth() - nRight, aPixel.getHeight() - nBottom}); + aGraphic = aBitmapEx; + } + // We have an explicit graphic for this media object, then go with that instead of // generating our own one. m_xImpl->m_xCachedSnapshot = aGraphic.GetXGraphic(); @@ -338,6 +354,11 @@ void SdrMediaObj::mediaPropertiesChanged( const ::avmedia::MediaItem& rNewProper m_xImpl->m_MediaProperties.setGraphic(rNewProperties.getGraphic()); } + if (nMaskSet & AVMediaSetMask::CROP) + { + m_xImpl->m_MediaProperties.setCrop(rNewProperties.getCrop()); + } + if( ( AVMediaSetMask::URL & nMaskSet ) && ( rNewProperties.getURL() != getURL() )) { diff --git a/svx/source/unodraw/unoprov.cxx b/svx/source/unodraw/unoprov.cxx index b459280c8b01..55631bdbc200 100644 --- a/svx/source/unodraw/unoprov.cxx +++ b/svx/source/unodraw/unoprov.cxx @@ -736,6 +736,7 @@ static SfxItemPropertyMapEntry const * ImplGetSvxMediaShapePropertyMap() { u"MediaMimeType", OWN_ATTR_MEDIA_MIMETYPE, cppu::UnoType<OUString>::get(), 0, 0}, { u"FallbackGraphic", OWN_ATTR_FALLBACK_GRAPHIC, cppu::UnoType<css::graphic::XGraphic>::get(), css::beans::PropertyAttribute::READONLY, 0}, { u"" UNO_NAME_GRAPHOBJ_GRAPHIC, OWN_ATTR_VALUE_GRAPHIC , cppu::UnoType<css::graphic::XGraphic>::get(), 0, 0}, + { u"" UNO_NAME_GRAPHIC_GRAPHICCROP, SDRATTR_GRAFCROP , cppu::UnoType<css::text::GraphicCrop>::get(), 0, 0}, { u"", 0, css::uno::Type(), 0, 0 } }; diff --git a/svx/source/unodraw/unoshap4.cxx b/svx/source/unodraw/unoshap4.cxx index 865ce0a3ee5b..50a2a7a09a12 100644 --- a/svx/source/unodraw/unoshap4.cxx +++ b/svx/source/unodraw/unoshap4.cxx @@ -783,7 +783,8 @@ bool SvxMediaShape::setPropertyValueImpl( const OUString& rName, const SfxItemPr if( ((pProperty->nWID >= OWN_ATTR_MEDIA_URL) && (pProperty->nWID <= OWN_ATTR_MEDIA_ZOOM)) || (pProperty->nWID == OWN_ATTR_MEDIA_STREAM) || (pProperty->nWID == OWN_ATTR_MEDIA_MIMETYPE) - || (pProperty->nWID == OWN_ATTR_VALUE_GRAPHIC)) + || (pProperty->nWID == OWN_ATTR_VALUE_GRAPHIC) + || (pProperty->nWID == SDRATTR_GRAFCROP)) { SdrMediaObj* pMedia = static_cast< SdrMediaObj* >( GetSdrObject() ); ::avmedia::MediaItem aItem; @@ -886,6 +887,19 @@ bool SvxMediaShape::setPropertyValueImpl( const OUString& rName, const SfxItemPr #endif break; + case SDRATTR_GRAFCROP: +#if HAVE_FEATURE_AVMEDIA + { + text::GraphicCrop aCrop; + if (rValue >>= aCrop) + { + bOk = true; + aItem.setCrop(aCrop); + } + } +#endif + break; + case OWN_ATTR_MEDIA_STREAM: #if HAVE_FEATURE_AVMEDIA try @@ -942,7 +956,8 @@ bool SvxMediaShape::getPropertyValueImpl( const OUString& rName, const SfxItemPr || (pProperty->nWID == OWN_ATTR_MEDIA_TEMPFILEURL) || (pProperty->nWID == OWN_ATTR_MEDIA_MIMETYPE) || (pProperty->nWID == OWN_ATTR_FALLBACK_GRAPHIC) - || (pProperty->nWID == OWN_ATTR_VALUE_GRAPHIC)) + || (pProperty->nWID == OWN_ATTR_VALUE_GRAPHIC) + || (pProperty->nWID == SDRATTR_GRAFCROP)) { SdrMediaObj* pMedia = static_cast< SdrMediaObj* >( GetSdrObject() ); const ::avmedia::MediaItem aItem( pMedia->getMediaProperties() ); @@ -1025,6 +1040,15 @@ bool SvxMediaShape::getPropertyValueImpl( const OUString& rName, const SfxItemPr #endif break; + case SDRATTR_GRAFCROP: +#if HAVE_FEATURE_AVMEDIA + { + text::GraphicCrop aCrop = aItem.getCrop(); + rValue <<= aCrop; + } +#endif + break; + case OWN_ATTR_FALLBACK_GRAPHIC: rValue <<= pMedia->getSnapshot(); break; -- 2.35.3 From 6894da107db06c66356e52844c4a8d263e0a64d8 Mon Sep 17 00:00:00 2001 From: Miklos Vajna <vmiklos@collabora.com> Date: Fri, 26 Aug 2022 10:24:39 +0200 Subject: [PATCH] tdf#149971 avmedia: implement video crop support in the gsteamer backend If a media shape had cropping defined, we already took that into account when presenting a preview for it, but not during video playback. The reason for this is that the preview may be set by a file importer (e.g. PPTX) explicitly, in which case the preview is a bitmap we get without any video processing. As a start, implement video crop for the gstreamer backend (used on Linux), and also pass in the media item (containing crop and other properties) both during the edit view (MediaWindowImpl) and presenting (ViewMediaShape). We pass in the whole media item, so in case later other filters (e.g. black-and-white) are wanted, we have all that info in the backends already. Other backends (avmediaMacAVF and avmediawin) are untouched so far. svx/qa/unit/data/video-snapshot.pptx is modified to have a yellow border when cropping is unimplemented, which is now not visible with the gtreamer backend, matching PowerPoint behavior. PPTX export was working out of the box already. (cherry picked from commit 916848d877a788d02e2e7c980872314839101798) Conflicts: avmedia/source/viewer/mediawindow_impl.cxx Change-Id: If26b7a4391bcffe9cbddd9933e1bab69be52924e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138969 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com> --- avmedia/Library_avmediagst.mk | 1 + avmedia/source/gstreamer/gstplayer.cxx | 30 ++++++++++++++++++ avmedia/source/viewer/mediawindow_impl.cxx | 8 ++++- avmedia/source/viewer/mediawindow_impl.hxx | 1 + .../source/engine/shapes/viewmediashape.cxx | 14 +++++++- 7 files changed, 54 insertions(+), 4 deletions(-) diff --git a/avmedia/Library_avmediagst.mk b/avmedia/Library_avmediagst.mk index 699d0197b50e..93ad7514f94b 100644 --- a/avmedia/Library_avmediagst.mk +++ b/avmedia/Library_avmediagst.mk @@ -33,6 +33,7 @@ $(eval $(call gb_Library_use_libraries,avmediagst,\ salhelper \ tl \ vcl \ + avmedia \ )) $(eval $(call gb_Library_add_exception_objects,avmediagst,\ diff --git a/avmedia/source/gstreamer/gstplayer.cxx b/avmedia/source/gstreamer/gstplayer.cxx index 397fe8809d93..6884654b6be3 100644 --- a/avmedia/source/gstreamer/gstplayer.cxx +++ b/avmedia/source/gstreamer/gstplayer.cxx @@ -29,6 +29,8 @@ #include <vector> #include <math.h> +#include <com/sun/star/text/GraphicCrop.hpp> + #include <cppuhelper/supportsservice.hxx> #include <sal/log.hxx> #include <rtl/string.hxx> @@ -36,6 +38,8 @@ #include <vcl/svapp.hxx> #include <vcl/syschild.hxx> #include <vcl/sysdata.hxx> +#include <vcl/graph.hxx> +#include <avmedia/mediaitem.hxx> #include "gstplayer.hxx" #include "gstframegrabber.hxx" @@ -866,6 +870,32 @@ uno::Reference< ::media::XPlayerWindow > SAL_CALL Player::createPlayerWindow( co g_object_set(G_OBJECT(mpPlaybin), "video-sink", pVideosink, nullptr); g_object_set(G_OBJECT(mpPlaybin), "force-aspect-ratio", FALSE, nullptr); + if ((rArguments.getLength() >= 4) && (rArguments[3] >>= pIntPtr) && pIntPtr) + { + auto pItem = reinterpret_cast<const avmedia::MediaItem*>(pIntPtr); + Graphic aGraphic = pItem->getGraphic(); + const text::GraphicCrop& rCrop = pItem->getCrop(); + if (!aGraphic.IsNone() && (rCrop.Bottom > 0 || rCrop.Left > 0 || rCrop.Right > 0 || rCrop.Top > 0)) + { + // The media item has a non-empty cropping set. Try to crop the video accordingly. + Size aPref = aGraphic.GetPrefSize(); + Size aPixel = aGraphic.GetSizePixel(); + tools::Long nLeft = aPixel.getWidth() * rCrop.Left / aPref.getWidth(); + tools::Long nTop = aPixel.getHeight() * rCrop.Top / aPref.getHeight(); + tools::Long nRight = aPixel.getWidth() * rCrop.Right / aPref.getWidth(); + tools::Long nBottom = aPixel.getHeight() * rCrop.Bottom / aPref.getHeight(); + GstElement* pVideoFilter = gst_element_factory_make("videocrop", nullptr); + if (pVideoFilter) + { + g_object_set(G_OBJECT(pVideoFilter), "left", nLeft, nullptr); + g_object_set(G_OBJECT(pVideoFilter), "top", nTop, nullptr); + g_object_set(G_OBJECT(pVideoFilter), "right", nRight, nullptr); + g_object_set(G_OBJECT(pVideoFilter), "bottom", nBottom, nullptr); + g_object_set(G_OBJECT(mpPlaybin), "video-filter", pVideoFilter, nullptr); + } + } + } + if (!mbUseGtkSink) { mnWindowID = pEnvData->GetWindowHandle(pParentWindow->ImplGetFrame()); diff --git a/avmedia/source/viewer/mediawindow_impl.cxx b/avmedia/source/viewer/mediawindow_impl.cxx index fcc06488e913..0a0e80dc0d3f 100644 --- a/avmedia/source/viewer/mediawindow_impl.cxx +++ b/avmedia/source/viewer/mediawindow_impl.cxx @@ -30,6 +30,7 @@ #include <sal/log.hxx> #include <comphelper/processfactory.hxx> #include <tools/diagnose_ex.h> +#include <comphelper/scopeguard.hxx> #include <tools/urlobj.hxx> #include <unotools/securityoptions.hxx> #include <vcl/bitmapex.hxx> @@ -307,6 +308,9 @@ void MediaWindowImpl::updateMediaItem( MediaItem& rItem ) const void MediaWindowImpl::executeMediaItem( const MediaItem& rItem ) { + mpItem = &rItem; + comphelper::ScopeGuard g([this] { this->mpItem = nullptr; }); + const AVMediaSetMask nMaskSet = rItem.getMaskSet(); // set URL first @@ -427,7 +431,9 @@ void MediaWindowImpl::onURLChanged() uno::Sequence<uno::Any> aArgs{ uno::Any(nParentWindowHandle), uno::Any(awt::Rectangle(aPoint.X(), aPoint.Y(), aSize.Width(), aSize.Height())), - uno::Any(reinterpret_cast<sal_IntPtr>(mpChildWindow.get())) + uno::Any(reinterpret_cast<sal_IntPtr>(mpChildWindow.get())), + // Media item contains media properties, e.g. cropping. + uno::Any(reinterpret_cast<sal_IntPtr>(mpItem)) }; try diff --git a/avmedia/source/viewer/mediawindow_impl.hxx b/avmedia/source/viewer/mediawindow_impl.hxx index 8bceebb08d15..aa95fde22444 100644 --- a/avmedia/source/viewer/mediawindow_impl.hxx +++ b/avmedia/source/viewer/mediawindow_impl.hxx @@ -150,6 +150,7 @@ private: VclPtr<MediaWindowControl> mpMediaWindowControl; std::unique_ptr<BitmapEx> mpEmptyBmpEx; std::unique_ptr<BitmapEx> mpAudioBmpEx; + const MediaItem* mpItem = nullptr; }; }} // end namespace avmedia::priv diff --git a/slideshow/source/engine/shapes/viewmediashape.cxx b/slideshow/source/engine/shapes/viewmediashape.cxx index 52a86be889d7..0b24b12b2812 100644 --- a/slideshow/source/engine/shapes/viewmediashape.cxx +++ b/slideshow/source/engine/shapes/viewmediashape.cxx @@ -36,6 +36,8 @@ #include <canvas/canvastools.hxx> #include <cppcanvas/canvas.hxx> #include <avmedia/mediawindow.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdomedia.hxx> #include <com/sun/star/awt/XWindow.hpp> #include <com/sun/star/beans/XPropertySet.hpp> @@ -441,10 +443,20 @@ namespace slideshow::internal aAWTRect.X = aAWTRect.Y = 0; + SdrObject* pObj = SdrObject::getSdrObjectFromXShape(mxShape); + auto pMediaObj = dynamic_cast<SdrMediaObj*>(pObj); + const avmedia::MediaItem* pMediaItem = nullptr; + if (pMediaObj) + { + pMediaItem = &pMediaObj->getMediaProperties(); + } + uno::Sequence< uno::Any > aArgs{ uno::Any(nParentWindowHandle), uno::Any(aAWTRect), - uno::Any(reinterpret_cast< sal_IntPtr >( mpMediaWindow.get() )) + uno::Any(reinterpret_cast< sal_IntPtr >( mpMediaWindow.get() )), + // Media item contains media properties, e.g. cropping. + uno::Any(reinterpret_cast< sal_IntPtr >( pMediaItem )) }; mxPlayerWindow.set( mxPlayer->createPlayerWindow( aArgs ) ); -- 2.35.3 From 3b88c304dce2e9d64b9d19b25ed57df5b581e834 Mon Sep 17 00:00:00 2001 From: Miklos Vajna <vmiklos@collabora.com> 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. (cherry picked from commit cbc6e67d3c88fb6ae39c304604a98eaa504f19cc) Conflicts: xmloff/qa/unit/draw.cxx xmloff/source/draw/shapeexport.cxx Change-Id: I6115284c1f4cf342b3296cd0ac3beb70a809fd1b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138970 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com> --- include/svx/unoshape.hxx | 2 + svx/source/unodraw/unoshap4.cxx | 25 ++++++++++++ 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 3d3d5bea3a9b..b8d50458a4a1 100644 --- a/include/svx/unoshape.hxx +++ b/include/svx/unoshape.hxx @@ -843,6 +843,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 50a2a7a09a12..a5f2516161ac 100644 --- a/svx/source/unodraw/unoshap4.cxx +++ b/svx/source/unodraw/unoshap4.cxx @@ -1064,4 +1064,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<SdrMediaObj*>(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/source/draw/shapeexport.cxx b/xmloff/source/draw/shapeexport.cxx index d47ea15b2758..0f3e86ee8d5a 100644 --- a/xmloff/source/draw/shapeexport.cxx +++ b/xmloff/source/draw/shapeexport.cxx @@ -99,6 +99,7 @@ #include <tools/globname.hxx> #include <tools/helpers.hxx> #include <tools/diagnose_ex.h> +#include <vcl/graph.hxx> #include <xmloff/contextid.hxx> #include <xmloff/families.hxx> @@ -3387,7 +3388,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<SvXMLElementExport>(mrExport, XML_NAMESPACE_DRAW, XML_PLUGIN, !( nFeatures & XMLShapeExportFlags::NO_WS ), true); // export parameters const OUString aFalseStr( "false" ), aTrueStr( "true" ); @@ -3437,6 +3438,57 @@ void XMLShapeExport::ImpExportMediaShape( delete new SvXMLElementExport( mrExport, XML_NAMESPACE_DRAW, XML_PARAM, false, true ); } + pPluginOBJ.reset(); + + uno::Reference<graphic::XGraphic> xGraphic; + xPropSet->getPropertyValue("Graphic") >>= xGraphic; + Graphic aGraphic(xGraphic); + if (!aGraphic.IsNone()) + { + // The media has a preview, export it. + uno::Reference<embed::XStorage> xPictureStorage; + uno::Reference<embed::XStorage> xStorage; + uno::Reference<io::XStream> 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<uno::XComponentContext> xContext = GetExport().getComponentContext(); + uno::Reference<graphic::XGraphicProvider> xProvider( + graphic::GraphicProvider::create(xContext)); + uno::Sequence<beans::PropertyValue> aArgs{ + comphelper::makePropertyValue("MimeType", OUString("image/png")), + comphelper::makePropertyValue("OutputStream", xPictureStream->getOutputStream()) + }; + xProvider->storeGraphic(xGraphic, aArgs); + if (xPictureStorage.is()) + { + uno::Reference<embed::XTransactedObject> 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 76ca2c4fe4d9..442116980270 100644 --- a/xmloff/source/draw/ximpshap.cxx +++ b/xmloff/source/draw/ximpshap.cxx @@ -2908,6 +2908,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) @@ -3302,6 +3308,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 ) { @@ -3311,10 +3318,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())) -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor