xref: /trunk/main/drawinglayer/source/primitive2d/polypolygonprimitive2d.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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