include/svx/svdobj.hxx                        |    4 
 sd/qa/unit/AnnotationTest.cxx                 |   31 +-
 sd/qa/unit/tiledrendering/tiledrendering.cxx  |  279 +++++++++++++++-----------
 sd/source/ui/tools/SlideshowLayerRenderer.cxx |  158 +++++++++-----
 4 files changed, 284 insertions(+), 188 deletions(-)

New commits:
commit 1efddf160508c2fdd860ad3815c553aaaa6aa460
Author:     Marco Cecchetti <marco.cecche...@collabora.com>
AuthorDate: Tue Nov 5 18:50:18 2024 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Mar 21 20:11:41 2025 +0100

    slideshow: create a placeholder even if text field content is hidden
    
    A placeholder always needs to be exported even if the content is hidden
    since it
    could be visible on another slide and master page layers should be
    cached on the
    client.
    In order to support text fields different from the default ones a hash
    is used
    for linking text field placeholder and text field content in place of
    the text
    field type.
    Any text field content should be sent first, so that when the client try
    to draw
    a master page layer corresponding to a text field placeholder the
    content is
    already available.
    Slideshow unit tests have been updated to match the new implementation.
    
    Includes:
    
            Author:     Marco Cecchetti <marco.cecche...@collabora.com>
            AuthorDate: Tue Mar 11 18:46:13 2025 +0100
    
                AnnotationTest: UniqueID regression
    
                By when incrementing the static counter used by UniqueID has 
been moved
                from getID() method to ctor, it's wrong to expect that created
                annotations have consecutive ids.
    
    Change-Id: I845888d141e0f02c2066a9cb17d89ab152bf28b8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183201
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/include/svx/svdobj.hxx b/include/svx/svdobj.hxx
index f5ee902d7778..297ee9530a61 100644
--- a/include/svx/svdobj.hxx
+++ b/include/svx/svdobj.hxx
@@ -31,6 +31,7 @@
 #include <svx/svdtypes.hxx>
 #include <svx/svdobjkind.hxx>
 #include <svx/svxdllapi.h>
+#include <tools/UniqueID.hxx>
 #include <tools/link.hxx>
 #include <tools/gen.hxx>
 #include <unotools/resmgr.hxx>
@@ -268,6 +269,8 @@ public:
     virtual void SAL_CALL acquire() noexcept override final;
     virtual void SAL_CALL release() noexcept override final;
 
+    sal_uInt64 GetUniqueID() const { return maUniqueID.getID(); }
+
     // SdrModel/SdrPage access on SdrObject level
     SdrPage* getSdrPageFromSdrObject() const;
     SdrModel& getSdrModelFromSdrObject() const;
@@ -949,6 +952,7 @@ private:
     std::unique_ptr<Impl>             mpImpl;
     SdrObjList*                       mpParentOfSdrObject;     // list that 
includes this object
     sal_uInt32                        m_nOrdNum;      // order number of the 
object in the list
+    class UniqueID                          maUniqueID;
     std::unique_ptr<SfxGrabBagItem>   m_pGrabBagItem; // holds the GrabBagItem 
property
     // Position in the navigation order. SAL_MAX_UINT32 when not used.
     sal_uInt32                        mnNavigationPosition;
diff --git a/sd/qa/unit/AnnotationTest.cxx b/sd/qa/unit/AnnotationTest.cxx
index 060f81f55526..146d7fcb7c6a 100644
--- a/sd/qa/unit/AnnotationTest.cxx
+++ b/sd/qa/unit/AnnotationTest.cxx
@@ -187,13 +187,10 @@ CPPUNIT_TEST_FIXTURE(AnnotationTest, testAnnotationDelete)
     dispatchCommand(mxComponent, u".uno:InsertAnnotation"_ustr, {});
 
     CPPUNIT_ASSERT_EQUAL(size_t(3), pPage->GetObjCount());
-
-    sal_uInt64 nID = pPage->getAnnotations().front()->GetId();
-
     CPPUNIT_ASSERT_EQUAL(size_t(3), pPage->getAnnotations().size());
-    CPPUNIT_ASSERT_EQUAL(sal_uInt64(nID + 0), 
pPage->getAnnotations().at(0)->GetId());
-    CPPUNIT_ASSERT_EQUAL(sal_uInt64(nID + 1), 
pPage->getAnnotations().at(1)->GetId());
-    CPPUNIT_ASSERT_EQUAL(sal_uInt64(nID + 2), 
pPage->getAnnotations().at(2)->GetId());
+
+    sal_uInt64 nAnnot1ID = pPage->getAnnotations().at(0)->GetId();
+    sal_uInt64 nAnnot3ID = pPage->getAnnotations().at(2)->GetId();
 
     auto xAnnotation = pPage->getAnnotations().at(1);
 
@@ -205,8 +202,8 @@ CPPUNIT_TEST_FIXTURE(AnnotationTest, testAnnotationDelete)
     CPPUNIT_ASSERT_EQUAL(size_t(2), pPage->GetObjCount());
     CPPUNIT_ASSERT_EQUAL(size_t(2), pPage->getAnnotations().size());
 
