Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / drawinglayer / source / primitive2d / polypolygonprimitive2d.cxx
blob73f40a1f319ab26b13bdccf81a9025440852c40e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
21 #include <basegfx/polygon/b2dpolypolygontools.hxx>
22 #include <basegfx/utils/canvastools.hxx>
23 #include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
24 #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
25 #include <drawinglayer/primitive2d/fillhatchprimitive2d.hxx>
26 #include <basegfx/matrix/b2dhommatrix.hxx>
27 #include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx>
28 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
29 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
30 #include <basegfx/matrix/b2dhommatrixtools.hxx>
31 #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
32 #include <drawinglayer/geometry/viewinformation2d.hxx>
33 #include <vcl/graph.hxx>
36 using namespace com::sun::star;
39 namespace drawinglayer
41 namespace primitive2d
43 void PolyPolygonHairlinePrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
45 const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
46 const sal_uInt32 nCount(aPolyPolygon.count());
48 if(nCount)
50 for(sal_uInt32 a(0); a < nCount; a++)
52 rContainer.push_back(new PolygonHairlinePrimitive2D(aPolyPolygon.getB2DPolygon(a), getBColor()));
57 PolyPolygonHairlinePrimitive2D::PolyPolygonHairlinePrimitive2D(const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::BColor& rBColor)
58 : BufferedDecompositionPrimitive2D(),
59 maPolyPolygon(rPolyPolygon),
60 maBColor(rBColor)
64 bool PolyPolygonHairlinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
66 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
68 const PolyPolygonHairlinePrimitive2D& rCompare = static_cast<const PolyPolygonHairlinePrimitive2D&>(rPrimitive);
70 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
71 && getBColor() == rCompare.getBColor());
74 return false;
77 basegfx::B2DRange PolyPolygonHairlinePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
79 // return range
80 return basegfx::utils::getRange(getB2DPolyPolygon());
83 // provide unique ID
84 ImplPrimitive2DIDBlock(PolyPolygonHairlinePrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONHAIRLINEPRIMITIVE2D)
86 } // end of namespace primitive2d
87 } // end of namespace drawinglayer
90 namespace drawinglayer
92 namespace primitive2d
94 void PolyPolygonMarkerPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
96 const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
97 const sal_uInt32 nCount(aPolyPolygon.count());
99 if(nCount)
101 for(sal_uInt32 a(0); a < nCount; a++)
103 rContainer.push_back(
104 new PolygonMarkerPrimitive2D(
105 aPolyPolygon.getB2DPolygon(a),
106 getRGBColorA(),
107 getRGBColorB(),
108 getDiscreteDashLength()));
113 PolyPolygonMarkerPrimitive2D::PolyPolygonMarkerPrimitive2D(
114 const basegfx::B2DPolyPolygon& rPolyPolygon,
115 const basegfx::BColor& rRGBColorA,
116 const basegfx::BColor& rRGBColorB,
117 double fDiscreteDashLength)
118 : BufferedDecompositionPrimitive2D(),
119 maPolyPolygon(rPolyPolygon),
120 maRGBColorA(rRGBColorA),
121 maRGBColorB(rRGBColorB),
122 mfDiscreteDashLength(fDiscreteDashLength)
126 bool PolyPolygonMarkerPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
128 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
130 const PolyPolygonMarkerPrimitive2D& rCompare = static_cast<const PolyPolygonMarkerPrimitive2D&>(rPrimitive);
132 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
133 && getRGBColorA() == rCompare.getRGBColorA()
134 && getRGBColorB() == rCompare.getRGBColorB()
135 && getDiscreteDashLength() == rCompare.getDiscreteDashLength());
138 return false;
141 basegfx::B2DRange PolyPolygonMarkerPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
143 // return range
144 return basegfx::utils::getRange(getB2DPolyPolygon());
147 // provide unique ID
148 ImplPrimitive2DIDBlock(PolyPolygonMarkerPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONMARKERPRIMITIVE2D)
150 } // end of namespace primitive2d
151 } // end of namespace drawinglayer
154 namespace drawinglayer
156 namespace primitive2d
158 void PolyPolygonStrokePrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
160 const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon());
161 const sal_uInt32 nCount(aPolyPolygon.count());
163 if(nCount)
165 for(sal_uInt32 a(0); a < nCount; a++)
167 rContainer.push_back(
168 new PolygonStrokePrimitive2D(
169 aPolyPolygon.getB2DPolygon(a), getLineAttribute(), getStrokeAttribute()));
174 PolyPolygonStrokePrimitive2D::PolyPolygonStrokePrimitive2D(
175 const basegfx::B2DPolyPolygon& rPolyPolygon,
176 const attribute::LineAttribute& rLineAttribute,
177 const attribute::StrokeAttribute& rStrokeAttribute)
178 : BufferedDecompositionPrimitive2D(),
179 maPolyPolygon(rPolyPolygon),
180 maLineAttribute(rLineAttribute),
181 maStrokeAttribute(rStrokeAttribute)
185 PolyPolygonStrokePrimitive2D::PolyPolygonStrokePrimitive2D(
186 const basegfx::B2DPolyPolygon& rPolyPolygon,
187 const attribute::LineAttribute& rLineAttribute)
188 : BufferedDecompositionPrimitive2D(),
189 maPolyPolygon(rPolyPolygon),
190 maLineAttribute(rLineAttribute),
191 maStrokeAttribute()
195 bool PolyPolygonStrokePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
197 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
199 const PolyPolygonStrokePrimitive2D& rCompare = static_cast<const PolyPolygonStrokePrimitive2D&>(rPrimitive);
201 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
202 && getLineAttribute() == rCompare.getLineAttribute()
203 && getStrokeAttribute() == rCompare.getStrokeAttribute());
206 return false;
209 basegfx::B2DRange PolyPolygonStrokePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
211 // get range of it (subdivided)
212 basegfx::B2DRange aRetval(basegfx::utils::getRange(getB2DPolyPolygon()));
214 // if width, grow by line width
215 if(getLineAttribute().getWidth())
217 aRetval.grow(getLineAttribute().getWidth() / 2.0);
220 return aRetval;
223 // provide unique ID
224 ImplPrimitive2DIDBlock(PolyPolygonStrokePrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONSTROKEPRIMITIVE2D)
226 } // end of namespace primitive2d
227 } // end of namespace drawinglayer
230 namespace drawinglayer
232 namespace primitive2d
234 PolyPolygonColorPrimitive2D::PolyPolygonColorPrimitive2D(
235 const basegfx::B2DPolyPolygon& rPolyPolygon,
236 const basegfx::BColor& rBColor)
237 : BasePrimitive2D(),
238 maPolyPolygon(rPolyPolygon),
239 maBColor(rBColor)
243 bool PolyPolygonColorPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
245 if(BasePrimitive2D::operator==(rPrimitive))
247 const PolyPolygonColorPrimitive2D& rCompare = static_cast<const PolyPolygonColorPrimitive2D&>(rPrimitive);
249 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
250 && getBColor() == rCompare.getBColor());
253 return false;
256 basegfx::B2DRange PolyPolygonColorPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
258 // return range
259 return basegfx::utils::getRange(getB2DPolyPolygon());
262 // provide unique ID
263 ImplPrimitive2DIDBlock(PolyPolygonColorPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D)
265 } // end of namespace primitive2d
266 } // end of namespace drawinglayer
269 namespace drawinglayer
271 namespace primitive2d
273 void PolyPolygonGradientPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
275 if(!getFillGradient().isDefault())
277 // create SubSequence with FillGradientPrimitive2D
278 const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange());
279 FillGradientPrimitive2D* pNewGradient = new FillGradientPrimitive2D(
280 aPolyPolygonRange,
281 getDefinitionRange(),
282 getFillGradient());
283 const Primitive2DReference xSubRef(pNewGradient);
284 const Primitive2DContainer aSubSequence { xSubRef };
286 // create mask primitive
287 rContainer.push_back(new MaskPrimitive2D(getB2DPolyPolygon(), aSubSequence));
291 PolyPolygonGradientPrimitive2D::PolyPolygonGradientPrimitive2D(
292 const basegfx::B2DPolyPolygon& rPolyPolygon,
293 const attribute::FillGradientAttribute& rFillGradient)
294 : BufferedDecompositionPrimitive2D(),
295 maPolyPolygon(rPolyPolygon),
296 maDefinitionRange(rPolyPolygon.getB2DRange()),
297 maFillGradient(rFillGradient)
301 PolyPolygonGradientPrimitive2D::PolyPolygonGradientPrimitive2D(
302 const basegfx::B2DPolyPolygon& rPolyPolygon,
303 const basegfx::B2DRange& rDefinitionRange,
304 const attribute::FillGradientAttribute& rFillGradient)
305 : BufferedDecompositionPrimitive2D(),
306 maPolyPolygon(rPolyPolygon),
307 maDefinitionRange(rDefinitionRange),
308 maFillGradient(rFillGradient)
312 bool PolyPolygonGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
314 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
316 const PolyPolygonGradientPrimitive2D& rCompare = static_cast<const PolyPolygonGradientPrimitive2D&>(rPrimitive);
318 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
319 && getDefinitionRange() == rCompare.getDefinitionRange()
320 && getFillGradient() == rCompare.getFillGradient());
323 return false;
326 // provide unique ID
327 ImplPrimitive2DIDBlock(PolyPolygonGradientPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D)
329 } // end of namespace primitive2d
330 } // end of namespace drawinglayer
333 namespace drawinglayer
335 namespace primitive2d
337 void PolyPolygonHatchPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
339 if(!getFillHatch().isDefault())
341 // create SubSequence with FillHatchPrimitive2D
342 const basegfx::B2DRange aPolyPolygonRange(getB2DPolyPolygon().getB2DRange());
343 FillHatchPrimitive2D* pNewHatch = new FillHatchPrimitive2D(
344 aPolyPolygonRange,
345 getDefinitionRange(),
346 getBackgroundColor(),
347 getFillHatch());
348 const Primitive2DReference xSubRef(pNewHatch);
349 const Primitive2DContainer aSubSequence { xSubRef };
351 // create mask primitive
352 rContainer.push_back(new MaskPrimitive2D(getB2DPolyPolygon(), aSubSequence));
356 PolyPolygonHatchPrimitive2D::PolyPolygonHatchPrimitive2D(
357 const basegfx::B2DPolyPolygon& rPolyPolygon,
358 const basegfx::BColor& rBackgroundColor,
359 const attribute::FillHatchAttribute& rFillHatch)
360 : BufferedDecompositionPrimitive2D(),
361 maPolyPolygon(rPolyPolygon),
362 maDefinitionRange(rPolyPolygon.getB2DRange()),
363 maBackgroundColor(rBackgroundColor),
364 maFillHatch(rFillHatch)
368 PolyPolygonHatchPrimitive2D::PolyPolygonHatchPrimitive2D(
369 const basegfx::B2DPolyPolygon& rPolyPolygon,
370 const basegfx::B2DRange& rDefinitionRange,
371 const basegfx::BColor& rBackgroundColor,
372 const attribute::FillHatchAttribute& rFillHatch)
373 : BufferedDecompositionPrimitive2D(),
374 maPolyPolygon(rPolyPolygon),
375 maDefinitionRange(rDefinitionRange),
376 maBackgroundColor(rBackgroundColor),
377 maFillHatch(rFillHatch)
381 bool PolyPolygonHatchPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
383 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
385 const PolyPolygonHatchPrimitive2D& rCompare = static_cast<const PolyPolygonHatchPrimitive2D&>(rPrimitive);
387 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
388 && getDefinitionRange() == rCompare.getDefinitionRange()
389 && getBackgroundColor() == rCompare.getBackgroundColor()
390 && getFillHatch() == rCompare.getFillHatch());
393 return false;
396 // provide unique ID
397 ImplPrimitive2DIDBlock(PolyPolygonHatchPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D)
399 } // end of namespace primitive2d
400 } // end of namespace drawinglayer
403 namespace drawinglayer
405 namespace primitive2d
407 void PolyPolygonGraphicPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
409 if(!getFillGraphic().isDefault())
411 const Graphic& rGraphic = getFillGraphic().getGraphic();
412 const GraphicType aType(rGraphic.GetType());
414 // is there a bitmap or a metafile (do we have content)?
415 if(GraphicType::Bitmap == aType || GraphicType::GdiMetafile == aType)
417 const Size aPrefSize(rGraphic.GetPrefSize());
419 // does content have a size?
420 if(aPrefSize.Width() && aPrefSize.Height())
422 // create SubSequence with FillGraphicPrimitive2D based on polygon range
423 const basegfx::B2DRange aOutRange(getB2DPolyPolygon().getB2DRange());
424 const basegfx::B2DHomMatrix aNewObjectTransform(
425 basegfx::utils::createScaleTranslateB2DHomMatrix(
426 aOutRange.getRange(),
427 aOutRange.getMinimum()));
428 Primitive2DReference xSubRef;
430 if(aOutRange != getDefinitionRange())
432 // we want to paint (tiled) content which is defined relative to DefinitionRange
433 // with the same tiling and offset(s) in the traget range of the geometry (the
434 // polygon). The range given in the local FillGraphicAttribute defines the position
435 // of the graphic in unit coordinates relative to the DefinitionRange. Transform
436 // this using DefinitionRange to get to the global definition and then with the
437 // inverse transformation from the target range to go to unit coordinates relative
438 // to that traget coordinate system.
439 basegfx::B2DRange aAdaptedRange(getFillGraphic().getGraphicRange());
441 const basegfx::B2DHomMatrix aFromDefinitionRangeToGlobal(
442 basegfx::utils::createScaleTranslateB2DHomMatrix(
443 getDefinitionRange().getRange(),
444 getDefinitionRange().getMinimum()));
446 aAdaptedRange.transform(aFromDefinitionRangeToGlobal);
448 basegfx::B2DHomMatrix aFromGlobalToOutRange(
449 basegfx::utils::createScaleTranslateB2DHomMatrix(
450 aOutRange.getRange(),
451 aOutRange.getMinimum()));
452 aFromGlobalToOutRange.invert();
454 aAdaptedRange.transform(aFromGlobalToOutRange);
456 const drawinglayer::attribute::FillGraphicAttribute aAdaptedFillGraphicAttribute(
457 getFillGraphic().getGraphic(),
458 aAdaptedRange,
459 getFillGraphic().getTiling(),
460 getFillGraphic().getOffsetX(),
461 getFillGraphic().getOffsetY());
463 xSubRef = new FillGraphicPrimitive2D(
464 aNewObjectTransform,
465 aAdaptedFillGraphicAttribute);
467 else
469 xSubRef = new FillGraphicPrimitive2D(
470 aNewObjectTransform,
471 getFillGraphic());
474 // embed to mask primitive
475 rContainer.push_back(
476 new MaskPrimitive2D(
477 getB2DPolyPolygon(),
478 Primitive2DContainer { xSubRef }));
484 PolyPolygonGraphicPrimitive2D::PolyPolygonGraphicPrimitive2D(
485 const basegfx::B2DPolyPolygon& rPolyPolygon,
486 const basegfx::B2DRange& rDefinitionRange,
487 const attribute::FillGraphicAttribute& rFillGraphic)
488 : BufferedDecompositionPrimitive2D(),
489 maPolyPolygon(rPolyPolygon),
490 maDefinitionRange(rDefinitionRange),
491 maFillGraphic(rFillGraphic)
495 bool PolyPolygonGraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
497 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
499 const PolyPolygonGraphicPrimitive2D& rCompare = static_cast<const PolyPolygonGraphicPrimitive2D&>(rPrimitive);
501 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
502 && getDefinitionRange() == rCompare.getDefinitionRange()
503 && getFillGraphic() == rCompare.getFillGraphic());
506 return false;
509 // provide unique ID
510 ImplPrimitive2DIDBlock(PolyPolygonGraphicPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D)
512 } // end of namespace primitive2d
513 } // end of namespace drawinglayer
516 namespace drawinglayer
518 namespace primitive2d
520 void PolyPolygonSelectionPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
522 if(getTransparence() >= 1.0 || !getB2DPolyPolygon().count())
523 return;
525 Primitive2DContainer aRetval;
527 if(getFill() && getB2DPolyPolygon().isClosed())
529 // create fill primitive
530 const Primitive2DReference aFill(
531 new PolyPolygonColorPrimitive2D(
532 getB2DPolyPolygon(),
533 getColor()));
535 aRetval = Primitive2DContainer { aFill };
538 if(getDiscreteGrow() > 0.0)
540 const attribute::LineAttribute aLineAttribute(
541 getColor(),
542 getDiscreteGrow() * getDiscreteUnit() * 2.0);
543 const Primitive2DReference aFatLine(
544 new PolyPolygonStrokePrimitive2D(
545 getB2DPolyPolygon(),
546 aLineAttribute));
548 aRetval.push_back(aFatLine);
551 // embed filled to transparency (if used)
552 if(!aRetval.empty() && getTransparence() > 0.0)
554 const Primitive2DReference aTrans(
555 new UnifiedTransparencePrimitive2D(
556 aRetval,
557 getTransparence()));
559 aRetval = Primitive2DContainer { aTrans };
562 rContainer.insert(rContainer.end(), aRetval.begin(), aRetval.end());
565 PolyPolygonSelectionPrimitive2D::PolyPolygonSelectionPrimitive2D(
566 const basegfx::B2DPolyPolygon& rPolyPolygon,
567 const basegfx::BColor& rColor,
568 double fTransparence,
569 double fDiscreteGrow,
570 bool bFill)
571 : DiscreteMetricDependentPrimitive2D(),
572 maPolyPolygon(rPolyPolygon),
573 maColor(rColor),
574 mfTransparence(fTransparence),
575 mfDiscreteGrow(fabs(fDiscreteGrow)),
576 mbFill(bFill)
580 bool PolyPolygonSelectionPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
582 if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
584 const PolyPolygonSelectionPrimitive2D& rCompare = static_cast<const PolyPolygonSelectionPrimitive2D&>(rPrimitive);
586 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon()
587 && getColor() == rCompare.getColor()
588 && getTransparence() == rCompare.getTransparence()
589 && getDiscreteGrow() == rCompare.getDiscreteGrow()
590 && getFill() == rCompare.getFill());
593 return false;
596 basegfx::B2DRange PolyPolygonSelectionPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
598 basegfx::B2DRange aRetval(basegfx::utils::getRange(getB2DPolyPolygon()));
600 if(getDiscreteGrow() > 0.0)
602 // get the current DiscreteUnit (not sure if getDiscreteUnit() is updated here, better go safe way)
603 const double fDiscreteUnit((rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)).getLength());
605 aRetval.grow(fDiscreteUnit * getDiscreteGrow());
608 return aRetval;
611 // provide unique ID
612 ImplPrimitive2DIDBlock(PolyPolygonSelectionPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONSELECTIONPRIMITIVE2D)
614 } // end of namespace primitive2d
615 } // end of namespace drawinglayer
617 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */