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