-    CPPUNIT_ASSERT_EQUAL(sal_uInt64(nID + 0), 
pPage->getAnnotations().at(0)->GetId());
-    CPPUNIT_ASSERT_EQUAL(sal_uInt64(nID + 2), 
pPage->getAnnotations().at(1)->GetId());
+    CPPUNIT_ASSERT_EQUAL(nAnnot1ID, pPage->getAnnotations().at(0)->GetId());
+    CPPUNIT_ASSERT_EQUAL(nAnnot3ID, pPage->getAnnotations().at(1)->GetId());
 }
 
 CPPUNIT_TEST_FIXTURE(AnnotationTest, testAnnotationInsertUndoRedo)
@@ -226,34 +223,32 @@ CPPUNIT_TEST_FIXTURE(AnnotationTest, 
testAnnotationInsertUndoRedo)
     SdrObject* pObject = pPage->GetObj(0);
     CPPUNIT_ASSERT_EQUAL(SdrObjKind::Annotation, pObject->GetObjIdentifier());
 
-    sal_uInt64 nID = pPage->getAnnotations().front()->GetId();
-
-    CPPUNIT_ASSERT_EQUAL(sal_uInt64(nID + 0), 
pPage->getAnnotations().at(0)->GetId());
-    CPPUNIT_ASSERT_EQUAL(sal_uInt64(nID + 1), 
pPage->getAnnotations().at(1)->GetId());
+    sal_uInt64 nAnnot1ID = pPage->getAnnotations().at(0)->GetId();
+    sal_uInt64 nAnnot2ID = pPage->getAnnotations().at(1)->GetId();
 
     dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
     CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount());
     CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->getAnnotations().size());
-    CPPUNIT_ASSERT_EQUAL(sal_uInt64(nID + 0), 
pPage->getAnnotations().at(0)->GetId());
+    CPPUNIT_ASSERT_EQUAL(nAnnot1ID, pPage->getAnnotations().at(0)->GetId());
 
     dispatchCommand(mxComponent, u".uno:Redo"_ustr, {});
     CPPUNIT_ASSERT_EQUAL(size_t(2), pPage->GetObjCount());
     CPPUNIT_ASSERT_EQUAL(size_t(2), pPage->getAnnotations().size());
-    CPPUNIT_ASSERT_EQUAL(sal_uInt64(nID + 0), 
pPage->getAnnotations().at(0)->GetId());
-    CPPUNIT_ASSERT_EQUAL(sal_uInt64(nID + 1), 
pPage->getAnnotations().at(1)->GetId());
+    CPPUNIT_ASSERT_EQUAL(nAnnot1ID, pPage->getAnnotations().at(0)->GetId());
+    CPPUNIT_ASSERT_EQUAL(nAnnot2ID, pPage->getAnnotations().at(1)->GetId());
 
     dispatchCommand(mxComponent, u".uno:DeleteAnnotation"_ustr, {});
 
     CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount());
     CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->getAnnotations().size());
-    CPPUNIT_ASSERT_EQUAL(sal_uInt64(nID + 0), 
pPage->getAnnotations().at(0)->GetId());
+    CPPUNIT_ASSERT_EQUAL(nAnnot1ID, pPage->getAnnotations().at(0)->GetId());
 
     dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
 
     CPPUNIT_ASSERT_EQUAL(size_t(2), pPage->GetObjCount());
     CPPUNIT_ASSERT_EQUAL(size_t(2), pPage->getAnnotations().size());
-    CPPUNIT_ASSERT_EQUAL(sal_uInt64(nID + 0), 
pPage->getAnnotations().at(0)->GetId());
-    CPPUNIT_ASSERT_EQUAL(sal_uInt64(nID + 1), 
pPage->getAnnotations().at(1)->GetId());
+    CPPUNIT_ASSERT_EQUAL(nAnnot1ID, pPage->getAnnotations().at(0)->GetId());
+    CPPUNIT_ASSERT_EQUAL(nAnnot2ID, pPage->getAnnotations().at(1)->GetId());
 }
 
 CPPUNIT_TEST_FIXTURE(AnnotationTest, testAnnotationPositionUpdate)
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx 
b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index 17f55ae25122..e8b6e4c497eb 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -2994,7 +2994,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_WithFie
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
         CPPUNIT_ASSERT(bIsBitmapLayer);
 
