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 <drawinglayer/primitive2d/sceneprimitive2d.hxx>
30 : : #include <basegfx/tools/canvastools.hxx>
31 : : #include <basegfx/polygon/b2dpolygontools.hxx>
32 : : #include <basegfx/polygon/b2dpolygon.hxx>
33 : : #include <basegfx/polygon/b2dpolygonclipper.hxx>
34 : : #include <basegfx/polygon/b2dpolypolygontools.hxx>
35 : : #include <basegfx/matrix/b2dhommatrix.hxx>
36 : : #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
37 : : #include <drawinglayer/processor3d/zbufferprocessor3d.hxx>
38 : : #include <drawinglayer/processor3d/shadow3dextractor.hxx>
39 : : #include <drawinglayer/geometry/viewinformation2d.hxx>
40 : : #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
41 : : #include <svtools/optionsdrawinglayer.hxx>
42 : : #include <drawinglayer/processor3d/geometry2dextractor.hxx>
43 : : #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
44 : :
45 : : //////////////////////////////////////////////////////////////////////////////
46 : :
47 : : using namespace com::sun::star;
48 : :
49 : : //////////////////////////////////////////////////////////////////////////////
50 : :
51 : : namespace drawinglayer
52 : : {
53 : : namespace primitive2d
54 : : {
55 : 120 : bool ScenePrimitive2D::impGetShadow3D(const geometry::ViewInformation2D& /*rViewInformation*/) const
56 : : {
57 [ + - ]: 120 : ::osl::MutexGuard aGuard( m_aMutex );
58 : :
59 : : // create on demand
60 [ + + ][ + - ]: 120 : if(!mbShadow3DChecked && getChildren3D().hasElements())
[ + + ]
61 : : {
62 : 15 : basegfx::B3DVector aLightNormal;
63 [ + - ]: 15 : const double fShadowSlant(getSdrSceneAttribute().getShadowSlant());
64 [ + - ]: 15 : const basegfx::B3DRange aScene3DRange(primitive3d::getB3DRangeFromPrimitive3DSequence(getChildren3D(), getViewInformation3D()));
65 : :
66 [ + - ][ + - ]: 15 : if(maSdrLightingAttribute.getLightVector().size())
67 : : {
68 : : // get light normal from first light and normalize
69 [ + - ][ + - ]: 15 : aLightNormal = maSdrLightingAttribute.getLightVector()[0].getDirection();
[ + - ][ + - ]
70 [ + - ]: 15 : aLightNormal.normalize();
71 : : }
72 : :
73 : : // create shadow extraction processor
74 : : processor3d::Shadow3DExtractingProcessor aShadowProcessor(
75 : 15 : getViewInformation3D(),
76 : 15 : getObjectTransformation(),
77 : : aLightNormal,
78 : : fShadowSlant,
79 [ + - ]: 15 : aScene3DRange);
80 : :
81 : : // process local primitives
82 [ + - ]: 15 : aShadowProcessor.process(getChildren3D());
83 : :
84 : : // fetch result and set checked flag
85 [ + - ][ + - ]: 15 : const_cast< ScenePrimitive2D* >(this)->maShadowPrimitives = aShadowProcessor.getPrimitive2DSequence();
[ + - ]
86 [ + - ]: 15 : const_cast< ScenePrimitive2D* >(this)->mbShadow3DChecked = true;
87 : : }
88 : :
89 : : // return if there are shadow primitives
90 [ + - ]: 120 : return maShadowPrimitives.hasElements();
91 : : }
92 : :
93 : 30 : void ScenePrimitive2D::calculateDiscreteSizes(
94 : : const geometry::ViewInformation2D& rViewInformation,
95 : : basegfx::B2DRange& rDiscreteRange,
96 : : basegfx::B2DRange& rVisibleDiscreteRange,
97 : : basegfx::B2DRange& rUnitVisibleRange) const
98 : : {
99 : : // use unit range and transform to discrete coordinates
100 : 30 : rDiscreteRange = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0);
101 [ + - ]: 30 : rDiscreteRange.transform(rViewInformation.getObjectToViewTransformation() * getObjectTransformation());
102 : :
103 : : // clip it against discrete Viewport (if set)
104 : 30 : rVisibleDiscreteRange = rDiscreteRange;
105 : :
106 [ + + ]: 30 : if(!rViewInformation.getViewport().isEmpty())
107 : : {
108 : 4 : rVisibleDiscreteRange.intersect(rViewInformation.getDiscreteViewport());
109 : : }
110 : :
111 [ - + ]: 30 : if(rVisibleDiscreteRange.isEmpty())
112 : : {
113 : 0 : rUnitVisibleRange = rVisibleDiscreteRange;
114 : : }
115 : : else
116 : : {
117 : : // create UnitVisibleRange containing unit range values [0.0 .. 1.0] describing
118 : : // the relative position of rVisibleDiscreteRange inside rDiscreteRange
119 [ - + ][ + - ]: 30 : const double fDiscreteScaleFactorX(basegfx::fTools::equalZero(rDiscreteRange.getWidth()) ? 1.0 : 1.0 / rDiscreteRange.getWidth());
120 [ - + ][ + - ]: 30 : const double fDiscreteScaleFactorY(basegfx::fTools::equalZero(rDiscreteRange.getHeight()) ? 1.0 : 1.0 / rDiscreteRange.getHeight());
121 : :
122 [ + - ]: 30 : const double fMinX(basegfx::fTools::equal(rVisibleDiscreteRange.getMinX(), rDiscreteRange.getMinX())
123 : : ? 0.0
124 [ # # ][ # # ]: 30 : : (rVisibleDiscreteRange.getMinX() - rDiscreteRange.getMinX()) * fDiscreteScaleFactorX);
[ + - ]
125 [ + - ]: 30 : const double fMinY(basegfx::fTools::equal(rVisibleDiscreteRange.getMinY(), rDiscreteRange.getMinY())
126 : : ? 0.0
127 [ # # ][ # # ]: 30 : : (rVisibleDiscreteRange.getMinY() - rDiscreteRange.getMinY()) * fDiscreteScaleFactorY);
[ + - ]
128 : :
129 [ + - ]: 30 : const double fMaxX(basegfx::fTools::equal(rVisibleDiscreteRange.getMaxX(), rDiscreteRange.getMaxX())
130 : : ? 1.0
131 [ # # ][ # # ]: 30 : : (rVisibleDiscreteRange.getMaxX() - rDiscreteRange.getMinX()) * fDiscreteScaleFactorX);
[ + - ]
132 [ + - ]: 30 : const double fMaxY(basegfx::fTools::equal(rVisibleDiscreteRange.getMaxY(), rDiscreteRange.getMaxY())
133 : : ? 1.0
134 [ + - ][ + - ]: 30 : : (rVisibleDiscreteRange.getMaxY() - rDiscreteRange.getMinY()) * fDiscreteScaleFactorY);
[ + + ]
135 : :
136 : 30 : rUnitVisibleRange = basegfx::B2DRange(fMinX, fMinY, fMaxX, fMaxY);
137 : : }
138 : 30 : }
139 : :
140 : 15 : Primitive2DSequence ScenePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
141 : : {
142 [ + - ]: 15 : Primitive2DSequence aRetval;
143 : :
144 : : // create 2D shadows from contained 3D primitives. This creates the shadow primitives on demand and tells if
145 : : // there are some or not. Do this at start, the shadow might still be visible even when the scene is not
146 [ + - ][ - + ]: 15 : if(impGetShadow3D(rViewInformation))
147 : : {
148 : : // test visibility
149 : : const basegfx::B2DRange aShadow2DRange(
150 [ # # ]: 0 : getB2DRangeFromPrimitive2DSequence(maShadowPrimitives, rViewInformation));
151 : : const basegfx::B2DRange aViewRange(
152 [ # # ]: 0 : rViewInformation.getViewport());
153 : :
154 [ # # ][ # # ]: 0 : if(aViewRange.isEmpty() || aShadow2DRange.overlaps(aViewRange))
[ # # ][ # # ]
[ # # ]
155 : : {
156 : : // add extracted 2d shadows (before 3d scene creations itself)
157 [ # # ]: 0 : aRetval = maShadowPrimitives;
158 : : }
159 : : }
160 : :
161 : : // get the involved ranges (see helper method calculateDiscreteSizes for details)
162 [ + - ]: 15 : basegfx::B2DRange aDiscreteRange;
163 [ + - ]: 15 : basegfx::B2DRange aVisibleDiscreteRange;
164 [ + - ]: 15 : basegfx::B2DRange aUnitVisibleRange;
165 : :
166 [ + - ]: 15 : calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange);
167 : :
168 [ + - ][ + - ]: 15 : if(!aVisibleDiscreteRange.isEmpty())
169 : : {
170 : : // test if discrete view size (pixel) maybe too big and limit it
171 [ + - ]: 15 : double fViewSizeX(aVisibleDiscreteRange.getWidth());
172 [ + - ]: 15 : double fViewSizeY(aVisibleDiscreteRange.getHeight());
173 : 15 : const double fViewVisibleArea(fViewSizeX * fViewSizeY);
174 [ + - ]: 15 : const SvtOptionsDrawinglayer aDrawinglayerOpt;
175 [ + - ]: 15 : const double fMaximumVisibleArea(aDrawinglayerOpt.GetQuadratic3DRenderLimit());
176 : 15 : double fReduceFactor(1.0);
177 : :
178 [ - + ]: 15 : if(fViewVisibleArea > fMaximumVisibleArea)
179 : : {
180 : 0 : fReduceFactor = sqrt(fMaximumVisibleArea / fViewVisibleArea);
181 : 0 : fViewSizeX *= fReduceFactor;
182 : 0 : fViewSizeY *= fReduceFactor;
183 : : }
184 : :
185 [ + - ][ - + ]: 15 : if(rViewInformation.getReducedDisplayQuality())
186 : : {
187 : : // when reducing the visualisation is allowed (e.g. an OverlayObject
188 : : // only needed for dragging), reduce resolution extra
189 : : // to speed up dragging interactions
190 : 0 : const double fArea(fViewSizeX * fViewSizeY);
191 : 0 : double fReducedVisualisationFactor(1.0 / (sqrt(fArea) * (1.0 / 170.0)));
192 : :
193 [ # # ]: 0 : if(fReducedVisualisationFactor > 1.0)
194 : : {
195 : 0 : fReducedVisualisationFactor = 1.0;
196 : : }
197 [ # # ]: 0 : else if(fReducedVisualisationFactor < 0.20)
198 : : {
199 : 0 : fReducedVisualisationFactor = 0.20;
200 : : }
201 : :
202 [ # # ]: 0 : if(fReducedVisualisationFactor != 1.0)
203 : : {
204 : 0 : fReduceFactor *= fReducedVisualisationFactor;
205 : 0 : fViewSizeX *= fReducedVisualisationFactor;
206 : 0 : fViewSizeY *= fReducedVisualisationFactor;
207 : : }
208 : : }
209 : :
210 : : // calculate logic render size in world coordinates for usage in renderer
211 : : basegfx::B2DVector aLogicRenderSize(
212 [ + - ]: 15 : aDiscreteRange.getWidth() * fReduceFactor,
213 [ + - ]: 30 : aDiscreteRange.getHeight() * fReduceFactor);
214 [ + - ][ + - ]: 15 : aLogicRenderSize *= rViewInformation.getInverseObjectToViewTransformation();
215 : :
216 : : // determine the oversample value
217 : : static sal_uInt16 nDefaultOversampleValue(3);
218 [ + - ][ - + ]: 15 : const sal_uInt16 nOversampleValue(aDrawinglayerOpt.IsAntiAliasing() ? nDefaultOversampleValue : 0);
219 : :
220 : : // use default 3D primitive processor to create BitmapEx for aUnitVisiblePart and process
221 : : processor3d::ZBufferProcessor3D aZBufferProcessor3D(
222 : 15 : getViewInformation3D(),
223 : : rViewInformation,
224 : 15 : getSdrSceneAttribute(),
225 : 15 : getSdrLightingAttribute(),
226 : : aLogicRenderSize.getX(),
227 : : aLogicRenderSize.getY(),
228 : : aUnitVisibleRange,
229 [ + - ]: 30 : nOversampleValue);
230 : :
231 [ + - ]: 15 : aZBufferProcessor3D.process(getChildren3D());
232 [ + - ]: 15 : aZBufferProcessor3D.finish();
233 : :
234 [ + - ][ + - ]: 15 : const_cast< ScenePrimitive2D* >(this)->maOldRenderedBitmap = aZBufferProcessor3D.getBitmapEx();
[ + - ]
235 : 15 : const Size aBitmapSizePixel(maOldRenderedBitmap.GetSizePixel());
236 : :
237 [ + - ][ + - ]: 15 : if(aBitmapSizePixel.getWidth() && aBitmapSizePixel.getHeight())
[ + - ]
238 : : {
239 : : // create transform for the created bitmap in discrete coordinates first.
240 [ + - ]: 15 : basegfx::B2DHomMatrix aNew2DTransform;
241 : :
242 [ + - ][ + - ]: 15 : aNew2DTransform.set(0, 0, aVisibleDiscreteRange.getWidth());
243 [ + - ][ + - ]: 15 : aNew2DTransform.set(1, 1, aVisibleDiscreteRange.getHeight());
244 [ + - ][ + - ]: 15 : aNew2DTransform.set(0, 2, aVisibleDiscreteRange.getMinX());
245 [ + - ][ + - ]: 15 : aNew2DTransform.set(1, 2, aVisibleDiscreteRange.getMinY());
246 : :
247 : : // transform back to world coordinates for usage in primitive creation
248 [ + - ][ + - ]: 15 : aNew2DTransform *= rViewInformation.getInverseObjectToViewTransformation();
249 : :
250 : : // create bitmap primitive and add
251 [ + - ][ + - ]: 15 : const Primitive2DReference xRef(new BitmapPrimitive2D(maOldRenderedBitmap, aNew2DTransform));
[ + - ]
252 [ + - ]: 15 : appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xRef);
253 : :
254 : : // test: Allow to add an outline in the debugger when tests are needed
255 : : static bool bAddOutlineToCreated3DSceneRepresentation(false);
256 : :
257 [ - + ]: 15 : if(bAddOutlineToCreated3DSceneRepresentation)
258 : : {
259 [ # # ]: 0 : basegfx::B2DPolygon aOutline(basegfx::tools::createUnitPolygon());
260 [ # # ]: 0 : aOutline.transform(aNew2DTransform);
261 [ # # ][ # # ]: 0 : const Primitive2DReference xRef2(new PolygonHairlinePrimitive2D(aOutline, basegfx::BColor(1.0, 0.0, 0.0)));
[ # # ]
262 [ # # ][ # # ]: 0 : appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, xRef2);
263 [ + - ]: 15 : }
264 [ + - ][ + - ]: 15 : }
265 : : }
266 : :
267 : 15 : return aRetval;
268 : : }
269 : :
270 : 0 : Primitive2DSequence ScenePrimitive2D::getGeometry2D() const
271 : : {
272 : 0 : Primitive2DSequence aRetval;
273 : :
274 : : // create 2D projected geometry from 3D geometry
275 [ # # ]: 0 : if(getChildren3D().hasElements())
276 : : {
277 : : // create 2D geometry extraction processor
278 : : processor3d::Geometry2DExtractingProcessor aGeometryProcessor(
279 : 0 : getViewInformation3D(),
280 [ # # ]: 0 : getObjectTransformation());
281 : :
282 : : // process local primitives
283 [ # # ]: 0 : aGeometryProcessor.process(getChildren3D());
284 : :
285 : : // fetch result
286 [ # # ][ # # ]: 0 : aRetval = aGeometryProcessor.getPrimitive2DSequence();
287 : : }
288 : :
289 : 0 : return aRetval;
290 : : }
291 : :
292 : 0 : Primitive2DSequence ScenePrimitive2D::getShadow2D(const geometry::ViewInformation2D& rViewInformation) const
293 : : {
294 : 0 : Primitive2DSequence aRetval;
295 : :
296 : : // create 2D shadows from contained 3D primitives
297 [ # # ][ # # ]: 0 : if(impGetShadow3D(rViewInformation))
298 : : {
299 : : // add extracted 2d shadows (before 3d scene creations itself)
300 [ # # ]: 0 : aRetval = maShadowPrimitives;
301 : : }
302 : :
303 : 0 : return aRetval;
304 : : }
305 : :
306 : 0 : bool ScenePrimitive2D::tryToCheckLastVisualisationDirectHit(const basegfx::B2DPoint& rLogicHitPoint, bool& o_rResult) const
307 : : {
308 [ # # ][ # # ]: 0 : if(!maOldRenderedBitmap.IsEmpty() && !maOldUnitVisiblePart.isEmpty())
[ # # ]
309 : : {
310 [ # # ]: 0 : basegfx::B2DHomMatrix aInverseSceneTransform(getObjectTransformation());
311 [ # # ]: 0 : aInverseSceneTransform.invert();
312 [ # # ]: 0 : const basegfx::B2DPoint aRelativePoint(aInverseSceneTransform * rLogicHitPoint);
313 : :
314 [ # # ][ # # ]: 0 : if(maOldUnitVisiblePart.isInside(aRelativePoint))
315 : : {
316 : : // calculate coordinates relative to visualized part
317 [ # # ]: 0 : double fDivisorX(maOldUnitVisiblePart.getWidth());
318 [ # # ]: 0 : double fDivisorY(maOldUnitVisiblePart.getHeight());
319 : :
320 [ # # ]: 0 : if(basegfx::fTools::equalZero(fDivisorX))
321 : : {
322 : 0 : fDivisorX = 1.0;
323 : : }
324 : :
325 [ # # ]: 0 : if(basegfx::fTools::equalZero(fDivisorY))
326 : : {
327 : 0 : fDivisorY = 1.0;
328 : : }
329 : :
330 [ # # ]: 0 : const double fRelativeX((aRelativePoint.getX() - maOldUnitVisiblePart.getMinX()) / fDivisorX);
331 [ # # ]: 0 : const double fRelativeY((aRelativePoint.getY() - maOldUnitVisiblePart.getMinY()) / fDivisorY);
332 : :
333 : : // combine with real BitmapSizePixel to get bitmap coordinates
334 : 0 : const Size aBitmapSizePixel(maOldRenderedBitmap.GetSizePixel());
335 : 0 : const sal_Int32 nX(basegfx::fround(fRelativeX * aBitmapSizePixel.Width()));
336 : 0 : const sal_Int32 nY(basegfx::fround(fRelativeY * aBitmapSizePixel.Height()));
337 : :
338 : : // try to get a statement about transparency in that pixel
339 [ # # ]: 0 : o_rResult = (0xff != maOldRenderedBitmap.GetTransparency(nX, nY));
340 : 0 : return true;
341 [ # # ][ # # ]: 0 : }
[ # # ]
342 : : }
343 : :
344 : 0 : return false;
345 : : }
346 : :
347 : 15 : ScenePrimitive2D::ScenePrimitive2D(
348 : : const primitive3d::Primitive3DSequence& rxChildren3D,
349 : : const attribute::SdrSceneAttribute& rSdrSceneAttribute,
350 : : const attribute::SdrLightingAttribute& rSdrLightingAttribute,
351 : : const basegfx::B2DHomMatrix& rObjectTransformation,
352 : : const geometry::ViewInformation3D& rViewInformation3D)
353 : : : BufferedDecompositionPrimitive2D(),
354 : : mxChildren3D(rxChildren3D),
355 : : maSdrSceneAttribute(rSdrSceneAttribute),
356 : : maSdrLightingAttribute(rSdrLightingAttribute),
357 : : maObjectTransformation(rObjectTransformation),
358 : : maViewInformation3D(rViewInformation3D),
359 : : maShadowPrimitives(),
360 : : mbShadow3DChecked(false),
361 : : mfOldDiscreteSizeX(0.0),
362 : : mfOldDiscreteSizeY(0.0),
363 : : maOldUnitVisiblePart(),
364 [ + - ][ + - ]: 15 : maOldRenderedBitmap()
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
365 : : {
366 : 15 : }
367 : :
368 : 0 : bool ScenePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
369 : : {
370 [ # # ]: 0 : if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
371 : : {
372 : 0 : const ScenePrimitive2D& rCompare = (ScenePrimitive2D&)rPrimitive;
373 : :
374 : 0 : return (primitive3d::arePrimitive3DSequencesEqual(getChildren3D(), rCompare.getChildren3D())
375 : 0 : && getSdrSceneAttribute() == rCompare.getSdrSceneAttribute()
376 : 0 : && getSdrLightingAttribute() == rCompare.getSdrLightingAttribute()
377 : 0 : && getObjectTransformation() == rCompare.getObjectTransformation()
378 [ # # ][ # # : 0 : && getViewInformation3D() == rCompare.getViewInformation3D());
# # # # #
# ]
379 : : }
380 : :
381 : 0 : return false;
382 : : }
383 : :
384 : 105 : basegfx::B2DRange ScenePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
385 : : {
386 : : // transform unit range to discrete coordinate range
387 : 105 : basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
388 [ + - ]: 105 : aRetval.transform(rViewInformation.getObjectToViewTransformation() * getObjectTransformation());
389 : :
390 : : // force to discrete expanded bounds (it grows, so expanding works perfectly well)
391 [ + - ]: 105 : aRetval.expand(basegfx::B2DTuple(floor(aRetval.getMinX()), floor(aRetval.getMinY())));
392 [ + - ]: 105 : aRetval.expand(basegfx::B2DTuple(ceil(aRetval.getMaxX()), ceil(aRetval.getMaxY())));
393 : :
394 : : // transform back from discrete (view) to world coordinates
395 : 105 : aRetval.transform(rViewInformation.getInverseObjectToViewTransformation());
396 : :
397 : : // expand by evtl. existing shadow primitives
398 [ - + ]: 105 : if(impGetShadow3D(rViewInformation))
399 : : {
400 [ # # ]: 0 : const basegfx::B2DRange aShadow2DRange(getB2DRangeFromPrimitive2DSequence(maShadowPrimitives, rViewInformation));
401 : :
402 [ # # ][ # # ]: 0 : if(!aShadow2DRange.isEmpty())
403 : : {
404 [ # # ]: 0 : aRetval.expand(aShadow2DRange);
405 : : }
406 : : }
407 : :
408 : 105 : return aRetval;
409 : : }
410 : :
411 : 15 : Primitive2DSequence ScenePrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
412 : : {
413 [ + - ]: 15 : ::osl::MutexGuard aGuard( m_aMutex );
414 : :
415 : : // get the involved ranges (see helper method calculateDiscreteSizes for details)
416 [ + - ]: 15 : basegfx::B2DRange aDiscreteRange;
417 [ + - ]: 15 : basegfx::B2DRange aUnitVisibleRange;
418 : 15 : bool bNeedNewDecomposition(false);
419 : 15 : bool bDiscreteSizesAreCalculated(false);
420 : :
421 [ - + ]: 15 : if(getBuffered2DDecomposition().hasElements())
422 : : {
423 [ # # ]: 0 : basegfx::B2DRange aVisibleDiscreteRange;
424 [ # # ]: 0 : calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange);
425 : 0 : bDiscreteSizesAreCalculated = true;
426 : :
427 : : // needs to be painted when the new part is not part of the last
428 : : // decomposition
429 [ # # ][ # # ]: 0 : if(!maOldUnitVisiblePart.isInside(aUnitVisibleRange))
430 : : {
431 : 0 : bNeedNewDecomposition = true;
432 : : }
433 : :
434 : : // display has changed and cannot be reused when resolution got bigger. It
435 : : // can be reused when resolution got smaller, though.
436 [ # # ]: 0 : if(!bNeedNewDecomposition)
437 : : {
438 [ # # ]: 0 : if(basegfx::fTools::more(aDiscreteRange.getWidth(), mfOldDiscreteSizeX) ||
[ # # # # ]
[ # # ]
[ # # # # ]
439 [ # # ][ # # ]: 0 : basegfx::fTools::more(aDiscreteRange.getHeight(), mfOldDiscreteSizeY))
[ # # ]
440 : : {
441 : 0 : bNeedNewDecomposition = true;
442 : : }
443 : : }
444 : : }
445 : :
446 [ - + ]: 15 : if(bNeedNewDecomposition)
447 : : {
448 : : // conditions of last local decomposition have changed, delete
449 [ # # ][ # # ]: 0 : const_cast< ScenePrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence());
[ # # ]
450 : : }
451 : :
452 [ + - ]: 15 : if(!getBuffered2DDecomposition().hasElements())
453 : : {
454 [ + - ]: 15 : if(!bDiscreteSizesAreCalculated)
455 : : {
456 [ + - ]: 15 : basegfx::B2DRange aVisibleDiscreteRange;
457 [ + - ]: 15 : calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange);
458 : : }
459 : :
460 : : // remember last used NewDiscreteSize and NewUnitVisiblePart
461 : 15 : ScenePrimitive2D* pThat = const_cast< ScenePrimitive2D* >(this);
462 [ + - ]: 15 : pThat->mfOldDiscreteSizeX = aDiscreteRange.getWidth();
463 [ + - ]: 15 : pThat->mfOldDiscreteSizeY = aDiscreteRange.getHeight();
464 : 15 : pThat->maOldUnitVisiblePart = aUnitVisibleRange;
465 : : }
466 : :
467 : : // use parent implementation
468 [ + - ][ + - ]: 15 : return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation);
469 : : }
470 : :
471 : : // provide unique ID
472 : 30 : ImplPrimitrive2DIDBlock(ScenePrimitive2D, PRIMITIVE2D_ID_SCENEPRIMITIVE2D)
473 : :
474 : : } // end of namespace primitive2d
475 : : } // end of namespace drawinglayer
476 : :
477 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|