diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2024-08-21 11:25:05 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2024-11-21 12:57:19 +0100 |
commit | a44a406de423b3d69183cc2e23f1e5f121518fab (patch) | |
tree | 3837eda78227936b13abcf2dbc6bb8a4f54c2faf /sd/source/ui/tools | |
parent | 512ef23224987e3107e66241db3b42934e15a561 (diff) |
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>
Diffstat (limited to 'sd/source/ui/tools')
-rw-r--r-- | sd/source/ui/tools/SlideshowLayerRenderer.cxx | 154 |
1 files changed, 81 insertions, 73 deletions
diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx b/sd/source/ui/tools/SlideshowLayerRenderer.cxx index 486823b0aa9c..3e1297225d4c 100644 --- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx +++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx @@ -24,13 +24,6 @@ namespace sd { -struct RenderOptions -{ - bool mbIncludeBackground = true; - bool mbSkipMainPageObjects = false; - bool mbSkipMasterPageObjects = false; -}; - struct RenderContext { SdrModel& mrModel; @@ -44,7 +37,7 @@ struct RenderContext , mrPage(rPage) , maVirtualDevice(DeviceFormat::WITHOUT_ALPHA) { - // Turn of spelling + // Turn off spelling SdrOutliner& rOutliner = mrModel.GetDrawOutliner(); mnSavedControlBits = rOutliner.GetControlWord(); rOutliner.SetControlWord(mnSavedControlBits & ~EEControlBits::ONLINESPELLING); @@ -77,14 +70,31 @@ struct RenderContext 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 { protected: - RenderOptions maOptions; + RenderState& mrRenderState; public: - ObjectRedirector(RenderOptions const& rOptions) - : maOptions(rOptions) + ObjectRedirector(RenderState& rRenderState) + : mrRenderState(rRenderState) { } @@ -93,36 +103,62 @@ public: const sdr::contact::DisplayInfo& rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) override { - SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject(); - SdrPage* pPage = pObject ? pObject->getSdrPageFromSdrObject() : nullptr; + if (mrRenderState.mbSkipAllInThisPass) + return; - if (pObject == nullptr || pPage == nullptr) - { - // Not a SdrObject or a object not connected to a page (object with no page) + SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject(); + // Check if we are rendering an object that is valid to render (exists, and not empty) + if (pObject == nullptr || pObject->IsEmptyPresObj()) return; - } - if (maOptions.mbSkipMasterPageObjects && pPage->IsMasterPage()) + SdrPage* pPage = pObject->getSdrPageFromSdrObject(); + // Does the object have a page + if (pPage == nullptr) return; - if (maOptions.mbSkipMainPageObjects && !pPage->IsMasterPage()) + // is the object visible and not hidden by any option + const bool bVisible + = pObject->getSdrPageFromSdrObject()->checkVisibility(rOriginal, rDisplayInfo, true); + + if (!bVisible) return; - const bool bDoCreateGeometry( - pObject->getSdrPageFromSdrObject()->checkVisibility(rOriginal, rDisplayInfo, true)); + // Check if we have already rendered the object + if (mrRenderState.isObjectAlreadyRendered(pObject)) + return; - if (!bDoCreateGeometry - && (pObject->GetObjInventor() != SdrInventor::Default - || pObject->GetObjIdentifier() != SdrObjKind::Page)) + // Check if we are in correct stage + if (mrRenderState.meStage == RenderStage::Master && !pPage->IsMasterPage()) { - return; + 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 (pObject->IsEmptyPresObj()) + if (mrRenderState.meStage == RenderStage::Master && hasFields(pObject) + && mrRenderState.mbStopRenderingWhenField && !mrRenderState.mbFirstObjectInPass) + { + mrRenderState.mbStopRenderingWhenField = false; + mrRenderState.mbSkipAllInThisPass = true; return; + } + // render the object sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence( rOriginal, rDisplayInfo, rVisitor); + + mrRenderState.mbFirstObjectInPass = false; + mrRenderState.maObjectsDone.insert(pObject); + mrRenderState.mbPassHasOutput = true; } }; @@ -148,8 +184,9 @@ SlideshowLayerRenderer::SlideshowLayerRenderer(SdrPage& rPage) , mrModel(rPage.getSdrModelFromSdrPage()) { if (!hasEmptyMaster(rPage)) - maRenderStages.emplace_back(SlideRenderStage::Master); - maRenderStages.emplace_back(SlideRenderStage::Slide); + maRenderState.meStage = RenderStage::Master; + else + maRenderState.meStage = RenderStage::Slide; } Size SlideshowLayerRenderer::calculateAndSetSizePixel(Size const& rDesiredSizePixel) @@ -161,8 +198,7 @@ Size SlideshowLayerRenderer::calculateAndSetSizePixel(Size const& rDesiredSizePi return maSlideSize; } -void SlideshowLayerRenderer::createViewAndDraw(RenderContext& rRenderContext, - RenderOptions const& rRenderOptions) +void SlideshowLayerRenderer::createViewAndDraw(RenderContext& rRenderContext) { SdrView aView(mrModel, rRenderContext.maVirtualDevice); aView.SetPageVisible(false); @@ -172,29 +208,24 @@ void SlideshowLayerRenderer::createViewAndDraw(RenderContext& rRenderContext, aView.SetGridVisible(false); aView.SetHlplVisible(false); aView.SetGlueVisible(false); - aView.setHideBackground(!rRenderOptions.mbIncludeBackground); + aView.setHideBackground(!maRenderState.includeBackground()); aView.ShowSdrPage(&mrPage); Size aPageSize(mrPage.GetSize()); Point aPoint; vcl::Region aRegion(::tools::Rectangle(aPoint, aPageSize)); - ObjectRedirector aRedirector(rRenderOptions); + ObjectRedirector aRedirector(maRenderState); 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; - aJsonWriter.put("group", "MasterPage"); + aJsonWriter.put("group", maRenderState.stageString()); + aJsonWriter.put("index", maRenderState.currentIndex()); aJsonWriter.put("slideHash", GetInterfaceHash(GetXDrawPageForSdrPage(&mrPage))); - aJsonWriter.put("index", 0); + aJsonWriter.put("type", "bitmap"); { auto aContentNode = aJsonWriter.startNode("content"); @@ -203,47 +234,24 @@ bool SlideshowLayerRenderer::renderMaster(unsigned char* pBuffer, OString& rJson } rJsonMsg = aJsonWriter.finishAndGetAsOString(); - return true; + maRenderState.incrementIndex(); } -bool SlideshowLayerRenderer::renderSlide(unsigned char* pBuffer, OString& rJsonMsg) +bool SlideshowLayerRenderer::render(unsigned char* pBuffer, OString& rJsonMsg) { - RenderOptions aRenderOptions; - aRenderOptions.mbSkipMasterPageObjects = true; + // Reset state + maRenderState.resetPass(); RenderContext aRenderContext(pBuffer, mrModel, mrPage, maSlideSize); - createViewAndDraw(aRenderContext, aRenderOptions); + createViewAndDraw(aRenderContext); - ::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) -{ - if (maRenderStages.empty()) + // Check if we are done rendering all passes + if (maRenderState.noMoreOutput()) return false; - auto eRenderStage = maRenderStages.front(); - maRenderStages.pop_front(); + writeJSON(rJsonMsg); - switch (eRenderStage) - { - case SlideRenderStage::Master: - return renderMaster(pBuffer, rJsonMsg); - case SlideRenderStage::Slide: - return renderSlide(pBuffer, rJsonMsg); - }; + maRenderState.mnCurrentPass++; return true; } |