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/polygonprimitive2d.hxx>
30 : : #include <basegfx/tools/canvastools.hxx>
31 : : #include <basegfx/polygon/b2dpolygontools.hxx>
32 : : #include <basegfx/polygon/b2dpolypolygontools.hxx>
33 : : #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
34 : : #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
35 : : #include <drawinglayer/geometry/viewinformation2d.hxx>
36 : : #include <basegfx/polygon/b2dlinegeometry.hxx>
37 : :
38 : : //////////////////////////////////////////////////////////////////////////////
39 : :
40 : : using namespace com::sun::star;
41 : :
42 : : //////////////////////////////////////////////////////////////////////////////
43 : :
44 : : namespace drawinglayer
45 : : {
46 : : namespace primitive2d
47 : : {
48 : 108709 : PolygonHairlinePrimitive2D::PolygonHairlinePrimitive2D(
49 : : const basegfx::B2DPolygon& rPolygon,
50 : : const basegfx::BColor& rBColor)
51 : : : BasePrimitive2D(),
52 : : maPolygon(rPolygon),
53 [ + - ]: 108709 : maBColor(rBColor)
54 : : {
55 : 108709 : }
56 : :
57 : 7479 : bool PolygonHairlinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
58 : : {
59 [ + - ]: 7479 : if(BasePrimitive2D::operator==(rPrimitive))
60 : : {
61 : 7479 : const PolygonHairlinePrimitive2D& rCompare = (PolygonHairlinePrimitive2D&)rPrimitive;
62 : :
63 : 7479 : return (getB2DPolygon() == rCompare.getB2DPolygon()
64 [ + - ][ + + ]: 7479 : && getBColor() == rCompare.getBColor());
65 : : }
66 : :
67 : 7479 : return false;
68 : : }
69 : :
70 : 9918 : basegfx::B2DRange PolygonHairlinePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
71 : : {
72 : : // this is a hairline, thus the line width is view-dependent. Get range of polygon
73 : : // as base size
74 : 9918 : basegfx::B2DRange aRetval(getB2DPolygon().getB2DRange());
75 : :
76 [ + - ]: 9918 : if(!aRetval.isEmpty())
77 : : {
78 : : // Calculate view-dependent hairline width
79 [ + - ][ + - ]: 9918 : const basegfx::B2DVector aDiscreteSize(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0));
80 [ + - ]: 9918 : const double fDiscreteHalfLineWidth(aDiscreteSize.getLength() * 0.5);
81 : :
82 [ + - ]: 9918 : if(basegfx::fTools::more(fDiscreteHalfLineWidth, 0.0))
83 : : {
84 [ + - ]: 9918 : aRetval.grow(fDiscreteHalfLineWidth);
85 : 9918 : }
86 : : }
87 : :
88 : : // return range
89 : 9918 : return aRetval;
90 : : }
91 : :
92 : : // provide unique ID
93 : 160036 : ImplPrimitrive2DIDBlock(PolygonHairlinePrimitive2D, PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D)
94 : :
95 : : } // end of namespace primitive2d
96 : : } // end of namespace drawinglayer
97 : :
98 : : //////////////////////////////////////////////////////////////////////////////
99 : :
100 : : namespace drawinglayer
101 : : {
102 : : namespace primitive2d
103 : : {
104 : 0 : Primitive2DSequence PolygonMarkerPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
105 : : {
106 : : // calculate logic DashLength
107 [ # # ][ # # ]: 0 : const basegfx::B2DVector aDashVector(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(getDiscreteDashLength(), 0.0));
108 : 0 : const double fLogicDashLength(aDashVector.getX());
109 : :
110 [ # # ][ # # ]: 0 : if(fLogicDashLength > 0.0 && !getRGBColorA().equal(getRGBColorB()))
[ # # ]
111 : : {
112 : : // apply dashing; get line and gap snippets
113 [ # # ]: 0 : ::std::vector< double > aDash;
114 [ # # ]: 0 : basegfx::B2DPolyPolygon aDashedPolyPolyA;
115 [ # # ]: 0 : basegfx::B2DPolyPolygon aDashedPolyPolyB;
116 : :
117 [ # # ]: 0 : aDash.push_back(fLogicDashLength);
118 [ # # ]: 0 : aDash.push_back(fLogicDashLength);
119 [ # # ]: 0 : basegfx::tools::applyLineDashing(getB2DPolygon(), aDash, &aDashedPolyPolyA, &aDashedPolyPolyB, 2.0 * fLogicDashLength);
120 : :
121 : : // prepare return value
122 [ # # ]: 0 : Primitive2DSequence aRetval(2);
123 : :
124 [ # # ][ # # ]: 0 : aRetval[0] = Primitive2DReference(new PolyPolygonHairlinePrimitive2D(aDashedPolyPolyA, getRGBColorA()));
[ # # ][ # # ]
[ # # ]
125 [ # # ][ # # ]: 0 : aRetval[1] = Primitive2DReference(new PolyPolygonHairlinePrimitive2D(aDashedPolyPolyB, getRGBColorB()));
[ # # ][ # # ]
[ # # ]
126 : :
127 [ # # ][ # # ]: 0 : return aRetval;
[ # # ][ # # ]
128 : : }
129 : : else
130 : : {
131 [ # # ][ # # ]: 0 : const Primitive2DReference xRef(new PolygonHairlinePrimitive2D(getB2DPolygon(), getRGBColorA()));
[ # # ]
132 [ # # ]: 0 : return Primitive2DSequence(&xRef, 1L);
133 : 0 : }
134 : : }
135 : :
136 : 0 : PolygonMarkerPrimitive2D::PolygonMarkerPrimitive2D(
137 : : const basegfx::B2DPolygon& rPolygon,
138 : : const basegfx::BColor& rRGBColorA,
139 : : const basegfx::BColor& rRGBColorB,
140 : : double fDiscreteDashLength)
141 : : : BufferedDecompositionPrimitive2D(),
142 : : maPolygon(rPolygon),
143 : : maRGBColorA(rRGBColorA),
144 : : maRGBColorB(rRGBColorB),
145 : : mfDiscreteDashLength(fDiscreteDashLength),
146 [ # # ][ # # ]: 0 : maLastInverseObjectToViewTransformation()
147 : : {
148 : 0 : }
149 : :
150 : 0 : bool PolygonMarkerPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
151 : : {
152 [ # # ]: 0 : if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
153 : : {
154 : 0 : const PolygonMarkerPrimitive2D& rCompare = (PolygonMarkerPrimitive2D&)rPrimitive;
155 : :
156 : 0 : return (getB2DPolygon() == rCompare.getB2DPolygon()
157 : 0 : && getRGBColorA() == rCompare.getRGBColorA()
158 : 0 : && getRGBColorB() == rCompare.getRGBColorB()
159 [ # # ][ # # : 0 : && getDiscreteDashLength() == rCompare.getDiscreteDashLength());
# # # # ]
160 : : }
161 : :
162 : 0 : return false;
163 : : }
164 : :
165 : 0 : basegfx::B2DRange PolygonMarkerPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
166 : : {
167 : : // this is a hairline, thus the line width is view-dependent. Get range of polygon
168 : : // as base size
169 : 0 : basegfx::B2DRange aRetval(getB2DPolygon().getB2DRange());
170 : :
171 [ # # ]: 0 : if(!aRetval.isEmpty())
172 : : {
173 : : // Calculate view-dependent hairline width
174 [ # # ][ # # ]: 0 : const basegfx::B2DVector aDiscreteSize(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0));
175 [ # # ]: 0 : const double fDiscreteHalfLineWidth(aDiscreteSize.getLength() * 0.5);
176 : :
177 [ # # ]: 0 : if(basegfx::fTools::more(fDiscreteHalfLineWidth, 0.0))
178 : : {
179 [ # # ]: 0 : aRetval.grow(fDiscreteHalfLineWidth);
180 : 0 : }
181 : : }
182 : :
183 : : // return range
184 : 0 : return aRetval;
185 : : }
186 : :
187 : 0 : Primitive2DSequence PolygonMarkerPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
188 : : {
189 [ # # ]: 0 : ::osl::MutexGuard aGuard( m_aMutex );
190 : 0 : bool bNeedNewDecomposition(false);
191 : :
192 [ # # ]: 0 : if(getBuffered2DDecomposition().hasElements())
193 : : {
194 [ # # ][ # # ]: 0 : if(rViewInformation.getInverseObjectToViewTransformation() != maLastInverseObjectToViewTransformation)
[ # # ]
195 : : {
196 : 0 : bNeedNewDecomposition = true;
197 : : }
198 : : }
199 : :
200 [ # # ]: 0 : if(bNeedNewDecomposition)
201 : : {
202 : : // conditions of last local decomposition have changed, delete
203 [ # # ][ # # ]: 0 : const_cast< PolygonMarkerPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence());
[ # # ]
204 : : }
205 : :
206 [ # # ]: 0 : if(!getBuffered2DDecomposition().hasElements())
207 : : {
208 : : // remember last used InverseObjectToViewTransformation
209 : 0 : PolygonMarkerPrimitive2D* pThat = const_cast< PolygonMarkerPrimitive2D* >(this);
210 [ # # ][ # # ]: 0 : pThat->maLastInverseObjectToViewTransformation = rViewInformation.getInverseObjectToViewTransformation();
211 : : }
212 : :
213 : : // use parent implementation
214 [ # # ][ # # ]: 0 : return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation);
215 : : }
216 : :
217 : : // provide unique ID
218 : 0 : ImplPrimitrive2DIDBlock(PolygonMarkerPrimitive2D, PRIMITIVE2D_ID_POLYGONMARKERPRIMITIVE2D)
219 : :
220 : : } // end of namespace primitive2d
221 : : } // end of namespace drawinglayer
222 : :
223 : : //////////////////////////////////////////////////////////////////////////////
224 : :
225 : : namespace drawinglayer
226 : : {
227 : : namespace primitive2d
228 : : {
229 : 20586 : Primitive2DSequence PolygonStrokePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
230 : : {
231 [ + - ]: 20586 : if(getB2DPolygon().count())
232 : : {
233 : : // #i102241# try to simplify before usage
234 [ + - ]: 20586 : const basegfx::B2DPolygon aB2DPolygon(basegfx::tools::simplifyCurveSegments(getB2DPolygon()));
235 [ + - ]: 20586 : basegfx::B2DPolyPolygon aHairLinePolyPolygon;
236 : :
237 [ + - ][ + + ]: 20586 : if(getStrokeAttribute().isDefault() || 0.0 == getStrokeAttribute().getFullDotDashLen())
[ + - ][ + + ]
[ + + ]
238 : : {
239 : : // no line dashing, just copy
240 [ + - ]: 19969 : aHairLinePolyPolygon.append(aB2DPolygon);
241 : : }
242 : : else
243 : : {
244 : : // apply LineStyle
245 : : basegfx::tools::applyLineDashing(
246 [ + - ]: 617 : aB2DPolygon, getStrokeAttribute().getDotDashArray(),
247 [ + - ][ + - ]: 1234 : &aHairLinePolyPolygon, 0, getStrokeAttribute().getFullDotDashLen());
248 : : }
249 : :
250 [ + - ]: 20586 : const sal_uInt32 nCount(aHairLinePolyPolygon.count());
251 : :
252 [ + - ][ + - ]: 20586 : if(!getLineAttribute().isDefault() && getLineAttribute().getWidth())
[ + - ][ + + ]
[ + + ]
253 : : {
254 : : // create fat line data
255 [ + - ]: 1870 : const double fHalfLineWidth(getLineAttribute().getWidth() / 2.0);
256 [ + - ]: 1870 : const basegfx::B2DLineJoin aLineJoin(getLineAttribute().getLineJoin());
257 [ + - ]: 1870 : basegfx::B2DPolyPolygon aAreaPolyPolygon;
258 : :
259 [ + + ]: 11483 : for(sal_uInt32 a(0L); a < nCount; a++)
260 : : {
261 : : // New version of createAreaGeometry; now creates bezier polygons
262 : : aAreaPolyPolygon.append(basegfx::tools::createAreaGeometry(
263 [ + - ][ + - ]: 9613 : aHairLinePolyPolygon.getB2DPolygon(a), fHalfLineWidth, aLineJoin));
[ + - ][ + - ]
[ + - ]
264 : : }
265 : :
266 : : // prepare return value
267 [ + - ][ + - ]: 1870 : Primitive2DSequence aRetval(aAreaPolyPolygon.count());
268 : :
269 : : // create primitive
270 [ + - ][ + + ]: 13219 : for(sal_uInt32 b(0L); b < aAreaPolyPolygon.count(); b++)
271 : : {
272 : : // put into single polyPolygon primitives to make clear that this is NOT meant
273 : : // to be painted as a single PolyPolygon (XORed as fill rule). Alternatively, a
274 : : // melting process may be used here one day.
275 [ + - ][ + - ]: 11349 : const basegfx::B2DPolyPolygon aNewPolyPolygon(aAreaPolyPolygon.getB2DPolygon(b));
[ + - ]
276 : : static bool bTestByUsingRandomColor(false);
277 : : const basegfx::BColor aColor(bTestByUsingRandomColor
278 : 0 : ? basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0)
279 [ - + ][ + - ]: 11349 : : getLineAttribute().getColor());
280 [ + - ][ + - ]: 11349 : const Primitive2DReference xRef(new PolyPolygonColorPrimitive2D(aNewPolyPolygon, aColor));
[ + - ]
281 [ + - ][ + - ]: 11349 : aRetval[b] = xRef;
282 [ + - ]: 11349 : }
283 : :
284 [ + - ][ + - ]: 1870 : return aRetval;
[ + - ]
285 : : }
286 : : else
287 : : {
288 : : // prepare return value
289 : : const Primitive2DReference xRef(
290 : : new PolyPolygonHairlinePrimitive2D(
291 : : aHairLinePolyPolygon,
292 [ + - ][ + - ]: 18716 : getLineAttribute().getColor()));
[ + - ][ + - ]
293 : :
294 [ + - ]: 18716 : return Primitive2DSequence(&xRef, 1);
295 [ + - ][ + - ]: 20586 : }
296 : : }
297 : : else
298 : : {
299 : 20586 : return Primitive2DSequence();
300 : : }
301 : : }
302 : :
303 : 28727 : PolygonStrokePrimitive2D::PolygonStrokePrimitive2D(
304 : : const basegfx::B2DPolygon& rPolygon,
305 : : const attribute::LineAttribute& rLineAttribute,
306 : : const attribute::StrokeAttribute& rStrokeAttribute)
307 : : : BufferedDecompositionPrimitive2D(),
308 : : maPolygon(rPolygon),
309 : : maLineAttribute(rLineAttribute),
310 [ + - ][ + - ]: 28727 : maStrokeAttribute(rStrokeAttribute)
[ + - ]
311 : : {
312 : 28727 : }
313 : :
314 : 1459 : PolygonStrokePrimitive2D::PolygonStrokePrimitive2D(
315 : : const basegfx::B2DPolygon& rPolygon,
316 : : const attribute::LineAttribute& rLineAttribute)
317 : : : BufferedDecompositionPrimitive2D(),
318 : : maPolygon(rPolygon),
319 : : maLineAttribute(rLineAttribute),
320 [ + - ][ + - ]: 1459 : maStrokeAttribute()
[ + - ]
321 : : {
322 : 1459 : }
323 : :
324 : 108 : bool PolygonStrokePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
325 : : {
326 [ + - ]: 108 : if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
327 : : {
328 : 108 : const PolygonStrokePrimitive2D& rCompare = (PolygonStrokePrimitive2D&)rPrimitive;
329 : :
330 : 108 : return (getB2DPolygon() == rCompare.getB2DPolygon()
331 : 108 : && getLineAttribute() == rCompare.getLineAttribute()
332 [ + - ]: 216 : && getStrokeAttribute() == rCompare.getStrokeAttribute());
[ + - + - ]
333 : : }
334 : :
335 : 108 : return false;
336 : : }
337 : :
338 : 346628 : basegfx::B2DRange PolygonStrokePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
339 : : {
340 : 346628 : basegfx::B2DRange aRetval;
341 : :
342 [ + + ]: 346628 : if(getLineAttribute().getWidth())
343 : : {
344 [ + + ]: 71700 : if(basegfx::B2DLINEJOIN_MITER == getLineAttribute().getLineJoin())
345 : : {
346 : : // if line is mitered, use parent call since mitered line
347 : : // geometry may use more space than the geometry grown by half line width
348 : 222 : aRetval = BufferedDecompositionPrimitive2D::getB2DRange(rViewInformation);
349 : : }
350 : : else
351 : : {
352 : : // for all other B2DLINEJOIN_* get the range from the base geometry
353 : : // and expand by half the line width
354 : 71478 : aRetval = getB2DPolygon().getB2DRange();
355 : 71478 : aRetval.grow(getLineAttribute().getWidth() * 0.5);
356 : : }
357 : : }
358 : : else
359 : : {
360 : : // this is a hairline, thus the line width is view-dependent. Get range of polygon
361 : : // as base size
362 : 274928 : aRetval = getB2DPolygon().getB2DRange();
363 : :
364 [ + - ]: 274928 : if(!aRetval.isEmpty())
365 : : {
366 : : // Calculate view-dependent hairline width
367 [ + - ][ + - ]: 274928 : const basegfx::B2DVector aDiscreteSize(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0));
368 [ + - ]: 274928 : const double fDiscreteHalfLineWidth(aDiscreteSize.getLength() * 0.5);
369 : :
370 [ + - ]: 274928 : if(basegfx::fTools::more(fDiscreteHalfLineWidth, 0.0))
371 : : {
372 [ + - ]: 274928 : aRetval.grow(fDiscreteHalfLineWidth);
373 : 274928 : }
374 : : }
375 : : }
376 : :
377 : 346628 : return aRetval;
378 : : }
379 : :
380 : : // provide unique ID
381 : 56812 : ImplPrimitrive2DIDBlock(PolygonStrokePrimitive2D, PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D)
382 : :
383 : : } // end of namespace primitive2d
384 : : } // end of namespace drawinglayer
385 : :
386 : : //////////////////////////////////////////////////////////////////////////////
387 : :
388 : : namespace drawinglayer
389 : : {
390 : : namespace primitive2d
391 : : {
392 : 0 : Primitive2DSequence PolygonWavePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
393 : : {
394 : 0 : Primitive2DSequence aRetval;
395 : :
396 [ # # ][ # # ]: 0 : if(getB2DPolygon().count())
397 : : {
398 : 0 : const bool bHasWidth(!basegfx::fTools::equalZero(getWaveWidth()));
399 : 0 : const bool bHasHeight(!basegfx::fTools::equalZero(getWaveHeight()));
400 : :
401 [ # # ][ # # ]: 0 : if(bHasWidth && bHasHeight)
402 : : {
403 : : // create waveline curve
404 [ # # ]: 0 : const basegfx::B2DPolygon aWaveline(basegfx::tools::createWaveline(getB2DPolygon(), getWaveWidth(), getWaveHeight()));
405 [ # # ][ # # ]: 0 : const Primitive2DReference xRef(new PolygonStrokePrimitive2D(aWaveline, getLineAttribute(), getStrokeAttribute()));
[ # # ]
406 [ # # ][ # # ]: 0 : aRetval = Primitive2DSequence(&xRef, 1);
[ # # ][ # # ]
407 : : }
408 : : else
409 : : {
410 : : // flat waveline, decompose to simple line primitive
411 [ # # ][ # # ]: 0 : const Primitive2DReference xRef(new PolygonStrokePrimitive2D(getB2DPolygon(), getLineAttribute(), getStrokeAttribute()));
[ # # ]
412 [ # # ][ # # ]: 0 : aRetval = Primitive2DSequence(&xRef, 1);
[ # # ]
413 : : }
414 : : }
415 : :
416 : 0 : return aRetval;
417 : : }
418 : :
419 : 0 : PolygonWavePrimitive2D::PolygonWavePrimitive2D(
420 : : const basegfx::B2DPolygon& rPolygon,
421 : : const attribute::LineAttribute& rLineAttribute,
422 : : const attribute::StrokeAttribute& rStrokeAttribute,
423 : : double fWaveWidth,
424 : : double fWaveHeight)
425 : : : PolygonStrokePrimitive2D(rPolygon, rLineAttribute, rStrokeAttribute),
426 : : mfWaveWidth(fWaveWidth),
427 : 0 : mfWaveHeight(fWaveHeight)
428 : : {
429 [ # # ]: 0 : if(mfWaveWidth < 0.0)
430 : : {
431 : 0 : mfWaveWidth = 0.0;
432 : : }
433 : :
434 [ # # ]: 0 : if(mfWaveHeight < 0.0)
435 : : {
436 : 0 : mfWaveHeight = 0.0;
437 : : }
438 : 0 : }
439 : :
440 : 0 : PolygonWavePrimitive2D::PolygonWavePrimitive2D(
441 : : const basegfx::B2DPolygon& rPolygon,
442 : : const attribute::LineAttribute& rLineAttribute,
443 : : double fWaveWidth,
444 : : double fWaveHeight)
445 : : : PolygonStrokePrimitive2D(rPolygon, rLineAttribute),
446 : : mfWaveWidth(fWaveWidth),
447 : 0 : mfWaveHeight(fWaveHeight)
448 : : {
449 [ # # ]: 0 : if(mfWaveWidth < 0.0)
450 : : {
451 : 0 : mfWaveWidth = 0.0;
452 : : }
453 : :
454 [ # # ]: 0 : if(mfWaveHeight < 0.0)
455 : : {
456 : 0 : mfWaveHeight = 0.0;
457 : : }
458 : 0 : }
459 : :
460 : 0 : bool PolygonWavePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
461 : : {
462 [ # # ]: 0 : if(PolygonStrokePrimitive2D::operator==(rPrimitive))
463 : : {
464 : 0 : const PolygonWavePrimitive2D& rCompare = (PolygonWavePrimitive2D&)rPrimitive;
465 : :
466 : 0 : return (getWaveWidth() == rCompare.getWaveWidth()
467 [ # # ][ # # ]: 0 : && getWaveHeight() == rCompare.getWaveHeight());
468 : : }
469 : :
470 : 0 : return false;
471 : : }
472 : :
473 : 0 : basegfx::B2DRange PolygonWavePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
474 : : {
475 : : // get range of parent
476 : 0 : basegfx::B2DRange aRetval(PolygonStrokePrimitive2D::getB2DRange(rViewInformation));
477 : :
478 : : // if WaveHeight, grow by it
479 [ # # ]: 0 : if(basegfx::fTools::more(getWaveHeight(), 0.0))
480 : : {
481 : 0 : aRetval.grow(getWaveHeight());
482 : : }
483 : :
484 : : // if line width, grow by it
485 [ # # ][ # # ]: 0 : if(basegfx::fTools::more(getLineAttribute().getWidth(), 0.0))
486 : : {
487 : 0 : aRetval.grow(getLineAttribute().getWidth() * 0.5);
488 : : }
489 : :
490 : 0 : return aRetval;
491 : : }
492 : :
493 : : // provide unique ID
494 : 0 : ImplPrimitrive2DIDBlock(PolygonWavePrimitive2D, PRIMITIVE2D_ID_POLYGONWAVEPRIMITIVE2D)
495 : :
496 : : } // end of namespace primitive2d
497 : : } // end of namespace drawinglayer
498 : :
499 : : //////////////////////////////////////////////////////////////////////////////
500 : :
501 : : namespace drawinglayer
502 : : {
503 : : namespace primitive2d
504 : : {
505 : 8 : Primitive2DSequence PolygonStrokeArrowPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
506 : : {
507 : : // copy local polygon, it may be changed
508 [ + - ]: 8 : basegfx::B2DPolygon aLocalPolygon(getB2DPolygon());
509 [ + - ]: 8 : aLocalPolygon.removeDoublePoints();
510 [ + - ]: 8 : basegfx::B2DPolyPolygon aArrowA;
511 [ + - ]: 8 : basegfx::B2DPolyPolygon aArrowB;
512 : :
513 [ + - ][ + - ]: 8 : if(!aLocalPolygon.isClosed() && aLocalPolygon.count() > 1)
[ + - ][ + - ]
[ + - ]
514 : : {
515 : : // apply arrows
516 [ + - ]: 8 : const double fPolyLength(basegfx::tools::getLength(aLocalPolygon));
517 : 8 : double fStart(0.0);
518 : 8 : double fEnd(0.0);
519 : 8 : double fStartOverlap(0.0);
520 : 8 : double fEndOverlap(0.0);
521 : :
522 [ + - ][ + - ]: 8 : if(!getStart().isDefault() && getStart().isActive())
[ + - ][ + + ]
[ + + ]
523 : : {
524 : : // create start arrow primitive and consume
525 : : aArrowA = basegfx::tools::createAreaGeometryForLineStartEnd(
526 [ + - ]: 10 : aLocalPolygon, getStart().getB2DPolyPolygon(), true, getStart().getWidth(),
527 [ + - ][ - + ]: 15 : fPolyLength, getStart().isCentered() ? 0.5 : 0.0, &fStart);
[ + - ][ + - ]
[ + - ][ + - ]
528 : :
529 : : // create some overlapping, compromise between straight and peaked markers
530 : : // for marker width 0.3cm and marker line width 0.02cm
531 [ + - ]: 5 : fStartOverlap = getStart().getWidth() / 15.0;
532 : : }
533 : :
534 [ + - ][ + - ]: 8 : if(!getEnd().isDefault() && getEnd().isActive())
[ + - ][ + + ]
[ + + ]
535 : : {
536 : : // create end arrow primitive and consume
537 : : aArrowB = basegfx::tools::createAreaGeometryForLineStartEnd(
538 [ + - ]: 6 : aLocalPolygon, getEnd().getB2DPolyPolygon(), false, getEnd().getWidth(),
539 [ + - ][ - + ]: 9 : fPolyLength, getEnd().isCentered() ? 0.5 : 0.0, &fEnd);
[ + - ][ + - ]
[ + - ][ + - ]
540 : :
541 : : // create some overlapping
542 [ + - ]: 3 : fEndOverlap = getEnd().getWidth() / 15.0;
543 : : }
544 : :
545 [ + + ][ + - ]: 8 : if(0.0 != fStart || 0.0 != fEnd)
546 : : {
547 : : // build new poly, consume something from old poly
548 [ + - ][ + - ]: 8 : aLocalPolygon = basegfx::tools::getSnippetAbsolute(aLocalPolygon, fStart-fStartOverlap, fPolyLength - fEnd + fEndOverlap, fPolyLength);
[ + - ]
549 : : }
550 : : }
551 : :
552 : : // prepare return value
553 [ + - ][ + + ]: 8 : Primitive2DSequence aRetval(1L + (aArrowA.count() ? 1L : 0L) + (aArrowB.count() ? 1L : 0L));
[ + - ][ + + ]
[ + - ]
554 : 8 : sal_uInt32 nInd(0L);
555 : :
556 : : // add shaft
557 : : const Primitive2DReference xRefShaft(new
558 : : PolygonStrokePrimitive2D(
559 [ + - ][ + - ]: 8 : aLocalPolygon, getLineAttribute(), getStrokeAttribute()));
[ + - ]
560 [ + - ][ + - ]: 8 : aRetval[nInd++] = xRefShaft;
561 : :
562 [ + - ][ + + ]: 8 : if(aArrowA.count())
563 : : {
564 : : const Primitive2DReference xRefA(
565 : : new PolyPolygonColorPrimitive2D(
566 [ + - ][ + - ]: 5 : aArrowA, getLineAttribute().getColor()));
[ + - ][ + - ]
567 [ + - ][ + - ]: 5 : aRetval[nInd++] = xRefA;
568 : : }
569 : :
570 [ + - ][ + + ]: 8 : if(aArrowB.count())
571 : : {
572 : : const Primitive2DReference xRefB(
573 : : new PolyPolygonColorPrimitive2D(
574 [ + - ][ + - ]: 3 : aArrowB, getLineAttribute().getColor()));
[ + - ][ + - ]
575 [ + - ][ + - ]: 3 : aRetval[nInd++] = xRefB;
576 : : }
577 : :
578 [ + - ][ + - ]: 8 : return aRetval;
[ + - ]
579 : : }
580 : :
581 : 8 : PolygonStrokeArrowPrimitive2D::PolygonStrokeArrowPrimitive2D(
582 : : const basegfx::B2DPolygon& rPolygon,
583 : : const attribute::LineAttribute& rLineAttribute,
584 : : const attribute::StrokeAttribute& rStrokeAttribute,
585 : : const attribute::LineStartEndAttribute& rStart,
586 : : const attribute::LineStartEndAttribute& rEnd)
587 : : : PolygonStrokePrimitive2D(rPolygon, rLineAttribute, rStrokeAttribute),
588 : : maStart(rStart),
589 [ + - ][ + - ]: 8 : maEnd(rEnd)
590 : : {
591 : 8 : }
592 : :
593 : 0 : bool PolygonStrokeArrowPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
594 : : {
595 [ # # ]: 0 : if(PolygonStrokePrimitive2D::operator==(rPrimitive))
596 : : {
597 : 0 : const PolygonStrokeArrowPrimitive2D& rCompare = (PolygonStrokeArrowPrimitive2D&)rPrimitive;
598 : :
599 : 0 : return (getStart() == rCompare.getStart()
600 [ # # ][ # # ]: 0 : && getEnd() == rCompare.getEnd());
601 : : }
602 : :
603 : 0 : return false;
604 : : }
605 : :
606 : 39 : basegfx::B2DRange PolygonStrokeArrowPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
607 : : {
608 [ + - ]: 39 : basegfx::B2DRange aRetval;
609 : :
610 [ + - ][ + + ]: 39 : if(getStart().isActive() || getEnd().isActive())
[ + - ][ + - ]
[ + - ]
611 : : {
612 : : // use decomposition when line start/end is used
613 [ + - ]: 39 : return BufferedDecompositionPrimitive2D::getB2DRange(rViewInformation);
614 : : }
615 : : else
616 : : {
617 : : // get range from parent
618 [ # # ]: 39 : return PolygonStrokePrimitive2D::getB2DRange(rViewInformation);
619 : : }
620 : : }
621 : :
622 : : // provide unique ID
623 : 16 : ImplPrimitrive2DIDBlock(PolygonStrokeArrowPrimitive2D, PRIMITIVE2D_ID_POLYGONSTROKEARROWPRIMITIVE2D)
624 : :
625 : : } // end of namespace primitive2d
626 : : } // end of namespace drawinglayer
627 : :
628 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|