-        debugWriteImageToFile(1, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         BitmapEx aBitmapEx = vcl::bitmap::CreateFromData(pBuffer.data(), 
nViewWidth, nViewHeight, nViewWidth * 4, /*nBitsPerPixel*/32, true, true);
 
@@ -3002,17 +3002,16 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_WithFie
         CPPUNIT_ASSERT_EQUAL(aTransparentColor, aBitmapEx.GetPixelColor(nLeft, 
nTop));
 
         // bottom-left corner
-        CPPUNIT_ASSERT_EQUAL(aTransparentColor, aBitmapEx.GetPixelColor(nLeft, 
nBottom));
+        CPPUNIT_ASSERT_EQUAL(Color(0x90, 0x80, 0xff), 
aBitmapEx.GetPixelColor(nLeft, nBottom));
 
         // bottom-right corner
-        CPPUNIT_ASSERT_EQUAL(Color(0xff, 0xd0, 0x40), 
aBitmapEx.GetPixelColor(nRight, nBottom));
+        CPPUNIT_ASSERT_EQUAL(aTransparentColor, 
aBitmapEx.GetPixelColor(nRight, nBottom));
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
 
-        CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(std::string("TextFields"), 
aTree.get_child("group").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(0, aTree.get_child("index").get_value<int>());
-        CPPUNIT_ASSERT_EQUAL(std::string("bitmap"), 
aTree.get_child("type").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
     }
 
@@ -3024,7 +3023,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_WithFie
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
         CPPUNIT_ASSERT(bIsBitmapLayer);
         // TODO - check JSON content
-        debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        debugWriteImageToFile(3, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         BitmapEx aBitmapEx = vcl::bitmap::CreateFromData(pBuffer.data(), 
nViewWidth, nViewHeight, nViewWidth * 4, /*nBitsPerPixel*/32, true, true);
 
@@ -3043,9 +3042,8 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_WithFie
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
 
-        CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(std::string("TextFields"), 
aTree.get_child("group").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(1, aTree.get_child("index").get_value<int>());
-        CPPUNIT_ASSERT_EQUAL(std::string("bitmap"), 
aTree.get_child("type").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
     }
 
@@ -3057,7 +3055,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_WithFie
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
         CPPUNIT_ASSERT(bIsBitmapLayer);
 
-        debugWriteImageToFile(3, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        debugWriteImageToFile(4, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         BitmapEx aBitmapEx = vcl::bitmap::CreateFromData(pBuffer.data(), 
nViewWidth, nViewHeight, nViewWidth * 4, /*nBitsPerPixel*/32, true, true);
 
@@ -3065,20 +3063,56 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_WithFie
         CPPUNIT_ASSERT_EQUAL(aTransparentColor, aBitmapEx.GetPixelColor(nLeft, 
nTop));
 
         // bottom-left corner
-        CPPUNIT_ASSERT_EQUAL(Color(0x90, 0x80, 0xff), 
aBitmapEx.GetPixelColor(nLeft, nBottom));
+        CPPUNIT_ASSERT_EQUAL(aTransparentColor, aBitmapEx.GetPixelColor(nLeft, 
nBottom));
 
         // bottom-right corner
-        CPPUNIT_ASSERT_EQUAL(aTransparentColor, 
aBitmapEx.GetPixelColor(nRight, nBottom));
+        CPPUNIT_ASSERT_EQUAL(Color(0xff, 0xd0, 0x40), 
aBitmapEx.GetPixelColor(nRight, nBottom));
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
 
         CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
-        CPPUNIT_ASSERT_EQUAL(2, aTree.get_child("index").get_value<int>());
+        CPPUNIT_ASSERT_EQUAL(0, aTree.get_child("index").get_value<int>());
         CPPUNIT_ASSERT_EQUAL(std::string("bitmap"), 
aTree.get_child("type").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
     }
 
+    {
+        std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
+        bool bIsBitmapLayer = true;
+        double dScale = 1.0;
+        OUString aJson;
+        CPPUNIT_ASSERT(
+            !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
+        CPPUNIT_ASSERT(!bIsBitmapLayer);
+
+        boost::property_tree::ptree aTree;
+        readJSON(aTree, aJson);
+
+        CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(1, aTree.get_child("index").get_value<int>());
+        CPPUNIT_ASSERT_EQUAL(std::string("placeholder"), 
aTree.get_child("type").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
+    }
+
+    {
+        std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
+        bool bIsBitmapLayer = true;
+        double dScale = 1.0;
+        OUString aJson;
+        CPPUNIT_ASSERT(
+            !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
+        CPPUNIT_ASSERT(!bIsBitmapLayer);
+
+        boost::property_tree::ptree aTree;
+        readJSON(aTree, aJson);
+
+        CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(2, aTree.get_child("index").get_value<int>());
+        CPPUNIT_ASSERT_EQUAL(std::string("placeholder"), 
aTree.get_child("type").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
+    }
+
     {
         std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
         bool bIsBitmapLayer = false;
@@ -3087,7 +3121,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_WithFie
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
         CPPUNIT_ASSERT(bIsBitmapLayer);
 
-        debugWriteImageToFile(4, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        debugWriteImageToFile(5, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         BitmapEx aBitmapEx = vcl::bitmap::CreateFromData(pBuffer.data(), 
nViewWidth, nViewHeight, nViewWidth * 4, /*nBitsPerPixel*/32, true, true);
 
@@ -3157,141 +3191,148 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_SlideNu
 
     {
         std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
-        bool bIsBitmapLayer = true;
+        bool bIsBitmapLayer = false;
         OUString aJson;
         double dScale = 1.0;
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
-        CPPUNIT_ASSERT(!bIsBitmapLayer);
+        CPPUNIT_ASSERT(bIsBitmapLayer);
 
         debugWriteImageToFile(1, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
 
-        CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(std::string("TextFields"), 
aTree.get_child("group").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(0, aTree.get_child("index").get_value<int>());
-        CPPUNIT_ASSERT_EQUAL(std::string("placeholder"), 
aTree.get_child("type").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
         {
             auto aContentChild = aTree.get_child("content");
-            CPPUNIT_ASSERT_EQUAL(std::string("DateTime"), 
aContentChild.get_child("type").get_value<std::string>());
+            CPPUNIT_ASSERT_EQUAL(std::string("SlideNumber"), 
aContentChild.get_child("type").get_value<std::string>());
+            CPPUNIT_ASSERT_EQUAL(true, has_child(aContentChild, "content"));
+            auto aContentChildChild = aContentChild.get_child("content");
+            CPPUNIT_ASSERT_EQUAL(std::string("%IMAGETYPE%"), 
aContentChildChild.get_child("type").get_value<std::string>());
+            CPPUNIT_ASSERT_EQUAL(std::string("%IMAGECHECKSUM%"), 
aContentChildChild.get_child("checksum").get_value<std::string>());
         }
     }
 
     {
         std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
-        bool bIsBitmapLayer = true;
+        bool bIsBitmapLayer = false;
         OUString aJson;
         double dScale = 1.0;
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
-        CPPUNIT_ASSERT(!bIsBitmapLayer);
+        CPPUNIT_ASSERT(bIsBitmapLayer);
 
         debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
 
-        CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(std::string("TextFields"), 
aTree.get_child("group").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(1, aTree.get_child("index").get_value<int>());
-        CPPUNIT_ASSERT_EQUAL(std::string("placeholder"), 
aTree.get_child("type").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
         {
             auto aContentChild = aTree.get_child("content");
             CPPUNIT_ASSERT_EQUAL(std::string("Footer"), 
aContentChild.get_child("type").get_value<std::string>());
+            CPPUNIT_ASSERT_EQUAL(true, has_child(aContentChild, "content"));
+            auto aContentChildChild = aContentChild.get_child("content");
+            CPPUNIT_ASSERT_EQUAL(std::string("%IMAGETYPE%"), 
aContentChildChild.get_child("type").get_value<std::string>());
+            CPPUNIT_ASSERT_EQUAL(std::string("%IMAGECHECKSUM%"), 
aContentChildChild.get_child("checksum").get_value<std::string>());
         }
     }
 
     {
         std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
-        bool bIsBitmapLayer = true;
+        bool bIsBitmapLayer = false;
         OUString aJson;
         double dScale = 1.0;
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
-        CPPUNIT_ASSERT(!bIsBitmapLayer);
+        CPPUNIT_ASSERT(bIsBitmapLayer);
 
         debugWriteImageToFile(3, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
 
-        CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(std::string("TextFields"), 
aTree.get_child("group").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(2, aTree.get_child("index").get_value<int>());
-        CPPUNIT_ASSERT_EQUAL(std::string("placeholder"), 
aTree.get_child("type").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
         {
             auto aContentChild = aTree.get_child("content");
-            CPPUNIT_ASSERT_EQUAL(std::string("SlideNumber"), 
aContentChild.get_child("type").get_value<std::string>());
+            CPPUNIT_ASSERT_EQUAL(std::string("DateTime"), 
aContentChild.get_child("type").get_value<std::string>());
+            CPPUNIT_ASSERT_EQUAL(true, has_child(aContentChild, "content"));
+            auto aContentChildChild = aContentChild.get_child("content");
+            CPPUNIT_ASSERT_EQUAL(std::string("%IMAGETYPE%"), 
aContentChildChild.get_child("type").get_value<std::string>());
+            CPPUNIT_ASSERT_EQUAL(std::string("%IMAGECHECKSUM%"), 
aContentChildChild.get_child("checksum").get_value<std::string>());
         }
     }
 
     {
         std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
-        bool bIsBitmapLayer = false;
+        bool bIsBitmapLayer = true;
         OUString aJson;
         double dScale = 1.0;
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
-        CPPUNIT_ASSERT(bIsBitmapLayer);
+        CPPUNIT_ASSERT(!bIsBitmapLayer);
 
         debugWriteImageToFile(4, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
 
-        CPPUNIT_ASSERT_EQUAL(std::string("DrawPage"), 
aTree.get_child("group").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(0, aTree.get_child("index").get_value<int>());
-        CPPUNIT_ASSERT_EQUAL(std::string("bitmap"), 
aTree.get_child("type").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(std::string("placeholder"), 
aTree.get_child("type").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
+        {
+            auto aContentChild = aTree.get_child("content");
+            CPPUNIT_ASSERT_EQUAL(std::string("DateTime"), 
aContentChild.get_child("type").get_value<std::string>());
+        }
     }
 
     {
         std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
-        bool bIsBitmapLayer = false;
+        bool bIsBitmapLayer = true;
         OUString aJson;
         double dScale = 1.0;
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
-        CPPUNIT_ASSERT(bIsBitmapLayer);
+        CPPUNIT_ASSERT(!bIsBitmapLayer);
 
         debugWriteImageToFile(5, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
 
-        CPPUNIT_ASSERT_EQUAL(std::string("TextFields"), 
aTree.get_child("group").get_value<std::string>());
-        CPPUNIT_ASSERT_EQUAL(0, aTree.get_child("index").get_value<int>());
+        CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(1, aTree.get_child("index").get_value<int>());
+        CPPUNIT_ASSERT_EQUAL(std::string("placeholder"), 
aTree.get_child("type").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
         {
             auto aContentChild = aTree.get_child("content");
-            CPPUNIT_ASSERT_EQUAL(std::string("DateTime"), 
aContentChild.get_child("type").get_value<std::string>());
-            CPPUNIT_ASSERT_EQUAL(true, has_child(aContentChild, "content"));
-            auto aContentChildChild = aContentChild.get_child("content");
-            CPPUNIT_ASSERT_EQUAL(std::string("%IMAGETYPE%"), 
aContentChildChild.get_child("type").get_value<std::string>());
-            CPPUNIT_ASSERT_EQUAL(std::string("%IMAGECHECKSUM%"), 
aContentChildChild.get_child("checksum").get_value<std::string>());
-        }
+            CPPUNIT_ASSERT_EQUAL(std::string("Footer"), 
aContentChild.get_child("type").get_value<std::string>());
+       }
     }
 
     {
         std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
-        bool bIsBitmapLayer = false;
+        bool bIsBitmapLayer = true;
         OUString aJson;
         double dScale = 1.0;
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
-        CPPUNIT_ASSERT(bIsBitmapLayer);
+        CPPUNIT_ASSERT(!bIsBitmapLayer);
 
         debugWriteImageToFile(6, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
 
-        CPPUNIT_ASSERT_EQUAL(std::string("TextFields"), 
aTree.get_child("group").get_value<std::string>());
-        CPPUNIT_ASSERT_EQUAL(1, aTree.get_child("index").get_value<int>());
+        CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(2, aTree.get_child("index").get_value<int>());
+        CPPUNIT_ASSERT_EQUAL(std::string("placeholder"), 
aTree.get_child("type").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
         {
             auto aContentChild = aTree.get_child("content");
-            CPPUNIT_ASSERT_EQUAL(std::string("Footer"), 
aContentChild.get_child("type").get_value<std::string>());
-            CPPUNIT_ASSERT_EQUAL(true, has_child(aContentChild, "content"));
-            auto aContentChildChild = aContentChild.get_child("content");
-            CPPUNIT_ASSERT_EQUAL(std::string("%IMAGETYPE%"), 
aContentChildChild.get_child("type").get_value<std::string>());
-            CPPUNIT_ASSERT_EQUAL(std::string("%IMAGECHECKSUM%"), 
aContentChildChild.get_child("checksum").get_value<std::string>());
+            CPPUNIT_ASSERT_EQUAL(std::string("SlideNumber"), 
aContentChild.get_child("type").get_value<std::string>());
         }
     }
 
@@ -3303,22 +3344,15 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_SlideNu
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
         CPPUNIT_ASSERT(bIsBitmapLayer);
 
-        debugWriteImageToFile(6, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        debugWriteImageToFile(7, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
 
-        CPPUNIT_ASSERT_EQUAL(std::string("TextFields"), 
aTree.get_child("group").get_value<std::string>());
-        CPPUNIT_ASSERT_EQUAL(2, aTree.get_child("index").get_value<int>());
+        CPPUNIT_ASSERT_EQUAL(std::string("DrawPage"), 
aTree.get_child("group").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(0, aTree.get_child("index").get_value<int>());
+        CPPUNIT_ASSERT_EQUAL(std::string("bitmap"), 
aTree.get_child("type").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
-        {
-            auto aContentChild = aTree.get_child("content");
-            CPPUNIT_ASSERT_EQUAL(std::string("SlideNumber"), 
aContentChild.get_child("type").get_value<std::string>());
-            CPPUNIT_ASSERT_EQUAL(true, has_child(aContentChild, "content"));
-            auto aContentChildChild = aContentChild.get_child("content");
-            CPPUNIT_ASSERT_EQUAL(std::string("%IMAGETYPE%"), 
aContentChildChild.get_child("type").get_value<std::string>());
-            CPPUNIT_ASSERT_EQUAL(std::string("%IMAGECHECKSUM%"), 
aContentChildChild.get_child("checksum").get_value<std::string>());
-        }
     }
 
     {
@@ -3376,50 +3410,65 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_Animati
 
     {
         std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
-        bool bIsBitmapLayer = false;
+        bool bIsBitmapLayer = true;
         double dScale = 1.0;
         OUString aJson;
-        
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
-        CPPUNIT_ASSERT(bIsBitmapLayer);
-        debugWriteImageToFile(1, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        CPPUNIT_ASSERT(
+            !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
+        CPPUNIT_ASSERT(!bIsBitmapLayer);
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
 
         CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(0, aTree.get_child("index").get_value<int>());
-        CPPUNIT_ASSERT_EQUAL(std::string("bitmap"), 
aTree.get_child("type").get_value<std::string>());
-
+        CPPUNIT_ASSERT_EQUAL(std::string("placeholder"), 
aTree.get_child("type").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
         auto aContentChild = aTree.get_child("content");
-        CPPUNIT_ASSERT_EQUAL(false, has_child(aContentChild, "hash"));
-        CPPUNIT_ASSERT_EQUAL(false, has_child(aContentChild, "initVisible"));
-        CPPUNIT_ASSERT_EQUAL(std::string("%IMAGETYPE%"), 
aContentChild.get_child("type").get_value<std::string>());
-        CPPUNIT_ASSERT_EQUAL(std::string("%IMAGECHECKSUM%"), 
aContentChild.get_child("checksum").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(std::string("DateTime"), 
aContentChild.get_child("type").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(true, has_child(aContentChild, "hash"));
     }
 
     {
         std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
-        bool bIsBitmapLayer = false;
+        bool bIsBitmapLayer = true;
         double dScale = 1.0;
         OUString aJson;
-        
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
-        CPPUNIT_ASSERT(bIsBitmapLayer);
-        debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        CPPUNIT_ASSERT(
+            !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
+        CPPUNIT_ASSERT(!bIsBitmapLayer);
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
 
         CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(1, aTree.get_child("index").get_value<int>());
-        CPPUNIT_ASSERT_EQUAL(std::string("bitmap"), 
aTree.get_child("type").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(std::string("placeholder"), 
aTree.get_child("type").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
+        auto aContentChild = aTree.get_child("content");
+        CPPUNIT_ASSERT_EQUAL(std::string("Footer"), 
aContentChild.get_child("type").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(true, has_child(aContentChild, "hash"));
+    }
+
+    {
+        std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
+        bool bIsBitmapLayer = true;
+        double dScale = 1.0;
+        OUString aJson;
+        CPPUNIT_ASSERT(
+            !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
+        CPPUNIT_ASSERT(!bIsBitmapLayer);
 
+        boost::property_tree::ptree aTree;
+        readJSON(aTree, aJson);
+
+        CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(2, aTree.get_child("index").get_value<int>());
+        CPPUNIT_ASSERT_EQUAL(std::string("placeholder"), 
aTree.get_child("type").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
         auto aContentChild = aTree.get_child("content");
-        CPPUNIT_ASSERT_EQUAL(false, has_child(aContentChild, "hash"));
-        CPPUNIT_ASSERT_EQUAL(false, has_child(aContentChild, "initVisible"));
-        CPPUNIT_ASSERT_EQUAL(std::string("%IMAGETYPE%"), 
aContentChild.get_child("type").get_value<std::string>());
-        CPPUNIT_ASSERT_EQUAL(std::string("%IMAGECHECKSUM%"), 
aContentChild.get_child("checksum").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(std::string("SlideNumber"), 
aContentChild.get_child("type").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(true, has_child(aContentChild, "hash"));
     }
 
     {
@@ -3429,7 +3478,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_Animati
         OUString aJson;
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
         CPPUNIT_ASSERT(bIsBitmapLayer);
-        debugWriteImageToFile(3, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        debugWriteImageToFile(1, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
@@ -3458,7 +3507,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_Animati
         OUString aJson;
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
         CPPUNIT_ASSERT(bIsBitmapLayer);
-        debugWriteImageToFile(4, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
@@ -3535,54 +3584,66 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_Animati
 
     {
         std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
-        bool bIsBitmapLayer = false;
+        bool bIsBitmapLayer = true;
         double dScale = 1.0;
         OUString aJson;
-        
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
-        CPPUNIT_ASSERT(bIsBitmapLayer);
-
-        debugWriteImageToFile(1, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        CPPUNIT_ASSERT(
+            !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
+        CPPUNIT_ASSERT(!bIsBitmapLayer);
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
 
         CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(0, aTree.get_child("index").get_value<int>());
-        CPPUNIT_ASSERT_EQUAL(std::string("bitmap"), 
aTree.get_child("type").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(std::string("placeholder"), 
aTree.get_child("type").get_value<std::string>());
 
         CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
         auto aContentChild = aTree.get_child("content");
-        CPPUNIT_ASSERT_EQUAL(false, has_child(aContentChild, "hash"));
-        CPPUNIT_ASSERT_EQUAL(false, has_child(aContentChild, "initVisible"));
-        CPPUNIT_ASSERT_EQUAL(false, has_child(aContentChild, "bounds"));
-        CPPUNIT_ASSERT_EQUAL(std::string("%IMAGETYPE%"), 
aContentChild.get_child("type").get_value<std::string>());
-        CPPUNIT_ASSERT_EQUAL(std::string("%IMAGECHECKSUM%"), 
aContentChild.get_child("checksum").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(std::string("DateTime"), 
aContentChild.get_child("type").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(true, has_child(aContentChild, "hash"));
     }
 
     {
         std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
-        bool bIsBitmapLayer = false;
+        bool bIsBitmapLayer = true;
         double dScale = 1.0;
         OUString aJson;
-        
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
-        CPPUNIT_ASSERT(bIsBitmapLayer);
-
-        debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        CPPUNIT_ASSERT(
+            !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
+        CPPUNIT_ASSERT(!bIsBitmapLayer);
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
 
         CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(1, aTree.get_child("index").get_value<int>());
-        CPPUNIT_ASSERT_EQUAL(std::string("bitmap"), 
aTree.get_child("type").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(std::string("placeholder"), 
aTree.get_child("type").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
+        auto aContentChild = aTree.get_child("content");
+        CPPUNIT_ASSERT_EQUAL(std::string("Footer"), 
aContentChild.get_child("type").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(true, has_child(aContentChild, "hash"));
+    }
+
+    {
+        std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
+        bool bIsBitmapLayer = true;
+        double dScale = 1.0;
+        OUString aJson;
+        CPPUNIT_ASSERT(
+            !pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
+        CPPUNIT_ASSERT(!bIsBitmapLayer);
+
+        boost::property_tree::ptree aTree;
+        readJSON(aTree, aJson);
 
+        CPPUNIT_ASSERT_EQUAL(std::string("MasterPage"), 
aTree.get_child("group").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(2, aTree.get_child("index").get_value<int>());
+        CPPUNIT_ASSERT_EQUAL(std::string("placeholder"), 
aTree.get_child("type").get_value<std::string>());
         CPPUNIT_ASSERT_EQUAL(true, has_child(aTree, "content"));
         auto aContentChild = aTree.get_child("content");
-        CPPUNIT_ASSERT_EQUAL(false, has_child(aContentChild, "hash"));
-        CPPUNIT_ASSERT_EQUAL(false, has_child(aContentChild, "initVisible"));
-        CPPUNIT_ASSERT_EQUAL(false, has_child(aContentChild, "bounds"));
-        CPPUNIT_ASSERT_EQUAL(std::string("%IMAGETYPE%"), 
aContentChild.get_child("type").get_value<std::string>());
-        CPPUNIT_ASSERT_EQUAL(std::string("%IMAGECHECKSUM%"), 
aContentChild.get_child("checksum").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(std::string("SlideNumber"), 
aContentChild.get_child("type").get_value<std::string>());
+        CPPUNIT_ASSERT_EQUAL(true, has_child(aContentChild, "hash"));
     }
 
     {
@@ -3593,7 +3654,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_Animati
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
         CPPUNIT_ASSERT(bIsBitmapLayer);
 
-        debugWriteImageToFile(3, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        debugWriteImageToFile(1, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
@@ -3619,7 +3680,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_Animati
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
         CPPUNIT_ASSERT(bIsBitmapLayer);
 
-        debugWriteImageToFile(4, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
@@ -3649,7 +3710,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_Animati
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
         CPPUNIT_ASSERT(bIsBitmapLayer);
 
-        debugWriteImageToFile(5, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        debugWriteImageToFile(3, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
@@ -3679,7 +3740,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_Animati
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
         CPPUNIT_ASSERT(bIsBitmapLayer);
 
-        debugWriteImageToFile(6, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        debugWriteImageToFile(4, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
@@ -3705,7 +3766,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, 
testSlideshowLayeredRendering_Animati
         
CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), 
bIsBitmapLayer, dScale, aJson));
         CPPUNIT_ASSERT(bIsBitmapLayer);
 
-        debugWriteImageToFile(7, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
+        debugWriteImageToFile(5, pBuffer, nViewWidth, nViewHeight, 
aJson.toUtf8().getStr());
 
         boost::property_tree::ptree aTree;
         readJSON(aTree, aJson);
diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx 
b/sd/source/ui/tools/SlideshowLayerRenderer.cxx
index 8a4c7e6dfbbe..6729c3f23c57 100644
--- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx
+++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx
@@ -95,20 +95,55 @@ public:
 
 namespace
 {
-bool hasFields(SdrObject* pObject)
+sal_Int32 getFieldType(SdrObject* pObject)
 {
     auto* pTextObject = dynamic_cast<SdrTextObj*>(pObject);
     if (!pTextObject)
-        return false;
+        return -2;
 
     OutlinerParaObject* pOutlinerParagraphObject = 
pTextObject->GetOutlinerParaObject();
     if (pOutlinerParagraphObject)
     {
         const EditTextObject& rEditText = 
pOutlinerParagraphObject->GetTextObject();
-        if (rEditText.IsFieldObject())
-            return true;
+        if (rEditText.IsFieldObject() && rEditText.GetField() && 
rEditText.GetField()->GetField())
+            return rEditText.GetField()->GetField()->GetClassId();
     }
-    return false;
+    return -2;
+}
+
+bool hasFields(SdrObject* pObject) { return getFieldType(pObject) > -2; }
+
+OUString getFieldName(sal_Int32 nType)
+{
+    switch (nType)
+    {
+        case text::textfield::Type::PAGE:
+            return u"Page"_ustr;
+        case text::textfield::Type::PAGE_NAME:
+            return u"PageName"_ustr;
+        default:
+            return u""_ustr;
+    }
+}
+
+OUString getMasterTextFieldType(SdrObject* pObject)
+{
+    OUString aType;
+
+    uno::Reference<drawing::XShape> xShape = pObject->getUnoShape();
+    if (!xShape.is())
+        return aType;
+
+    OUString sShapeType = xShape->getShapeType();
+
+    if (sShapeType == u"com.sun.star.presentation.SlideNumberShape")
+        aType = u"SlideNumber"_ustr;
+    else if (sShapeType == u"com.sun.star.presentation.FooterShape")
+        aType = u"Footer"_ustr;
+    else if (sShapeType == u"com.sun.star.presentation.DateTimeShape")
+        aType = u"DateTime"_ustr;
+
+    return aType;
 }
 
 /// Sets visible for all kinds of polypolys in the container
@@ -251,27 +286,11 @@ private:
         mpCurrentRenderPass = newRenderPass();
     }
 
-    OUString getMasterTextFieldString(SdrObject* pObject)
+    bool isTextFieldVisible(std::u16string_view svType) const
     {
-        OUString aType;
-
-        uno::Reference<drawing::XShape> xShape = pObject->getUnoShape();
-        if (!xShape.is())
-            return aType;
-
-        OUString sShapeType = xShape->getShapeType();
-
-        if (mrRenderState.mbSlideNumberEnabled
-            && sShapeType == u"com.sun.star.presentation.SlideNumberShape")
-            aType = u"SlideNumber"_ustr;
-        else if (mrRenderState.mbFooterEnabled
-                 && sShapeType == u"com.sun.star.presentation.FooterShape")
-            aType = u"Footer"_ustr;
-        else if (mrRenderState.mbDateTimeEnabled
-                 && sShapeType == u"com.sun.star.presentation.DateTimeShape")
-            aType = u"DateTime"_ustr;
-
-        return aType;
+        return (mrRenderState.mbSlideNumberEnabled && svType == u"SlideNumber")
+               || (mrRenderState.mbFooterEnabled && svType == u"Footer")
+               || (mrRenderState.mbDateTimeEnabled && svType == u"DateTime");
     }
 
 public:
@@ -287,9 +306,13 @@ public:
         if (mrRenderState.maRenderPasses.back().isEmpty())
             mrRenderState.maRenderPasses.pop_back();
 
+        // Merge text field render passes into the main render pass list.
+        // We prepend them, so that they are rendered and sent to the client 
first.
+        // So, when the client try to draw a master page layer corresponding
+        // to a text field placeholder the content is already available.
         for (auto& rRenderWork : mrRenderState.maTextFields)
         {
-            mrRenderState.maRenderPasses.push_back(rRenderWork);
+            mrRenderState.maRenderPasses.push_front(rRenderWork);
         }
     }
 
@@ -314,19 +337,58 @@ public:
         const bool bVisible
             = pObject->getSdrPageFromSdrObject()->checkVisibility(rOriginal, 
rDisplayInfo, true);
 
-        if (!bVisible)
-            return;
-
         // Determine the current stage, depending on the page
         RenderStage eCurrentStage
             = pPage->IsMasterPage() ? RenderStage::Master : RenderStage::Slide;
 
+        OUString sTextFieldType = getMasterTextFieldType(pObject);
+        bool isPresentationTextField = !sTextFieldType.isEmpty();
+        if (!isPresentationTextField)
+        {
+            sTextFieldType = getFieldName(getFieldType(pObject));
+        }
+
+        // Check if the object has slide number, footer, date/time
+        if (eCurrentStage == RenderStage::Master && !sTextFieldType.isEmpty())
+        {
+            // it's not possible to set visibility for non-presentation text 
fields
+            bool bIsTextFieldVisible
+                = !isPresentationTextField || 
isTextFieldVisible(sTextFieldType);
+
+            // A placeholder always needs to be exported even if the content 
is hidden
+            // since it could be visible on another slide and master page 
layers should be cached
+            // on the client
+            closeRenderPass();
+
+            mpCurrentRenderPass->maObjectsAndParagraphs.emplace(pObject, 
std::deque<sal_Int32>());
+            mpCurrentRenderPass->meStage = eCurrentStage;
+            mpCurrentRenderPass->mbPlaceholder = true;
+            mpCurrentRenderPass->maFieldType = sTextFieldType;
+            mpCurrentRenderPass->mpObject = pObject;
+            closeRenderPass();
+
+            // Collect text field content if it's visible
+            // Both checks are needed!
+            if (bVisible && bIsTextFieldVisible)
+            {
+                RenderPass aTextFieldPass;
+                aTextFieldPass.maObjectsAndParagraphs.emplace(pObject, 
std::deque<sal_Int32>());
+                aTextFieldPass.meStage = RenderStage::TextFields;
+                aTextFieldPass.maFieldType = sTextFieldType;
+                aTextFieldPass.mpObject = pObject;
+
+                mrRenderState.maTextFields.push_back(aTextFieldPass);
+            }
+            return;
+        }
+
+        if (!bVisible)
+            return;
+
         // We switched from master objects to slide objects
         if (eCurrentStage == RenderStage::Slide && mePreviousStage == 
RenderStage::Master)
             closeRenderPass();
 
-        OUString sTextFieldString = getMasterTextFieldString(pObject);
-
         // check if object is in an animation
         auto aIterator = mrRenderState.maAnimationRenderInfoList.find(pObject);
         if (aIterator != mrRenderState.maAnimationRenderInfoList.end())
@@ -382,36 +444,6 @@ public:
                 closeRenderPass();
             }
         }
-        // Check if the object has slide number, footer, date/time
-        else if (eCurrentStage == RenderStage::Master && 
!sTextFieldString.isEmpty())
-        {
-            closeRenderPass();
-
-            mpCurrentRenderPass->maObjectsAndParagraphs.emplace(pObject, 
std::deque<sal_Int32>());
-            mpCurrentRenderPass->meStage = eCurrentStage;
-            mpCurrentRenderPass->mbPlaceholder = true;
-            mpCurrentRenderPass->maFieldType = sTextFieldString;
-            mpCurrentRenderPass->mpObject = pObject;
-            closeRenderPass();
-
-            RenderPass aTextFieldPass;
-            aTextFieldPass.maObjectsAndParagraphs.emplace(pObject, 
std::deque<sal_Int32>());
-            aTextFieldPass.meStage = RenderStage::TextFields;
-            aTextFieldPass.maFieldType = sTextFieldString;
-            aTextFieldPass.mpObject = pObject;
-
-            mrRenderState.maTextFields.push_back(aTextFieldPass);
-        }
-        // Check if the object has fields
-        else if (eCurrentStage == RenderStage::Master && hasFields(pObject))
-        {
-            closeRenderPass();
-
-            mpCurrentRenderPass->maObjectsAndParagraphs.emplace(pObject, 
std::deque<sal_Int32>());
-            mpCurrentRenderPass->meStage = eCurrentStage;
-            mpCurrentRenderPass->mpObject = pObject;
-            closeRenderPass();
-        }
         // No special handling is needed, just add the object to the current 
rendering pass
         else
         {
@@ -749,12 +781,16 @@ void SlideshowLayerRenderer::writeJSON(OString& rJsonMsg, 
RenderPass const& rRen
             {
                 auto aContentNode = aJsonWriter.startNode("content");
                 aJsonWriter.put("type", rRenderPass.maFieldType);
+                std::string sHash = pObject ? 
std::to_string(pObject->GetUniqueID()) : "";
+                aJsonWriter.put("hash", sHash);
             }
         }
         else if (rRenderPass.meStage == RenderStage::TextFields)
         {
             auto aContentNode = aJsonWriter.startNode("content");
             aJsonWriter.put("type", rRenderPass.maFieldType);
+            std::string sHash = pObject ? 
std::to_string(pObject->GetUniqueID()) : "";
+            aJsonWriter.put("hash", sHash);
             writeContentNode(aJsonWriter);
         }
         else

Reply via email to