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