LibreOffice Module svx (master) 1
viewobjectcontactofpageobj.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <vcl/idle.hxx>
23#include <svx/svdopage.hxx>
25#include <svtools/colorcfg.hxx>
31#include <svx/svdpage.hxx>
32#include <svx/unoapi.hxx>
35#include <vcl/canvastools.hxx>
36
37using namespace com::sun::star;
38
39namespace sdr::contact {
40
42{
43private:
44 // the ViewObjectContactOfPageObj using this painter
46
47public:
48 // basic constructor/destructor
50 virtual ~PagePrimitiveExtractor() override;
51
52 // LazyInvalidate request. Supported here to not automatically
53 // invalidate the second interaction state all the time at the
54 // original OC
55 virtual void setLazyInvalidate(ViewObjectContact& rVOC) override;
56
57 // From baseclass Timer, the timeout call triggered by the LazyInvalidate mechanism
58 virtual void Invoke() final override;
59
60 // get primitive visualization
61 drawinglayer::primitive2d::Primitive2DContainer createPrimitive2DSequenceForPage();
62
63 // Own reaction on changes which will be forwarded to the OC of the owner-VOC
64 virtual void InvalidatePartOfView(const basegfx::B2DRange& rRange) const override;
65
66 // forward access to SdrPageView of ViewObjectContactOfPageObj
67 virtual bool isOutputToPrinter() const override;
68 virtual bool isOutputToRecordingMetaFile() const override;
69 virtual bool isOutputToPDFFile() const override;
70 virtual bool isDrawModeGray() const override;
71 virtual bool isDrawModeHighContrast() const override;
72 virtual SdrPageView* TryToGetSdrPageView() const override;
73 virtual OutputDevice* TryToGetOutputDevice() const override;
74};
75
78: ObjectContactOfPagePainter(rVOC.GetObjectContact()), Idle("svx PagePrimitiveExtractor"),
80{
81 // make this renderer a preview renderer
82 setPreviewRenderer(true);
83
84 // init timer
85 SetPriority(TaskPriority::HIGH_IDLE);
86 Stop();
87}
88
90{
91 // execute missing LazyInvalidates and stop timer
92 Invoke();
93}
94
96{
97 // do NOT call parent, but remember that something is to do by
98 // starting the LazyInvalidateTimer
99 Start();
100}
101
102// From baseclass Timer, the timeout call triggered by the LazyInvalidate mechanism
104{
105 // stop the timer
106 Stop();
107
108 // invalidate all LazyInvalidate VOCs new situations
109 const sal_uInt32 nVOCCount(getViewObjectContactCount());
110
111 for(sal_uInt32 a(0); a < nVOCCount; a++)
112 {
113 ViewObjectContact* pCandidate = getViewObjectContact(a);
114 pCandidate->triggerLazyInvalidate();
115 }
116}
117
119{
121 SdrPage* pStartPage = GetStartPage();
122
123 if(pStartPage)
124 {
125 // update own ViewInformation2D for visualized page
127 drawinglayer::geometry::ViewInformation2D aNewViewInformation2D(rOriginalViewInformation);
128
129 // #i101075# use empty range for page content here to force
130 // the content not to be physically clipped in any way. This
131 // would be possible, but would require the internal transformation
132 // which maps between the page visualisation object and the page
133 // content, including the aspect ratios (for details see in
134 // PagePreviewPrimitive2D::create2DDecomposition)
135 aNewViewInformation2D.setViewport(basegfx::B2DRange());
136
137 aNewViewInformation2D.setVisualizedPage(GetXDrawPageForSdrPage(pStartPage));
138
139 // no time; page previews are not animated
140 aNewViewInformation2D.setViewTime(0.0);
141
142 updateViewInformation2D(aNewViewInformation2D);
143
144 // create copy of DisplayInfo to set PagePainting
145 DisplayInfo aDisplayInfo;
146
147 // get page's VOC
148 ViewObjectContact& rDrawPageVOContact = pStartPage->GetViewContact().GetViewObjectContact(*this);
149
150 // get whole Primitive2DContainer
151 rDrawPageVOContact.getPrimitive2DSequenceHierarchy(aDisplayInfo, xRetval);
152 }
153
154 return xRetval;
155}
156
158{
159 // an invalidate is called at this view, this needs to be translated to an invalidate
160 // for the using VOC. Coordinates are in page coordinate system.
161 const SdrPage* pStartPage = GetStartPage();
162
163 if(pStartPage && !rRange.isEmpty())
164 {
165 const basegfx::B2DRange aPageRange(0.0, 0.0, static_cast<double>(pStartPage->GetWidth()), static_cast<double>(pStartPage->GetHeight()));
166
167 if(rRange.overlaps(aPageRange))
168 {
169 // if object on the page is inside or overlapping with page, create ActionChanged() for
170 // involved VOC
172 }
173 }
174}
175
176// forward access to SdrPageView to VOCOfPageObj
184
186{
187 const SdrPageObj& rPageObject(static_cast< ViewContactOfPageObj& >(GetViewContact()).GetPageObj());
188 const SdrPage* pPage = rPageObject.GetReferencedPage();
189 const svtools::ColorConfig aColorConfig;
190
191 // get PageObject's geometry
192 basegfx::B2DHomMatrix aPageObjectTransform;
193 {
194 const tools::Rectangle aPageObjectModelData(rPageObject.GetLastBoundRect());
195 const basegfx::B2DRange aPageObjectBound = vcl::unotools::b2DRectangleFromRectangle(aPageObjectModelData);
196
197 aPageObjectTransform.set(0, 0, aPageObjectBound.getWidth());
198 aPageObjectTransform.set(1, 1, aPageObjectBound.getHeight());
199 aPageObjectTransform.set(0, 2, aPageObjectBound.getMinX());
200 aPageObjectTransform.set(1, 2, aPageObjectBound.getMinY());
201 }
202
203 // #i102637# add gray frame also when printing and page exists (handout pages)
204 const bool bCreateGrayFrame(!GetObjectContact().isOutputToPrinter() || pPage);
205
206 // get displayed page's content. This is the unscaled page content
207 if(mpExtractor && pPage)
208 {
209 // get displayed page's geometry
211 const Size aPageSize(pPage->GetSize());
212 const double fPageWidth(aPageSize.getWidth());
213 const double fPageHeight(aPageSize.getHeight());
214
215 // The case that a PageObject contains another PageObject which visualizes the
216 // same page again would lead to a recursion. Limit that recursion depth to one
217 // by using a local static bool
218 static bool bInCreatePrimitive2D(false);
219
220 if(bInCreatePrimitive2D)
221 {
222 // Recursion is possible. Create a replacement primitive
223 xPageContent.resize(2);
224 const Color aDocColor(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
226 const Color aBorderColor = aBorderConfig.bIsVisible ? aBorderConfig.nColor : aDocColor;
227 const basegfx::B2DRange aPageBound(0.0, 0.0, fPageWidth, fPageHeight);
229
230 // add replacement fill
233
234 // add replacement border
236 new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(std::move(aOutline), aBorderColor.getBColor()));
237 }
238 else
239 {
240 // set recursion flag
241 bInCreatePrimitive2D = true;
242
243 // init extractor, guarantee existence, set page there
244 mpExtractor->SetStartPage(pPage);
245
246 // #i105548# also need to copy the VOCRedirector for sub-content creation
247 mpExtractor->SetViewObjectContactRedirector(GetObjectContact().GetViewObjectContactRedirector());
248
249 // create page content
250 xPageContent = mpExtractor->createPrimitive2DSequenceForPage();
251
252 // #i105548# reset VOCRedirector to not accidentally have a pointer to a
253 // temporary class, so calls to it are avoided safely
254 mpExtractor->SetViewObjectContactRedirector(nullptr);
255
256 // reset recursion flag
257 bInCreatePrimitive2D = false;
258 }
259
260 // prepare retval
261 if(!xPageContent.empty())
262 {
263 const uno::Reference< drawing::XDrawPage > xDrawPage(GetXDrawPageForSdrPage(const_cast< SdrPage*>(pPage)));
265 xDrawPage, aPageObjectTransform, fPageWidth, fPageHeight, std::move(xPageContent)));
266 rVisitor.visit(xPagePreview);
267 }
268 }
269 else if(bCreateGrayFrame)
270 {
271 // #i105146# no content, but frame display. To make hitting the page preview objects
272 // on the handout page more simple, add hidden fill geometry
275 aPageObjectTransform));
276 rVisitor.visit(xFrameHit);
277 }
278
279 // add a gray outline frame, except not when printing
280 if(bCreateGrayFrame)
281 {
282 const Color aFrameColor(aColorConfig.GetColorValue(svtools::OBJECTBOUNDARIES).nColor);
284 aOwnOutline.transform(aPageObjectTransform);
285
287 new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(std::move(aOwnOutline), aFrameColor.getBColor()));
288
289 rVisitor.visit(xGrayFrame);
290 }
291}
292
294: ViewObjectContactOfSdrObj(rObjectContact, rViewContact),
295 mpExtractor(new PagePrimitiveExtractor(*this))
296{
297}
298
300{
301 // delete the helper OC
302 if(mpExtractor)
303 {
304 // remember candidate and reset own pointer to avoid action when createPrimitive2DSequence()
305 // would be called for any reason
306 std::unique_ptr<PagePrimitiveExtractor> pCandidate = std::move(mpExtractor);
307
308 // also reset the StartPage to avoid ActionChanged() forwardings in the
309 // PagePrimitiveExtractor::InvalidatePartOfView() implementation
310 pCandidate->SetStartPage(nullptr);
311 }
312}
313
314}
315
316/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
basegfx::BColor getBColor() const
virtual void Start(bool bStartTimer=true) override
virtual const tools::Rectangle & GetLastBoundRect() const
Definition: svdobj.cxx:940
SdrPage * GetReferencedPage() const
Definition: svdopage.hxx:55
A SdrPage contains exactly one SdrObjList and a description of the physical page dimensions (size / m...
Definition: svdpage.hxx:377
const sdr::contact::ViewContact & GetViewContact() const
Definition: svdpage.cxx:1165
Size GetSize() const
Definition: svdpage.cxx:1458
tools::Long GetHeight() const
Definition: svdpage.cxx:1489
tools::Long GetWidth() const
Definition: svdpage.cxx:1463
constexpr tools::Long getHeight() const
constexpr tools::Long getWidth() const
void SetPriority(TaskPriority ePriority)
void Stop()
void set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue)
void transform(const basegfx::B2DHomMatrix &rMatrix)
TYPE getWidth() const
TYPE getMinX() const
TYPE getMinY() const
bool isEmpty() const
TYPE getHeight() const
bool overlaps(const Range2D &rRange) const
void setViewport(const basegfx::B2DRange &rNew)
void setVisualizedPage(const css::uno::Reference< css::drawing::XDrawPage > &rNew)
virtual void visit(const Primitive2DReference &)=0
virtual bool isDrawModeGray() const
virtual SdrPageView * TryToGetSdrPageView() const
access to SdrPageView. May return 0L like the default implementations do. Override as needed.
virtual bool isDrawModeHighContrast() const
virtual OutputDevice * TryToGetOutputDevice() const
access to OutputDevice. May return 0L like the default implementations do. Override as needed.
virtual bool isOutputToPDFFile() const
virtual bool isOutputToPrinter() const
const drawinglayer::geometry::ViewInformation2D & getViewInformation2D() const
virtual bool isOutputToRecordingMetaFile() const
virtual bool isDrawModeHighContrast() const override
virtual void setLazyInvalidate(ViewObjectContact &rVOC) override
drawinglayer::primitive2d::Primitive2DContainer createPrimitive2DSequenceForPage()
ViewObjectContactOfPageObj & mrViewObjectContactOfPageObj
PagePrimitiveExtractor(ViewObjectContactOfPageObj &rVOC)
virtual SdrPageView * TryToGetSdrPageView() const override
virtual void InvalidatePartOfView(const basegfx::B2DRange &rRange) const override
virtual bool isOutputToRecordingMetaFile() const override
virtual OutputDevice * TryToGetOutputDevice() const override
ViewObjectContact & GetViewObjectContact(ObjectContact &rObjectContact)
Definition: viewcontact.cxx:65
ViewObjectContactOfPageObj(ObjectContact &rObjectContact, ViewContact &rViewContact)
virtual void createPrimitive2DSequence(const DisplayInfo &rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor &rVisitor) const override
std::unique_ptr< PagePrimitiveExtractor > mpExtractor
ObjectContact & GetObjectContact() const
virtual void getPrimitive2DSequenceHierarchy(DisplayInfo &rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor &rVisitor) const
ColorConfigValue GetColorValue(ColorConfigEntry eEntry, bool bSmart=true) const
uno_Any a
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
B2DPolygon const & createUnitPolygon()
rtl::Reference< BasePrimitive2D > Primitive2DReference
Primitive2DReference createHiddenGeometryPrimitives2D(const basegfx::B2DHomMatrix &rMatrix)
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
uno::Reference< drawing::XDrawPage > GetXDrawPageForSdrPage(SdrPage *pPage) noexcept
returns a StarOffice API wrapper for the given SdrPage
Definition: unopage.cxx:873