drawinglayer/source/processor2d/baseprocessor2d.cxx                            
         |    3 
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx                        
         |    4 
 
sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animations_DifferentKindOfTextBox.odp
 |binary
 sd/qa/unit/tiledrendering/tiledrendering.cxx                                   
         |   86 ++++++++++
 sd/source/ui/tools/SlideshowLayerRenderer.cxx                                  
         |   25 +-
 5 files changed, 104 insertions(+), 14 deletions(-)

New commits:
commit cde8bf6bcf3b361bd107276efe14b2a221826399
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Wed Oct 16 09:30:11 2024 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Mar 12 18:30:54 2025 +0100

    slideshow: fix para. rendering when using SdrBlockTextPrimitive2D
    
    If using an empty ViewInformation, it is possible that the prim.
    decomposition is redone, when a different ViewInformation is used.
    This removes all visibility flags for the paragraphs, so the whole
    text is rendered. This fixes the issue by using the same instance
    of the ViewInformation that is also used later for rendering the
    primitives to the VirtualDevice, so the buffered decomposition is
    used.
    
    Also a test is added - it checks the hash of the buffer, which
    should be different for all 3 layers. For this the tostring has
    to be moved to the common hash.hxx, so we can reuse it in out
    tests.
    
    Includes:
    
            Author:     Marco Cecchetti <marco.cecche...@collabora.com>
            AuthorDate: Wed Mar 5 23:15:33 2025 +0100
    
                slideshow: regression: layer with paragraph has not the 
expected content
    
                Change-Id: I850c6922cdd358eee35074fbff04f238994b2c76
    
    Otherwise 'make -C sd -sr CppunitTest_sd_tiledrendering
    
CPPUNIT_TEST_NAME=testSlideshowLayeredRendering_Animation_DifferentKindOfTextBox'
    would fail.
    
    Change-Id: I4c951215a52e302d3b7b60a30c1b995002e53a4b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182833
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

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:
diff --git 
a/sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animations_DifferentKindOfTextBox.odp
 
b/sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animations_DifferentKindOfTextBox.odp
new file mode 100644
index 000000000000..47777662805f
Binary files /dev/null and 
b/sd/qa/unit/tiledrendering/data/SlideRenderingTest_Animations_DifferentKindOfTextBox.odp
 differ
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx 
b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index 01d987433404..a6c3714a3b75 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -18,6 +18,7 @@
 #include <comphelper/propertysequence.hxx>
 #include <comphelper/propertyvalue.hxx>
 #include <comphelper/string.hxx>
+#include <comphelper/hash.hxx>
 #include <editeng/eeitem.hxx>
 #include <editeng/editids.hrc>
 #include <editeng/editobj.hxx>
@@ -3422,6 +3423,91 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_Animati
     pXImpressDocument->postSlideshowCleanup();
 }
 
+namespace
+{
+template <typename T>
+bool is_unique(std::vector<T> vec)
+{
+    std::sort(vec.begin(), vec.end());
+    return std::unique(vec.begin(), vec.end()) == vec.end();
+}
+}
+
+CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_Animation_DifferentKindOfTextBox)
+{
+    SdXImpressDocument* pXImpressDocument = 
createDoc("SlideRenderingTest_Animations_DifferentKindOfTextBox.odp");
+    
pXImpressDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
+    sd::ViewShell* pViewShell = 
pXImpressDocument->GetDocShell()->GetViewShell();
+    CPPUNIT_ASSERT(pViewShell);
+    SdPage* pPage = pViewShell->GetActualPage();
+    CPPUNIT_ASSERT(pPage);
+    sal_Int32 nViewWidth = 2000;
+    sal_Int32 nViewHeight = 2000;
+
+    std::string sHash = GetInterfaceHash(GetXDrawPageForSdrPage(pPage));
+    CPPUNIT_ASSERT(pXImpressDocument->createSlideRenderer(sHash.c_str(), 0, 
nViewWidth, nViewHeight, true, true));
+    CPPUNIT_ASSERT_EQUAL(2000, nViewWidth);
+    CPPUNIT_ASSERT_EQUAL(1500, nViewHeight);
+
+    std::vector<std::string> aHashes;
+
+    {
+        std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
+        bool bIsBitmapLayer = false;
+        OUString rJsonMsg;
+        double dScale = 1.0;
+        
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, rJsonMsg));
+
+        // Remember the hash of the buffer for uniqueness check
+        auto aBufferHash = comphelper::Hash::calculateHash(pBuffer.data(), 
pBuffer.size(), comphelper::HashType::SHA1);
+        aHashes.push_back(comphelper::hashToString(aBufferHash));
+
+        debugWriteImageToFile(1, pBuffer, nViewWidth, nViewHeight, 
rJsonMsg.toUtf8().getStr());
+    }
+
+    {
+        std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
+        bool bIsBitmapLayer = false;
+        OUString rJsonMsg;
+        double dScale = 1.0;
+        
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, rJsonMsg));
+
+        // Remember the hash of the buffer for uniqueness check
+        auto aBufferHash = comphelper::Hash::calculateHash(pBuffer.data(), 
pBuffer.size(), comphelper::HashType::SHA1);
+        aHashes.push_back(comphelper::hashToString(aBufferHash));
+
+        debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, 
rJsonMsg.toUtf8().getStr());
+    }
+
+    {
+        std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
+        bool bIsBitmapLayer = false;
+        OUString rJsonMsg;
+        double dScale = 1.0;
+        
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, rJsonMsg));
+
+        // Remember the hash of the buffer for uniqueness check
+        auto aBufferHash = comphelper::Hash::calculateHash(pBuffer.data(), 
pBuffer.size(), comphelper::HashType::SHA1);
+        aHashes.push_back(comphelper::hashToString(aBufferHash));
+
+        debugWriteImageToFile(3, pBuffer, nViewWidth, nViewHeight, 
rJsonMsg.toUtf8().getStr());
+    }
+
+    // check if all hashes are unique
+    CPPUNIT_ASSERT(is_unique(aHashes));
+
+    // Check we are done
+    {
+        std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
+        bool bIsBitmapLayer = false;
+        OUString rJsonMsg;
+        double dScale = 1.0;
+        CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, rJsonMsg));
+    }
+
+    pXImpressDocument->postSlideshowCleanup();
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx 
b/sd/source/ui/tools/SlideshowLayerRenderer.cxx
index 143acfb5e668..3fb9160f6297 100644
--- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx
+++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx
@@ -138,7 +138,8 @@ void 
changeBackground(drawinglayer::primitive2d::Primitive2DContainer const& rCo
 }
 
 drawinglayer::primitive2d::TextHierarchyBlockPrimitive2D*
