summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/svx/svdpntv.hxx6
-rw-r--r--sd/qa/unit/tiledrendering/data/SlideRenderingTest.odpbin29095 -> 26099 bytes
-rw-r--r--sd/qa/unit/tiledrendering/tiledrendering.cxx66
-rw-r--r--sd/source/ui/inc/SlideshowLayerRenderer.hxx21
-rw-r--r--sd/source/ui/tools/SlideshowLayerRenderer.cxx159
-rw-r--r--sd/source/ui/unoidl/unomodel.cxx2
-rw-r--r--svx/source/sdr/contact/viewobjectcontactofmasterpagedescriptor.cxx7
-rw-r--r--svx/source/svdraw/svdpntv.cxx1
8 files changed, 216 insertions, 46 deletions
diff --git a/include/svx/svdpntv.hxx b/include/svx/svdpntv.hxx
index 8665262f0508..df3c95131590 100644
--- a/include/svx/svdpntv.hxx
+++ b/include/svx/svdpntv.hxx
@@ -207,7 +207,8 @@ protected:
bool mbHideChart : 1;
bool mbHideDraw : 1; // hide draw objects other than form controls
bool mbHideFormControl : 1; // hide form controls only
- bool mbPaintTextEdit : 1; // if should paint currently edited text
+ bool mbHideBackground : 1; // don't draw the (page's or matser page's) background
+ bool mbPaintTextEdit : 1; // if should paint currently edited text
public:
// Interface for BufferedOoutputAllowed flag
@@ -473,10 +474,13 @@ public:
bool getHideChart() const { return mbHideChart; }
bool getHideDraw() const { return mbHideDraw; }
bool getHideFormControl() const { return mbHideFormControl; }
+ bool getHideBackground() const { return mbHideBackground; }
+
void setHideOle(bool bNew) { if(bNew != mbHideOle) mbHideOle = bNew; }
void setHideChart(bool bNew) { if(bNew != mbHideChart) mbHideChart = bNew; }
void setHideDraw(bool bNew) { if(bNew != mbHideDraw) mbHideDraw = bNew; }
void setHideFormControl(bool bNew) { if(bNew != mbHideFormControl) mbHideFormControl = bNew; }
+ void setHideBackground(bool bNew) { mbHideBackground = bNew; }
void SetGridCoarse(const Size& rSiz) { maGridBig=rSiz; }
void SetGridFine(const Size& rSiz) {
diff --git a/sd/qa/unit/tiledrendering/data/SlideRenderingTest.odp b/sd/qa/unit/tiledrendering/data/SlideRenderingTest.odp
index 4c7d4f101e32..8ffd7d38f051 100644
--- a/sd/qa/unit/tiledrendering/data/SlideRenderingTest.odp
+++ b/sd/qa/unit/tiledrendering/data/SlideRenderingTest.odp
Binary files differ
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index bb57cddf4bbc..604ec9047736 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -3177,8 +3177,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering)
// The doucment has nothing set for the background, so it should be application color = white
// On the master slide there is a (blue) rectangle on the right side - top-left should be transparent
// On the main slide there is a (green) rectanlge on the top-left size - right side should be transparent
- // enable layer output to PNG files
- const bool bOutputPNG = false;
+
+ const bool bOutputPNG = false; // Control layer output to PNG files
+
SdXImpressDocument* pXImpressDocument = createDoc("SlideRenderingTest.odp");
pXImpressDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
@@ -3189,16 +3190,18 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering)
sal_Int32 nViewHeight = 2000;
CPPUNIT_ASSERT(pXImpressDocument->createSlideRenderer(0, nViewWidth, nViewHeight, true, true));
CPPUNIT_ASSERT_EQUAL(2000, nViewWidth);
- CPPUNIT_ASSERT_EQUAL(1125, nViewHeight); // adjusted to the slide aspect ratio
- std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
- bool bIsBitmapLayer = false;
- OUString rJsonMsg;
+ CPPUNIT_ASSERT_EQUAL(1125, nViewHeight);
- CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg));
- CPPUNIT_ASSERT(bIsBitmapLayer);
- // TODO - check JSON content
- // printf ("1 %s\n\n", rJsonMsg.toUtf8().getStr());
+ const Color aTransparentColor(ColorAlpha, 0x00000000);
{
+ std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
+ bool bIsBitmapLayer = false;
+ OUString rJsonMsg;
+ CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg));
+ CPPUNIT_ASSERT(bIsBitmapLayer);
+ // TODO - check JSON content
+ // printf ("1 %s\n\n", rJsonMsg.toUtf8().getStr());
+
BitmapEx aBitmapEx = vcl::bitmap::CreateFromData(pBuffer.data(), nViewWidth, nViewHeight, nViewWidth * 4, /*nBitsPerPixel*/32, true, true);
if (bOutputPNG)
{
@@ -3207,14 +3210,49 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering)
aPNGWriter.write(aBitmapEx);
}
+ // top-left corner
+ CPPUNIT_ASSERT_EQUAL(aTransparentColor, aBitmapEx.GetPixelColor(20, 20));
+
+ // bottom-left corner
+ CPPUNIT_ASSERT_EQUAL(aTransparentColor, aBitmapEx.GetPixelColor(20, nViewHeight - 20));
+
+ // bottom-right corner
+ CPPUNIT_ASSERT_EQUAL(Color(0xff, 0xd0, 0x40), aBitmapEx.GetPixelColor(nViewWidth - 20, nViewHeight - 20));
+ }
+
+ {
+ std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
+ bool bIsBitmapLayer = false;
+ OUString rJsonMsg;
+ CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg));
+ CPPUNIT_ASSERT(bIsBitmapLayer);
+ // TODO - check JSON content
+ // printf ("2 %s\n\n", rJsonMsg.toUtf8().getStr());
+
+ BitmapEx aBitmapEx = vcl::bitmap::CreateFromData(pBuffer.data(), nViewWidth, nViewHeight, nViewWidth * 4, /*nBitsPerPixel*/32, true, true);
+ if (bOutputPNG)
+ {
+ SvFileStream aStream("/home/quikee/XXX_02.png", StreamMode::WRITE | StreamMode::TRUNC);
+ vcl::PngImageWriter aPNGWriter(aStream);
+ aPNGWriter.write(aBitmapEx);
+ }
+
+ // top-left corner
+ CPPUNIT_ASSERT_EQUAL(Color(0x00, 0x50, 0x90), aBitmapEx.GetPixelColor(20, 20));
+
// bottom-left corner
- CPPUNIT_ASSERT_EQUAL(Color(ColorAlpha, 0x00000000), aBitmapEx.GetPixelColor(20, nViewHeight - 20));
+ CPPUNIT_ASSERT_EQUAL(aTransparentColor, aBitmapEx.GetPixelColor(20, nViewHeight - 20));
// bottom-right corner
- CPPUNIT_ASSERT_EQUAL(Color(0xff, 0xd5, 0x46), aBitmapEx.GetPixelColor(nViewWidth - 20, nViewHeight - 20));
+ CPPUNIT_ASSERT_EQUAL(aTransparentColor, aBitmapEx.GetPixelColor(nViewWidth - 20, nViewHeight - 20));
+ }
+
+ {
+ std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4);
+ bool bIsBitmapLayer = false;
+ OUString rJsonMsg;
+ CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg));
}
- // should return true - no more content
- CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg));
pXImpressDocument->postSlideshowCleanup();
}
diff --git a/sd/source/ui/inc/SlideshowLayerRenderer.hxx b/sd/source/ui/inc/SlideshowLayerRenderer.hxx
index 28525839d579..33c2ca69d502 100644
--- a/sd/source/ui/inc/SlideshowLayerRenderer.hxx
+++ b/sd/source/ui/inc/SlideshowLayerRenderer.hxx
@@ -12,23 +12,36 @@
#include <sddllapi.h>
#include <tools/gen.hxx>
#include <rtl/string.hxx>
+#include <deque>
class SdrPage;
-class BitmapEx;
+class SdrModel;
+
class Size;
namespace sd
{
+enum class SlideRenderStage
+{
+ Master,
+ Slide
+};
+
class SD_DLLPUBLIC SlideshowLayerRenderer
{
- SdrPage* mpPage;
+ SdrPage& mrPage;
+ SdrModel& mrModel;
+
Size maSlideSize;
- bool bRenderDone = false;
+
+ std::deque<SlideRenderStage> maRenderStages;
public:
- SlideshowLayerRenderer(SdrPage* pPage);
+ SlideshowLayerRenderer(SdrPage& rPage);
Size calculateAndSetSizePixel(Size const& rDesiredSizePixel);
bool render(unsigned char* pBuffer, OString& rJsonMsg);
+ bool renderMaster(unsigned char* pBuffer, OString& rJsonMsg);
+ bool renderSlide(unsigned char* pBuffer, OString& rJsonMsg);
};
} // end of namespace sd
diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx b/sd/source/ui/tools/SlideshowLayerRenderer.cxx
index e618dd2fac33..5f6fe8d7eda1 100644
--- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx
+++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx
@@ -14,7 +14,9 @@
#include <svx/unoapi.hxx>
#include <svx/sdr/contact/viewobjectcontact.hxx>
#include <svx/sdr/contact/viewcontact.hxx>
+#include <svx/sdr/contact/objectcontact.hxx>
#include <svx/svdoutl.hxx>
+#include <svx/svdpagv.hxx>
#include <vcl/virdev.hxx>
#include <tools/helpers.hxx>
#include <tools/json_writer.hxx>
@@ -23,9 +25,23 @@ namespace sd
{
namespace
{
-class SelectObjectRedirector : public sdr::contact::ViewObjectContactRedirector
+struct RedirectorOptions
{
+ bool mbSkipMainPageObjects = false;
+ bool mbSkipMasterPageObjects = false;
+};
+
+class ObjectRedirector : public sdr::contact::ViewObjectContactRedirector
+{
+protected:
+ RedirectorOptions maOptions;
+
public:
+ ObjectRedirector(RedirectorOptions const& rOptions)
+ : maOptions(rOptions)
+ {
+ }
+
virtual void createRedirectedPrimitive2DSequence(
const sdr::contact::ViewObjectContact& rOriginal,
const sdr::contact::DisplayInfo& rDisplayInfo,
@@ -37,12 +53,15 @@ public:
if (pObject == nullptr || pPage == nullptr)
{
// Not a SdrObject or a object not connected to a page (object with no page)
-
- //sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(
- // rOriginal, rDisplayInfo, rVisitor);
return;
}
+ if (maOptions.mbSkipMasterPageObjects && pPage->IsMasterPage())
+ return;
+
+ if (maOptions.mbSkipMainPageObjects && !pPage->IsMasterPage())
+ return;
+
const bool bDoCreateGeometry(
pObject->getSdrPageFromSdrObject()->checkVisibility(rOriginal, rDisplayInfo, true));
@@ -60,43 +79,116 @@ public:
rOriginal, rDisplayInfo, rVisitor);
}
};
+
+bool hasEmptyMaster(SdrPage const& rPage)
+{
+ if (!rPage.TRG_HasMasterPage())
+ return true;
+
+ SdrPage& rMaster = rPage.TRG_GetMasterPage();
+ for (size_t i = 0; i < rMaster.GetObjCount(); i++)
+ {
+ auto pObject = rMaster.GetObj(i);
+ if (!pObject->IsEmptyPresObj())
+ return false;
+ }
+ return true;
}
-SlideshowLayerRenderer::SlideshowLayerRenderer(SdrPage* pPage)
- : mpPage(pPage)
+} // end anonymous namespace
+
+SlideshowLayerRenderer::SlideshowLayerRenderer(SdrPage& rPage)
+ : mrPage(rPage)
+ , mrModel(rPage.getSdrModelFromSdrPage())
{
+ if (!hasEmptyMaster(rPage))
+ maRenderStages.emplace_back(SlideRenderStage::Master);
+ maRenderStages.emplace_back(SlideRenderStage::Slide);
}
Size SlideshowLayerRenderer::calculateAndSetSizePixel(Size const& rDesiredSizePixel)
{
- if (!mpPage)
- return Size();
-
- double fRatio = double(mpPage->GetHeight()) / mpPage->GetWidth();
+ double fRatio = double(mrPage.GetHeight()) / mrPage.GetWidth();
Size aSize(rDesiredSizePixel.Width(), ::tools::Long(rDesiredSizePixel.Width() * fRatio));
maSlideSize = aSize;
return maSlideSize;
}
-bool SlideshowLayerRenderer::render(unsigned char* pBuffer, OString& rJsonMsg)
+bool SlideshowLayerRenderer::renderMaster(unsigned char* pBuffer, OString& rJsonMsg)
{
- if (bRenderDone)
- return false;
+ SdrOutliner& rOutliner = mrModel.GetDrawOutliner();
+ const EEControlBits nOldControlBits(rOutliner.GetControlWord());
+ EEControlBits nControlBits = nOldControlBits & ~EEControlBits::ONLINESPELLING;
+ rOutliner.SetControlWord(nControlBits);
- if (!mpPage)
- return false;
+ ScopedVclPtrInstance<VirtualDevice> pDevice(DeviceFormat::WITHOUT_ALPHA);
+ pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
+
+ pDevice->SetOutputSizePixelScaleOffsetAndLOKBuffer(maSlideSize, Fraction(1.0), Point(),
+ pBuffer);
+
+ Point aPoint;
+ Size aPageSize(mrPage.GetSize());
+
+ MapMode aMapMode(MapUnit::Map100thMM);
+ const Fraction aFracX(maSlideSize.Width(), pDevice->LogicToPixel(aPageSize, aMapMode).Width());
+ aMapMode.SetScaleX(aFracX);
+
+ const Fraction aFracY(maSlideSize.Height(),
+ pDevice->LogicToPixel(aPageSize, aMapMode).Height());
+ aMapMode.SetScaleY(aFracY);
+
+ pDevice->SetMapMode(aMapMode);
- SdrModel& rModel = mpPage->getSdrModelFromSdrPage();
+ SdrView aView(mrModel, pDevice);
+
+ aView.SetPageVisible(false);
+ aView.SetPageShadowVisible(false);
+ aView.SetPageBorderVisible(false);
+ aView.SetBordVisible(false);
+ aView.SetGridVisible(false);
+ aView.SetHlplVisible(false);
+ aView.SetGlueVisible(false);
+ aView.setHideBackground(false);
+ aView.ShowSdrPage(&mrPage);
+
+ vcl::Region aRegion(::tools::Rectangle(aPoint, aPageSize));
+ ObjectRedirector aRedirector({ .mbSkipMainPageObjects = true });
+ aView.CompleteRedraw(pDevice, aRegion, &aRedirector);
+
+ ::tools::JsonWriter aJsonWriter;
+ aJsonWriter.put("group", "MasterPage");
+ aJsonWriter.put("slideHash", GetInterfaceHash(GetXDrawPageForSdrPage(&mrPage)));
+ aJsonWriter.put("index", 0);
+ aJsonWriter.put("type", "bitmap");
+ {
+ ::tools::ScopedJsonWriterNode aContentNode = aJsonWriter.startNode("content");
+ aJsonWriter.put("type", "%IMAGETYPE%");
+ aJsonWriter.put("checksum", "%IMAGECHECKSUM%");
+ }
+ rJsonMsg = aJsonWriter.finishAndGetAsOString();
+
+ rOutliner.SetControlWord(nOldControlBits);
+
+ return true;
+}
+
+bool SlideshowLayerRenderer::renderSlide(unsigned char* pBuffer, OString& rJsonMsg)
+{
+ SdrOutliner& rOutliner = mrModel.GetDrawOutliner();
+ const EEControlBits nOldControlBits(rOutliner.GetControlWord());
+ EEControlBits nControlBits = nOldControlBits & ~EEControlBits::ONLINESPELLING;
+ rOutliner.SetControlWord(nControlBits);
ScopedVclPtrInstance<VirtualDevice> pDevice(DeviceFormat::WITHOUT_ALPHA);
pDevice->SetBackground(Wallpaper(COL_TRANSPARENT));
- pDevice->SetOutputSizePixelScaleOffsetAndLOKBuffer(maSlideSize, Fraction(2.0), Point(),
+ pDevice->SetOutputSizePixelScaleOffsetAndLOKBuffer(maSlideSize, Fraction(1.0), Point(),
pBuffer);
Point aPoint;
- Size aPageSize(mpPage->GetSize());
+ Size aPageSize(mrPage.GetSize());
MapMode aMapMode(MapUnit::Map100thMM);
const Fraction aFracX(maSlideSize.Width(), pDevice->LogicToPixel(aPageSize, aMapMode).Width());
@@ -108,7 +200,7 @@ bool SlideshowLayerRenderer::render(unsigned char* pBuffer, OString& rJsonMsg)
pDevice->SetMapMode(aMapMode);
- SdrView aView(rModel, pDevice);
+ SdrView aView(mrModel, pDevice);
aView.SetPageVisible(false);
aView.SetPageShadowVisible(false);
@@ -117,16 +209,16 @@ bool SlideshowLayerRenderer::render(unsigned char* pBuffer, OString& rJsonMsg)
aView.SetGridVisible(false);
aView.SetHlplVisible(false);
aView.SetGlueVisible(false);
-
- aView.ShowSdrPage(mpPage);
+ aView.setHideBackground(true);
+ aView.ShowSdrPage(&mrPage);
vcl::Region aRegion(::tools::Rectangle(aPoint, aPageSize));
- SelectObjectRedirector aRedirector;
+ ObjectRedirector aRedirector({ .mbSkipMasterPageObjects = true });
aView.CompleteRedraw(pDevice, aRegion, &aRedirector);
::tools::JsonWriter aJsonWriter;
aJsonWriter.put("group", "DrawPage");
- aJsonWriter.put("slideHash", GetInterfaceHash(GetXDrawPageForSdrPage(mpPage)));
+ aJsonWriter.put("slideHash", GetInterfaceHash(GetXDrawPageForSdrPage(&mrPage)));
aJsonWriter.put("index", 0);
aJsonWriter.put("type", "bitmap");
{
@@ -136,7 +228,26 @@ bool SlideshowLayerRenderer::render(unsigned char* pBuffer, OString& rJsonMsg)
}
rJsonMsg = aJsonWriter.finishAndGetAsOString();
- bRenderDone = true;
+ rOutliner.SetControlWord(nOldControlBits);
+
+ return true;
+}
+
+bool SlideshowLayerRenderer::render(unsigned char* pBuffer, OString& rJsonMsg)
+{
+ if (maRenderStages.empty())
+ return false;
+
+ auto eRenderStage = maRenderStages.front();
+ maRenderStages.pop_front();
+
+ switch (eRenderStage)
+ {
+ case SlideRenderStage::Master:
+ return renderMaster(pBuffer, rJsonMsg);
+ case SlideRenderStage::Slide:
+ return renderSlide(pBuffer, rJsonMsg);
+ };
return true;
}
diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx
index d388e6f80ee6..146a708f66d1 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -4419,7 +4419,7 @@ bool SdXImpressDocument::createSlideRenderer(
if (!pPage)
return false;
- mpSlideshowLayerRenderer.reset(new SlideshowLayerRenderer(pPage));
+ mpSlideshowLayerRenderer.reset(new SlideshowLayerRenderer(*pPage));
Size aDesiredSize(nViewWidth, nViewHeight);
Size aCalculatedSize = mpSlideshowLayerRenderer->calculateAndSetSizePixel(aDesiredSize);
nViewWidth = aCalculatedSize.Width();
diff --git a/svx/source/sdr/contact/viewobjectcontactofmasterpagedescriptor.cxx b/svx/source/sdr/contact/viewobjectcontactofmasterpagedescriptor.cxx
index baa039b1bb0f..2cd4b64c2fe8 100644
--- a/svx/source/sdr/contact/viewobjectcontactofmasterpagedescriptor.cxx
+++ b/svx/source/sdr/contact/viewobjectcontactofmasterpagedescriptor.cxx
@@ -23,6 +23,8 @@
#include <svx/sdr/contact/displayinfo.hxx>
#include <svx/sdr/contact/objectcontact.hxx>
#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdview.hxx>
#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
@@ -78,12 +80,13 @@ namespace sdr::contact
aPreprocessedLayers &= rDescriptor.GetVisibleLayers();
rDisplayInfo.SetProcessLayers(aPreprocessedLayers);
rDisplayInfo.SetSubContentActive(true);
-
+ const SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView();
+ bool bHideBackground = pSdrPageView ? pSdrPageView->GetView().getHideBackground() : false;
// check layer visibility (traditionally was member of layer 1)
if(aPreprocessedLayers.IsSet(SdrLayerID(1)))
{
// hide PageBackground for special DrawModes; historical reasons
- if(!GetObjectContact().isDrawModeGray() && !GetObjectContact().isDrawModeHighContrast())
+ if (!bHideBackground && !GetObjectContact().isDrawModeGray() && !GetObjectContact().isDrawModeHighContrast())
{
// if visible, create the default background primitive sequence
static_cast< ViewContactOfMasterPageDescriptor& >(GetViewContact()).getViewIndependentPrimitive2DContainer(rVisitor);
diff --git a/svx/source/svdraw/svdpntv.cxx b/svx/source/svdraw/svdpntv.cxx
index 5fcea85745f5..1aa512072586 100644
--- a/svx/source/svdraw/svdpntv.cxx
+++ b/svx/source/svdraw/svdpntv.cxx
@@ -165,6 +165,7 @@ SdrPaintView::SdrPaintView(SdrModel& rSdrModel, OutputDevice* pOut)
, mbHideChart(false)
, mbHideDraw(false)
, mbHideFormControl(false)
+ , mbHideBackground(false)
, mbPaintTextEdit(true)
, maGridColor(COL_BLACK)
{