Make rendering more flexible, render fields in separate layer
If the amster page has a field (like slide number) then render the objects containing fields into a separate master slide layer. Also change the rendering in such a way to be more flexible and has less conditions. So in the renderer it doesn't really matter if we are rendering a master slide or slide, what matters only is if the object is already rendered and if we need to stop rendering for some specified reason (like we encountered a field and need to stop rendering and need to switch to a new layer). Change-Id: I37ea2528427bbc1b3de938f960fb344866ee9399 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176911 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
This commit is contained in:
parent
512ef23224
commit
a44a406de4
BIN
sd/qa/unit/tiledrendering/data/SlideRenderingTest_WithFields.odp
Normal file
BIN
sd/qa/unit/tiledrendering/data/SlideRenderingTest_WithFields.odp
Normal file
Binary file not shown.
@ -3119,12 +3119,8 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testPresentationInfo)
|
|||||||
CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering)
|
CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering)
|
||||||
{
|
{
|
||||||
// Check rendering of slideshow layers (as in the document):
|
// Check rendering of slideshow layers (as in the document):
|
||||||
// - background layer
|
|
||||||
// - master slide layer
|
// - master slide layer
|
||||||
// - main slide layer
|
// - main slide layer
|
||||||
// The document 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) rectangle on the top-left size - right side should be transparent
|
|
||||||
|
|
||||||
const bool bOutputPNG = false; // Control layer output to PNG files
|
const bool bOutputPNG = false; // Control layer output to PNG files
|
||||||
|
|
||||||
@ -3204,6 +3200,118 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering)
|
|||||||
pXImpressDocument->postSlideshowCleanup();
|
pXImpressDocument->postSlideshowCleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_WithFields)
|
||||||
|
{
|
||||||
|
// Check rendering of slideshow layers (as in the document):
|
||||||
|
// - master slide layer
|
||||||
|
// - main slide layer
|
||||||
|
|
||||||
|
const bool bOutputPNG = false; // Control layer output to PNG files
|
||||||
|
|
||||||
|
SdXImpressDocument* pXImpressDocument = createDoc("SlideRenderingTest_WithFields.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;
|
||||||
|
CPPUNIT_ASSERT(pXImpressDocument->createSlideRenderer(0, nViewWidth, nViewHeight, true, true));
|
||||||
|
CPPUNIT_ASSERT_EQUAL(2000, nViewWidth);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(1125, nViewHeight);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
SvFileStream aStream("/home/quikee/XXX_01.png", StreamMode::WRITE | StreamMode::TRUNC);
|
||||||
|
vcl::PngImageWriter aPNGWriter(aStream);
|
||||||
|
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(aTransparentColor, aBitmapEx.GetPixelColor(20, 20));
|
||||||
|
|
||||||
|
// bottom-left corner
|
||||||
|
CPPUNIT_ASSERT_EQUAL(Color(0x90, 0x80, 0xff), aBitmapEx.GetPixelColor(20, nViewHeight - 20));
|
||||||
|
|
||||||
|
// bottom-right corner
|
||||||
|
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));
|
||||||
|
CPPUNIT_ASSERT(bIsBitmapLayer);
|
||||||
|
// TODO - check JSON content
|
||||||
|
// printf ("3 %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_03.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(aTransparentColor, aBitmapEx.GetPixelColor(20, nViewHeight - 20));
|
||||||
|
|
||||||
|
// bottom-right corner
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
pXImpressDocument->postSlideshowCleanup();
|
||||||
|
}
|
||||||
|
|
||||||
CPPUNIT_PLUGIN_IMPLEMENT();
|
CPPUNIT_PLUGIN_IMPLEMENT();
|
||||||
|
|
||||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||||
|
@ -13,41 +13,125 @@
|
|||||||
#include <tools/gen.hxx>
|
#include <tools/gen.hxx>
|
||||||
#include <rtl/string.hxx>
|
#include <rtl/string.hxx>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
class SdrPage;
|
class SdrPage;
|
||||||
class SdrModel;
|
class SdrModel;
|
||||||
|
class SdrObject;
|
||||||
|
|
||||||
class Size;
|
class Size;
|
||||||
|
|
||||||
namespace sd
|
namespace sd
|
||||||
{
|
{
|
||||||
struct RenderContext;
|
struct RenderContext;
|
||||||
struct RenderOptions;
|
|
||||||
|
|
||||||
enum class SlideRenderStage
|
enum class RenderStage
|
||||||
{
|
{
|
||||||
Master,
|
Master,
|
||||||
Slide
|
Slide
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Holds rendering state, properties and switches through all rendering passes */
|
||||||
|
struct RenderState
|
||||||
|
{
|
||||||
|
RenderStage meStage = RenderStage::Master;
|
||||||
|
|
||||||
|
sal_Int32 mnMasterIndex = 0;
|
||||||
|
bool mbStopRenderingWhenField = true;
|
||||||
|
|
||||||
|
std::unordered_set<SdrObject*> maObjectsDone;
|
||||||
|
sal_Int32 mnIndex = 0;
|
||||||
|
|
||||||
|
bool mbFirstObjectInPass = true;
|
||||||
|
bool mbPassHasOutput = false;
|
||||||
|
bool mbSkipAllInThisPass = false;
|
||||||
|
|
||||||
|
sal_Int32 mnCurrentPass = 0;
|
||||||
|
|
||||||
|
/// increments index depending on the current render stage
|
||||||
|
void incrementIndex()
|
||||||
|
{
|
||||||
|
if (meStage == RenderStage::Master)
|
||||||
|
mnMasterIndex++;
|
||||||
|
else
|
||||||
|
mnIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// returns the current stage as string
|
||||||
|
OString stageString()
|
||||||
|
{
|
||||||
|
if (meStage == RenderStage::Master)
|
||||||
|
return "MasterPage"_ostr;
|
||||||
|
return "DrawPage"_ostr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// returns the current index depending on the current render stage
|
||||||
|
sal_Int32 currentIndex()
|
||||||
|
{
|
||||||
|
if (meStage == RenderStage::Master)
|
||||||
|
return mnMasterIndex;
|
||||||
|
return mnIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// resets properties that are valid for one pass
|
||||||
|
void resetPass()
|
||||||
|
{
|
||||||
|
mbFirstObjectInPass = true;
|
||||||
|
mbPassHasOutput = false;
|
||||||
|
mbSkipAllInThisPass = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return if there was no rendering output in the pass
|
||||||
|
bool noMoreOutput()
|
||||||
|
{
|
||||||
|
// no output and we don't skip anything
|
||||||
|
return !mbPassHasOutput && !mbSkipAllInThisPass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// should include background in rendering
|
||||||
|
bool includeBackground()
|
||||||
|
{
|
||||||
|
// include background only if we are rendering the first pass
|
||||||
|
return mnCurrentPass == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isObjectAlreadyRendered(SdrObject* pObject)
|
||||||
|
{
|
||||||
|
return maObjectsDone.find(pObject) != maObjectsDone.end();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Renders a slide */
|
||||||
class SD_DLLPUBLIC SlideshowLayerRenderer
|
class SD_DLLPUBLIC SlideshowLayerRenderer
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
SdrPage& mrPage;
|
SdrPage& mrPage;
|
||||||
SdrModel& mrModel;
|
SdrModel& mrModel;
|
||||||
Size maSlideSize;
|
Size maSlideSize;
|
||||||
|
RenderState maRenderState;
|
||||||
|
|
||||||
std::deque<SlideRenderStage> maRenderStages;
|
void createViewAndDraw(RenderContext& rRenderContext);
|
||||||
|
void writeJSON(OString& rJsonMsg);
|
||||||
void cleanupRendering(RenderContext& rRenderContext);
|
|
||||||
void setupRendering(unsigned char* pBuffer, RenderContext& rRenderContext);
|
|
||||||
void createViewAndDraw(RenderContext& rRenderContext, RenderOptions const& rRenderOptions);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SlideshowLayerRenderer(SdrPage& rPage);
|
SlideshowLayerRenderer(SdrPage& rPage);
|
||||||
|
|
||||||
|
/** Calculate and set the slide size depending on input desired size (in pixels)
|
||||||
|
*
|
||||||
|
* Input the desired size in pixels, and the actual size pixels will be caluclated
|
||||||
|
* depending on the size of the slide and the desired size. The size can differ,
|
||||||
|
* because the it must match the slide aspect ratio.
|
||||||
|
**/
|
||||||
Size calculateAndSetSizePixel(Size const& rDesiredSizePixel);
|
Size calculateAndSetSizePixel(Size const& rDesiredSizePixel);
|
||||||
|
|
||||||
|
/** Renders one layer
|
||||||
|
*
|
||||||
|
* The slide layer is rendered into the input buffer, which must be the byte size
|
||||||
|
* of the calcualted size in pixels * 4 (RGBA).
|
||||||
|
* 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, OString& rJsonMsg);
|
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
|
} // end of namespace sd
|
||||||
|
@ -24,13 +24,6 @@
|
|||||||
|
|
||||||
namespace sd
|
namespace sd
|
||||||
{
|
{
|
||||||
struct RenderOptions
|
|
||||||
{
|
|
||||||
bool mbIncludeBackground = true;
|
|
||||||
bool mbSkipMainPageObjects = false;
|
|
||||||
bool mbSkipMasterPageObjects = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RenderContext
|
struct RenderContext
|
||||||
{
|
{
|
||||||
SdrModel& mrModel;
|
SdrModel& mrModel;
|
||||||
@ -44,7 +37,7 @@ struct RenderContext
|
|||||||
, mrPage(rPage)
|
, mrPage(rPage)
|
||||||
, maVirtualDevice(DeviceFormat::WITHOUT_ALPHA)
|
, maVirtualDevice(DeviceFormat::WITHOUT_ALPHA)
|
||||||
{
|
{
|
||||||
// Turn of spelling
|
// Turn off spelling
|
||||||
SdrOutliner& rOutliner = mrModel.GetDrawOutliner();
|
SdrOutliner& rOutliner = mrModel.GetDrawOutliner();
|
||||||
mnSavedControlBits = rOutliner.GetControlWord();
|
mnSavedControlBits = rOutliner.GetControlWord();
|
||||||
rOutliner.SetControlWord(mnSavedControlBits & ~EEControlBits::ONLINESPELLING);
|
rOutliner.SetControlWord(mnSavedControlBits & ~EEControlBits::ONLINESPELLING);
|
||||||
@ -77,14 +70,31 @@ struct RenderContext
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
bool hasFields(SdrObject* pObject)
|
||||||
|
{
|
||||||
|
auto* pTextObject = dynamic_cast<SdrTextObj*>(pObject);
|
||||||
|
if (!pTextObject)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
OutlinerParaObject* pOutlinerParagraphObject = pTextObject->GetOutlinerParaObject();
|
||||||
|
if (pOutlinerParagraphObject)
|
||||||
|
{
|
||||||
|
const EditTextObject& rEditText = pOutlinerParagraphObject->GetTextObject();
|
||||||
|
if (rEditText.IsFieldObject())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** VOC redirector to control which object should be rendered and which not */
|
||||||
class ObjectRedirector : public sdr::contact::ViewObjectContactRedirector
|
class ObjectRedirector : public sdr::contact::ViewObjectContactRedirector
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
RenderOptions maOptions;
|
RenderState& mrRenderState;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ObjectRedirector(RenderOptions const& rOptions)
|
ObjectRedirector(RenderState& rRenderState)
|
||||||
: maOptions(rOptions)
|
: mrRenderState(rRenderState)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,36 +103,62 @@ public:
|
|||||||
const sdr::contact::DisplayInfo& rDisplayInfo,
|
const sdr::contact::DisplayInfo& rDisplayInfo,
|
||||||
drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) override
|
drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) override
|
||||||
{
|
{
|
||||||
|
if (mrRenderState.mbSkipAllInThisPass)
|
||||||
|
return;
|
||||||
|
|
||||||
SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject();
|
SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject();
|
||||||
SdrPage* pPage = pObject ? pObject->getSdrPageFromSdrObject() : nullptr;
|
// Check if we are rendering an object that is valid to render (exists, and not empty)
|
||||||
|
if (pObject == nullptr || pObject->IsEmptyPresObj())
|
||||||
|
return;
|
||||||
|
|
||||||
if (pObject == nullptr || pPage == nullptr)
|
SdrPage* pPage = pObject->getSdrPageFromSdrObject();
|
||||||
|
// Does the object have a page
|
||||||
|
if (pPage == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// is the object visible and not hidden by any option
|
||||||
|
const bool bVisible
|
||||||
|
= pObject->getSdrPageFromSdrObject()->checkVisibility(rOriginal, rDisplayInfo, true);
|
||||||
|
|
||||||
|
if (!bVisible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check if we have already rendered the object
|
||||||
|
if (mrRenderState.isObjectAlreadyRendered(pObject))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check if we are in correct stage
|
||||||
|
if (mrRenderState.meStage == RenderStage::Master && !pPage->IsMasterPage())
|
||||||
{
|
{
|
||||||
// Not a SdrObject or a object not connected to a page (object with no page)
|
if (mrRenderState.mbFirstObjectInPass)
|
||||||
|
{
|
||||||
|
// if this is the first object - change from master to slide
|
||||||
|
// means we are done with rendering of master layers
|
||||||
|
mrRenderState.meStage = RenderStage::Slide;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if not, we have to stop rendering all further objects
|
||||||
|
mrRenderState.mbSkipAllInThisPass = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mrRenderState.meStage == RenderStage::Master && hasFields(pObject)
|
||||||
|
&& mrRenderState.mbStopRenderingWhenField && !mrRenderState.mbFirstObjectInPass)
|
||||||
|
{
|
||||||
|
mrRenderState.mbStopRenderingWhenField = false;
|
||||||
|
mrRenderState.mbSkipAllInThisPass = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maOptions.mbSkipMasterPageObjects && pPage->IsMasterPage())
|
// render the object
|
||||||
return;
|
|
||||||
|
|
||||||
if (maOptions.mbSkipMainPageObjects && !pPage->IsMasterPage())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const bool bDoCreateGeometry(
|
|
||||||
pObject->getSdrPageFromSdrObject()->checkVisibility(rOriginal, rDisplayInfo, true));
|
|
||||||
|
|
||||||
if (!bDoCreateGeometry
|
|
||||||
&& (pObject->GetObjInventor() != SdrInventor::Default
|
|
||||||
|| pObject->GetObjIdentifier() != SdrObjKind::Page))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pObject->IsEmptyPresObj())
|
|
||||||
return;
|
|
||||||
|
|
||||||
sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(
|
sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(
|
||||||
rOriginal, rDisplayInfo, rVisitor);
|
rOriginal, rDisplayInfo, rVisitor);
|
||||||
|
|
||||||
|
mrRenderState.mbFirstObjectInPass = false;
|
||||||
|
mrRenderState.maObjectsDone.insert(pObject);
|
||||||
|
mrRenderState.mbPassHasOutput = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -148,8 +184,9 @@ SlideshowLayerRenderer::SlideshowLayerRenderer(SdrPage& rPage)
|
|||||||
, mrModel(rPage.getSdrModelFromSdrPage())
|
, mrModel(rPage.getSdrModelFromSdrPage())
|
||||||
{
|
{
|
||||||
if (!hasEmptyMaster(rPage))
|
if (!hasEmptyMaster(rPage))
|
||||||
maRenderStages.emplace_back(SlideRenderStage::Master);
|
maRenderState.meStage = RenderStage::Master;
|
||||||
maRenderStages.emplace_back(SlideRenderStage::Slide);
|
else
|
||||||
|
maRenderState.meStage = RenderStage::Slide;
|
||||||
}
|
}
|
||||||
|
|
||||||
Size SlideshowLayerRenderer::calculateAndSetSizePixel(Size const& rDesiredSizePixel)
|
Size SlideshowLayerRenderer::calculateAndSetSizePixel(Size const& rDesiredSizePixel)
|
||||||
@ -161,8 +198,7 @@ Size SlideshowLayerRenderer::calculateAndSetSizePixel(Size const& rDesiredSizePi
|
|||||||
return maSlideSize;
|
return maSlideSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlideshowLayerRenderer::createViewAndDraw(RenderContext& rRenderContext,
|
void SlideshowLayerRenderer::createViewAndDraw(RenderContext& rRenderContext)
|
||||||
RenderOptions const& rRenderOptions)
|
|
||||||
{
|
{
|
||||||
SdrView aView(mrModel, rRenderContext.maVirtualDevice);
|
SdrView aView(mrModel, rRenderContext.maVirtualDevice);
|
||||||
aView.SetPageVisible(false);
|
aView.SetPageVisible(false);
|
||||||
@ -172,29 +208,24 @@ void SlideshowLayerRenderer::createViewAndDraw(RenderContext& rRenderContext,
|
|||||||
aView.SetGridVisible(false);
|
aView.SetGridVisible(false);
|
||||||
aView.SetHlplVisible(false);
|
aView.SetHlplVisible(false);
|
||||||
aView.SetGlueVisible(false);
|
aView.SetGlueVisible(false);
|
||||||
aView.setHideBackground(!rRenderOptions.mbIncludeBackground);
|
aView.setHideBackground(!maRenderState.includeBackground());
|
||||||
aView.ShowSdrPage(&mrPage);
|
aView.ShowSdrPage(&mrPage);
|
||||||
|
|
||||||
Size aPageSize(mrPage.GetSize());
|
Size aPageSize(mrPage.GetSize());
|
||||||
Point aPoint;
|
Point aPoint;
|
||||||
|
|
||||||
vcl::Region aRegion(::tools::Rectangle(aPoint, aPageSize));
|
vcl::Region aRegion(::tools::Rectangle(aPoint, aPageSize));
|
||||||
ObjectRedirector aRedirector(rRenderOptions);
|
ObjectRedirector aRedirector(maRenderState);
|
||||||
aView.CompleteRedraw(rRenderContext.maVirtualDevice, aRegion, &aRedirector);
|
aView.CompleteRedraw(rRenderContext.maVirtualDevice, aRegion, &aRedirector);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SlideshowLayerRenderer::renderMaster(unsigned char* pBuffer, OString& rJsonMsg)
|
void SlideshowLayerRenderer::writeJSON(OString& rJsonMsg)
|
||||||
{
|
{
|
||||||
RenderOptions aRenderOptions;
|
|
||||||
aRenderOptions.mbSkipMainPageObjects = true;
|
|
||||||
|
|
||||||
RenderContext aRenderContext(pBuffer, mrModel, mrPage, maSlideSize);
|
|
||||||
createViewAndDraw(aRenderContext, aRenderOptions);
|
|
||||||
|
|
||||||
::tools::JsonWriter aJsonWriter;
|
::tools::JsonWriter aJsonWriter;
|
||||||
aJsonWriter.put("group", "MasterPage");
|
aJsonWriter.put("group", maRenderState.stageString());
|
||||||
|
aJsonWriter.put("index", maRenderState.currentIndex());
|
||||||
aJsonWriter.put("slideHash", GetInterfaceHash(GetXDrawPageForSdrPage(&mrPage)));
|
aJsonWriter.put("slideHash", GetInterfaceHash(GetXDrawPageForSdrPage(&mrPage)));
|
||||||
aJsonWriter.put("index", 0);
|
|
||||||
aJsonWriter.put("type", "bitmap");
|
aJsonWriter.put("type", "bitmap");
|
||||||
{
|
{
|
||||||
auto aContentNode = aJsonWriter.startNode("content");
|
auto aContentNode = aJsonWriter.startNode("content");
|
||||||
@ -203,47 +234,24 @@ bool SlideshowLayerRenderer::renderMaster(unsigned char* pBuffer, OString& rJson
|
|||||||
}
|
}
|
||||||
rJsonMsg = aJsonWriter.finishAndGetAsOString();
|
rJsonMsg = aJsonWriter.finishAndGetAsOString();
|
||||||
|
|
||||||
return true;
|
maRenderState.incrementIndex();
|
||||||
}
|
|
||||||
|
|
||||||
bool SlideshowLayerRenderer::renderSlide(unsigned char* pBuffer, OString& rJsonMsg)
|
|
||||||
{
|
|
||||||
RenderOptions aRenderOptions;
|
|
||||||
aRenderOptions.mbSkipMasterPageObjects = true;
|
|
||||||
|
|
||||||
RenderContext aRenderContext(pBuffer, mrModel, mrPage, maSlideSize);
|
|
||||||
createViewAndDraw(aRenderContext, aRenderOptions);
|
|
||||||
|
|
||||||
::tools::JsonWriter aJsonWriter;
|
|
||||||
aJsonWriter.put("group", "DrawPage");
|
|
||||||
aJsonWriter.put("slideHash", GetInterfaceHash(GetXDrawPageForSdrPage(&mrPage)));
|
|
||||||
aJsonWriter.put("index", 0);
|
|
||||||
aJsonWriter.put("type", "bitmap");
|
|
||||||
{
|
|
||||||
auto aContentNode = aJsonWriter.startNode("content");
|
|
||||||
aJsonWriter.put("type", "%IMAGETYPE%");
|
|
||||||
aJsonWriter.put("checksum", "%IMAGECHECKSUM%");
|
|
||||||
}
|
|
||||||
rJsonMsg = aJsonWriter.finishAndGetAsOString();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SlideshowLayerRenderer::render(unsigned char* pBuffer, OString& rJsonMsg)
|
bool SlideshowLayerRenderer::render(unsigned char* pBuffer, OString& rJsonMsg)
|
||||||
{
|
{
|
||||||
if (maRenderStages.empty())
|
// Reset state
|
||||||
|
maRenderState.resetPass();
|
||||||
|
|
||||||
|
RenderContext aRenderContext(pBuffer, mrModel, mrPage, maSlideSize);
|
||||||
|
createViewAndDraw(aRenderContext);
|
||||||
|
|
||||||
|
// Check if we are done rendering all passes
|
||||||
|
if (maRenderState.noMoreOutput())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto eRenderStage = maRenderStages.front();
|
writeJSON(rJsonMsg);
|
||||||
maRenderStages.pop_front();
|
|
||||||
|
|
||||||
switch (eRenderStage)
|
maRenderState.mnCurrentPass++;
|
||||||
{
|
|
||||||
case SlideRenderStage::Master:
|
|
||||||
return renderMaster(pBuffer, rJsonMsg);
|
|
||||||
case SlideRenderStage::Slide:
|
|
||||||
return renderSlide(pBuffer, rJsonMsg);
|
|
||||||
};
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user