-findTextBlock(drawinglayer::primitive2d::Primitive2DContainer const& 
rContainer)
+findTextBlock(drawinglayer::primitive2d::Primitive2DContainer const& 
rContainer,
+              drawinglayer::geometry::ViewInformation2D const& 
rViewInformation2D)
 {
     for (size_t i = 0; i < rContainer.size(); i++)
     {
@@ -157,7 +158,8 @@ 
findTextBlock(drawinglayer::primitive2d::Primitive2DContainer const& rContainer)
                 = 
dynamic_cast<drawinglayer::primitive2d::GroupPrimitive2D*>(pBasePrimitive);
             if (pGroupPrimitive)
             {
-                auto* pTextBlock = 
findTextBlock(pGroupPrimitive->getChildren());
+                auto* pTextBlock
+                    = findTextBlock(pGroupPrimitive->getChildren(), 
rViewInformation2D);
                 if (pTextBlock)
                     return pTextBlock;
             }
@@ -169,9 +171,8 @@ 
findTextBlock(drawinglayer::primitive2d::Primitive2DContainer const& rContainer)
             {
                 // try to decompose
                 drawinglayer::primitive2d::Primitive2DContainer 
aPrimitiveContainer;
-                pBasePrimitive->get2DDecomposition(aPrimitiveContainer,
-                                                   
drawinglayer::geometry::ViewInformation2D());
-                auto* pTextBlock = findTextBlock(aPrimitiveContainer);
+                pBasePrimitive->get2DDecomposition(aPrimitiveContainer, 
rViewInformation2D);
+                auto* pTextBlock = findTextBlock(aPrimitiveContainer, 
rViewInformation2D);
                 if (pTextBlock)
                     return pTextBlock;
             }
@@ -181,9 +182,10 @@ 
findTextBlock(drawinglayer::primitive2d::Primitive2DContainer const& rContainer)
 }
 
 void modifyParagraphs(drawinglayer::primitive2d::Primitive2DContainer& 
rContainer,
+                      drawinglayer::geometry::ViewInformation2D const& 
rViewInformation2D,
                       std::deque<sal_Int32> const& rPreserveIndices, bool 
bRenderObject)
 {
-    auto* pTextBlock = findTextBlock(rContainer);
+    auto* pTextBlock = findTextBlock(rContainer, rViewInformation2D);
 
     if (pTextBlock)
     {
@@ -243,6 +245,10 @@ public:
             return;
 
         SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject();
+
+        drawinglayer::geometry::ViewInformation2D const& rViewInformation2D
+            = rOriginal.GetObjectContact().getViewInformation2D();
+
         // Check if we are rendering an object that is valid to render 
(exists, and not empty)
         if (pObject == nullptr || pObject->IsEmptyPresObj())
             return;
@@ -338,7 +344,8 @@ public:
 
             if (bRenderOtherParagraphs)
             {
-                modifyParagraphs(rContainer, nOtherParagraphs, true); // 
render the object
+                modifyParagraphs(rContainer, rViewInformation2D, 
nOtherParagraphs,
+                                 true); // render the object
                 mrRenderState.mnCurrentTargetParagraph = -1;
             }
             else
@@ -348,8 +355,8 @@ public:
 
                 std::deque<sal_Int32> aPreserveParagraphs{ nParagraph };
                 mrRenderState.mnCurrentTargetParagraph = nParagraph;
-                modifyParagraphs(rContainer, aPreserveParagraphs,
-                                 false); // render only the paragraphs
+                // render only the paragraphs
+                modifyParagraphs(rContainer, rViewInformation2D, 
aPreserveParagraphs, false);
             }
         }
 

Reply via email to