1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: viewobjectcontactofpageobj.cxx,v $
11 * $Revision: 1.2.18.1 $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_svx.hxx"
35 #include <svx/sdr/contact/viewobjectcontactofpageobj.hxx>
36 #include <svx/sdr/contact/viewcontactofpageobj.hxx>
37 #include <svx/svdopage.hxx>
38 #include <svx/sdr/contact/displayinfo.hxx>
39 #include <basegfx/polygon/b2dpolygontools.hxx>
40 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
41 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
42 #include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
43 #include <basegfx/matrix/b2dhommatrix.hxx>
44 #include <svx/svdpage.hxx>
46 #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx>
48 //////////////////////////////////////////////////////////////////////////////
50 using namespace com::sun::star
;
52 //////////////////////////////////////////////////////////////////////////////
58 class PagePrimitiveExtractor
: public ObjectContactOfPagePainter
, public Timer
61 // the ViewObjectContactOfPageObj using this painter
62 ViewObjectContactOfPageObj
& mrViewObjectContactOfPageObj
;
65 // basic constructor/destructor
66 PagePrimitiveExtractor(ViewObjectContactOfPageObj
& rVOC
);
67 virtual ~PagePrimitiveExtractor();
69 // LazyInvalidate request. Supported here to not automatically
70 // invalidate the second interaction state all the time at the
72 virtual void setLazyInvalidate(ViewObjectContact
& rVOC
);
74 // From baseclass Timer, the timeout call triggered by te LazyInvalidate mechanism
75 virtual void Timeout();
77 // get primitive visualization
78 drawinglayer::primitive2d::Primitive2DSequence
createPrimitive2DSequenceForPage(const DisplayInfo
& rDisplayInfo
);
80 // Own reaction on changes which will be forwarded to the OC of the owner-VOC
81 virtual void InvalidatePartOfView(const basegfx::B2DRange
& rRange
) const;
83 // forward access to SdrPageView of ViewObjectContactOfPageObj
84 virtual bool isOutputToPrinter() const;
85 virtual bool isOutputToWindow() const;
86 virtual bool isOutputToVirtualDevice() const;
87 virtual bool isOutputToRecordingMetaFile() const;
88 virtual bool isOutputToPDFFile() const;
89 virtual bool isDrawModeGray() const;
90 virtual bool isDrawModeBlackWhite() const;
91 virtual bool isDrawModeHighContrast() const;
92 virtual SdrPageView
* TryToGetSdrPageView() const;
93 virtual OutputDevice
* TryToGetOutputDevice() const;
96 PagePrimitiveExtractor::PagePrimitiveExtractor(
97 ViewObjectContactOfPageObj
& rVOC
)
98 : ObjectContactOfPagePainter(0, rVOC
.GetObjectContact()),
99 mrViewObjectContactOfPageObj(rVOC
)
101 // make this renderer a preview renderer
102 setPreviewRenderer(true);
109 PagePrimitiveExtractor::~PagePrimitiveExtractor()
111 // execute missing LazyInvalidates and stop timer
115 void PagePrimitiveExtractor::setLazyInvalidate(ViewObjectContact
& /*rVOC*/)
117 // do NOT call parent, but remember that something is to do by
118 // starting the LazyInvalidateTimer
122 // From baseclass Timer, the timeout call triggered by te LazyInvalidate mechanism
123 void PagePrimitiveExtractor::Timeout()
128 // invalidate all LazyInvalidate VOCs new situations
129 const sal_uInt32
nVOCCount(getViewObjectContactCount());
131 for(sal_uInt32
a(0); a
< nVOCCount
; a
++)
133 ViewObjectContact
* pCandidate
= getViewObjectContact(a
);
134 pCandidate
->triggerLazyInvalidate();
138 drawinglayer::primitive2d::Primitive2DSequence
PagePrimitiveExtractor::createPrimitive2DSequenceForPage(const DisplayInfo
& /*rDisplayInfo*/)
140 drawinglayer::primitive2d::Primitive2DSequence xRetval
;
141 const SdrPage
* pStartPage
= GetStartPage();
145 // update own ViewInformation2D for visualized page
146 const drawinglayer::geometry::ViewInformation2D
& rOriginalViewInformation
= mrViewObjectContactOfPageObj
.GetObjectContact().getViewInformation2D();
147 const drawinglayer::geometry::ViewInformation2D
aNewViewInformation2D(
148 rOriginalViewInformation
.getObjectTransformation(),
149 rOriginalViewInformation
.getViewTransformation(),
151 // #i101075# use empty range for page content here to force
152 // the content not to be physically clipped in any way. This
153 // would be possible, but would require the internal transformation
154 // which maps between the page visualisation object and the page
155 // content, including the aspect ratios (for details see in
156 // PagePreviewPrimitive2D::createLocalDecomposition)
159 GetXDrawPageForSdrPage(const_cast< SdrPage
* >(pStartPage
)),
160 0.0, // no time; page previews are not animated
161 rOriginalViewInformation
.getExtendedInformationSequence());
162 updateViewInformation2D(aNewViewInformation2D
);
164 // create copy of DisplayInfo to set PagePainting
165 DisplayInfo aDisplayInfo
;
168 ViewObjectContact
& rDrawPageVOContact
= pStartPage
->GetViewContact().GetViewObjectContact(*this);
170 // get whole Primitive2DSequence
171 xRetval
= rDrawPageVOContact
.getPrimitive2DSequenceHierarchy(aDisplayInfo
);
177 void PagePrimitiveExtractor::InvalidatePartOfView(const basegfx::B2DRange
& rRange
) const
179 // an invalidate is called at this view, this needs to be translated to an invalidate
180 // for the using VOC. Coordinates are in page coordinate system.
181 const SdrPage
* pStartPage
= GetStartPage();
183 if(pStartPage
&& !rRange
.isEmpty())
185 const basegfx::B2DRange
aPageRange(0.0, 0.0, (double)pStartPage
->GetWdt(), (double)pStartPage
->GetHgt());
187 if(rRange
.overlaps(aPageRange
))
189 // if object on the page is inside or overlapping with page, create ActionChanged() for
191 mrViewObjectContactOfPageObj
.ActionChanged();
196 // forward access to SdrPageView to VOCOfPageObj
197 bool PagePrimitiveExtractor::isOutputToPrinter() const { return mrViewObjectContactOfPageObj
.GetObjectContact().isOutputToPrinter(); }
198 bool PagePrimitiveExtractor::isOutputToWindow() const { return mrViewObjectContactOfPageObj
.GetObjectContact().isOutputToWindow(); }
199 bool PagePrimitiveExtractor::isOutputToVirtualDevice() const { return mrViewObjectContactOfPageObj
.GetObjectContact().isOutputToVirtualDevice(); }
200 bool PagePrimitiveExtractor::isOutputToRecordingMetaFile() const { return mrViewObjectContactOfPageObj
.GetObjectContact().isOutputToRecordingMetaFile(); }
201 bool PagePrimitiveExtractor::isOutputToPDFFile() const { return mrViewObjectContactOfPageObj
.GetObjectContact().isOutputToPDFFile(); }
202 bool PagePrimitiveExtractor::isDrawModeGray() const { return mrViewObjectContactOfPageObj
.GetObjectContact().isDrawModeGray(); }
203 bool PagePrimitiveExtractor::isDrawModeBlackWhite() const { return mrViewObjectContactOfPageObj
.GetObjectContact().isDrawModeBlackWhite(); }
204 bool PagePrimitiveExtractor::isDrawModeHighContrast() const { return mrViewObjectContactOfPageObj
.GetObjectContact().isDrawModeHighContrast(); }
205 SdrPageView
* PagePrimitiveExtractor::TryToGetSdrPageView() const { return mrViewObjectContactOfPageObj
.GetObjectContact().TryToGetSdrPageView(); }
206 OutputDevice
* PagePrimitiveExtractor::TryToGetOutputDevice() const { return mrViewObjectContactOfPageObj
.GetObjectContact().TryToGetOutputDevice(); }
207 } // end of namespace contact
208 } // end of namespace sdr
210 //////////////////////////////////////////////////////////////////////////////
216 drawinglayer::primitive2d::Primitive2DSequence
ViewObjectContactOfPageObj::createPrimitive2DSequence(const DisplayInfo
& rDisplayInfo
) const
218 drawinglayer::primitive2d::Primitive2DSequence xRetval
;
219 const SdrPageObj
& rPageObject((static_cast< ViewContactOfPageObj
& >(GetViewContact())).GetPageObj());
220 const SdrPage
* pPage
= rPageObject
.GetReferencedPage();
221 const svtools::ColorConfig aColorConfig
;
223 // get PageObject's geometry
224 basegfx::B2DHomMatrix aPageObjectTransform
;
226 const Rectangle
aPageObjectModelData(rPageObject
.GetLastBoundRect());
227 const basegfx::B2DRange
aPageObjectBound(
228 aPageObjectModelData
.Left(), aPageObjectModelData
.Top(),
229 aPageObjectModelData
.Right(), aPageObjectModelData
.Bottom());
231 aPageObjectTransform
.set(0, 0, aPageObjectBound
.getWidth());
232 aPageObjectTransform
.set(1, 1, aPageObjectBound
.getHeight());
233 aPageObjectTransform
.set(0, 2, aPageObjectBound
.getMinX());
234 aPageObjectTransform
.set(1, 2, aPageObjectBound
.getMinY());
237 // get displayed page's content. This is the uscaled page content
238 if(mpExtractor
&& pPage
)
240 // get displayed page's geometry
241 drawinglayer::primitive2d::Primitive2DSequence xPageContent
;
242 const Size
aPageSize(pPage
->GetSize());
243 const double fPageWidth(aPageSize
.getWidth());
244 const double fPageHeight(aPageSize
.getHeight());
246 // The case that a PageObject contains another PageObject which visualizes the
247 // same page again would lead to a recursion. Limit that recursion depth to one
248 // by using a local static bool
249 static bool bInCreatePrimitive2D(false);
251 if(bInCreatePrimitive2D
)
253 // Recursion is possible. Create a replacement primitive
254 xPageContent
.realloc(2);
255 const Color
aDocColor(aColorConfig
.GetColorValue(svtools::DOCCOLOR
).nColor
);
256 const Color
aBorderColor(aColorConfig
.GetColorValue(svtools::DOCBOUNDARIES
).nColor
);
257 const basegfx::B2DRange
aPageBound(0.0, 0.0, fPageWidth
, fPageHeight
);
258 const basegfx::B2DPolygon
aOutline(basegfx::tools::createPolygonFromRect(aPageBound
));
260 // add replacement fill
261 xPageContent
[0L] = drawinglayer::primitive2d::Primitive2DReference(
262 new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aOutline
), aDocColor
.getBColor()));
264 // add replacement border
265 xPageContent
[1L] = drawinglayer::primitive2d::Primitive2DReference(
266 new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline
, aBorderColor
.getBColor()));
270 // set recursion flag
271 bInCreatePrimitive2D
= true;
273 // init extractor, guarantee existance, set page there
274 mpExtractor
->SetStartPage(pPage
);
276 // create page content
277 xPageContent
= mpExtractor
->createPrimitive2DSequenceForPage(rDisplayInfo
);
279 // reset recursion flag
280 bInCreatePrimitive2D
= false;
284 if(xPageContent
.hasElements())
286 const uno::Reference
< drawing::XDrawPage
> xDrawPage(GetXDrawPageForSdrPage(const_cast< SdrPage
*>(pPage
)));
287 const drawinglayer::primitive2d::Primitive2DReference
xPagePreview(new drawinglayer::primitive2d::PagePreviewPrimitive2D(
288 xDrawPage
, aPageObjectTransform
, fPageWidth
, fPageHeight
, xPageContent
, true));
289 xRetval
= drawinglayer::primitive2d::Primitive2DSequence(&xPagePreview
, 1);
293 // add a gray outline frame, except not when printing
294 // #i102637# add frame also when printing and page exists (handout pages)
295 if(!GetObjectContact().isOutputToPrinter() || pPage
)
297 const Color
aFrameColor(aColorConfig
.GetColorValue(svtools::OBJECTBOUNDARIES
).nColor
);
298 basegfx::B2DPolygon
aOwnOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0)));
299 aOwnOutline
.transform(aPageObjectTransform
);
301 const drawinglayer::primitive2d::Primitive2DReference
xGrayFrame(
302 new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOwnOutline
, aFrameColor
.getBColor()));
304 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval
, xGrayFrame
);
310 ViewObjectContactOfPageObj::ViewObjectContactOfPageObj(ObjectContact
& rObjectContact
, ViewContact
& rViewContact
)
311 : ViewObjectContactOfSdrObj(rObjectContact
, rViewContact
),
312 mpExtractor(new PagePrimitiveExtractor(*this))
316 ViewObjectContactOfPageObj::~ViewObjectContactOfPageObj()
318 // delete the helper OC
321 // remember candidate and reset own pointer to avoid action when createPrimitive2DSequence()
322 // would be called for any reason
323 PagePrimitiveExtractor
* pCandidate
= mpExtractor
;
326 // also reset the StartPage to avoid ActionChanged() forwardings in the
327 // PagePrimitiveExtractor::InvalidatePartOfView() implementation
328 pCandidate
->SetStartPage(0);
332 } // end of namespace contact
333 } // end of namespace sdr
335 //////////////////////////////////////////////////////////////////////////////