1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 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/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 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 . 18 */ 19 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> 34 35 36 using namespace com::sun::star; 37 38 39 namespace drawinglayer 40 { 41 namespace primitive2d 42 { create2DDecomposition(Primitive2DContainer & rContainer,const geometry::ViewInformation2D &) const43 void PolyPolygonHairlinePrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const 44 { 45 const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon()); 46 const sal_uInt32 nCount(aPolyPolygon.count()); 47 48 if(nCount) 49 { 50 for(sal_uInt32 a(0); a < nCount; a++) 51 { 52 rContainer.push_back(new PolygonHairlinePrimitive2D(aPolyPolygon.getB2DPolygon(a), getBColor())); 53 } 54 } 55 } 56 PolyPolygonHairlinePrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::BColor & rBColor)57 PolyPolygonHairlinePrimitive2D::PolyPolygonHairlinePrimitive2D(const basegfx::B2DPolyPolygon& rPolyPolygon, const basegfx::BColor& rBColor) 58 : BufferedDecompositionPrimitive2D(), 59 maPolyPolygon(rPolyPolygon), 60 maBColor(rBColor) 61 { 62 } 63 operator ==(const BasePrimitive2D & rPrimitive) const64 bool PolyPolygonHairlinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 65 { 66 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 67 { 68 const PolyPolygonHairlinePrimitive2D& rCompare = static_cast<const PolyPolygonHairlinePrimitive2D&>(rPrimitive); 69 70 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon() 71 && getBColor() == rCompare.getBColor()); 72 } 73 74 return false; 75 } 76 getB2DRange(const geometry::ViewInformation2D &) const77 basegfx::B2DRange PolyPolygonHairlinePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const 78 { 79 // return range 80 return basegfx::utils::getRange(getB2DPolyPolygon()); 81 } 82 83 // provide unique ID 84 ImplPrimitive2DIDBlock(PolyPolygonHairlinePrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONHAIRLINEPRIMITIVE2D) 85 86 } // end of namespace primitive2d 87 } // end of namespace drawinglayer 88 89 90 namespace drawinglayer 91 { 92 namespace primitive2d 93 { create2DDecomposition(Primitive2DContainer & rContainer,const geometry::ViewInformation2D &) const94 void PolyPolygonMarkerPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const 95 { 96 const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon()); 97 const sal_uInt32 nCount(aPolyPolygon.count()); 98 99 if(nCount) 100 { 101 for(sal_uInt32 a(0); a < nCount; a++) 102 { 103 rContainer.push_back( 104 new PolygonMarkerPrimitive2D( 105 aPolyPolygon.getB2DPolygon(a), 106 getRGBColorA(), 107 getRGBColorB(), 108 getDiscreteDashLength())); 109 } 110 } 111 } 112 PolyPolygonMarkerPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::BColor & rRGBColorA,const basegfx::BColor & rRGBColorB,double fDiscreteDashLength)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) 123 { 124 } 125 operator ==(const BasePrimitive2D & rPrimitive) const126 bool PolyPolygonMarkerPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 127 { 128 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 129 { 130 const PolyPolygonMarkerPrimitive2D& rCompare = static_cast<const PolyPolygonMarkerPrimitive2D&>(rPrimitive); 131 132 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon() 133 && getRGBColorA() == rCompare.getRGBColorA() 134 && getRGBColorB() == rCompare.getRGBColorB() 135 && getDiscreteDashLength() == rCompare.getDiscreteDashLength()); 136 } 137 138 return false; 139 } 140 getB2DRange(const geometry::ViewInformation2D &) const141 basegfx::B2DRange PolyPolygonMarkerPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const 142 { 143 // return range 144 return basegfx::utils::getRange(getB2DPolyPolygon()); 145 } 146 147 // provide unique ID 148 ImplPrimitive2DIDBlock(PolyPolygonMarkerPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONMARKERPRIMITIVE2D) 149 150 } // end of namespace primitive2d 151 } // end of namespace drawinglayer 152 153 154 namespace drawinglayer 155 { 156 namespace primitive2d 157 { create2DDecomposition(Primitive2DContainer & rContainer,const geometry::ViewInformation2D &) const158 void PolyPolygonStrokePrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const 159 { 160 const basegfx::B2DPolyPolygon aPolyPolygon(getB2DPolyPolygon()); 161 const sal_uInt32 nCount(aPolyPolygon.count()); 162 163 if(nCount) 164 { 165 for(sal_uInt32 a(0); a < nCount; a++) 166 { 167 rContainer.push_back( 168 new PolygonStrokePrimitive2D( 169 aPolyPolygon.getB2DPolygon(a), getLineAttribute(), getStrokeAttribute())); 170 } 171 } 172 } 173 PolyPolygonStrokePrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const attribute::LineAttribute & rLineAttribute,const attribute::StrokeAttribute & rStrokeAttribute)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) 182 { 183 } 184 PolyPolygonStrokePrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const attribute::LineAttribute & rLineAttribute)185 PolyPolygonStrokePrimitive2D::PolyPolygonStrokePrimitive2D( 186 const basegfx::B2DPolyPolygon& rPolyPolygon, 187 const attribute::LineAttribute& rLineAttribute) 188 : BufferedDecompositionPrimitive2D(), 189 maPolyPolygon(rPolyPolygon), 190 maLineAttribute(rLineAttribute), 191 maStrokeAttribute() 192 { 193 } 194 operator ==(const BasePrimitive2D & rPrimitive) const195 bool PolyPolygonStrokePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 196 { 197 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 198 { 199 const PolyPolygonStrokePrimitive2D& rCompare = static_cast<const PolyPolygonStrokePrimitive2D&>(rPrimitive); 200 201 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon() 202 && getLineAttribute() == rCompare.getLineAttribute() 203 && getStrokeAttribute() == rCompare.getStrokeAttribute()); 204 } 205 206 return false; 207 } 208 getB2DRange(const geometry::ViewInformation2D &) const209 basegfx::B2DRange PolyPolygonStrokePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const 210 { 211 // get range of it (subdivided) 212 basegfx::B2DRange aRetval(basegfx::utils::getRange(getB2DPolyPolygon())); 213 214 // if width, grow by line width 215 if(getLineAttribute().getWidth()) 216 { 217 aRetval.grow(getLineAttribute().getWidth() / 2.0); 218 } 219 220 return aRetval; 221 } 222 223 // provide unique ID 224 ImplPrimitive2DIDBlock(PolyPolygonStrokePrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONSTROKEPRIMITIVE2D) 225 226 } // end of namespace primitive2d 227 } // end of namespace drawinglayer 228 229 230 namespace drawinglayer 231 { 232 namespace primitive2d 233 { PolyPolygonColorPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::BColor & rBColor)234 PolyPolygonColorPrimitive2D::PolyPolygonColorPrimitive2D( 235 const basegfx::B2DPolyPolygon& rPolyPolygon, 236 const basegfx::BColor& rBColor) 237 : BasePrimitive2D(), 238 maPolyPolygon(rPolyPolygon), 239 maBColor(rBColor) 240 { 241 } 242 operator ==(const BasePrimitive2D & rPrimitive) const243 bool PolyPolygonColorPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 244 { 245 if(BasePrimitive2D::operator==(rPrimitive)) 246 { 247 const PolyPolygonColorPrimitive2D& rCompare = static_cast<const PolyPolygonColorPrimitive2D&>(rPrimitive); 248 249 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon() 250 && getBColor() == rCompare.getBColor()); 251 } 252 253 return false; 254 } 255 getB2DRange(const geometry::ViewInformation2D &) const256 basegfx::B2DRange PolyPolygonColorPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const 257 { 258 // return range 259 return basegfx::utils::getRange(getB2DPolyPolygon()); 260 } 261 262 // provide unique ID 263 ImplPrimitive2DIDBlock(PolyPolygonColorPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D) 264 265 } // end of namespace primitive2d 266 } // end of namespace drawinglayer 267 268 269 namespace drawinglayer 270 { 271 namespace primitive2d 272 { create2DDecomposition(Primitive2DContainer & rContainer,const geometry::ViewInformation2D &) const273 void PolyPolygonGradientPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const 274 { 275 if(!getFillGradient().isDefault()) 276 { 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 }; 285 286 // create mask primitive 287 rContainer.push_back(new MaskPrimitive2D(getB2DPolyPolygon(), aSubSequence)); 288 } 289 } 290 PolyPolygonGradientPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const attribute::FillGradientAttribute & rFillGradient)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) 298 { 299 } 300 PolyPolygonGradientPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::B2DRange & rDefinitionRange,const attribute::FillGradientAttribute & 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) 309 { 310 } 311 operator ==(const BasePrimitive2D & rPrimitive) const312 bool PolyPolygonGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 313 { 314 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 315 { 316 const PolyPolygonGradientPrimitive2D& rCompare = static_cast<const PolyPolygonGradientPrimitive2D&>(rPrimitive); 317 318 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon() 319 && getDefinitionRange() == rCompare.getDefinitionRange() 320 && getFillGradient() == rCompare.getFillGradient()); 321 } 322 323 return false; 324 } 325 326 // provide unique ID 327 ImplPrimitive2DIDBlock(PolyPolygonGradientPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D) 328 329 } // end of namespace primitive2d 330 } // end of namespace drawinglayer 331 332 333 namespace drawinglayer 334 { 335 namespace primitive2d 336 { create2DDecomposition(Primitive2DContainer & rContainer,const geometry::ViewInformation2D &) const337 void PolyPolygonHatchPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const 338 { 339 if(!getFillHatch().isDefault()) 340 { 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 }; 350 351 // create mask primitive 352 rContainer.push_back(new MaskPrimitive2D(getB2DPolyPolygon(), aSubSequence)); 353 } 354 } 355 PolyPolygonHatchPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::BColor & rBackgroundColor,const attribute::FillHatchAttribute & rFillHatch)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) 365 { 366 } 367 PolyPolygonHatchPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::B2DRange & rDefinitionRange,const basegfx::BColor & rBackgroundColor,const attribute::FillHatchAttribute & 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) 378 { 379 } 380 operator ==(const BasePrimitive2D & rPrimitive) const381 bool PolyPolygonHatchPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 382 { 383 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 384 { 385 const PolyPolygonHatchPrimitive2D& rCompare = static_cast<const PolyPolygonHatchPrimitive2D&>(rPrimitive); 386 387 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon() 388 && getDefinitionRange() == rCompare.getDefinitionRange() 389 && getBackgroundColor() == rCompare.getBackgroundColor() 390 && getFillHatch() == rCompare.getFillHatch()); 391 } 392 393 return false; 394 } 395 396 // provide unique ID 397 ImplPrimitive2DIDBlock(PolyPolygonHatchPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D) 398 399 } // end of namespace primitive2d 400 } // end of namespace drawinglayer 401 402 403 namespace drawinglayer 404 { 405 namespace primitive2d 406 { create2DDecomposition(Primitive2DContainer & rContainer,const geometry::ViewInformation2D &) const407 void PolyPolygonGraphicPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const 408 { 409 if(!getFillGraphic().isDefault()) 410 { 411 const Graphic& rGraphic = getFillGraphic().getGraphic(); 412 const GraphicType aType(rGraphic.GetType()); 413 414 // is there a bitmap or a metafile (do we have content)? 415 if(GraphicType::Bitmap == aType || GraphicType::GdiMetafile == aType) 416 { 417 const Size aPrefSize(rGraphic.GetPrefSize()); 418 419 // does content have a size? 420 if(aPrefSize.Width() && aPrefSize.Height()) 421 { 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; 429 430 if(aOutRange != getDefinitionRange()) 431 { 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()); 440 441 const basegfx::B2DHomMatrix aFromDefinitionRangeToGlobal( 442 basegfx::utils::createScaleTranslateB2DHomMatrix( 443 getDefinitionRange().getRange(), 444 getDefinitionRange().getMinimum())); 445 446 aAdaptedRange.transform(aFromDefinitionRangeToGlobal); 447 448 basegfx::B2DHomMatrix aFromGlobalToOutRange( 449 basegfx::utils::createScaleTranslateB2DHomMatrix( 450 aOutRange.getRange(), 451 aOutRange.getMinimum())); 452 aFromGlobalToOutRange.invert(); 453 454 aAdaptedRange.transform(aFromGlobalToOutRange); 455 456 const drawinglayer::attribute::FillGraphicAttribute aAdaptedFillGraphicAttribute( 457 getFillGraphic().getGraphic(), 458 aAdaptedRange, 459 getFillGraphic().getTiling(), 460 getFillGraphic().getOffsetX(), 461 getFillGraphic().getOffsetY()); 462 463 xSubRef = new FillGraphicPrimitive2D( 464 aNewObjectTransform, 465 aAdaptedFillGraphicAttribute); 466 } 467 else 468 { 469 xSubRef = new FillGraphicPrimitive2D( 470 aNewObjectTransform, 471 getFillGraphic()); 472 } 473 474 // embed to mask primitive 475 rContainer.push_back( 476 new MaskPrimitive2D( 477 getB2DPolyPolygon(), 478 Primitive2DContainer { xSubRef })); 479 } 480 } 481 } 482 } 483 PolyPolygonGraphicPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::B2DRange & rDefinitionRange,const attribute::FillGraphicAttribute & rFillGraphic)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) 492 { 493 } 494 operator ==(const BasePrimitive2D & rPrimitive) const495 bool PolyPolygonGraphicPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 496 { 497 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 498 { 499 const PolyPolygonGraphicPrimitive2D& rCompare = static_cast<const PolyPolygonGraphicPrimitive2D&>(rPrimitive); 500 501 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon() 502 && getDefinitionRange() == rCompare.getDefinitionRange() 503 && getFillGraphic() == rCompare.getFillGraphic()); 504 } 505 506 return false; 507 } 508 509 // provide unique ID 510 ImplPrimitive2DIDBlock(PolyPolygonGraphicPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D) 511 512 } // end of namespace primitive2d 513 } // end of namespace drawinglayer 514 515 516 namespace drawinglayer 517 { 518 namespace primitive2d 519 { create2DDecomposition(Primitive2DContainer & rContainer,const geometry::ViewInformation2D &) const520 void PolyPolygonSelectionPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const 521 { 522 if(getTransparence() >= 1.0 || !getB2DPolyPolygon().count()) 523 return; 524 525 Primitive2DContainer aRetval; 526 527 if(getFill() && getB2DPolyPolygon().isClosed()) 528 { 529 // create fill primitive 530 const Primitive2DReference aFill( 531 new PolyPolygonColorPrimitive2D( 532 getB2DPolyPolygon(), 533 getColor())); 534 535 aRetval = Primitive2DContainer { aFill }; 536 } 537 538 if(getDiscreteGrow() > 0.0) 539 { 540 const attribute::LineAttribute aLineAttribute( 541 getColor(), 542 getDiscreteGrow() * getDiscreteUnit() * 2.0); 543 const Primitive2DReference aFatLine( 544 new PolyPolygonStrokePrimitive2D( 545 getB2DPolyPolygon(), 546 aLineAttribute)); 547 548 aRetval.push_back(aFatLine); 549 } 550 551 // embed filled to transparency (if used) 552 if(!aRetval.empty() && getTransparence() > 0.0) 553 { 554 const Primitive2DReference aTrans( 555 new UnifiedTransparencePrimitive2D( 556 aRetval, 557 getTransparence())); 558 559 aRetval = Primitive2DContainer { aTrans }; 560 } 561 562 rContainer.insert(rContainer.end(), aRetval.begin(), aRetval.end()); 563 } 564 PolyPolygonSelectionPrimitive2D(const basegfx::B2DPolyPolygon & rPolyPolygon,const basegfx::BColor & rColor,double fTransparence,double fDiscreteGrow,bool bFill)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) 577 { 578 } 579 operator ==(const BasePrimitive2D & rPrimitive) const580 bool PolyPolygonSelectionPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 581 { 582 if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive)) 583 { 584 const PolyPolygonSelectionPrimitive2D& rCompare = static_cast<const PolyPolygonSelectionPrimitive2D&>(rPrimitive); 585 586 return (getB2DPolyPolygon() == rCompare.getB2DPolyPolygon() 587 && getColor() == rCompare.getColor() 588 && getTransparence() == rCompare.getTransparence() 589 && getDiscreteGrow() == rCompare.getDiscreteGrow() 590 && getFill() == rCompare.getFill()); 591 } 592 593 return false; 594 } 595 getB2DRange(const geometry::ViewInformation2D & rViewInformation) const596 basegfx::B2DRange PolyPolygonSelectionPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 597 { 598 basegfx::B2DRange aRetval(basegfx::utils::getRange(getB2DPolyPolygon())); 599 600 if(getDiscreteGrow() > 0.0) 601 { 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()); 604 605 aRetval.grow(fDiscreteUnit * getDiscreteGrow()); 606 } 607 608 return aRetval; 609 } 610 611 // provide unique ID 612 ImplPrimitive2DIDBlock(PolyPolygonSelectionPrimitive2D, PRIMITIVE2D_ID_POLYPOLYGONSELECTIONPRIMITIVE2D) 613 614 } // end of namespace primitive2d 615 } // end of namespace drawinglayer 616 617 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 618