1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_drawinglayer.hxx"
30 
31 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
32 #include <basegfx/polygon/b2dpolypolygontools.hxx>
33 #include <basegfx/tools/canvastools.hxx>
34 #include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
35 #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
36 #include <drawinglayer/primitive2d/fillhatchprimitive2d.hxx>
37 #include <basegfx/matrix/b2dhommatrix.hxx>
38 #include <drawinglayer/primitive2d/fillbitmapprimitive2d.hxx>
39 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
40 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
41 
42 //////////////////////////////////////////////////////////////////////////////
43 
44 using namespace com::sun::star;
45 
46 //////////////////////////////////////////////////////////////////////////////
47 
48 namespace drawinglayer
49 {
50 	namespace primitive2d
51 	{
52 		Primitive2DSequence PolyPolygonHairlinePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
53 		{
54 			const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
55 			const sal_uInt32 nCount(aPolyPolygon.count());
56 
57 			if(nCount)
58 			{
59 				Primitive2DSequence aRetval(nCount);
60 
61 				for(sal_uInt32 a(0L); a < nCount; a++)
62 				{
63 					aRetval[a] = Primitive2DReference(new PolygonHairlinePrimitive2D(aPolyPolygon.getB2DPolygon(a), getBColor()));
64 				}
65 
66 				return aRetval;
67 			}
68 			else
69 			{
70 				return Primitive2DSequence();
71 			}
72 		}
73 
74 		PolyPolygonHairlinePrimitive2D::PolyPolygonHairlinePrimitive2D(const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::BColor& rBColor)
75 		:	BufferedDecompositionPrimitive2D(),
76 			maPolyPolygon(rPolyPolygon),
77 			maBColor(rBColor)
78 		{
79 		}
80 
81 		bool PolyPolygonHairlinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
82 		{
83 			if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
84 			{
85 				const PolyPolygonHairlinePrimitive2D& rCompare = (PolyPolygonHairlinePrimitive2D&)rPrimitive;
86 
87 				return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
88 					&& getBColor() == rCompare.getBColor());
89 			}
90 
91 			return false;
92 		}
93 
94 		basegfx::B2DRange PolyPolygonHairlinePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
95 		{
96 			// return range
97 			return basegfx::tools::getRange(getB2DPolyPolygon());
98 		}
99 
100 		// provide unique ID
101 		ImplPrimitrive2DIDBlock(PolyPolygonHairlinePrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONHAIRLINEPRIMITIVE2D)
102 
103 	} // end of namespace primitive2d
104 } // end of namespace drawinglayer
105 
106 //////////////////////////////////////////////////////////////////////////////
107 
108 namespace drawinglayer
109 {
110 	namespace primitive2d
111 	{
112 		Primitive2DSequence PolyPolygonMarkerPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
113 		{
114 			const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
115 			const sal_uInt32 nCount(aPolyPolygon.count());
116 
117 			if(nCount)
118 			{
119 				Primitive2DSequence aRetval(nCount);
120 
121 				for(sal_uInt32 a(0L); a < nCount; a++)
122 				{
123 					aRetval[a] = Primitive2DReference(new PolygonMarkerPrimitive2D(aPolyPolygon.getB2DPolygon(a), getRGBColorA(), getRGBColorB(), getDiscreteDashLength()));
124 				}
125 
126 				return aRetval;
127 			}
128 			else
129 			{
130 				return Primitive2DSequence();
131 			}
132 		}
133 
134 		PolyPolygonMarkerPrimitive2D::PolyPolygonMarkerPrimitive2D(
135 			const basegfx::B2DPolyPolygon& rPolyPolygon,
136 			const basegfx::BColor& rRGBColorA,
137 			const basegfx::BColor& rRGBColorB,
138 			double fDiscreteDashLength)
139 		:	BufferedDecompositionPrimitive2D(),
140 			maPolyPolygon(rPolyPolygon),
141 			maRGBColorA(rRGBColorA),
142 			maRGBColorB(rRGBColorB),
143 			mfDiscreteDashLength(fDiscreteDashLength)
144 		{
145 		}
146 
147 		bool PolyPolygonMarkerPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
148 		{
149 			if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
150 			{
151 				const PolyPolygonMarkerPrimitive2D& rCompare = (PolyPolygonMarkerPrimitive2D&)rPrimitive;
152 
153 				return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
154 					&& getRGBColorA() == rCompare.getRGBColorA()
155 					&& getRGBColorB() == rCompare.getRGBColorB()
156 					&& getDiscreteDashLength() == rCompare.getDiscreteDashLength());
157 			}
158 
159 			return false;
160 		}
161 
162 		basegfx::B2DRange PolyPolygonMarkerPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
163 		{
164 			// return range
165 			return basegfx::tools::getRange(getB2DPolyPolygon());
166 		}
167 
168 		// provide unique ID
169 		ImplPrimitrive2DIDBlock(PolyPolygonMarkerPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONMARKERPRIMITIVE2D)
170 
171 	} // end of namespace primitive2d
172 } // end of namespace drawinglayer
173 
174 //////////////////////////////////////////////////////////////////////////////
175 
176 namespace drawinglayer
177 {
178 	namespace primitive2d
179 	{
180 		Primitive2DSequence PolyPolygonStrokePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
181 		{
182 			const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
183 			const sal_uInt32 nCount(aPolyPolygon.count());
184 
185 			if(nCount)
186 			{
187 				Primitive2DSequence aRetval(nCount);
188 
189 				for(sal_uInt32 a(0L); a < nCount; a++)
190 				{
191 					aRetval[a] = Primitive2DReference(
192                         new PolygonStrokePrimitive2D(
193                             aPolyPolygon.getB2DPolygon(a), getLineAttribute(), getStrokeAttribute()));
194 				}
195 
196 				return aRetval;
197 			}
198 			else
199 			{
200 				return Primitive2DSequence();
201 			}
202 		}
203 
204 		PolyPolygonStrokePrimitive2D::PolyPolygonStrokePrimitive2D(
205 			const basegfx::B2DPolyPolygon& rPolyPolygon,
206   			const attribute::LineAttribute& rLineAttribute,
207 			const attribute::StrokeAttribute& rStrokeAttribute)
208 		:	BufferedDecompositionPrimitive2D(),
209 			maPolyPolygon(rPolyPolygon),
210             maLineAttribute(rLineAttribute),
211 			maStrokeAttribute(rStrokeAttribute)
212 		{
213 		}
214 
215 		PolyPolygonStrokePrimitive2D::PolyPolygonStrokePrimitive2D(
216 			const basegfx::B2DPolyPolygon& rPolyPolygon,
217   			const attribute::LineAttribute& rLineAttribute)
218 		:	BufferedDecompositionPrimitive2D(),
219 			maPolyPolygon(rPolyPolygon),
220             maLineAttribute(rLineAttribute),
221 			maStrokeAttribute()
222 		{
223 		}
224 
225 		bool PolyPolygonStrokePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
226 		{
227 			if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
228 			{
229 				const PolyPolygonStrokePrimitive2D& rCompare = (PolyPolygonStrokePrimitive2D&)rPrimitive;
230 
231 				return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
232 					&& getLineAttribute() == rCompare.getLineAttribute()
233 					&& getStrokeAttribute() == rCompare.getStrokeAttribute());
234 			}
235 
236 			return false;
237 		}
238 
239 		basegfx::B2DRange PolyPolygonStrokePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
240 		{
241 			// get range of it (subdivided)
242 			basegfx::B2DRange aRetval(basegfx::tools::getRange(getB2DPolyPolygon()));
243 
244 			// if width, grow by line width
245 			if(getLineAttribute().getWidth())
246 			{
247 				aRetval.grow(getLineAttribute().getWidth() / 2.0);
248 			}
249 
250 			return aRetval;
251 		}
252 
253 		// provide unique ID
254 		ImplPrimitrive2DIDBlock(PolyPolygonStrokePrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONSTROKEPRIMITIVE2D)
255 
256 	} // end of namespace primitive2d
257 } // end of namespace drawinglayer
258 
259 //////////////////////////////////////////////////////////////////////////////
260 
261 namespace drawinglayer
262 {
263 	namespace primitive2d
264 	{
265 		Primitive2DSequence PolyPolygonStrokeArrowPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
266 		{
267 			const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
268 			const sal_uInt32 nCount(aPolyPolygon.count());
269 
270 			if(nCount)
271 			{
272 				Primitive2DSequence aRetval(nCount);
273 
274 				for(sal_uInt32 a(0L); a < nCount; a++)
275 				{
276 					const basegfx::B2DPolygon aPolygon(aPolyPolygon.getB2DPolygon(a));
277 
278 					if(aPolygon.isClosed())
279 					{
280 						// no need for PolygonStrokeArrowPrimitive2D when polygon is closed
281 						aRetval[a] = Primitive2DReference(
282                             new PolygonStrokePrimitive2D(aPolygon, getLineAttribute(), getStrokeAttribute()));
283 					}
284 					else
285 					{
286 						aRetval[a] = Primitive2DReference(
287                             new PolygonStrokeArrowPrimitive2D(aPolygon, getLineAttribute(),
288                                 getStrokeAttribute(), getStart(), getEnd()));
289 					}
290 				}
291 
292 				return aRetval;
293 			}
294 			else
295 			{
296 				return Primitive2DSequence();
297 			}
298 		}
299 
300 		PolyPolygonStrokeArrowPrimitive2D::PolyPolygonStrokeArrowPrimitive2D(
301 			const basegfx::B2DPolyPolygon& rPolyPolygon,
302    			const attribute::LineAttribute& rLineAttribute,
303 			const attribute::StrokeAttribute& rStrokeAttribute,
304 			const attribute::LineStartEndAttribute& rStart,
305 			const attribute::LineStartEndAttribute& rEnd)
306 		:	PolyPolygonStrokePrimitive2D(rPolyPolygon, rLineAttribute, rStrokeAttribute),
307 			maStart(rStart),
308 			maEnd(rEnd)
309 		{
310 		}
311 
312 		PolyPolygonStrokeArrowPrimitive2D::PolyPolygonStrokeArrowPrimitive2D(
313 			const basegfx::B2DPolyPolygon& rPolyPolygon,
314    			const attribute::LineAttribute& rLineAttribute,
315 			const attribute::LineStartEndAttribute& rStart,
316 			const attribute::LineStartEndAttribute& rEnd)
317 		:	PolyPolygonStrokePrimitive2D(rPolyPolygon, rLineAttribute),
318 			maStart(rStart),
319 			maEnd(rEnd)
320 		{
321 		}
322 
323 		bool PolyPolygonStrokeArrowPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
324 		{
325 			if(PolyPolygonStrokePrimitive2D::operator==(rPrimitive))
326 			{
327 				const PolyPolygonStrokeArrowPrimitive2D& rCompare = (PolyPolygonStrokeArrowPrimitive2D&)rPrimitive;
328 
329 				return (getStart() == rCompare.getStart()
330 					&& getEnd() == rCompare.getEnd());
331 			}
332 
333 			return false;
334 		}
335 
336 		basegfx::B2DRange PolyPolygonStrokeArrowPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
337 		{
338 			basegfx::B2DRange aRetval;
339 
340 			if(getStart().isActive() || getEnd().isActive())
341 			{
342 				// use decomposition when line start/end is used
343 				return BufferedDecompositionPrimitive2D::getB2DRange(rViewInformation);
344 			}
345 			else
346 			{
347 				// get range from parent
348 				return PolyPolygonStrokePrimitive2D::getB2DRange(rViewInformation);
349 			}
350 		}
351 
352 		// provide unique ID
353 		ImplPrimitrive2DIDBlock(PolyPolygonStrokeArrowPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONSTROKEARROWPRIMITIVE2D)
354 
355 	} // end of namespace primitive2d
356 } // end of namespace drawinglayer
357 
358 //////////////////////////////////////////////////////////////////////////////
359 
360 namespace drawinglayer
361 {
362 	namespace primitive2d
363 	{
364 		PolyPolygonColorPrimitive2D::PolyPolygonColorPrimitive2D(
365 			const basegfx::B2DPolyPolygon& rPolyPolygon,
366 			const basegfx::BColor& rBColor)
367 		:	BasePrimitive2D(),
368 			maPolyPolygon(rPolyPolygon),
369 			maBColor(rBColor)
370 		{
371 		}
372 
373 		bool PolyPolygonColorPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
374 		{
375 			if(BasePrimitive2D::operator==(rPrimitive))
376 			{
377 				const PolyPolygonColorPrimitive2D& rCompare = (PolyPolygonColorPrimitive2D&)rPrimitive;
378 
379 				return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
380 					&& getBColor() == rCompare.getBColor());
381 			}
382 
383 			return false;
384 		}
385 
386 		basegfx::B2DRange PolyPolygonColorPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
387 		{
388 			// return range
389 			return basegfx::tools::getRange(getB2DPolyPolygon());
390 		}
391 
392 		// provide unique ID
393 		ImplPrimitrive2DIDBlock(PolyPolygonColorPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D)
394 
395 	} // end of namespace primitive2d
396 } // end of namespace drawinglayer
397 
398 //////////////////////////////////////////////////////////////////////////////
399 
400 namespace drawinglayer
401 {
402 	namespace primitive2d
403 	{
404 		Primitive2DSequence PolyPolygonGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
405 		{
406             if(!getFillGradient().isDefault())
407             {
408 			    // create SubSequence with FillGradientPrimitive2D
409 			    const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange());
410 			    FillGradientPrimitive2D* pNewGradient = new FillGradientPrimitive2D(aPolyPolygonRange, getFillGradient());
411 			    const Primitive2DReference xSubRef(pNewGradient);
412 			    const Primitive2DSequence aSubSequence(&xSubRef, 1L);
413 
414 			    // create mask primitive
415 			    MaskPrimitive2D* pNewMask = new MaskPrimitive2D(getB2DPolyPolygon(), aSubSequence);
416 			    const Primitive2DReference xRef(pNewMask);
417 
418                 return Primitive2DSequence(&xRef, 1);
419             }
420             else
421             {
422                 return Primitive2DSequence();
423             }
424 		}
425 
426 		PolyPolygonGradientPrimitive2D::PolyPolygonGradientPrimitive2D(
427 			const basegfx::B2DPolyPolygon& rPolyPolygon,
428 			const attribute::FillGradientAttribute& rFillGradient)
429 		:	BufferedDecompositionPrimitive2D(),
430 			maPolyPolygon(rPolyPolygon),
431 			maFillGradient(rFillGradient)
432 		{
433 		}
434 
435 		bool PolyPolygonGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
436 		{
437 			if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
438 			{
439 				const PolyPolygonGradientPrimitive2D& rCompare = (PolyPolygonGradientPrimitive2D&)rPrimitive;
440 
441 				return (getFillGradient() == rCompare.getFillGradient());
442 			}
443 
444 			return false;
445 		}
446 
447 		// provide unique ID
448 		ImplPrimitrive2DIDBlock(PolyPolygonGradientPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D)
449 
450 	} // end of namespace primitive2d
451 } // end of namespace drawinglayer
452 
453 //////////////////////////////////////////////////////////////////////////////
454 
455 namespace drawinglayer
456 {
457 	namespace primitive2d
458 	{
459 		Primitive2DSequence PolyPolygonHatchPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
460 		{
461             if(!getFillHatch().isDefault())
462             {
463 			    // create SubSequence with FillHatchPrimitive2D
464 			    const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange());
465 			    FillHatchPrimitive2D* pNewHatch = new FillHatchPrimitive2D(aPolyPolygonRange, getBackgroundColor(), getFillHatch());
466 			    const Primitive2DReference xSubRef(pNewHatch);
467 			    const Primitive2DSequence aSubSequence(&xSubRef, 1L);
468 
469 			    // create mask primitive
470 			    MaskPrimitive2D* pNewMask = new MaskPrimitive2D(getB2DPolyPolygon(), aSubSequence);
471 			    const Primitive2DReference xRef(pNewMask);
472 
473                 return Primitive2DSequence(&xRef, 1);
474             }
475             else
476             {
477                 return Primitive2DSequence();
478             }
479 		}
480 
481 		PolyPolygonHatchPrimitive2D::PolyPolygonHatchPrimitive2D(
482 			const basegfx::B2DPolyPolygon& rPolyPolygon,
483 			const basegfx::BColor& rBackgroundColor,
484 			const attribute::FillHatchAttribute& rFillHatch)
485 		:	BufferedDecompositionPrimitive2D(),
486 			maPolyPolygon(rPolyPolygon),
487 			maBackgroundColor(rBackgroundColor),
488 			maFillHatch(rFillHatch)
489 		{
490 		}
491 
492 		bool PolyPolygonHatchPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
493 		{
494 			if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
495 			{
496 				const PolyPolygonHatchPrimitive2D& rCompare = (PolyPolygonHatchPrimitive2D&)rPrimitive;
497 
498 				return (getBackgroundColor() == rCompare.getBackgroundColor()
499 					&& getFillHatch() == rCompare.getFillHatch());
500 			}
501 
502 			return false;
503 		}
504 
505 		// provide unique ID
506 		ImplPrimitrive2DIDBlock(PolyPolygonHatchPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D)
507 
508 	} // end of namespace primitive2d
509 } // end of namespace drawinglayer
510 
511 //////////////////////////////////////////////////////////////////////////////
512 
513 namespace drawinglayer
514 {
515 	namespace primitive2d
516 	{
517 		Primitive2DSequence PolyPolygonBitmapPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
518 		{
519             if(!getFillBitmap().isDefault())
520             {
521 			    // create SubSequence with FillBitmapPrimitive2D
522 			    const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange());
523 			    basegfx::B2DHomMatrix aNewObjectTransform;
524 			    aNewObjectTransform.set(0, 0, aPolyPolygonRange.getWidth());
525 			    aNewObjectTransform.set(1, 1, aPolyPolygonRange.getHeight());
526 			    aNewObjectTransform.set(0, 2, aPolyPolygonRange.getMinX());
527 			    aNewObjectTransform.set(1, 2, aPolyPolygonRange.getMinY());
528 			    FillBitmapPrimitive2D* pNewBitmap = new FillBitmapPrimitive2D(aNewObjectTransform, getFillBitmap());
529 			    const Primitive2DReference xSubRef(pNewBitmap);
530 			    const Primitive2DSequence aSubSequence(&xSubRef, 1L);
531 
532 			    // create mask primitive
533 			    MaskPrimitive2D* pNewMask = new MaskPrimitive2D(getB2DPolyPolygon(), aSubSequence);
534 			    const Primitive2DReference xRef(pNewMask);
535 
536                 return Primitive2DSequence(&xRef, 1);
537             }
538             else
539             {
540                 return Primitive2DSequence();
541             }
542 		}
543 
544 		PolyPolygonBitmapPrimitive2D::PolyPolygonBitmapPrimitive2D(
545 			const basegfx::B2DPolyPolygon& rPolyPolygon,
546 			const attribute::FillBitmapAttribute& rFillBitmap)
547 		:	BufferedDecompositionPrimitive2D(),
548 			maPolyPolygon(rPolyPolygon),
549 			maFillBitmap(rFillBitmap)
550 		{
551 		}
552 
553 		bool PolyPolygonBitmapPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
554 		{
555 			if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
556 			{
557 				const PolyPolygonBitmapPrimitive2D& rCompare = (PolyPolygonBitmapPrimitive2D&)rPrimitive;
558 
559 				return (getFillBitmap() == rCompare.getFillBitmap());
560 			}
561 
562 			return false;
563 		}
564 
565 		// provide unique ID
566 		ImplPrimitrive2DIDBlock(PolyPolygonBitmapPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONBITMAPPRIMITIVE2D)
567 
568 	} // end of namespace primitive2d
569 } // end of namespace drawinglayer
570 
571 //////////////////////////////////////////////////////////////////////////////
572 // eof
573