Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <svx/sdr/overlay/overlaymanager.hxx>
30 : : #include <basegfx/point/b2dpoint.hxx>
31 : : #include <basegfx/range/b2drange.hxx>
32 : : #include <tools/gen.hxx>
33 : : #include <vcl/outdev.hxx>
34 : : #include <vcl/window.hxx>
35 : : #include <svx/sdr/overlay/overlayobject.hxx>
36 : : #include <basegfx/matrix/b2dhommatrix.hxx>
37 : : #include <drawinglayer/processor2d/baseprocessor2d.hxx>
38 : : #include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
39 : :
40 : : //////////////////////////////////////////////////////////////////////////////
41 : :
42 : : using namespace com::sun::star;
43 : :
44 : : //////////////////////////////////////////////////////////////////////////////
45 : :
46 : : namespace sdr
47 : : {
48 : : namespace overlay
49 : : {
50 : 3292 : void OverlayManager::ImpDrawMembers(const basegfx::B2DRange& rRange, OutputDevice& rDestinationDevice) const
51 : : {
52 : 3292 : const sal_uInt32 nSize(maOverlayObjects.size());
53 : :
54 [ + + ]: 3292 : if(nSize)
55 : : {
56 : 3235 : const sal_uInt16 nOriginalAA(rDestinationDevice.GetAntialiasing());
57 : 3235 : const bool bIsAntiAliasing(getDrawinglayerOpt().IsAntiAliasing());
58 : :
59 : : // create processor
60 : : drawinglayer::processor2d::BaseProcessor2D* pProcessor =
61 : : ::drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
62 : : rDestinationDevice,
63 [ + - ]: 3235 : getCurrentViewInformation2D());
64 : :
65 [ + - ]: 3235 : if(pProcessor)
66 : : {
67 [ + - ][ + - ]: 18171 : for(OverlayObjectVector::const_iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); ++aIter)
[ + + ]
68 : : {
69 : : OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)");
70 [ + - ]: 14936 : const OverlayObject& rCandidate = **aIter;
71 : :
72 [ + - ]: 14936 : if(rCandidate.isVisible())
73 : : {
74 [ + - ]: 14936 : const drawinglayer::primitive2d::Primitive2DSequence& rSequence = rCandidate.getOverlayObjectPrimitive2DSequence();
75 : :
76 [ + - ]: 14936 : if(rSequence.hasElements())
77 : : {
78 [ + - ][ + - ]: 14936 : if(rRange.overlaps(rCandidate.getBaseRange()))
[ + + ]
79 : : {
80 [ - + ][ # # ]: 12400 : if(bIsAntiAliasing && rCandidate.allowsAntiAliase())
[ - + ]
81 : : {
82 [ # # ]: 0 : rDestinationDevice.SetAntialiasing(nOriginalAA | ANTIALIASING_ENABLE_B2DDRAW);
83 : : }
84 : : else
85 : : {
86 [ + - ]: 12400 : rDestinationDevice.SetAntialiasing(nOriginalAA & ~ANTIALIASING_ENABLE_B2DDRAW);
87 : : }
88 : :
89 [ + - ]: 12400 : pProcessor->process(rSequence);
90 : : }
91 [ + - ]: 14936 : }
92 : : }
93 : : }
94 : :
95 [ + - ]: 3235 : delete pProcessor;
96 : : }
97 : :
98 : : // restore AA settings
99 : 3235 : rDestinationDevice.SetAntialiasing(nOriginalAA);
100 : : }
101 : 3292 : }
102 : :
103 : 1278 : void OverlayManager::ImpStripeDefinitionChanged()
104 : : {
105 : 1278 : const sal_uInt32 nSize(maOverlayObjects.size());
106 : :
107 [ - + ]: 1278 : if(nSize)
108 : : {
109 [ # # ][ # # ]: 0 : for(OverlayObjectVector::iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); ++aIter)
[ # # ]
110 : : {
111 : : OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)");
112 [ # # ]: 0 : OverlayObject& rCandidate = **aIter;
113 [ # # ]: 0 : rCandidate.stripeDefinitionHasChanged();
114 : : }
115 : : }
116 : 1278 : }
117 : :
118 : 0 : double OverlayManager::getDiscreteOne() const
119 : : {
120 [ # # ]: 0 : if(basegfx::fTools::equalZero(mfDiscreteOne))
121 : : {
122 [ # # ][ # # ]: 0 : const basegfx::B2DVector aDiscreteInLogic(getOutputDevice().GetInverseViewTransformation() * basegfx::B2DVector(1.0, 0.0));
[ # # ]
123 [ # # ]: 0 : const_cast< OverlayManager* >(this)->mfDiscreteOne = aDiscreteInLogic.getLength();
124 : : }
125 : :
126 : 0 : return mfDiscreteOne;
127 : : }
128 : :
129 : 1278 : OverlayManager::OverlayManager(
130 : : OutputDevice& rOutputDevice,
131 : : OverlayManager* pOldOverlayManager)
132 : : : Scheduler(),
133 : : mnRefCount(0),
134 : : rmOutputDevice(rOutputDevice),
135 : : maOverlayObjects(),
136 : : maStripeColorA(Color(COL_BLACK)),
137 : : maStripeColorB(Color(COL_WHITE)),
138 : : mnStripeLengthPixel(5),
139 : : maDrawinglayerOpt(),
140 : : maViewTransformation(),
141 : : maViewInformation2D(),
142 [ + - ][ + - ]: 1278 : mfDiscreteOne(0.0)
[ + - ][ + - ]
[ + - ]
143 : : {
144 : : // set Property 'ReducedDisplayQuality' to true to allow simpler interaction
145 : : // visualisations
146 : : static bool bUseReducedDisplayQualityForDrag(true);
147 : :
148 [ + - ]: 1278 : if(bUseReducedDisplayQualityForDrag)
149 : : {
150 [ + - ]: 1278 : uno::Sequence< beans::PropertyValue > xProperties(1);
151 [ + - ][ + - ]: 1278 : xProperties[0].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ReducedDisplayQuality"));
152 [ + - ][ + - ]: 1278 : xProperties[0].Value <<= true;
153 [ + - ][ + - ]: 1278 : maViewInformation2D = drawinglayer::geometry::ViewInformation2D(xProperties);
[ + - ][ + - ]
154 : : }
155 : :
156 [ - + ]: 1278 : if(pOldOverlayManager)
157 : : {
158 : : // take over OverlayObjects from given OverlayManager. Copy
159 : : // the vector of pointers
160 [ # # ]: 0 : maOverlayObjects = pOldOverlayManager->maOverlayObjects;
161 : 0 : const sal_uInt32 nSize(maOverlayObjects.size());
162 : :
163 [ # # ]: 0 : if(nSize)
164 : : {
165 [ # # ][ # # ]: 0 : for(OverlayObjectVector::iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); ++aIter)
[ # # ]
166 : : {
167 : : OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)");
168 [ # # ]: 0 : OverlayObject& rCandidate = **aIter;
169 : :
170 : : // remove from old and add to new OverlayManager
171 [ # # ]: 0 : pOldOverlayManager->impApplyRemoveActions(rCandidate);
172 [ # # ]: 0 : impApplyAddActions(rCandidate);
173 : : }
174 : :
175 : 0 : pOldOverlayManager->maOverlayObjects.clear();
176 : : }
177 : : }
178 : 1278 : }
179 : :
180 : 18 : rtl::Reference<OverlayManager> OverlayManager::create(
181 : : OutputDevice& rOutputDevice,
182 : : OverlayManager* pOldOverlayManager)
183 : : {
184 : : return rtl::Reference<OverlayManager>(new OverlayManager(rOutputDevice,
185 [ + - ]: 18 : pOldOverlayManager));
186 : : }
187 : :
188 : 12311 : const drawinglayer::geometry::ViewInformation2D OverlayManager::getCurrentViewInformation2D() const
189 : : {
190 [ + - ][ + + ]: 12311 : if(getOutputDevice().GetViewTransformation() != maViewTransformation)
191 : : {
192 [ + - ]: 336 : basegfx::B2DRange aViewRange(maViewInformation2D.getViewport());
193 : :
194 [ + - ]: 336 : if(OUTDEV_WINDOW == getOutputDevice().GetOutDevType())
195 : : {
196 : 336 : const Size aOutputSizePixel(getOutputDevice().GetOutputSizePixel());
197 [ + - ]: 336 : aViewRange = basegfx::B2DRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight());
198 [ + - ][ + - ]: 336 : aViewRange.transform(getOutputDevice().GetInverseViewTransformation());
[ + - ]
199 : : }
200 : :
201 : 336 : OverlayManager* pThis = const_cast< OverlayManager* >(this);
202 : :
203 [ + - ][ + - ]: 336 : pThis->maViewTransformation = getOutputDevice().GetViewTransformation();
[ + - ]
204 : : pThis->maViewInformation2D = drawinglayer::geometry::ViewInformation2D(
205 [ + - ]: 336 : maViewInformation2D.getObjectTransformation(),
206 : : maViewTransformation,
207 : : aViewRange,
208 [ + - ]: 336 : maViewInformation2D.getVisualizedPage(),
209 : : maViewInformation2D.getViewTime(),
210 [ + - ][ + - ]: 672 : maViewInformation2D.getExtendedInformationSequence());
[ + - ][ + - ]
[ + - ]
211 : 336 : pThis->mfDiscreteOne = 0.0;
212 : : }
213 : :
214 : 12311 : return maViewInformation2D;
215 : : }
216 : :
217 : 8934 : void OverlayManager::impApplyRemoveActions(OverlayObject& rTarget)
218 : : {
219 : : // handle evtl. animation
220 [ - + ]: 8934 : if(rTarget.allowsAnimation())
221 : : {
222 : : // remove from event chain
223 : 0 : RemoveEvent(&rTarget);
224 : : }
225 : :
226 : : // make invisible
227 : 8934 : invalidateRange(rTarget.getBaseRange());
228 : :
229 : : // clear manager
230 : 8934 : rTarget.mpOverlayManager = 0;
231 : 8934 : }
232 : :
233 : 8944 : void OverlayManager::impApplyAddActions(OverlayObject& rTarget)
234 : : {
235 : : // set manager
236 : 8944 : rTarget.mpOverlayManager = this;
237 : :
238 : : // make visible
239 : 8944 : invalidateRange(rTarget.getBaseRange());
240 : :
241 : : // handle evtl. animation
242 [ - + ]: 8944 : if(rTarget.allowsAnimation())
243 : : {
244 : : // Trigger at current time to get alive. This will do the
245 : : // object-specific next time calculation and hand over adding
246 : : // again to the scheduler to the animated object, too. This works for
247 : : // a paused or non-paused animator.
248 : 0 : rTarget.Trigger(GetTime());
249 : : }
250 : 8944 : }
251 : :
252 [ + - ][ + - ]: 1187 : OverlayManager::~OverlayManager()
[ + - ][ + - ]
253 : : {
254 : : // The OverlayManager is not the owner of the OverlayObjects
255 : : // and thus will not delete them, but remove them. Profit here
256 : : // from knowing that all will be removed
257 : 1187 : const sal_uInt32 nSize(maOverlayObjects.size());
258 : :
259 [ + + ]: 1187 : if(nSize)
260 : : {
261 [ + - ][ + - ]: 676 : for(OverlayObjectVector::iterator aIter(maOverlayObjects.begin()); aIter != maOverlayObjects.end(); ++aIter)
[ + + ]
262 : : {
263 : : OSL_ENSURE(*aIter, "Corrupted OverlayObject List (!)");
264 [ + - ]: 454 : OverlayObject& rCandidate = **aIter;
265 [ + - ]: 454 : impApplyRemoveActions(rCandidate);
266 : : }
267 : :
268 : : // erase vector
269 : 222 : maOverlayObjects.clear();
270 : : }
271 [ - + ]: 1205 : }
272 : :
273 : 15634 : void OverlayManager::completeRedraw(const Region& rRegion, OutputDevice* pPreRenderDevice) const
274 : : {
275 [ + - ][ + + ]: 15634 : if(!rRegion.IsEmpty() && maOverlayObjects.size())
[ + + ]
276 : : {
277 : : // check for changed MapModes. That may influence the
278 : : // logical size of pixel based OverlayObjects (like BitmapHandles)
279 : : //ImpCheckMapModeChange();
280 : :
281 : : // paint members
282 [ + - ]: 2169 : const Rectangle aRegionBoundRect(rRegion.GetBoundRect());
283 : : const basegfx::B2DRange aRegionRange(
284 : 2169 : aRegionBoundRect.Left(), aRegionBoundRect.Top(),
285 [ + - ]: 4338 : aRegionBoundRect.Right(), aRegionBoundRect.Bottom());
286 : :
287 [ - + ]: 2169 : OutputDevice& rTarget = (pPreRenderDevice) ? *pPreRenderDevice : getOutputDevice();
288 [ + - ]: 2169 : ImpDrawMembers(aRegionRange, rTarget);
289 : : }
290 : 15634 : }
291 : :
292 : 0 : void OverlayManager::flush()
293 : : {
294 : : // default has nothing to do
295 : 0 : }
296 : :
297 : : // #i68597# part of content gets copied, react on it
298 : 0 : void OverlayManager::copyArea(const Point& /*rDestPt*/, const Point& /*rSrcPt*/, const Size& /*rSrcSize*/)
299 : : {
300 : : // unbuffered versions do nothing here
301 : 0 : }
302 : :
303 : 0 : void OverlayManager::restoreBackground(const Region& /*rRegion*/) const
304 : : {
305 : : // unbuffered versions do nothing here
306 : 0 : }
307 : :
308 : 8944 : void OverlayManager::add(OverlayObject& rOverlayObject)
309 : : {
310 : : OSL_ENSURE(0 == rOverlayObject.mpOverlayManager, "OverlayObject is added twice to an OverlayManager (!)");
311 : :
312 : : // add to the end of chain to preserve display order in paint
313 [ + - ]: 8944 : maOverlayObjects.push_back(&rOverlayObject);
314 : :
315 : : // execute add actions
316 : 8944 : impApplyAddActions(rOverlayObject);
317 : 8944 : }
318 : :
319 : 8480 : void OverlayManager::remove(OverlayObject& rOverlayObject)
320 : : {
321 : : OSL_ENSURE(rOverlayObject.mpOverlayManager == this, "OverlayObject is removed from wrong OverlayManager (!)");
322 : :
323 : : // execute remove actions
324 [ + - ]: 8480 : impApplyRemoveActions(rOverlayObject);
325 : :
326 : : // remove from vector
327 [ + - ]: 8480 : const OverlayObjectVector::iterator aFindResult = ::std::find(maOverlayObjects.begin(), maOverlayObjects.end(), &rOverlayObject);
328 [ + - ]: 8480 : const bool bFound(aFindResult != maOverlayObjects.end());
329 : : OSL_ENSURE(bFound, "OverlayObject NOT found at OverlayManager (!)");
330 : :
331 [ + - ]: 8480 : if(bFound)
332 : : {
333 [ + - ]: 8480 : maOverlayObjects.erase(aFindResult);
334 : : }
335 : 8480 : }
336 : :
337 : 454 : void OverlayManager::invalidateRange(const basegfx::B2DRange& rRange)
338 : : {
339 [ + - ]: 454 : if(OUTDEV_WINDOW == getOutputDevice().GetOutDevType())
340 : : {
341 [ - + ]: 454 : if(getDrawinglayerOpt().IsAntiAliasing())
342 : : {
343 : : // assume AA needs one pixel more and invalidate one pixel more
344 [ # # ]: 0 : const double fDiscreteOne(getDiscreteOne());
345 : : const Rectangle aInvalidateRectangle(
346 [ # # ]: 0 : (sal_Int32)floor(rRange.getMinX() - fDiscreteOne),
347 [ # # ]: 0 : (sal_Int32)floor(rRange.getMinY() - fDiscreteOne),
348 [ # # ]: 0 : (sal_Int32)ceil(rRange.getMaxX() + fDiscreteOne),
349 [ # # ][ # # ]: 0 : (sal_Int32)ceil(rRange.getMaxY() + fDiscreteOne));
350 : :
351 : : // simply invalidate
352 [ # # ]: 0 : ((Window&)getOutputDevice()).Invalidate(aInvalidateRectangle, INVALIDATE_NOERASE);
353 : : }
354 : : else
355 : : {
356 : : // #i77674# transform to rectangle. Use floor/ceil to get all covered
357 : : // discrete pixels, see #i75163# and OverlayManagerBuffered::invalidateRange
358 : : const Rectangle aInvalidateRectangle(
359 [ + - ][ + - ]: 454 : (sal_Int32)floor(rRange.getMinX()), (sal_Int32)floor(rRange.getMinY()),
360 [ + - ][ + - ]: 908 : (sal_Int32)ceil(rRange.getMaxX()), (sal_Int32)ceil(rRange.getMaxY()));
[ + - ]
361 : :
362 : : // simply invalidate
363 [ + - ]: 454 : ((Window&)getOutputDevice()).Invalidate(aInvalidateRectangle, INVALIDATE_NOERASE);
364 : : }
365 : : }
366 : 454 : }
367 : :
368 : : // stripe support ColA
369 : 1278 : void OverlayManager::setStripeColorA(Color aNew)
370 : : {
371 [ - + ]: 1278 : if(aNew != maStripeColorA)
372 : : {
373 : 0 : maStripeColorA = aNew;
374 : 0 : ImpStripeDefinitionChanged();
375 : : }
376 : 1278 : }
377 : :
378 : : // stripe support ColB
379 : 1278 : void OverlayManager::setStripeColorB(Color aNew)
380 : : {
381 [ - + ]: 1278 : if(aNew != maStripeColorB)
382 : : {
383 : 0 : maStripeColorB = aNew;
384 : 0 : ImpStripeDefinitionChanged();
385 : : }
386 : 1278 : }
387 : :
388 : : // stripe support StripeLengthPixel
389 : 1278 : void OverlayManager::setStripeLengthPixel(sal_uInt32 nNew)
390 : : {
391 [ + - ]: 1278 : if(nNew != mnStripeLengthPixel)
392 : : {
393 : 1278 : mnStripeLengthPixel = nNew;
394 : 1278 : ImpStripeDefinitionChanged();
395 : : }
396 : 1278 : }
397 : :
398 : 12623 : oslInterlockedCount OverlayManager::acquire()
399 : : {
400 : 12623 : return osl_incrementInterlockedCount( &mnRefCount );
401 : : }
402 : :
403 : 12532 : oslInterlockedCount OverlayManager::release()
404 : : {
405 : 12532 : oslInterlockedCount nCount( osl_decrementInterlockedCount( &mnRefCount ) );
406 [ + + ]: 12532 : if ( nCount == 0 )
407 [ + - ]: 1187 : delete this;
408 : 12532 : return nCount;
409 : : }
410 : :
411 : : } // end of namespace overlay
412 : : } // end of namespace sdr
413 : :
414 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|