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 <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
39 #include <drawinglayer/geometry/viewinformation2d.hxx>
40 #include <vcl/graph.hxx>
41 
42 //////////////////////////////////////////////////////////////////////////////
43 
44 using namespace com::sun::star;
45 
46 //////////////////////////////////////////////////////////////////////////////
47 
48 namespace drawinglayer
49 {
50     namespace primitive2d
51     {
create2DDecomposition(const geometry::ViewInformation2D &) const52         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 
PolyPolygonHairlinePrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::BColor & rBColor)74         PolyPolygonHairlinePrimitive2D::PolyPolygonHairlinePrimitive2D(const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::BColor& rBColor)
75         :   BufferedDecompositionPrimitive2D(),
76             maPolyPolygon(rPolyPolygon),
77             maBColor(rBColor)
78         {
79         }
80 
operator ==(const BasePrimitive2D & rPrimitive) const81         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 
getB2DRange(const geometry::ViewInformation2D &) const94         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     {
create2DDecomposition(const geometry::ViewInformation2D &) const112         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(
124                         new PolygonMarkerPrimitive2D(
125                             aPolyPolygon.getB2DPolygon(a),
126                             getRGBColorA(),
127                             getRGBColorB(),
128                             getDiscreteDashLength()));
129                 }
130 
131                 return aRetval;
132             }
133             else
134             {
135                 return Primitive2DSequence();
136             }
137         }
138 
PolyPolygonMarkerPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::BColor & rRGBColorA,const basegfx::BColor & rRGBColorB,double fDiscreteDashLength)139         PolyPolygonMarkerPrimitive2D::PolyPolygonMarkerPrimitive2D(
140             const basegfx::B2DPolyPolygon& rPolyPolygon,
141             const basegfx::BColor& rRGBColorA,
142             const basegfx::BColor& rRGBColorB,
143             double fDiscreteDashLength)
144         :   BufferedDecompositionPrimitive2D(),
145             maPolyPolygon(rPolyPolygon),
146             maRGBColorA(rRGBColorA),
147             maRGBColorB(rRGBColorB),
148             mfDiscreteDashLength(fDiscreteDashLength)
149         {
150         }
151 
operator ==(const BasePrimitive2D & rPrimitive) const152         bool PolyPolygonMarkerPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
153         {
154             if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
155             {
156                 const PolyPolygonMarkerPrimitive2D& rCompare = (PolyPolygonMarkerPrimitive2D&)rPrimitive;
157 
158                 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
159                     && getRGBColorA() == rCompare.getRGBColorA()
160                     && getRGBColorB() == rCompare.getRGBColorB()
161                     && getDiscreteDashLength() == rCompare.getDiscreteDashLength());
162             }
163 
164             return false;
165         }
166 
getB2DRange(const geometry::ViewInformation2D &) const167         basegfx::B2DRange PolyPolygonMarkerPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
168         {
169             // return range
170             return basegfx::tools::getRange(getB2DPolyPolygon());
171         }
172 
173         // provide unique ID
174         ImplPrimitrive2DIDBlock(PolyPolygonMarkerPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONMARKERPRIMITIVE2D)
175 
176     } // end of namespace primitive2d
177 } // end of namespace drawinglayer
178 
179 //////////////////////////////////////////////////////////////////////////////
180 
181 namespace drawinglayer
182 {
183     namespace primitive2d
184     {
create2DDecomposition(const geometry::ViewInformation2D &) const185         Primitive2DSequence PolyPolygonStrokePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
186         {
187             const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
188             const sal_uInt32 nCount(aPolyPolygon.count());
189 
190             if(nCount)
191             {
192                 Primitive2DSequence aRetval(nCount);
193 
194                 for(sal_uInt32 a(0L); a < nCount; a++)
195                 {
196                     aRetval[a] = Primitive2DReference(
197                         new PolygonStrokePrimitive2D(
198                             aPolyPolygon.getB2DPolygon(a), getLineAttribute(), getStrokeAttribute()));
199                 }
200 
201                 return aRetval;
202             }
203             else
204             {
205                 return Primitive2DSequence();
206             }
207         }
208 
PolyPolygonStrokePrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const attribute::LineAttribute & rLineAttribute,const attribute::StrokeAttribute & rStrokeAttribute)209         PolyPolygonStrokePrimitive2D::PolyPolygonStrokePrimitive2D(
210             const basegfx::B2DPolyPolygon& rPolyPolygon,
211             const attribute::LineAttribute& rLineAttribute,
212             const attribute::StrokeAttribute& rStrokeAttribute)
213         :   BufferedDecompositionPrimitive2D(),
214             maPolyPolygon(rPolyPolygon),
215             maLineAttribute(rLineAttribute),
216             maStrokeAttribute(rStrokeAttribute)
217         {
218         }
219 
PolyPolygonStrokePrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const attribute::LineAttribute & rLineAttribute)220         PolyPolygonStrokePrimitive2D::PolyPolygonStrokePrimitive2D(
221             const basegfx::B2DPolyPolygon& rPolyPolygon,
222             const attribute::LineAttribute& rLineAttribute)
223         :   BufferedDecompositionPrimitive2D(),
224             maPolyPolygon(rPolyPolygon),
225             maLineAttribute(rLineAttribute),
226             maStrokeAttribute()
227         {
228         }
229 
operator ==(const BasePrimitive2D & rPrimitive) const230         bool PolyPolygonStrokePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
231         {
232             if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
233             {
234                 const PolyPolygonStrokePrimitive2D& rCompare = (PolyPolygonStrokePrimitive2D&)rPrimitive;
235 
236                 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
237                     && getLineAttribute() == rCompare.getLineAttribute()
238                     && getStrokeAttribute() == rCompare.getStrokeAttribute());
239             }
240 
241             return false;
242         }
243 
getB2DRange(const geometry::ViewInformation2D &) const244         basegfx::B2DRange PolyPolygonStrokePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
245         {
246             // get range of it (subdivided)
247             basegfx::B2DRange aRetval(basegfx::tools::getRange(getB2DPolyPolygon()));
248 
249             // if width, grow by line width
250             if(getLineAttribute().getWidth())
251             {
252                 aRetval.grow(getLineAttribute().getWidth() / 2.0);
253             }
254 
255             return aRetval;
256         }
257 
258         // provide unique ID
259         ImplPrimitrive2DIDBlock(PolyPolygonStrokePrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONSTROKEPRIMITIVE2D)
260 
261     } // end of namespace primitive2d
262 } // end of namespace drawinglayer
263 
264 //////////////////////////////////////////////////////////////////////////////
265 
266 namespace drawinglayer
267 {
268     namespace primitive2d
269     {
create2DDecomposition(const geometry::ViewInformation2D &) const270         Primitive2DSequence PolyPolygonStrokeArrowPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
271         {
272             const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
273             const sal_uInt32 nCount(aPolyPolygon.count());
274 
275             if(nCount)
276             {
277                 Primitive2DSequence aRetval(nCount);
278 
279                 for(sal_uInt32 a(0L); a < nCount; a++)
280                 {
281                     const basegfx::B2DPolygon aPolygon(aPolyPolygon.getB2DPolygon(a));
282 
283                     if(aPolygon.isClosed())
284                     {
285                         // no need for PolygonStrokeArrowPrimitive2D when polygon is closed
286                         aRetval[a] = Primitive2DReference(
287                             new PolygonStrokePrimitive2D(aPolygon, getLineAttribute(), getStrokeAttribute()));
288                     }
289                     else
290                     {
291                         aRetval[a] = Primitive2DReference(
292                             new PolygonStrokeArrowPrimitive2D(aPolygon, getLineAttribute(),
293                                 getStrokeAttribute(), getStart(), getEnd()));
294                     }
295                 }
296 
297                 return aRetval;
298             }
299             else
300             {
301                 return Primitive2DSequence();
302             }
303         }
304 
PolyPolygonStrokeArrowPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const attribute::LineAttribute & rLineAttribute,const attribute::StrokeAttribute & rStrokeAttribute,const attribute::LineStartEndAttribute & rStart,const attribute::LineStartEndAttribute & rEnd)305         PolyPolygonStrokeArrowPrimitive2D::PolyPolygonStrokeArrowPrimitive2D(
306             const basegfx::B2DPolyPolygon& rPolyPolygon,
307             const attribute::LineAttribute& rLineAttribute,
308             const attribute::StrokeAttribute& rStrokeAttribute,
309             const attribute::LineStartEndAttribute& rStart,
310             const attribute::LineStartEndAttribute& rEnd)
311         :   PolyPolygonStrokePrimitive2D(rPolyPolygon, rLineAttribute, rStrokeAttribute),
312             maStart(rStart),
313             maEnd(rEnd)
314         {
315         }
316 
PolyPolygonStrokeArrowPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const attribute::LineAttribute & rLineAttribute,const attribute::LineStartEndAttribute & rStart,const attribute::LineStartEndAttribute & rEnd)317         PolyPolygonStrokeArrowPrimitive2D::PolyPolygonStrokeArrowPrimitive2D(
318             const basegfx::B2DPolyPolygon& rPolyPolygon,
319             const attribute::LineAttribute& rLineAttribute,
320             const attribute::LineStartEndAttribute& rStart,
321             const attribute::LineStartEndAttribute& rEnd)
322         :   PolyPolygonStrokePrimitive2D(rPolyPolygon, rLineAttribute),
323             maStart(rStart),
324             maEnd(rEnd)
325         {
326         }
327 
operator ==(const BasePrimitive2D & rPrimitive) const328         bool PolyPolygonStrokeArrowPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
329         {
330             if(PolyPolygonStrokePrimitive2D::operator==(rPrimitive))
331             {
332                 const PolyPolygonStrokeArrowPrimitive2D& rCompare = (PolyPolygonStrokeArrowPrimitive2D&)rPrimitive;
333 
334                 return (getStart() == rCompare.getStart()
335                     && getEnd() == rCompare.getEnd());
336             }
337 
338             return false;
339         }
340 
getB2DRange(const geometry::ViewInformation2D & rViewInformation) const341         basegfx::B2DRange PolyPolygonStrokeArrowPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
342         {
343             basegfx::B2DRange aRetval;
344 
345             if(getStart().isActive() || getEnd().isActive())
346             {
347                 // use decomposition when line start/end is used
348                 return BufferedDecompositionPrimitive2D::getB2DRange(rViewInformation);
349             }
350             else
351             {
352                 // get range from parent
353                 return PolyPolygonStrokePrimitive2D::getB2DRange(rViewInformation);
354             }
355         }
356 
357         // provide unique ID
358         ImplPrimitrive2DIDBlock(PolyPolygonStrokeArrowPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONSTROKEARROWPRIMITIVE2D)
359 
360     } // end of namespace primitive2d
361 } // end of namespace drawinglayer
362 
363 //////////////////////////////////////////////////////////////////////////////
364 
365 namespace drawinglayer
366 {
367     namespace primitive2d
368     {
PolyPolygonColorPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::BColor & rBColor)369         PolyPolygonColorPrimitive2D::PolyPolygonColorPrimitive2D(
370             const basegfx::B2DPolyPolygon& rPolyPolygon,
371             const basegfx::BColor& rBColor)
372         :   BasePrimitive2D(),
373             maPolyPolygon(rPolyPolygon),
374             maBColor(rBColor)
375         {
376         }
377 
operator ==(const BasePrimitive2D & rPrimitive) const378         bool PolyPolygonColorPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
379         {
380             if(BasePrimitive2D::operator==(rPrimitive))
381             {
382                 const PolyPolygonColorPrimitive2D& rCompare = (PolyPolygonColorPrimitive2D&)rPrimitive;
383 
384                 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
385                     && getBColor() == rCompare.getBColor());
386             }
387 
388             return false;
389         }
390 
getB2DRange(const geometry::ViewInformation2D &) const391         basegfx::B2DRange PolyPolygonColorPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
392         {
393             // return range
394             return basegfx::tools::getRange(getB2DPolyPolygon());
395         }
396 
397         // provide unique ID
398         ImplPrimitrive2DIDBlock(PolyPolygonColorPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D)
399 
400     } // end of namespace primitive2d
401 } // end of namespace drawinglayer
402 
403 //////////////////////////////////////////////////////////////////////////////
404 
405 namespace drawinglayer
406 {
407     namespace primitive2d
408     {
create2DDecomposition(const geometry::ViewInformation2D &) const409         Primitive2DSequence PolyPolygonGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
410         {
411             if(!getFillGradient().isDefault())
412             {
413                 // create SubSequence with FillGradientPrimitive2D
414                 const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange());
415                 FillGradientPrimitive2D* pNewGradient = new FillGradientPrimitive2D(
416                     aPolyPolygonRange,
417                     getDefinitionRange(),
418                     getFillGradient());
419                 const Primitive2DReference xSubRef(pNewGradient);
420                 const Primitive2DSequence aSubSequence(&xSubRef, 1L);
421 
422                 // create mask primitive
423                 MaskPrimitive2D* pNewMask = new MaskPrimitive2D(getB2DPolyPolygon(), aSubSequence);
424                 const Primitive2DReference xRef(pNewMask);
425 
426                 return Primitive2DSequence(&xRef, 1);
427             }
428             else
429             {
430                 return Primitive2DSequence();
431             }
432         }
433 
PolyPolygonGradientPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const attribute::FillGradientAttribute & rFillGradient)434         PolyPolygonGradientPrimitive2D::PolyPolygonGradientPrimitive2D(
435             const basegfx::B2DPolyPolygon& rPolyPolygon,
436             const attribute::FillGradientAttribute& rFillGradient)
437         :   BufferedDecompositionPrimitive2D(),
438             maPolyPolygon(rPolyPolygon),
439             maDefinitionRange(rPolyPolygon.getB2DRange()),
440             maFillGradient(rFillGradient)
441         {
442         }
443 
PolyPolygonGradientPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::B2DRange & rDefinitionRange,const attribute::FillGradientAttribute & rFillGradient)444         PolyPolygonGradientPrimitive2D::PolyPolygonGradientPrimitive2D(
445             const basegfx::B2DPolyPolygon& rPolyPolygon,
446             const basegfx::B2DRange& rDefinitionRange,
447             const attribute::FillGradientAttribute& rFillGradient)
448         :   BufferedDecompositionPrimitive2D(),
449             maPolyPolygon(rPolyPolygon),
450             maDefinitionRange(rDefinitionRange),
451             maFillGradient(rFillGradient)
452         {
453         }
454 
operator ==(const BasePrimitive2D & rPrimitive) const455         bool PolyPolygonGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
456         {
457             if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
458             {
459                 const PolyPolygonGradientPrimitive2D& rCompare = (PolyPolygonGradientPrimitive2D&)rPrimitive;
460 
461                 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
462                     && getDefinitionRange() == rCompare.getDefinitionRange()
463                     && getFillGradient() == rCompare.getFillGradient());
464             }
465 
466             return false;
467         }
468 
469         // provide unique ID
470         ImplPrimitrive2DIDBlock(PolyPolygonGradientPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D)
471 
472     } // end of namespace primitive2d
473 } // end of namespace drawinglayer
474 
475 //////////////////////////////////////////////////////////////////////////////
476 
477 namespace drawinglayer
478 {
479     namespace primitive2d
480     {
create2DDecomposition(const geometry::ViewInformation2D &) const481         Primitive2DSequence PolyPolygonHatchPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
482         {
483             if(!getFillHatch().isDefault())
484             {
485                 // create SubSequence with FillHatchPrimitive2D
486                 const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange());
487                 FillHatchPrimitive2D* pNewHatch = new FillHatchPrimitive2D(
488                     aPolyPolygonRange,
489                     getDefinitionRange(),
490                     getBackgroundColor(),
491                     getFillHatch());
492                 const Primitive2DReference xSubRef(pNewHatch);
493                 const Primitive2DSequence aSubSequence(&xSubRef, 1L);
494 
495                 // create mask primitive
496                 MaskPrimitive2D* pNewMask = new MaskPrimitive2D(getB2DPolyPolygon(), aSubSequence);
497                 const Primitive2DReference xRef(pNewMask);
498 
499                 return Primitive2DSequence(&xRef, 1);
500             }
501             else
502             {
503                 return Primitive2DSequence();
504             }
505         }
506 
PolyPolygonHatchPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::BColor & rBackgroundColor,const attribute::FillHatchAttribute & rFillHatch)507         PolyPolygonHatchPrimitive2D::PolyPolygonHatchPrimitive2D(
508             const basegfx::B2DPolyPolygon& rPolyPolygon,
509             const basegfx::BColor& rBackgroundColor,
510             const attribute::FillHatchAttribute& rFillHatch)
511         :   BufferedDecompositionPrimitive2D(),
512             maPolyPolygon(rPolyPolygon),
513             maDefinitionRange(rPolyPolygon.getB2DRange()),
514             maBackgroundColor(rBackgroundColor),
515             maFillHatch(rFillHatch)
516         {
517         }
518 
PolyPolygonHatchPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::B2DRange & rDefinitionRange,const basegfx::BColor & rBackgroundColor,const attribute::FillHatchAttribute & rFillHatch)519         PolyPolygonHatchPrimitive2D::PolyPolygonHatchPrimitive2D(
520             const basegfx::B2DPolyPolygon& rPolyPolygon,
521             const basegfx::B2DRange& rDefinitionRange,
522             const basegfx::BColor& rBackgroundColor,
523             const attribute::FillHatchAttribute& rFillHatch)
524         :   BufferedDecompositionPrimitive2D(),
525             maPolyPolygon(rPolyPolygon),
526             maDefinitionRange(rDefinitionRange),
527             maBackgroundColor(rBackgroundColor),
528             maFillHatch(rFillHatch)
529         {
530         }
531 
operator ==(const BasePrimitive2D & rPrimitive) const532         bool PolyPolygonHatchPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
533         {
534             if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
535             {
536                 const PolyPolygonHatchPrimitive2D& rCompare = (PolyPolygonHatchPrimitive2D&)rPrimitive;
537 
538                 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
539                     && getDefinitionRange() == rCompare.getDefinitionRange()
540                     && getBackgroundColor() == rCompare.getBackgroundColor()
541                     && getFillHatch() == rCompare.getFillHatch());
542             }
543 
544             return false;
545         }
546 
547         // provide unique ID
548         ImplPrimitrive2DIDBlock(PolyPolygonHatchPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D)
549 
550     } // end of namespace primitive2d
551 } // end of namespace drawinglayer
552 
553 //////////////////////////////////////////////////////////////////////////////
554 
555 namespace drawinglayer
556 {
557     namespace primitive2d
558     {
create2DDecomposition(const geometry::ViewInformation2D &) const559         Primitive2DSequence PolyPolygonGraphicPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
560         {
561             if(!getFillGraphic().isDefault())
562             {
563                 const Graphic& rGraphic = getFillGraphic().getGraphic();
564                 const GraphicType aType(rGraphic.GetType());
565 
566                 // is there a bitmap or a metafile (do we have content)?
567                 if(GRAPHIC_BITMAP == aType || GRAPHIC_GDIMETAFILE == aType)
568                 {
569                     const Size aPrefSize(rGraphic.GetPrefSize());
570 
571                     // does content have a size?
572                     if(aPrefSize.Width() && aPrefSize.Height())
573                     {
574                         // create SubSequence with FillGraphicPrimitive2D based on polygon range
575                         const basegfx::B2DRange aOutRange(getB2DPolyPolygon().getB2DRange());
576                         const basegfx::B2DHomMatrix aNewObjectTransform(
577                             basegfx::tools::createScaleTranslateB2DHomMatrix(
578                                 aOutRange.getRange(),
579                                 aOutRange.getMinimum()));
580                         Primitive2DReference xSubRef;
581 
582                         if(aOutRange != getDefinitionRange())
583                         {
584                             // we want to paint (tiled) content which is defined relative to DefinitionRange
585                             // with the same tiling and offset(s) in the traget range of the geometry (the
586                             // polygon). The range given in the local FillGraphicAttribute defines the position
587                             // of the graphic in unit coordinates relative to the DefinitionRange. Transform
588                             // this using DefinitionRange to get to the global definition and then with the
589                             // inverse transformation from the target range to go to unit coordinates relative
590                             // to that traget coordinate system.
591                             basegfx::B2DRange aAdaptedRange(getFillGraphic().getGraphicRange());
592 
593                             const basegfx::B2DHomMatrix aFromDefinitionRangeToGlobal(
594                                 basegfx::tools::createScaleTranslateB2DHomMatrix(
595                                     getDefinitionRange().getRange(),
596                                     getDefinitionRange().getMinimum()));
597 
598                             aAdaptedRange.transform(aFromDefinitionRangeToGlobal);
599 
600                             basegfx::B2DHomMatrix aFromGlobalToOutRange(
601                                 basegfx::tools::createScaleTranslateB2DHomMatrix(
602                                     aOutRange.getRange(),
603                                     aOutRange.getMinimum()));
604                             aFromGlobalToOutRange.invert();
605 
606                             aAdaptedRange.transform(aFromGlobalToOutRange);
607 
608                             const drawinglayer::attribute::FillGraphicAttribute aAdaptedFillGraphicAttribute(
609                                 getFillGraphic().getGraphic(),
610                                 aAdaptedRange,
611                                 getFillGraphic().getTiling(),
612                                 getFillGraphic().getOffsetX(),
613                                 getFillGraphic().getOffsetY());
614 
615                             xSubRef = new FillGraphicPrimitive2D(
616                                 aNewObjectTransform,
617                                 aAdaptedFillGraphicAttribute);
618                         }
619                         else
620                         {
621                             xSubRef = new FillGraphicPrimitive2D(
622                                 aNewObjectTransform,
623                                 getFillGraphic());
624                         }
625 
626                         // embed to mask primitive
627                         const Primitive2DReference xRef(
628                             new MaskPrimitive2D(
629                                 getB2DPolyPolygon(),
630                                 Primitive2DSequence(&xSubRef, 1)));
631 
632                         return Primitive2DSequence(&xRef, 1);
633                     }
634                 }
635             }
636 
637             return Primitive2DSequence();
638         }
639 
PolyPolygonGraphicPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const attribute::FillGraphicAttribute & rFillGraphic)640         PolyPolygonGraphicPrimitive2D::PolyPolygonGraphicPrimitive2D(
641             const basegfx::B2DPolyPolygon& rPolyPolygon,
642             const attribute::FillGraphicAttribute& rFillGraphic)
643         :   BufferedDecompositionPrimitive2D(),
644             maPolyPolygon(rPolyPolygon),
645             maDefinitionRange(rPolyPolygon.getB2DRange()),
646             maFillGraphic(rFillGraphic)
647         {
648         }
649 
PolyPolygonGraphicPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::B2DRange & rDefinitionRange,const attribute::FillGraphicAttribute & rFillGraphic)650         PolyPolygonGraphicPrimitive2D::PolyPolygonGraphicPrimitive2D(
651             const basegfx::B2DPolyPolygon& rPolyPolygon,
652             const basegfx::B2DRange& rDefinitionRange,
653             const attribute::FillGraphicAttribute& rFillGraphic)
654         :   BufferedDecompositionPrimitive2D(),
655             maPolyPolygon(rPolyPolygon),
656             maDefinitionRange(rDefinitionRange),
657             maFillGraphic(rFillGraphic)
658         {
659         }
660 
operator ==(const BasePrimitive2D & rPrimitive) const661         bool PolyPolygonGraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
662         {
663             if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
664             {
665                 const PolyPolygonGraphicPrimitive2D& rCompare = (PolyPolygonGraphicPrimitive2D&)rPrimitive;
666 
667                 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
668                     && getDefinitionRange() == rCompare.getDefinitionRange()
669                     && getFillGraphic() == rCompare.getFillGraphic());
670             }
671 
672             return false;
673         }
674 
675         // provide unique ID
676         ImplPrimitrive2DIDBlock(PolyPolygonGraphicPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D)
677 
678     } // end of namespace primitive2d
679 } // end of namespace drawinglayer
680 
681 //////////////////////////////////////////////////////////////////////////////
682 
683 namespace drawinglayer
684 {
685     namespace primitive2d
686     {
create2DDecomposition(const geometry::ViewInformation2D &) const687         Primitive2DSequence PolyPolygonSelectionPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
688         {
689             Primitive2DSequence aRetval;
690 
691             if(getTransparence() < 1.0 && getB2DPolyPolygon().count())
692             {
693                 if(getFill() && getB2DPolyPolygon().isClosed())
694                 {
695                     // create fill primitive
696                     const Primitive2DReference aFill(
697                         new PolyPolygonColorPrimitive2D(
698                             getB2DPolyPolygon(),
699                             getColor()));
700 
701                     aRetval = Primitive2DSequence(&aFill, 1);
702                 }
703 
704                 if(getDiscreteGrow() > 0.0)
705                 {
706                     const attribute::LineAttribute aLineAttribute(
707                         getColor(),
708                         getDiscreteGrow() * getDiscreteUnit() * 2.0);
709                     const Primitive2DReference aFatLine(
710                         new PolyPolygonStrokePrimitive2D(
711                             getB2DPolyPolygon(),
712                             aLineAttribute));
713 
714                     appendPrimitive2DReferenceToPrimitive2DSequence(aRetval, aFatLine);
715                 }
716 
717                 // embed filled to transparency (if used)
718                 if(aRetval.getLength() && getTransparence() > 0.0)
719                 {
720                     const Primitive2DReference aTrans(
721                         new UnifiedTransparencePrimitive2D(
722                             aRetval,
723                             getTransparence()));
724 
725                     aRetval = Primitive2DSequence(&aTrans, 1);
726                 }
727             }
728 
729             return aRetval;
730         }
731 
PolyPolygonSelectionPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::BColor & rColor,double fTransparence,double fDiscreteGrow,bool bFill)732         PolyPolygonSelectionPrimitive2D::PolyPolygonSelectionPrimitive2D(
733             const basegfx::B2DPolyPolygon& rPolyPolygon,
734             const basegfx::BColor& rColor,
735             double fTransparence,
736             double fDiscreteGrow,
737             bool bFill)
738         :   DiscreteMetricDependentPrimitive2D(),
739             maPolyPolygon(rPolyPolygon),
740             maColor(rColor),
741             mfTransparence(fTransparence),
742             mfDiscreteGrow(fabs(fDiscreteGrow)),
743             mbFill(bFill)
744         {
745         }
746 
operator ==(const BasePrimitive2D & rPrimitive) const747         bool PolyPolygonSelectionPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
748         {
749             if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
750             {
751                 const PolyPolygonSelectionPrimitive2D& rCompare = (PolyPolygonSelectionPrimitive2D&)rPrimitive;
752 
753                 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
754                     && getColor() == rCompare.getColor()
755                     && getTransparence() == rCompare.getTransparence()
756                     && getDiscreteGrow() == rCompare.getDiscreteGrow()
757                     && getFill() == rCompare.getFill());
758             }
759 
760             return false;
761         }
762 
getB2DRange(const geometry::ViewInformation2D & rViewInformation) const763         basegfx::B2DRange PolyPolygonSelectionPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
764         {
765             basegfx::B2DRange aRetval(basegfx::tools::getRange(getB2DPolyPolygon()));
766 
767             if(getDiscreteGrow() > 0.0)
768             {
769                 // get the current DiscreteUnit (not sure if getDiscreteUnit() is updated here, better go safe way)
770                 const double fDiscreteUnit((rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)).getLength());
771 
772                 aRetval.grow(fDiscreteUnit * getDiscreteGrow());
773             }
774 
775             return aRetval;
776         }
777 
778         // provide unique ID
779         ImplPrimitrive2DIDBlock(PolyPolygonSelectionPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONSELECTIONPRIMITIVE2D)
780 
781     } // end of namespace primitive2d
782 } // end of namespace drawinglayer
783 
784 //////////////////////////////////////////////////////////////////////////////
785 // eof
786