comphelper/source/misc/lok.cxx | 12 desktop/inc/lib/init.hxx | 2 drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx | 4 drawinglayer/source/processor2d/baseprocessor2d.cxx | 3 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx | 4 drawinglayer/source/tools/primitive2dxmldump.cxx | 14 include/comphelper/lok.hxx | 4 include/svx/svdobj.hxx | 4 sd/CppunitTest_sd_tiledrendering.mk | 1 sd/qa/unit/AnnotationTest.cxx | 31 sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_Group.odp |binary sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_Groups.odp |binary sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_MultiLevel_Group.odp |binary sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_Shape_Inside_A_Group.odp |binary sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animations_DifferentKindOfTextBox.odp |binary sd/qa/unit/tiledrendering/data/SlideRenderingTest_SlideNumber_Header_DateTime.odp |binary sd/qa/unit/tiledrendering/data/SlideRenderingTest_WithFields.odp |binary sd/qa/unit/tiledrendering/tiledrendering.cxx | 1416 ++++++++-- sd/source/ui/inc/SlideshowLayerRenderer.hxx | 128 sd/source/ui/inc/unomodel.hxx | 4 sd/source/ui/tools/SlideshowLayerRenderer.cxx | 713 ++++- sd/source/ui/unoidl/unomodel.cxx | 211 + 22 files changed, 2070 insertions(+), 481 deletions(-)
New commits: commit e0c836d84245afccd8aa52c5a1ad6242d8f711f5 Author: Marco Cecchetti <marco.cecche...@collabora.com> AuthorDate: Mon Mar 10 15:50:10 2025 +0100 Commit: Marco Cecchetti <marco.cecche...@collabora.com> CommitDate: Tue Mar 11 18:48:24 2025 +0100 lok: slideshow: regression: background not hidden for animated paragraph The layer for an animated paragraph included the backgound, too. It seems that in co 25.04 text primitive structure is changed. There is a group wrapping polygon and text primitives. Non-solid backgrounds seem to use the POLYPOLYGONRGBA primitive, now. Change-Id: I9fe548aacea1bf8a489befdd1a98d5fd5cb6609f diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx b/sd/source/ui/tools/SlideshowLayerRenderer.cxx index 2f2e271cae1a..9e080a893138 100644 --- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx +++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx @@ -165,17 +165,24 @@ bool isGroup(SdrObject* pObject) { return pObject->getChildrenOfSdrObject() != n /// Sets visible for all kinds of polypolys in the container void changePolyPolys( - drawinglayer::primitive2d::Primitive2DContainer& rContainer, bool bRenderObject, + const drawinglayer::primitive2d::Primitive2DContainer& rContainer, bool bRenderObject, std::vector<drawinglayer::primitive2d::Primitive2DReference>& rPrimitivesToUnhide) { for (auto& pBasePrimitive : rContainer) { - if (pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D + if (pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_GROUPPRIMITIVE2D) + { + auto& rGroupPrimitive = static_cast<drawinglayer::primitive2d::GroupPrimitive2D&>(*(pBasePrimitive.get())); + const drawinglayer::primitive2d::Primitive2DContainer& rChildren = rGroupPrimitive.getChildren(); + changePolyPolys(rChildren, bRenderObject, rPrimitivesToUnhide); + } + else if (pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONHAIRLINEPRIMITIVE2D - || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D) + || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D + || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONRGBAPRIMITIVE2D) { pBasePrimitive->setVisible(bRenderObject); if (!bRenderObject) commit 9c76c18fe9e949d00ddee411ade40869480d217a Author: Marco Cecchetti <marco.cecche...@collabora.com> AuthorDate: Sun Mar 9 10:50:56 2025 +0100 Commit: Marco Cecchetti <marco.cecche...@collabora.com> CommitDate: Tue Mar 11 18:48:24 2025 +0100 lok: slideshow: regression: mismatching slide hash Slide hash generated by getPresentationInfo and by renderNextSlideLayer didn't match Change-Id: Iba15828f486f4d29700eee19f8a5438884bfb8ab diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx index 44b04136d926..62e2d17ab01a 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx @@ -43,6 +43,7 @@ #include <sdpage.hxx> #include <undo/undomanager.hxx> #include <sfx2/request.hxx> +#include <unopage.hxx> #include <svx/svxids.hrc> #include <pres.hxx> @@ -2823,6 +2824,24 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testPresentationInfo) namespace { +std::string GetSlideHash(SdXImpressDocument* pDoc, sal_Int32 nSlideNumber) +{ + try + { + rtl::Reference<SdDrawPagesAccess> xDrawPages = pDoc->getSdDrawPages(); + SdGenericDrawPage* pSlide(xDrawPages->getDrawPageByIndex(nSlideNumber)); + if (pSlide) + { + return GetInterfaceHash(cppu::getXWeak(pSlide)); + } + } + catch (uno::Exception&) + { + CPPUNIT_FAIL("SdXImpressDocument::createLOKSlideRenderer: failed"); + } + return {}; +} + class SlideRendererChecker { private: @@ -2848,7 +2867,7 @@ public: SdPage* pPage = pDoc->GetSdPage(sal_uInt16(mnSlideNumber), PageKind::Standard); CPPUNIT_ASSERT(pPage); - std::string sHash = GetInterfaceHash(GetXDrawPageForSdrPage(pPage)); + std::string sHash = GetSlideHash(mpXImpressDocument, mnSlideNumber); CPPUNIT_ASSERT(mpXImpressDocument->createSlideRenderer( sHash.c_str(), mnSlideNumber, mnViewWidth, mnViewHeight, bRenderBackground, bRenderMasterPage)); @@ -3028,7 +3047,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering) CPPUNIT_ASSERT(pViewShell); SdPage* pPage = pViewShell->GetActualPage(); CPPUNIT_ASSERT(pPage); - std::string sHash = GetInterfaceHash(GetXDrawPageForSdrPage(pPage)); + std::string sHash = GetSlideHash(pXImpressDocument, 0); sal_Int32 nViewWidth = 2000; sal_Int32 nViewHeight = 2000; CPPUNIT_ASSERT(pXImpressDocument->createSlideRenderer(sHash.c_str(), 0, nViewWidth, nViewHeight, true, true)); @@ -3146,7 +3165,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_WithFie SdPage* pPage = pViewShell->GetActualPage(); CPPUNIT_ASSERT(pPage); - std::string sHash = GetInterfaceHash(GetXDrawPageForSdrPage(pPage)); + std::string sHash = GetSlideHash(pXImpressDocument, 0); sal_Int32 nViewWidth = 2000; sal_Int32 nViewHeight = 2000; CPPUNIT_ASSERT(pXImpressDocument->createSlideRenderer(sHash.c_str(), 0, nViewWidth, nViewHeight, true, true)); @@ -3526,7 +3545,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati CPPUNIT_ASSERT(pViewShell); SdPage* pPage = pViewShell->GetActualPage(); CPPUNIT_ASSERT(pPage); - std::string sHash = GetInterfaceHash(GetXDrawPageForSdrPage(pPage)); + std::string sHash = GetSlideHash(pXImpressDocument, 0); sal_Int32 nViewWidth = 2000; sal_Int32 nViewHeight = 2000; CPPUNIT_ASSERT(pXImpressDocument->createSlideRenderer(sHash.c_str(), 0, nViewWidth, nViewHeight, true, true)); @@ -3700,7 +3719,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati CPPUNIT_ASSERT(pPage); sal_Int32 nViewWidth = 2000; sal_Int32 nViewHeight = 2000; - std::string sHash = GetInterfaceHash(GetXDrawPageForSdrPage(pPage)); + std::string sHash = GetSlideHash(pXImpressDocument, 0); CPPUNIT_ASSERT(pXImpressDocument->createSlideRenderer(sHash.c_str(), 0, nViewWidth, nViewHeight, true, true)); CPPUNIT_ASSERT_EQUAL(2000, nViewWidth); CPPUNIT_ASSERT_EQUAL(1125, nViewHeight); @@ -3961,7 +3980,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati sal_Int32 nViewWidth = 2000; sal_Int32 nViewHeight = 2000; - std::string sHash = GetInterfaceHash(GetXDrawPageForSdrPage(pPage)); + std::string sHash = GetSlideHash(pXImpressDocument, 0); CPPUNIT_ASSERT(pXImpressDocument->createSlideRenderer(sHash.c_str(), 0, nViewWidth, nViewHeight, true, true)); CPPUNIT_ASSERT_EQUAL(2000, nViewWidth); CPPUNIT_ASSERT_EQUAL(1125, nViewHeight); @@ -4128,7 +4147,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati sal_Int32 nViewWidth = 2000; sal_Int32 nViewHeight = 2000; - std::string sHash = GetInterfaceHash(GetXDrawPageForSdrPage(pPage)); + std::string sHash = GetSlideHash(pXImpressDocument, 0); CPPUNIT_ASSERT(pXImpressDocument->createSlideRenderer(sHash.c_str(), 0, nViewWidth, nViewHeight, true, true)); CPPUNIT_ASSERT_EQUAL(2000, nViewWidth); CPPUNIT_ASSERT_EQUAL(1125, nViewHeight); @@ -4233,7 +4252,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati sal_Int32 nViewWidth = 2000; sal_Int32 nViewHeight = 2000; - std::string sHash = GetInterfaceHash(GetXDrawPageForSdrPage(pPage)); + std::string sHash = GetSlideHash(pXImpressDocument, 0); CPPUNIT_ASSERT(pXImpressDocument->createSlideRenderer(sHash.c_str(), 0, nViewWidth, nViewHeight, true, true)); CPPUNIT_ASSERT_EQUAL(2000, nViewWidth); CPPUNIT_ASSERT_EQUAL(1500, nViewHeight); diff --git a/sd/source/ui/inc/SlideshowLayerRenderer.hxx b/sd/source/ui/inc/SlideshowLayerRenderer.hxx index 39994d0ceb85..b701293deefb 100644 --- a/sd/source/ui/inc/SlideshowLayerRenderer.hxx +++ b/sd/source/ui/inc/SlideshowLayerRenderer.hxx @@ -167,6 +167,7 @@ class SD_DLLPUBLIC SlideshowLayerRenderer { private: SdrPage& mrPage; + OString msSlideHash; SdrModel& mrModel; Size maSlideSize; RenderState maRenderState; @@ -184,7 +185,8 @@ private: void cleanup(); public: - SlideshowLayerRenderer(SdrPage& rPage, bool bRenderBackground, bool bRenderMasterPage); + SlideshowLayerRenderer(SdrPage& rPage, const OString& rSlideHash, + bool bRenderBackground, bool bRenderMasterPage); /** Calculate and set the slide size depending on input desired size (in pixels) * diff --git a/sd/source/ui/inc/unomodel.hxx b/sd/source/ui/inc/unomodel.hxx index c4bb88802821..953f454afa36 100644 --- a/sd/source/ui/inc/unomodel.hxx +++ b/sd/source/ui/inc/unomodel.hxx @@ -312,7 +312,7 @@ public: /// @see vcl::ITiledRenderable::renderNextSlideLayer(). SD_DLLPUBLIC bool renderNextSlideLayer(unsigned char* pBuffer, bool& bIsBitmapLayer, double& rScale, OUString& rJsonMsg) override; - rtl::Reference< SdDrawPagesAccess > getSdDrawPages(); + SD_DLLPUBLIC rtl::Reference< SdDrawPagesAccess > getSdDrawPages(); // XComponent @@ -366,7 +366,7 @@ public: virtual void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) override; virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener ) override; - SdGenericDrawPage* getDrawPageByIndex( sal_Int32 Index ); + SD_DLLPUBLIC SdGenericDrawPage* getDrawPageByIndex( sal_Int32 Index ); }; /*********************************************************************** diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx b/sd/source/ui/tools/SlideshowLayerRenderer.cxx index e73fef4b8bee..2f2e271cae1a 100644 --- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx +++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx @@ -628,9 +628,11 @@ SdrObject* getObjectForShape(uno::Reference<drawing::XShape> const& xShape) } // end anonymous namespace -SlideshowLayerRenderer::SlideshowLayerRenderer(SdrPage& rPage, bool bRenderBackground, +SlideshowLayerRenderer::SlideshowLayerRenderer(SdrPage& rPage, const OString& rSlideHash, + bool bRenderBackground, bool bRenderMasterPage) : mrPage(rPage) + , msSlideHash(rSlideHash) , mrModel(rPage.getSdrModelFromSdrPage()) , mbRenderBackground(bRenderBackground) , mbRenderMasterPage(bRenderMasterPage) @@ -906,7 +908,7 @@ void SlideshowLayerRenderer::writeBackgroundJSON(OString& rJsonMsg) ::tools::JsonWriter aJsonWriter; aJsonWriter.put("group", maRenderState.stageString()); aJsonWriter.put("index", maRenderState.currentIndex()); - aJsonWriter.put("slideHash", GetInterfaceHash(GetXDrawPageForSdrPage(&mrPage))); + aJsonWriter.put("slideHash", msSlideHash); aJsonWriter.put("type", "bitmap"); writeContentNode(aJsonWriter); rJsonMsg = aJsonWriter.finishAndGetAsOString(); @@ -918,7 +920,7 @@ void SlideshowLayerRenderer::writeJSON(OString& rJsonMsg, RenderPass const& rRen ::tools::JsonWriter aJsonWriter; aJsonWriter.put("group", maRenderState.stageString()); aJsonWriter.put("index", maRenderState.currentIndex()); - aJsonWriter.put("slideHash", GetInterfaceHash(GetXDrawPageForSdrPage(&mrPage))); + aJsonWriter.put("slideHash", msSlideHash); SdrObject* pObject = rRenderPass.mpObject; sal_Int32 nParagraph = rRenderPass.mnParagraph; diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx index e8cb36b3cc53..f99ef80cf642 100644 --- a/sd/source/ui/unoidl/unomodel.cxx +++ b/sd/source/ui/unoidl/unomodel.cxx @@ -4833,12 +4833,12 @@ bool isRequestedSlideValid(SdDrawDocument* mpDoc, sal_Int32 nSlideNumber, const { try { - uno::Reference<drawing::XDrawPagesSupplier> xDrawPages(getXWeak(mpDoc->getUnoModel()), uno::UNO_QUERY_THROW); - uno::Reference<container::XIndexAccess> xSlides(xDrawPages->getDrawPages(), uno::UNO_QUERY_THROW); - uno::Reference<drawing::XDrawPage> xSlide(xSlides->getByIndex(nSlideNumber), uno::UNO_QUERY_THROW); - if (xSlide.is()) + SdXImpressDocument* pDoc = mpDoc->getUnoModel(); + rtl::Reference<SdDrawPagesAccess> xDrawPages = pDoc->getSdDrawPages(); + SdGenericDrawPage* pSlide(xDrawPages->getDrawPageByIndex(nSlideNumber)); + if (pSlide) { - return slideHash == GetInterfaceHash(xSlide); + return slideHash == GetInterfaceHash(cppu::getXWeak(pSlide)); } } catch (uno::Exception&) @@ -4862,7 +4862,7 @@ bool SdXImpressDocument::createSlideRenderer( if (!pPage) return false; - mpSlideshowLayerRenderer.reset(new SlideshowLayerRenderer(*pPage, bRenderBackground, bRenderMasterPage)); + mpSlideshowLayerRenderer.reset(new SlideshowLayerRenderer(*pPage, rSlideHash, bRenderBackground, bRenderMasterPage)); Size aDesiredSize(nViewWidth, nViewHeight); Size aCalculatedSize = mpSlideshowLayerRenderer->calculateAndSetSizePixel(aDesiredSize); nViewWidth = aCalculatedSize.Width(); commit 8b91248c08dd4be64dd6b68bdb8a00fb0eedb4f4 Author: Marco Cecchetti <marco.cecche...@collabora.com> AuthorDate: Wed Mar 5 23:15:33 2025 +0100 Commit: Marco Cecchetti <marco.cecche...@collabora.com> CommitDate: Tue Mar 11 18:48:24 2025 +0100 slideshow: regression: layer with paragraph has not the expected content In co-25.04 CairoPixelProcessor2D is used in place of VclPixelProcessor2D that causes the visibility setting to be not taken into account. This patch fixes the problem by checking for the visibility setting at a higher level. Change-Id: I850c6922cdd358eee35074fbff04f238994b2c76 diff --git a/drawinglayer/source/processor2d/baseprocessor2d.cxx b/drawinglayer/source/processor2d/baseprocessor2d.cxx index 437faa3a5016..8209ca00f0fb 100644 --- a/drawinglayer/source/processor2d/baseprocessor2d.cxx +++ b/drawinglayer/source/processor2d/baseprocessor2d.cxx @@ -62,7 +62,8 @@ namespace drawinglayer::processor2d { for (const primitive2d::Primitive2DReference& rCandidate : rSource) { - if (rCandidate) + // Skip, if not visible + if (rCandidate && rCandidate->getVisible()) processBasePrimitive2D(*rCandidate); } } diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index 98182a43a758..3264cdfc2a4a 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -192,10 +192,6 @@ bool VclPixelProcessor2D::tryDrawPolygonStrokePrimitive2DDirect( void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) { - // Skip, if not visible - if (!rCandidate.getVisible()) - return; - switch (rCandidate.getPrimitive2DID()) { case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D: commit ac4d225d3d54d4bb5e5d1fa7b3ac43c207c2c9de Author: Henry Castro <hcas...@collabora.com> AuthorDate: Mon Dec 16 07:42:05 2024 -0400 Commit: Marco Cecchetti <marco.cecche...@collabora.com> CommitDate: Tue Mar 11 18:48:24 2025 +0100 lokit: add scale parameter to "renderNextSlideLayer" When client side change the device pixel ratio. Signed-off-by: Henry Castro <hcas...@collabora.com> Change-Id: I6356ff2a2e6513ac835b5f02a755173aafe01dc9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178580 Reviewed-by: Marco Cecchetti <marco.cecche...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index fefcc5df8891..7e5f864e862a 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -1343,7 +1343,7 @@ static bool doc_createSlideRenderer( static void doc_postSlideshowCleanup(LibreOfficeKitDocument* pThis); static bool doc_renderNextSlideLayer( - LibreOfficeKitDocument* pThis, unsigned char* pBuffer, bool* bIsBitmapLayer, char** pJsonMsg); + LibreOfficeKitDocument* pThis, unsigned char* pBuffer, bool* bIsBitmapLayer, double* pScale, char** pJsonMsg); static void doc_setViewOption(LibreOfficeKitDocument* pDoc, const char* pOption, const char* pValue); @@ -5724,7 +5724,7 @@ static void doc_postSlideshowCleanup(LibreOfficeKitDocument* pThis) } static bool doc_renderNextSlideLayer( - LibreOfficeKitDocument* pThis, unsigned char* pBuffer, bool* pIsBitmapLayer, char** pJsonMessage) + LibreOfficeKitDocument* pThis, unsigned char* pBuffer, bool* pIsBitmapLayer, double* pScale, char** pJsonMessage) { SolarMutexGuard aGuard; SetLastExceptionMsg(); @@ -5737,7 +5737,7 @@ static bool doc_renderNextSlideLayer( } OUString sJsonMesssage; bool bIsBitmapLayer = false; - bool bDone = pDoc->renderNextSlideLayer(pBuffer, bIsBitmapLayer, sJsonMesssage); + bool bDone = pDoc->renderNextSlideLayer(pBuffer, bIsBitmapLayer, *pScale, sJsonMesssage); if (pJsonMessage) *pJsonMessage = convertOUString(sJsonMesssage); diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h index f8f64bc48652..66ff0418e326 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.h +++ b/include/LibreOfficeKit/LibreOfficeKit.h @@ -554,7 +554,7 @@ struct _LibreOfficeKitDocumentClass /// @see lok::Document::renderNextSlideLayer bool (*renderNextSlideLayer)( - LibreOfficeKitDocument* pThis, unsigned char* pBuffer, bool* bIsBitmapLayer, char** pJsonMessage); + LibreOfficeKitDocument* pThis, unsigned char* pBuffer, bool* bIsBitmapLayer, double* pScale, char** pJsonMessage); /// @see lok::Document::setViewOption void (*setViewOption)(LibreOfficeKitDocument* pThis, const char* pOption, const char* pValue); diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx index b311fa03d1a9..f6f581c1ca43 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.hxx +++ b/include/LibreOfficeKit/LibreOfficeKit.hxx @@ -932,9 +932,9 @@ public: } /// Render the slide layer - bool renderNextSlideLayer(unsigned char* pBuffer, bool* bIsBitmapLayer, char** pJsonMessage) + bool renderNextSlideLayer(unsigned char* pBuffer, bool* bIsBitmapLayer, double* pScale, char** pJsonMessage) { - return mpDoc->pClass->renderNextSlideLayer(mpDoc, pBuffer, bIsBitmapLayer, pJsonMessage); + return mpDoc->pClass->renderNextSlideLayer(mpDoc, pBuffer, bIsBitmapLayer, pScale, pJsonMessage); } /// Set named view options diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx index 9e57fc53b0a0..fa42c077df5f 100644 --- a/include/vcl/ITiledRenderable.hxx +++ b/include/vcl/ITiledRenderable.hxx @@ -405,7 +405,7 @@ public: } /** render slideshow layer*/ - virtual bool renderNextSlideLayer(unsigned char* /*pBuffer*/, bool& /*bIsBitmapLayer*/, OUString& /*rJsonMsg*/) + virtual bool renderNextSlideLayer(unsigned char* /*pBuffer*/, bool& /*bIsBitmapLayer*/, double& /*rScale*/, OUString& /*rJsonMsg*/) { return true; } diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx index d503c75ef8ec..44b04136d926 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx @@ -2864,9 +2864,10 @@ public: { std::vector<sal_uInt8> pBuffer(mnViewWidth * mnViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; CPPUNIT_ASSERT( - !mpXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + !mpXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); debugWriteImageToFile(mnImageFileStep++, pBuffer, mnViewWidth, mnViewHeight, aJson.toUtf8().getStr()); @@ -2888,9 +2889,10 @@ public: std::vector<sal_uInt8> pBuffer(mnViewWidth * mnViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; CPPUNIT_ASSERT_MESSAGE( - sMsg, !mpXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + sMsg, !mpXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT_MESSAGE(sMsg, bIsBitmapLayer); debugWriteImageToFile(mnImageFileStep++, pBuffer, mnViewWidth, mnViewHeight, @@ -2928,9 +2930,10 @@ public: std::vector<sal_uInt8> pBuffer(mnViewWidth * mnViewHeight * 4); bool bIsBitmapLayer = true; + double dScale = 1.0; OUString aJson; CPPUNIT_ASSERT_MESSAGE( - sMsg, !mpXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + sMsg, !mpXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT_MESSAGE(sMsg, !bIsBitmapLayer); boost::property_tree::ptree aTree; @@ -2955,9 +2958,10 @@ public: std::vector<sal_uInt8> pBuffer(mnViewWidth * mnViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; CPPUNIT_ASSERT_MESSAGE( - sMsg, !mpXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + sMsg, !mpXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT_MESSAGE(sMsg, bIsBitmapLayer); debugWriteImageToFile(mnImageFileStep++, pBuffer, mnViewWidth, mnViewHeight, @@ -3003,9 +3007,10 @@ public: { std::vector<sal_uInt8> pBuffer(mnViewWidth * mnViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; CPPUNIT_ASSERT( - mpXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + mpXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(aJson.isEmpty()); } }; @@ -3040,8 +3045,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering) { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); debugWriteImageToFile(0, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3058,8 +3064,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering) { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(bIsBitmapLayer); // TODO - check JSON content @@ -3088,8 +3095,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering) { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(bIsBitmapLayer); // TODO - check JSON content debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3118,8 +3126,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering) { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(aJson.isEmpty()); } @@ -3155,8 +3164,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_WithFie { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); debugWriteImageToFile(0, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); boost::property_tree::ptree aTree; @@ -3171,8 +3181,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_WithFie { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(bIsBitmapLayer); debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3199,8 +3210,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_WithFie { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(bIsBitmapLayer); // TODO - check JSON content debugWriteImageToFile(3, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3230,8 +3242,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_WithFie { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(bIsBitmapLayer); debugWriteImageToFile(4, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3259,9 +3272,10 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_WithFie { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = true; + double dScale = 1.0; OUString aJson; CPPUNIT_ASSERT( - !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(!bIsBitmapLayer); boost::property_tree::ptree aTree; @@ -3276,9 +3290,10 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_WithFie { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = true; + double dScale = 1.0; OUString aJson; CPPUNIT_ASSERT( - !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(!bIsBitmapLayer); boost::property_tree::ptree aTree; @@ -3293,8 +3308,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_WithFie { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(bIsBitmapLayer); debugWriteImageToFile(5, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3322,8 +3338,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_WithFie { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(aJson.isEmpty()); } @@ -3519,8 +3536,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(bIsBitmapLayer); debugWriteImageToFile(0, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3542,9 +3560,10 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = true; + double dScale = 1.0; OUString aJson; CPPUNIT_ASSERT( - !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(!bIsBitmapLayer); boost::property_tree::ptree aTree; @@ -3562,9 +3581,10 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = true; + double dScale = 1.0; OUString aJson; CPPUNIT_ASSERT( - !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(!bIsBitmapLayer); boost::property_tree::ptree aTree; @@ -3582,9 +3602,10 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = true; + double dScale = 1.0; OUString aJson; CPPUNIT_ASSERT( - !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(!bIsBitmapLayer); boost::property_tree::ptree aTree; @@ -3602,8 +3623,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(bIsBitmapLayer); debugWriteImageToFile(1, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3630,8 +3652,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(bIsBitmapLayer); debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3658,8 +3681,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(aJson.isEmpty()); } @@ -3684,8 +3708,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(bIsBitmapLayer); debugWriteImageToFile(0, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3709,9 +3734,10 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = true; + double dScale = 1.0; OUString aJson; CPPUNIT_ASSERT( - !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(!bIsBitmapLayer); boost::property_tree::ptree aTree; @@ -3729,9 +3755,10 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = true; + double dScale = 1.0; OUString aJson; CPPUNIT_ASSERT( - !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(!bIsBitmapLayer); boost::property_tree::ptree aTree; @@ -3749,9 +3776,10 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = true; + double dScale = 1.0; OUString aJson; CPPUNIT_ASSERT( - !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(!bIsBitmapLayer); boost::property_tree::ptree aTree; @@ -3769,8 +3797,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(bIsBitmapLayer); debugWriteImageToFile(1, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3794,8 +3823,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(bIsBitmapLayer); debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3823,8 +3853,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(bIsBitmapLayer); debugWriteImageToFile(3, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3852,8 +3883,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(bIsBitmapLayer); debugWriteImageToFile(4, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3877,8 +3909,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(bIsBitmapLayer); debugWriteImageToFile(5, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3906,8 +3939,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(aJson.isEmpty()); } @@ -3935,8 +3969,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); debugWriteImageToFile(0, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3957,8 +3992,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); debugWriteImageToFile(21, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -3979,8 +4015,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -4008,8 +4045,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); debugWriteImageToFile(3, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -4037,8 +4075,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); debugWriteImageToFile(4, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -4067,8 +4106,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(aJson.isEmpty()); } @@ -4096,8 +4136,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); debugWriteImageToFile(1, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -4118,8 +4159,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -4140,8 +4182,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); debugWriteImageToFile(3, pBuffer, nViewWidth, nViewHeight, aJson.toUtf8().getStr()); @@ -4170,8 +4213,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(aJson.isEmpty()); } @@ -4199,8 +4243,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); // Remember the hash of the buffer for uniqueness check auto aBufferHash = comphelper::Hash::calculateHash(pBuffer.data(), pBuffer.size(), comphelper::HashType::SHA1); @@ -4225,8 +4270,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); // Remember the hash of the buffer for uniqueness check auto aBufferHash = comphelper::Hash::calculateHash(pBuffer.data(), pBuffer.size(), comphelper::HashType::SHA1); @@ -4251,8 +4297,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); // Remember the hash of the buffer for uniqueness check auto aBufferHash = comphelper::Hash::calculateHash(pBuffer.data(), pBuffer.size(), comphelper::HashType::SHA1); @@ -4288,8 +4335,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; + double dScale = 1.0; OUString aJson; - CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, aJson)); + CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, dScale, aJson)); CPPUNIT_ASSERT(aJson.isEmpty()); } diff --git a/sd/source/ui/inc/SlideshowLayerRenderer.hxx b/sd/source/ui/inc/SlideshowLayerRenderer.hxx index e0cb1703789d..39994d0ceb85 100644 --- a/sd/source/ui/inc/SlideshowLayerRenderer.hxx +++ b/sd/source/ui/inc/SlideshowLayerRenderer.hxx @@ -201,7 +201,7 @@ public: * The properties of the layer are written to the input string in JSON format. * * @returns false, if nothing was rendered and rendering is done */ - bool render(unsigned char* pBuffer, bool& bIsBitmapLayer, OString& rJsonMsg); + bool render(unsigned char* pBuffer, bool& bIsBitmapLayer, double& scale, OString& rJsonMsg); }; } // end of namespace sd diff --git a/sd/source/ui/inc/unomodel.hxx b/sd/source/ui/inc/unomodel.hxx index a5898a0da24b..c4bb88802821 100644 --- a/sd/source/ui/inc/unomodel.hxx +++ b/sd/source/ui/inc/unomodel.hxx @@ -310,7 +310,7 @@ public: /// @see vcl::ITiledRenderable::postSlideshowCleanup(). SD_DLLPUBLIC void postSlideshowCleanup() override; /// @see vcl::ITiledRenderable::renderNextSlideLayer(). - SD_DLLPUBLIC bool renderNextSlideLayer(unsigned char* pBuffer, bool& bIsBitmapLayer, OUString& rJsonMsg) override; + SD_DLLPUBLIC bool renderNextSlideLayer(unsigned char* pBuffer, bool& bIsBitmapLayer, double& rScale, OUString& rJsonMsg) override; rtl::Reference< SdDrawPagesAccess > getSdDrawPages(); diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx b/sd/source/ui/tools/SlideshowLayerRenderer.cxx index a5e691fa185d..e73fef4b8bee 100644 --- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx +++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx @@ -60,12 +60,15 @@ private: EEControlBits mnSavedControlBits; Color maSavedBackgroundColor; + Fraction maScale; public: ScopedVclPtrInstance<VirtualDevice> maVirtualDevice; - RenderContext(unsigned char* pBuffer, SdrModel& rModel, SdrPage& rPage, Size const& rSlideSize) + RenderContext(unsigned char* pBuffer, SdrModel& rModel, SdrPage& rPage, Size const& rSlideSize, + const Fraction& rScale) : mrModel(rModel) + , maScale(rScale) , maVirtualDevice(DeviceFormat::WITHOUT_ALPHA) { SdrOutliner& rOutliner = mrModel.GetDrawOutliner(); @@ -80,8 +83,8 @@ public: maVirtualDevice->SetBackground(Wallpaper(COL_TRANSPARENT)); - maVirtualDevice->SetOutputSizePixelScaleOffsetAndLOKBuffer(rSlideSize, Fraction(1.0), - Point(), pBuffer); + maVirtualDevice->SetOutputSizePixelScaleOffsetAndLOKBuffer(rSlideSize, maScale, Point(), + pBuffer); Size aPageSize(rPage.GetSize()); MapMode aMapMode(MapUnit::Map100thMM); @@ -980,11 +983,12 @@ void SlideshowLayerRenderer::writeJSON(OString& rJsonMsg, RenderPass const& rRen maRenderState.incrementIndex(); } -bool SlideshowLayerRenderer::render(unsigned char* pBuffer, bool& bIsBitmapLayer, OString& rJsonMsg) +bool SlideshowLayerRenderer::render(unsigned char* pBuffer, bool& bIsBitmapLayer, double& rScale, + OString& rJsonMsg) { // We want to render one pass (one iteration through objects) - RenderContext aRenderContext(pBuffer, mrModel, mrPage, maSlideSize); + RenderContext aRenderContext(pBuffer, mrModel, mrPage, maSlideSize, Fraction(rScale)); // Render Background and analyze other passes if (maRenderState.meStage == RenderStage::Background) @@ -1007,7 +1011,7 @@ bool SlideshowLayerRenderer::render(unsigned char* pBuffer, bool& bIsBitmapLayer // We need to return a valid layer, so if background has to be skipped // render the next layer if (!mbRenderBackground) - render(pBuffer, bIsBitmapLayer, rJsonMsg); + render(pBuffer, bIsBitmapLayer, rScale, rJsonMsg); } else { diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx index 97ddfc782d5d..e8cb36b3cc53 100644 --- a/sd/source/ui/unoidl/unomodel.cxx +++ b/sd/source/ui/unoidl/unomodel.cxx @@ -4879,7 +4879,7 @@ void SdXImpressDocument::postSlideshowCleanup() pViewSh->destroyXSlideShowInstance(); } -bool SdXImpressDocument::renderNextSlideLayer(unsigned char* pBuffer, bool& bIsBitmapLayer, OUString& rJsonMsg) +bool SdXImpressDocument::renderNextSlideLayer(unsigned char* pBuffer, bool& bIsBitmapLayer, double& rScale, OUString& rJsonMsg) { bool bDone = true; @@ -4887,7 +4887,7 @@ bool SdXImpressDocument::renderNextSlideLayer(unsigned char* pBuffer, bool& bIsB return bDone; OString sMsg; - bool bOK = mpSlideshowLayerRenderer->render(pBuffer, bIsBitmapLayer, sMsg); + bool bOK = mpSlideshowLayerRenderer->render(pBuffer, bIsBitmapLayer, rScale, sMsg); if (bOK) { commit 85566f61b34c06549fb493e84f42f880d334900b Author: Marco Cecchetti <marco.cecche...@collabora.com> AuthorDate: Mon Dec 16 19:20:10 2024 +0100 Commit: Marco Cecchetti <marco.cecche...@collabora.com> CommitDate: Tue Mar 11 18:48:24 2025 +0100 lok: slideshow: effect for paragraph with auto font color can be wrong Color animations applied to a paragraph with font color set to auto didn't work. Here we implement a new way for retrieving the real paragraph font color. Change-Id: I72540964a6eddb75188c21f22b110a7e5007bcac Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178626 Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sd/source/ui/inc/SlideshowLayerRenderer.hxx b/sd/source/ui/inc/SlideshowLayerRenderer.hxx index 071b72ea5138..e0cb1703789d 100644 --- a/sd/source/ui/inc/SlideshowLayerRenderer.hxx +++ b/sd/source/ui/inc/SlideshowLayerRenderer.hxx @@ -28,6 +28,7 @@ #include <frozen/bits/defines.h> #include <frozen/bits/elsa_std.h> #include <frozen/unordered_set.h> +#include <tools/color.hxx> class SdrPage; class SdrModel; @@ -97,6 +98,8 @@ struct RenderPass bool mbPlaceholder = false; OUString maFieldType; + Color maFontColor = COL_AUTO; + bool isEmpty() { return maObjectsAndParagraphs.empty(); } }; diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx b/sd/source/ui/tools/SlideshowLayerRenderer.cxx index b28fa8bc418c..a5e691fa185d 100644 --- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx +++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx @@ -44,6 +44,7 @@ #include <drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx> #include <drawinglayer/primitive2d/Tools.hxx> #include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx> +#include <drawinglayer/primitive2d/textprimitive2d.hxx> #include <drawinglayer/tools/primitive2dxmldump.hxx> @@ -255,11 +256,45 @@ findTextBlock(drawinglayer::primitive2d::Primitive2DContainer const& rContainer, return nullptr; } +/// Retrieve paragraph font color to be used in the json message attached to the animated layer +Color getParagraphFontColor( + const drawinglayer::primitive2d::TextHierarchyParagraphPrimitive2D& pParagraphPrimitive2d) +{ + auto& rLinesContainer = const_cast<drawinglayer::primitive2d::Primitive2DContainer&>( + pParagraphPrimitive2d.getChildren()); + for (auto& pLine : rLinesContainer) + { + if (pLine->getPrimitive2DID() == PRIMITIVE2D_ID_TEXTHIERARCHYLINEPRIMITIVE2D) + { + auto& rLinePrimitive2d + = static_cast<drawinglayer::primitive2d::TextHierarchyLinePrimitive2D&>(*pLine); + auto& rPortionsContainer = const_cast<drawinglayer::primitive2d::Primitive2DContainer&>( + rLinePrimitive2d.getChildren()); + for (auto& pPortion : rPortionsContainer) + { + if (pPortion->getPrimitive2DID() == PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D) + { + auto& rPortionPrimitive2d + = static_cast<drawinglayer::primitive2d::TextSimplePortionPrimitive2D&>( + *pPortion); + Color aColor(rPortionPrimitive2d.getFontColor()); + SAL_INFO("sd", "SlideshowLayerRenderer: modifyParagraphs: " + "text: " + << rPortionPrimitive2d.getText() + << ", color: " << aColor.AsRGBHEXString()); + return aColor; + } + } + } + } + return COL_AUTO; +} + /// show/hide paragraphs in the container void modifyParagraphs( drawinglayer::primitive2d::Primitive2DContainer& rContainer, drawinglayer::geometry::ViewInformation2D const& rViewInformation2D, - std::deque<sal_Int32> const& rPreserveIndices, bool bRenderObject, + std::deque<sal_Int32> const& rPreserveIndices, bool bRenderObject, Color& rFontColor, std::vector<drawinglayer::primitive2d::Primitive2DReference>& rPrimitivesToUnhide) { auto* pTextBlock = findTextBlock(rContainer, rViewInformation2D); @@ -277,6 +312,8 @@ void modifyParagraphs( = static_cast<drawinglayer::primitive2d::TextHierarchyParagraphPrimitive2D&>( *pPrimitive); + rFontColor = getParagraphFontColor(pParagraphPrimitive2d); + // find the index auto aIterator = std::find(rPreserveIndices.begin(), rPreserveIndices.end(), nIndex); @@ -530,10 +567,10 @@ class RenderPassObjectRedirector : public sdr::contact::ViewObjectContactRedirec { protected: RenderState& mrRenderState; - RenderPass const& mrRenderPass; + RenderPass& mrRenderPass; public: - RenderPassObjectRedirector(RenderState& rRenderState, RenderPass const& rRenderPass) + RenderPassObjectRedirector(RenderState& rRenderState, RenderPass& rRenderPass) : mrRenderState(rRenderState) , mrRenderPass(rRenderPass) { @@ -570,7 +607,7 @@ public: = static_cast<drawinglayer::primitive2d::Primitive2DContainer&>(rVisitor); modifyParagraphs(rContainer, rViewInformation2D, rParagraphs, - mrRenderPass.mbRenderObjectBackground, + mrRenderPass.mbRenderObjectBackground, mrRenderPass.maFontColor, mrRenderState.maPrimitivesToUnhide); } } @@ -807,51 +844,9 @@ void writeBoundingBox(::tools::JsonWriter& aJsonWriter, SdrObject* pObject) aJsonWriter.put("height", aRect.GetHeight()); } -uno::Reference<text::XTextRange> -getParagraphFromShape(int nPara, uno::Reference<beans::XPropertySet> const& xShape) -{ - uno::Reference<text::XText> xText - = uno::Reference<text::XTextRange>(xShape, uno::UNO_QUERY_THROW)->getText(); - if (!xText.is()) - return {}; - - uno::Reference<container::XEnumerationAccess> paraEnumAccess(xText, uno::UNO_QUERY); - if (!paraEnumAccess.is()) - return {}; - uno::Reference<container::XEnumeration> paraEnum(paraEnumAccess->createEnumeration()); - if (!paraEnum.is()) - return {}; - - for (int i = 0; i < nPara; ++i) - paraEnum->nextElement(); - - uno::Reference<text::XTextRange> xParagraph(paraEnum->nextElement(), uno::UNO_QUERY_THROW); - - return xParagraph; -} - -void writeFontColor(::tools::JsonWriter& aJsonWriter, SdrObject* pObject, sal_Int32 nParagraph) -{ - uno::Reference<drawing::XShape> xShape = GetXShapeForSdrObject(pObject); - uno::Reference<beans::XPropertySet> xShapePropSet(xShape, uno::UNO_QUERY_THROW); - if (!xShapePropSet.is()) - return; - - uno::Reference<text::XTextRange> xParagraph = getParagraphFromShape(nParagraph, xShapePropSet); - if (!xParagraph.is()) - return; - - uno::Reference<beans::XPropertySet> xPropSet(xParagraph->getStart(), uno::UNO_QUERY_THROW); - if (!xPropSet) - return; - - Color aCharColor; - xPropSet->getPropertyValue("CharColor") >>= aCharColor; - aJsonWriter.put("fontColor", "#" + aCharColor.AsRGBHEXString()); -} - void writeAnimated(::tools::JsonWriter& aJsonWriter, AnimationLayerInfo const& rLayerInfo, - SdrObject* pObject, sal_Int32 nParagraph = -1) + SdrObject* pObject, sal_Int32 nParagraph = -1, + const Color& rFontColor = COL_AUTO) { aJsonWriter.put("type", "animated"); { @@ -890,7 +885,12 @@ void writeAnimated(::tools::JsonWriter& aJsonWriter, AnimationLayerInfo const& r } else { - writeFontColor(aJsonWriter, pObject, nParagraph); + if (rFontColor == COL_AUTO) + { + SAL_WARN("sd", "SlideshowLayerRenderer: on writing JSON info for an animated " + "paragraph layer: font color is set to auto."); + } + aJsonWriter.put("fontColor", "#" + rFontColor.AsRGBHEXString()); } } } @@ -931,7 +931,8 @@ void SlideshowLayerRenderer::writeJSON(OString& rJsonMsg, RenderPass const& rRen auto aParagraphInfoIterator = rInfo.maParagraphInfos.find(nParagraph); if (aParagraphInfoIterator != rInfo.maParagraphInfos.end()) { - writeAnimated(aJsonWriter, aParagraphInfoIterator->second, pObject, nParagraph); + writeAnimated(aJsonWriter, aParagraphInfoIterator->second, pObject, nParagraph, + rRenderPass.maFontColor); } } else if (rInfo.moObjectInfo) @@ -1015,7 +1016,7 @@ bool SlideshowLayerRenderer::render(unsigned char* pBuffer, bool& bIsBitmapLayer cleanup(); return false; } - auto const& rRenderPass = maRenderState.maRenderPasses.front(); + auto& rRenderPass = maRenderState.maRenderPasses.front(); maRenderState.meStage = rRenderPass.meStage; bIsBitmapLayer = !rRenderPass.mbPlaceholder; commit 5da5b7ac0556a4c08d4d093889092604b2ab612a Author: Marco Cecchetti <marco.cecche...@collabora.com> AuthorDate: Thu Dec 12 20:59:17 2024 +0100 Commit: Marco Cecchetti <marco.cecche...@collabora.com> CommitDate: Tue Mar 11 18:48:24 2025 +0100 slideshow: fix for animated paragraph with bg color partly transparent Given a text shape with a background color with alpha component != 0, 1 a layer related to an animated paragraph includes also the background which is clearly wrong. Change-Id: Ib3a2ffb5bc01506400897f946ca4d6c23f8eb388 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178388 Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx b/sd/source/ui/tools/SlideshowLayerRenderer.cxx index a1f74649c45c..b28fa8bc418c 100644 --- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx +++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx @@ -42,6 +42,7 @@ #include <drawinglayer/primitive2d/Primitive2DContainer.hxx> #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> #include <drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx> +#include <drawinglayer/primitive2d/Tools.hxx> #include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx> #include <drawinglayer/tools/primitive2dxmldump.hxx> @@ -169,7 +170,8 @@ void changePolyPolys( || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D - || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONHAIRLINEPRIMITIVE2D) + || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONHAIRLINEPRIMITIVE2D + || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_UNIFIEDTRANSPARENCEPRIMITIVE2D) { pBasePrimitive->setVisible(bRenderObject); if (!bRenderObject) commit cfef322e966e5b840a298ad091b995fe53cab28e Author: Marco Cecchetti <marco.cecche...@collabora.com> AuthorDate: Wed Dec 11 13:50:51 2024 +0100 Commit: Marco Cecchetti <marco.cecche...@collabora.com> CommitDate: Tue Mar 11 18:48:24 2025 +0100 slideshow: map motion animation to the correct animation node on export Change-Id: I292a37d0c0a08c601b844704ef514877f58cfcf7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178349 Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx index 8f088d57b6f2..97ddfc782d5d 100644 --- a/sd/source/ui/unoidl/unomodel.cxx +++ b/sd/source/ui/unoidl/unomodel.cxx @@ -421,7 +421,7 @@ constexpr auto constTransitionSubTypeToString = mapEnumToString<sal_Int16>({ constexpr auto constAnimationNodeTypeToString = mapEnumToString<sal_Int16>({ { AnimationNodeType::ANIMATE, "Animate" }, { AnimationNodeType::ANIMATECOLOR, "AnimateColor" }, - { AnimationNodeType::ANIMATEMOTION, "Animate" }, + { AnimationNodeType::ANIMATEMOTION, "AnimateMotion" }, { AnimationNodeType::ANIMATEPHYSICS, "Animate" }, { AnimationNodeType::ANIMATETRANSFORM, "AnimateTransform" }, { AnimationNodeType::AUDIO, "Audio" }, commit cd2bad4917ee73adc615f1ea2b182d45189226a2 Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Mon Dec 9 16:53:26 2024 +0900 Commit: Marco Cecchetti <marco.cecche...@collabora.com> CommitDate: Tue Mar 11 18:48:24 2025 +0100 slideshow: reset visibility of primitives after rendering If the visible flag is not reset to true, it may be used outside of slideshow rendering. Change-Id: I42589b75c85d6e24af65a4d910bec4ac0c1a45e4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178128 Reviewed-by: Marco Cecchetti <marco.cecche...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sd/source/ui/inc/SlideshowLayerRenderer.hxx b/sd/source/ui/inc/SlideshowLayerRenderer.hxx index 840251a72ac9..071b72ea5138 100644 --- a/sd/source/ui/inc/SlideshowLayerRenderer.hxx +++ b/sd/source/ui/inc/SlideshowLayerRenderer.hxx @@ -23,6 +23,7 @@ #include <optional> #include <unordered_map> #include <unordered_set> +#include <drawinglayer/primitive2d/CommonTypes.hxx> #include <frozen/bits/defines.h> #include <frozen/bits/elsa_std.h> @@ -111,6 +112,8 @@ struct RenderState std::array<sal_Int32, 4> maIndices = { 0, 0, 0, 0 }; + std::vector<drawinglayer::primitive2d::Primitive2DReference> maPrimitivesToUnhide; + SdrObject* mpCurrentTarget = nullptr; sal_Int32 mnCurrentTargetParagraph = -1; @@ -175,6 +178,7 @@ private: void setupAnimations(); void setupMasterPageFields(); void resolveEffect(CustomAnimationEffectPtr const& rEffect); + void cleanup(); public: SlideshowLayerRenderer(SdrPage& rPage, bool bRenderBackground, bool bRenderMasterPage); diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx b/sd/source/ui/tools/SlideshowLayerRenderer.cxx index 1cf6613aef6e..a1f74649c45c 100644 --- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx +++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx @@ -159,8 +159,9 @@ OUString getMasterTextFieldType(SdrObject* pObject) bool isGroup(SdrObject* pObject) { return pObject->getChildrenOfSdrObject() != nullptr; } /// Sets visible for all kinds of polypolys in the container -void changePolyPolys(drawinglayer::primitive2d::Primitive2DContainer& rContainer, - bool bRenderObject) +void changePolyPolys( + drawinglayer::primitive2d::Primitive2DContainer& rContainer, bool bRenderObject, + std::vector<drawinglayer::primitive2d::Primitive2DReference>& rPrimitivesToUnhide) { for (auto& pBasePrimitive : rContainer) { @@ -171,13 +172,16 @@ void changePolyPolys(drawinglayer::primitive2d::Primitive2DContainer& rContainer || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONHAIRLINEPRIMITIVE2D) { pBasePrimitive->setVisible(bRenderObject); + if (!bRenderObject) + rPrimitivesToUnhide.push_back(pBasePrimitive); } } } /// Searches for rectangle primitive and changes if the background should be rendered -void changeBackground(drawinglayer::primitive2d::Primitive2DContainer const& rContainer, - bool bRenderObject) +void changeBackground( + drawinglayer::primitive2d::Primitive2DContainer const& rContainer, bool bRenderObject, + std::vector<drawinglayer::primitive2d::Primitive2DReference>& rPrimitivesToUnhide) { for (size_t i = 0; i < rContainer.size(); i++) { @@ -187,7 +191,7 @@ void changeBackground(drawinglayer::primitive2d::Primitive2DContainer const& rCo drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer; pBasePrimitive->get2DDecomposition(aPrimitiveContainer, drawinglayer::geometry::ViewInformation2D()); - changePolyPolys(aPrimitiveContainer, bRenderObject); + changePolyPolys(aPrimitiveContainer, bRenderObject, rPrimitivesToUnhide); } } } @@ -250,9 +254,11 @@ findTextBlock(drawinglayer::primitive2d::Primitive2DContainer const& rContainer, } /// show/hide paragraphs in the container -void modifyParagraphs(drawinglayer::primitive2d::Primitive2DContainer& rContainer, - drawinglayer::geometry::ViewInformation2D const& rViewInformation2D, - std::deque<sal_Int32> const& rPreserveIndices, bool bRenderObject) +void modifyParagraphs( + drawinglayer::primitive2d::Primitive2DContainer& rContainer, + drawinglayer::geometry::ViewInformation2D const& rViewInformation2D, + std::deque<sal_Int32> const& rPreserveIndices, bool bRenderObject, + std::vector<drawinglayer::primitive2d::Primitive2DReference>& rPrimitivesToUnhide) { auto* pTextBlock = findTextBlock(rContainer, rViewInformation2D); @@ -277,11 +283,13 @@ void modifyParagraphs(drawinglayer::primitive2d::Primitive2DContainer& rContaine bool bHideIndex = aIterator == rPreserveIndices.end(); pParagraphPrimitive2d.setVisible(!bHideIndex); + if (bHideIndex) + rPrimitivesToUnhide.push_back(pPrimitive); } nIndex++; } - changeBackground(rContainer, bRenderObject); + changeBackground(rContainer, bRenderObject, rPrimitivesToUnhide); } } @@ -558,8 +566,10 @@ public: auto const& rViewInformation2D = rOriginal.GetObjectContact().getViewInformation2D(); auto rContainer = static_cast<drawinglayer::primitive2d::Primitive2DContainer&>(rVisitor); + modifyParagraphs(rContainer, rViewInformation2D, rParagraphs, - mrRenderPass.mbRenderObjectBackground); + mrRenderPass.mbRenderObjectBackground, + mrRenderState.maPrimitivesToUnhide); } } }; @@ -999,8 +1009,10 @@ bool SlideshowLayerRenderer::render(unsigned char* pBuffer, bool& bIsBitmapLayer else { if (maRenderState.maRenderPasses.empty()) + { + cleanup(); return false; - + } auto const& rRenderPass = maRenderState.maRenderPasses.front(); maRenderState.meStage = rRenderPass.meStage; @@ -1019,6 +1031,14 @@ bool SlideshowLayerRenderer::render(unsigned char* pBuffer, bool& bIsBitmapLayer return true; } +void SlideshowLayerRenderer::cleanup() +{ + for (auto& pPrimitive : maRenderState.maPrimitivesToUnhide) + { + pPrimitive->setVisible(true); + } +} + } // end of namespace sd /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit e5012bd87aef5603ef4b9d219f286a9a8f53237d Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Mon Dec 9 15:55:57 2024 +0900 Commit: Marco Cecchetti <marco.cecche...@collabora.com> CommitDate: Tue Mar 11 18:48:24 2025 +0100 slideshow: need to set the page background color to the outliner This is needed or else we don't correctly determine and set what the auto color is for a particular page, which has the result that sometimes we set the text color to white where it should be black and probably also vice-versa. Change-Id: If17a008a49fbdd87e6bbb5299fe8efe506165a1b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178122 Reviewed-by: Marco Cecchetti <marco.cecche...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx b/sd/source/ui/tools/SlideshowLayerRenderer.cxx index 739d4c7eaf0c..1cf6613aef6e 100644 --- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx +++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx @@ -57,6 +57,7 @@ private: SdrModel& mrModel; EEControlBits mnSavedControlBits; + Color maSavedBackgroundColor; public: ScopedVclPtrInstance<VirtualDevice> maVirtualDevice; @@ -65,8 +66,13 @@ public: : mrModel(rModel) , maVirtualDevice(DeviceFormat::WITHOUT_ALPHA) { - // Turn off spelling SdrOutliner& rOutliner = mrModel.GetDrawOutliner(); + + // Set the background color + maSavedBackgroundColor = rOutliner.GetBackgroundColor(); + rOutliner.SetBackgroundColor(rPage.GetPageBackgroundColor()); + + // Turn off spelling mnSavedControlBits = rOutliner.GetControlWord(); rOutliner.SetControlWord(mnSavedControlBits & ~EEControlBits::ONLINESPELLING); @@ -93,6 +99,7 @@ public: // Restore spelling SdrOutliner& rOutliner = mrModel.GetDrawOutliner(); rOutliner.SetControlWord(mnSavedControlBits); + rOutliner.SetBackgroundColor(maSavedBackgroundColor); } }; commit f5ba36f4752a744418d35b0419a1d8cf0b9d4bd9 Author: Marco Cecchetti <marco.cecche...@collabora.com> AuthorDate: Tue Dec 3 18:59:50 2024 +0100 Commit: Marco Cecchetti <marco.cecche...@collabora.com> CommitDate: Tue Mar 11 18:48:23 2025 +0100 lok: slideshow: handle text object in edit mode This patch allows to render a text object in edit mode by decomposing a TextHierarchyEditPrimitive2D instance in place of using TextEditDrawing. That avoids to have artifacts displayed while playing the slideshow such as a tiny rectangle around the edited text shape. Moreover it allows to animate a single paragraph even when the related text object is in edit mode. Change-Id: I0c27dc0953dd1b0fb7ae70f41e569587f3a623ac Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177755 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/comphelper/source/misc/lok.cxx b/comphelper/source/misc/lok.cxx index 22895ba65661..4e06e0cfb2cd 100644 --- a/comphelper/source/misc/lok.cxx +++ b/comphelper/source/misc/lok.cxx @@ -40,6 +40,8 @@ static bool g_bViewIdForVisCursorInvalidation(false); static bool g_bLocalRendering(false); +static bool g_bSlideshowRendering(false); + static Compat g_eCompatFlags(Compat::none); static std::function<bool(void*, int)> g_pAnyInputCallback; @@ -205,6 +207,16 @@ bool isLocalRendering() return g_bLocalRendering; } +void setSlideshowRendering(bool bSlideshowRendering) +{ + g_bSlideshowRendering = bSlideshowRendering; +} + +bool isSlideshowRendering() +{ + return g_bSlideshowRendering; +} + void setCompatFlag(Compat flag) { g_eCompatFlags = static_cast<Compat>(g_eCompatFlags | flag); } bool isCompatFlagSet(Compat flag) { return (g_eCompatFlags & flag) == flag; } diff --git a/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx b/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx index 73a21e3c5722..d0a69ad9a336 100644 --- a/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx @@ -19,6 +19,7 @@ #include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx> #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> +#include <comphelper/lok.hxx> using namespace com::sun::star; @@ -146,7 +147,8 @@ namespace drawinglayer::primitive2d const geometry::ViewInformation2D& rViewInformation) const { // check if TextEdit is active. If not, process. If yes, suppress the content - if (!rViewInformation.getTextEditActive()) + // lok case: always decompose it when we're rendering a slide show + if (!rViewInformation.getTextEditActive() || comphelper::LibreOfficeKit::isSlideshowRendering()) GroupPrimitive2D::get2DDecomposition(rVisitor, rViewInformation); } diff --git a/drawinglayer/source/tools/primitive2dxmldump.cxx b/drawinglayer/source/tools/primitive2dxmldump.cxx index b8d40bd51f75..fb0d78a66be4 100644 --- a/drawinglayer/source/tools/primitive2dxmldump.cxx +++ b/drawinglayer/source/tools/primitive2dxmldump.cxx @@ -64,6 +64,7 @@ #include <drawinglayer/attribute/fillgradientattribute.hxx> #include <drawinglayer/attribute/sdrfillgraphicattribute.hxx> #include <drawinglayer/attribute/materialattribute3d.hxx> +#include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx> using namespace drawinglayer::primitive2d; @@ -1109,6 +1110,19 @@ void Primitive2dXmlDump::decomposeAndWrite( break; } + case PRIMITIVE2D_ID_TEXTHIERARCHYEDITPRIMITIVE2D: + { + rWriter.startElement("texthierarchyedit"); + runDecomposeAndRecurse(pBasePrimitive, rWriter); + const auto* pTextHierarchyEditPrimitive + = dynamic_cast<const drawinglayer::primitive2d::TextHierarchyEditPrimitive2D*>( + pBasePrimitive); + if (pTextHierarchyEditPrimitive) + decomposeAndWrite(pTextHierarchyEditPrimitive->getChildren(), rWriter); + rWriter.endElement(); + break; + } + case PRIMITIVE2D_ID_TEXTHIERARCHYPARAGRAPHPRIMITIVE2D: { // TextHierarchyParagraphPrimitive2D. diff --git a/include/comphelper/lok.hxx b/include/comphelper/lok.hxx index 2502a7c354c0..2945d16186e4 100644 --- a/include/comphelper/lok.hxx +++ b/include/comphelper/lok.hxx @@ -70,6 +70,10 @@ COMPHELPER_DLLPUBLIC bool isForkedChild(); COMPHELPER_DLLPUBLIC void setLocalRendering(bool bLocalRendering = true); COMPHELPER_DLLPUBLIC bool isLocalRendering(); +/// Used by SlideshowLayerRenderer for signaling that a slide rendering is occurring. +COMPHELPER_DLLPUBLIC void setSlideshowRendering(bool bSlideshowRendering); +COMPHELPER_DLLPUBLIC bool isSlideshowRendering(); + /// Check whether clients want a part number in an invalidation payload. COMPHELPER_DLLPUBLIC bool isPartInInvalidation(); /// Set whether clients want a part number in an invalidation payload. diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx b/sd/source/ui/tools/SlideshowLayerRenderer.cxx index 577d3b986f3c..739d4c7eaf0c 100644 --- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx +++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx @@ -31,6 +31,7 @@ #include <drawdoc.hxx> #include <unokywds.hxx> #include <comphelper/servicehelper.hxx> +#include <comphelper/lok.hxx> #include <com/sun/star/animations/XAnimate.hpp> #include <com/sun/star/animations/XAnimationNode.hpp> @@ -42,7 +43,6 @@ #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> #include <drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx> #include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx> -#include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx> #include <drawinglayer/tools/primitive2dxmldump.hxx> @@ -225,6 +225,18 @@ findTextBlock(drawinglayer::primitive2d::Primitive2DContainer const& rContainer, if (pTextBlock) return pTextBlock; } + + // for text object in edit mode + auto* pTextEditPrimitive + = dynamic_cast<drawinglayer::primitive2d::TextHierarchyEditPrimitive2D*>( + pBasePrimitive); + if (pTextEditPrimitive) + { + auto* pTextBlock + = findTextBlock(pTextEditPrimitive->getChildren(), rViewInformation2D); + if (pTextBlock) + return pTextBlock; + } } } return nullptr; @@ -740,7 +752,20 @@ void SlideshowLayerRenderer::createViewAndDraw( Point aPoint; vcl::Region aRegion(::tools::Rectangle(aPoint, aPageSize)); - aView.CompleteRedraw(rRenderContext.maVirtualDevice, aRegion, pRedirector); + + // Rendering of a text shape in edit mode is performed by decomposing the TextHierarchyEditPrimitive2D instance. + // Usually such kind of primitive doesn't decompose on primitive processing, so we need to signal through a flag + // that a slideshow rendering is going to be performed in order to enable the decomposition. + // Using TextHierarchyEditPrimitive2D decomposition in place of TextEditDrawing for rendering a text object + // in edit mode allows to animate a single paragraph even when the related text object is in edit mode. + comphelper::LibreOfficeKit::setSlideshowRendering(true); + // Redraw slide but skip EndCompleteRedraw() which uses TextEditDrawing for rendering text when a text object is + // in edit mode. TextEditDrawing was causing to have artifacts displayed while playing the slideshow such as + // a tiny rectangle around the edited text shape. + SdrPaintWindow* pPaintWindow = aView.BeginCompleteRedraw(rRenderContext.maVirtualDevice); + OSL_ENSURE(pPaintWindow, "SlideshowLayerRenderer::createViewAndDraw: No OutDev (!)"); + aView.DoCompleteRedraw(*pPaintWindow, aRegion, pRedirector); + comphelper::LibreOfficeKit::setSlideshowRendering(false); } namespace commit 798b959d6dcc14b89830a4d61a30da3db4c05951 Author: Marco Cecchetti <marco.cecche...@collabora.com> AuthorDate: Thu Nov 28 13:23:11 2024 +0100 Commit: Marco Cecchetti <marco.cecche...@collabora.com> CommitDate: Tue Mar 11 18:48:23 2025 +0100 lok: slideshow: support effects applied to a group of shapes What has been achieved: - when a group is animated a layer with all shapes belonging to the group is created and marked as an animated layer - any effect applied to a shape belonging to a group (animated or not) is discarded - any effect based on color animations applied to a group of shapes is discarded For the last 2 points, we mimic the same behavior that occurs on LibreOffice. Unit tests for several scenarios as been provided. Change-Id: Ie094ac2a6a85f08e0e873062b0a780fe322c83bd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177479 Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sd/CppunitTest_sd_tiledrendering.mk b/sd/CppunitTest_sd_tiledrendering.mk index d5b44028ff05..81a464179a9d 100644 --- a/sd/CppunitTest_sd_tiledrendering.mk +++ b/sd/CppunitTest_sd_tiledrendering.mk @@ -46,6 +46,7 @@ $(eval $(call gb_CppunitTest_set_include,sd_tiledrendering,\ -I$(SRCDIR)/sd/inc \ -I$(SRCDIR)/sd/source/ui/inc \ -I$(SRCDIR)/sd/qa/unit \ + -I$(WORKDIR)/UnpackedTarball/frozen/include \ $$(INCLUDE) \ )) diff --git a/sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_Group.odp b/sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_Group.odp new file mode 100644 index 000000000000..8be4426d207b Binary files /dev/null and b/sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_Group.odp differ diff --git a/sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_Groups.odp b/sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_Groups.odp new file mode 100644 index 000000000000..73191f3901c2 Binary files /dev/null and b/sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_Groups.odp differ diff --git a/sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_MultiLevel_Group.odp b/sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_MultiLevel_Group.odp new file mode 100644 index 000000000000..7d3555f57988 Binary files /dev/null and b/sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_MultiLevel_Group.odp differ diff --git a/sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_Shape_Inside_A_Group.odp b/sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_Shape_Inside_A_Group.odp new file mode 100644 index 000000000000..3265dd11e013 Binary files /dev/null and b/sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animated_Shape_Inside_A_Group.odp differ diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx index 6f916fd7cb0f..d503c75ef8ec 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx @@ -2949,7 +2949,7 @@ public: } } - void checkPageLayer(int nIndex, const std::string& rGroup) + void checkPageLayer(int nIndex, const std::string& rGroup, bool bIsAnimated = false) { const std::string sMsg = rGroup + " Layer Index: " + std::to_string(nIndex); @@ -2969,9 +2969,34 @@ public: CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg, rGroup, aTree.get_child("group").get_value<std::string>()); CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg, nIndex, aTree.get_child("index").get_value<int>()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg, std::string("bitmap"), - aTree.get_child("type").get_value<std::string>()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg, true, has_child(aTree, "content")); + + if (!bIsAnimated) + { + CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg, std::string("bitmap"), + aTree.get_child("type").get_value<std::string>()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg, true, has_child(aTree, "content")); + } + else + { + CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg, std::string("animated"), + aTree.get_child("type").get_value<std::string>()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg, true, has_child(aTree, "content")); + + auto aContentChild = aTree.get_child("content"); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg, true, has_child(aContentChild, "hash")); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg, true, has_child(aContentChild, "initVisible")); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg, std::string("bitmap"), + aContentChild.get_child("type").get_value<std::string>()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg, true, has_child(aContentChild, "content")); + + auto aContentChildChild = aContentChild.get_child("content"); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + sMsg, std::string("%IMAGETYPE%"), + aContentChildChild.get_child("type").get_value<std::string>()); + CPPUNIT_ASSERT_EQUAL_MESSAGE( + sMsg, std::string("%IMAGECHECKSUM%"), + aContentChildChild.get_child("checksum").get_value<std::string>()); + } } void checkFinalEmptyLayer() @@ -3389,6 +3414,91 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Skip_Ba pXImpressDocument->postSlideshowCleanup(); } +CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animated_Shape_Inside_A_Group) +{ + // 1 not animated groups made up by 2 shapes + // one of the 2 shapes is animated + + SdXImpressDocument* pXImpressDocument + = createDoc("SlideRenderingTest_Animated_Shape_Inside_A_Group.odp"); + pXImpressDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>()); + SlideRendererChecker aSlideRendererChecker(pXImpressDocument, 0, 2000, 2000, false, false); + aSlideRendererChecker.checkSlideSize(2000, 1125); + + // not animated group, no layer should be created for the animated shape + aSlideRendererChecker.checkPageLayer(0, "DrawPage", /*bIsAnimated=*/ false); + + aSlideRendererChecker.checkFinalEmptyLayer(); + + pXImpressDocument->postSlideshowCleanup(); +} + +CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animated_Group) +{ + // 1 animated groups made up by 2 not animated shapes + // a single not animated shape + + SdXImpressDocument* pXImpressDocument = createDoc("SlideRenderingTest_Animated_Group.odp"); + pXImpressDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>()); + SlideRendererChecker aSlideRendererChecker(pXImpressDocument, 0, 2000, 2000, false, false); + aSlideRendererChecker.checkSlideSize(2000, 1125); + + // animated group + aSlideRendererChecker.checkPageLayer(0, "DrawPage", /*bIsAnimated=*/ true); + + // not animated shape + aSlideRendererChecker.checkPageLayer(1, "DrawPage", /*bIsAnimated=*/ false); + + aSlideRendererChecker.checkFinalEmptyLayer(); + + pXImpressDocument->postSlideshowCleanup(); +} + +CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animated_Groups) +{ + // 2 animated groups made up by 2 shapes each + + SdXImpressDocument* pXImpressDocument = createDoc("SlideRenderingTest_Animated_Groups.odp"); + pXImpressDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>()); + SlideRendererChecker aSlideRendererChecker(pXImpressDocument, 0, 2000, 2000, false, false); + aSlideRendererChecker.checkSlideSize(2000, 1125); + + // 1st group + aSlideRendererChecker.checkPageLayer(0, "DrawPage", /*bIsAnimated=*/ true); + + // 2nd group + aSlideRendererChecker.checkPageLayer(1, "DrawPage", /*bIsAnimated=*/ true); + + aSlideRendererChecker.checkFinalEmptyLayer(); + + pXImpressDocument->postSlideshowCleanup(); +} + +CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animated_MultiLevel_Group) +{ + // 3 1st level groups made up by 2 shapes each + // the 1st group is not animated but one of its shape is + // the 2nd group is animated, none of its shapes is + // the 3rd group is animated with a color based effect + // 1st and 2nd group are grouped together and the 2nd level group is animated + + SdXImpressDocument* pXImpressDocument = createDoc("SlideRenderingTest_Animated_MultiLevel_Group.odp"); + pXImpressDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>()); + SlideRendererChecker aSlideRendererChecker(pXImpressDocument, 0, 2000, 2000, false, false); + aSlideRendererChecker.checkSlideSize(2000, 1125); + + // a single layer should be created for the highest level group, + // embedded animated groups or animated shapes should be ignored + aSlideRendererChecker.checkPageLayer(0, "DrawPage", /*bIsAnimated=*/ true); + + // a group with applied an effect based on color animations should not be animated + aSlideRendererChecker.checkPageLayer(1, "DrawPage", /*bIsAnimated=*/ false); + + aSlideRendererChecker.checkFinalEmptyLayer(); + + pXImpressDocument->postSlideshowCleanup(); +} + CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animations) { // Check rendering of animated objects - each in own layer diff --git a/sd/source/ui/inc/SlideshowLayerRenderer.hxx b/sd/source/ui/inc/SlideshowLayerRenderer.hxx index c150bb352c8d..840251a72ac9 100644 --- a/sd/source/ui/inc/SlideshowLayerRenderer.hxx +++ b/sd/source/ui/inc/SlideshowLayerRenderer.hxx @@ -24,6 +24,10 @@ #include <unordered_map> #include <unordered_set> +#include <frozen/bits/defines.h> +#include <frozen/bits/elsa_std.h> +#include <frozen/unordered_set.h> + class SdrPage; class SdrModel; class SdrObject; @@ -41,6 +45,21 @@ class ViewObjectContactRedirector; namespace sd { +constexpr auto constNonValidEffectsForGroupSet = frozen::make_unordered_set<std::string_view>({ + "ooo-emphasis-fill-color", + "ooo-emphasis-font-color", + "ooo-emphasis-line-color", + "ooo-emphasis-color-blend", + "ooo-emphasis-complementary-color", + "ooo-emphasis-complementary-color-2", + "ooo-emphasis-contrasting-color", + "ooo-emphasis-darken", + "ooo-emphasis-desaturate", + "ooo-emphasis-flash-bulb", + "ooo-emphasis-lighten", + "ooo-emphasis-grow-with-color", +}); + class RenderContext; enum class RenderStage diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx b/sd/source/ui/tools/SlideshowLayerRenderer.cxx index 4762d083f490..577d3b986f3c 100644 --- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx +++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx @@ -149,6 +149,8 @@ OUString getMasterTextFieldType(SdrObject* pObject) return aType; } +bool isGroup(SdrObject* pObject) { return pObject->getChildrenOfSdrObject() != nullptr; } + /// Sets visible for all kinds of polypolys in the container void changePolyPolys(drawinglayer::primitive2d::Primitive2DContainer& rContainer, bool bRenderObject) @@ -297,6 +299,18 @@ private: || (mrRenderState.mbDateTimeEnabled && svType == u"DateTime"); } + SdrObject* getAnimatedAncestor(SdrObject* pObject) const + { + SdrObject* pAncestor = pObject; + while ((pAncestor = pAncestor->getParentSdrObjectFromSdrObject())) + { + auto aIterator = mrRenderState.maAnimationRenderInfoList.find(pAncestor); + if (aIterator != mrRenderState.maAnimationRenderInfoList.end()) + return pAncestor; + } + return pAncestor; + } + public: AnalyzeRenderingRedirector(RenderState& rRenderState, bool bRenderMasterPage) : mrRenderState(rRenderState) @@ -455,9 +469,26 @@ public: closeRenderPass(); } } - // No specal handling is needed, just add the object to the current rendering pass + // check if object is part of an animated group + else if (SdrObject* pAncestor = getAnimatedAncestor(pObject)) + { + // a new animated group is started ? + if (mpCurrentRenderPass->mpObject && mpCurrentRenderPass->mpObject != pAncestor) + closeRenderPass(); + + // Add the animated object + mpCurrentRenderPass->maObjectsAndParagraphs.emplace(pObject, std::deque<sal_Int32>()); + mpCurrentRenderPass->meStage = eCurrentStage; + mpCurrentRenderPass->mbAnimation = true; + mpCurrentRenderPass->mpObject = pAncestor; + } + // No special handling is needed, just add the object to the current rendering pass else { + // an animated group is complete ? + if (mpCurrentRenderPass->mpObject) + closeRenderPass(); + mpCurrentRenderPass->maObjectsAndParagraphs.emplace(pObject, std::deque<sal_Int32>()); mpCurrentRenderPass->meStage = eCurrentStage; } @@ -563,6 +594,20 @@ void SlideshowLayerRenderer::resolveEffect(CustomAnimationEffectPtr const& rEffe if (!pObject) return; + // afaics, when a shape is part of a group any applied effect is ignored, + // so no layer should be created + if (pObject->getParentSdrObjectFromSdrObject()) + return; + + // some kind of effect, like the ones based on color animations, + // is ignored when applied to a group + if (isGroup(pObject)) + { + if (constNonValidEffectsForGroupSet.find(rEffect->getPresetId().toUtf8()) + != constNonValidEffectsForGroupSet.end()) + return; + } + AnimationRenderInfo aAnimationInfo; auto aIterator = maRenderState.maAnimationRenderInfoList.find(pObject); if (aIterator != maRenderState.maAnimationRenderInfoList.end()) @@ -777,27 +822,33 @@ void writeAnimated(::tools::JsonWriter& aJsonWriter, AnimationLayerInfo const& r writeContentNode(aJsonWriter); writeBoundingBox(aJsonWriter, pObject); - if (nParagraph < 0) + // a group of object has no such property + if (!isGroup(pObject)) { - drawing::FillStyle aFillStyle - = pObject->GetProperties().GetItem(XATTR_FILLSTYLE).GetValue(); - if (aFillStyle == drawing::FillStyle::FillStyle_SOLID) + if (nParagraph < 0) { - auto aFillColor = pObject->GetProperties().GetItem(XATTR_FILLCOLOR).GetColorValue(); - aJsonWriter.put("fillColor", "#" + aFillColor.AsRGBHEXString()); + drawing::FillStyle aFillStyle + = pObject->GetProperties().GetItem(XATTR_FILLSTYLE).GetValue(); + if (aFillStyle == drawing::FillStyle::FillStyle_SOLID) + { + auto aFillColor + = pObject->GetProperties().GetItem(XATTR_FILLCOLOR).GetColorValue(); + aJsonWriter.put("fillColor", "#" + aFillColor.AsRGBHEXString()); + } + drawing::LineStyle aLineStyle + = pObject->GetProperties().GetItem(XATTR_LINESTYLE).GetValue(); + if (aLineStyle == drawing::LineStyle::LineStyle_SOLID) + { + auto aLineColor + = pObject->GetProperties().GetItem(XATTR_LINECOLOR).GetColorValue(); + aJsonWriter.put("lineColor", "#" + aLineColor.AsRGBHEXString()); + } } - drawing::LineStyle aLineStyle - = pObject->GetProperties().GetItem(XATTR_LINESTYLE).GetValue(); - if (aLineStyle == drawing::LineStyle::LineStyle_SOLID) + else { - auto aLineColor = pObject->GetProperties().GetItem(XATTR_LINECOLOR).GetColorValue(); - aJsonWriter.put("lineColor", "#" + aLineColor.AsRGBHEXString()); + writeFontColor(aJsonWriter, pObject, nParagraph); } } - else - { - writeFontColor(aJsonWriter, pObject, nParagraph); - } } } -e ... etc. - the rest is truncated