1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_drawinglayer.hxx" 30 31 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 32 #include <basegfx/tools/canvastools.hxx> 33 #include <basegfx/polygon/b2dpolygontools.hxx> 34 #include <basegfx/polygon/b2dpolypolygontools.hxx> 35 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 36 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 37 #include <drawinglayer/geometry/viewinformation2d.hxx> 38 #include <basegfx/polygon/b2dlinegeometry.hxx> 39 40 ////////////////////////////////////////////////////////////////////////////// 41 42 using namespace com::sun::star; 43 44 ////////////////////////////////////////////////////////////////////////////// 45 46 namespace drawinglayer 47 { 48 namespace primitive2d 49 { 50 PolygonHairlinePrimitive2D::PolygonHairlinePrimitive2D( 51 const basegfx::B2DPolygon& rPolygon, 52 const basegfx::BColor& rBColor) 53 : BasePrimitive2D(), 54 maPolygon(rPolygon), 55 maBColor(rBColor) 56 { 57 } 58 59 bool PolygonHairlinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 60 { 61 if(BasePrimitive2D::operator==(rPrimitive)) 62 { 63 const PolygonHairlinePrimitive2D& rCompare = (PolygonHairlinePrimitive2D&)rPrimitive; 64 65 return (getB2DPolygon() == rCompare.getB2DPolygon() 66 && getBColor() == rCompare.getBColor()); 67 } 68 69 return false; 70 } 71 72 basegfx::B2DRange PolygonHairlinePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 73 { 74 // this is a hairline, thus the line width is view-dependent. Get range of polygon 75 // as base size 76 basegfx::B2DRange aRetval(getB2DPolygon().getB2DRange()); 77 78 if(!aRetval.isEmpty()) 79 { 80 // Calculate view-dependent hairline width 81 const basegfx::B2DVector aDiscreteSize(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)); 82 const double fDiscreteHalfLineWidth(aDiscreteSize.getLength() * 0.5); 83 84 if(basegfx::fTools::more(fDiscreteHalfLineWidth, 0.0)) 85 { 86 aRetval.grow(fDiscreteHalfLineWidth); 87 } 88 } 89 90 // return range 91 return aRetval; 92 } 93 94 // provide unique ID 95 ImplPrimitrive2DIDBlock(PolygonHairlinePrimitive2D, PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D) 96 97 } // end of namespace primitive2d 98 } // end of namespace drawinglayer 99 100 ////////////////////////////////////////////////////////////////////////////// 101 102 namespace drawinglayer 103 { 104 namespace primitive2d 105 { 106 Primitive2DSequence PolygonMarkerPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const 107 { 108 // calculate logic DashLength 109 const basegfx::B2DVector aDashVector(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(getDiscreteDashLength(), 0.0)); 110 const double fLogicDashLength(aDashVector.getX()); 111 112 if(fLogicDashLength > 0.0 && !getRGBColorA().equal(getRGBColorB())) 113 { 114 // apply dashing; get line and gap snippets 115 ::std::vector< double > aDash; 116 basegfx::B2DPolyPolygon aDashedPolyPolyA; 117 basegfx::B2DPolyPolygon aDashedPolyPolyB; 118 119 aDash.push_back(fLogicDashLength); 120 aDash.push_back(fLogicDashLength); 121 basegfx::tools::applyLineDashing(getB2DPolygon(), aDash, &aDashedPolyPolyA, &aDashedPolyPolyB, 2.0 * fLogicDashLength); 122 123 // prepare return value 124 Primitive2DSequence aRetval(2); 125 126 aRetval[0] = Primitive2DReference(new PolyPolygonHairlinePrimitive2D(aDashedPolyPolyA, getRGBColorA())); 127 aRetval[1] = Primitive2DReference(new PolyPolygonHairlinePrimitive2D(aDashedPolyPolyB, getRGBColorB())); 128 129 return aRetval; 130 } 131 else 132 { 133 const Primitive2DReference xRef(new PolygonHairlinePrimitive2D(getB2DPolygon(), getRGBColorA())); 134 return Primitive2DSequence(&xRef, 1L); 135 } 136 } 137 138 PolygonMarkerPrimitive2D::PolygonMarkerPrimitive2D( 139 const basegfx::B2DPolygon& rPolygon, 140 const basegfx::BColor& rRGBColorA, 141 const basegfx::BColor& rRGBColorB, 142 double fDiscreteDashLength) 143 : BufferedDecompositionPrimitive2D(), 144 maPolygon(rPolygon), 145 maRGBColorA(rRGBColorA), 146 maRGBColorB(rRGBColorB), 147 mfDiscreteDashLength(fDiscreteDashLength), 148 maLastInverseObjectToViewTransformation() 149 { 150 } 151 152 bool PolygonMarkerPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 153 { 154 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 155 { 156 const PolygonMarkerPrimitive2D& rCompare = (PolygonMarkerPrimitive2D&)rPrimitive; 157 158 return (getB2DPolygon() == rCompare.getB2DPolygon() 159 && getRGBColorA() == rCompare.getRGBColorA() 160 && getRGBColorB() == rCompare.getRGBColorB() 161 && getDiscreteDashLength() == rCompare.getDiscreteDashLength()); 162 } 163 164 return false; 165 } 166 167 basegfx::B2DRange PolygonMarkerPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 168 { 169 // this is a hairline, thus the line width is view-dependent. Get range of polygon 170 // as base size 171 basegfx::B2DRange aRetval(getB2DPolygon().getB2DRange()); 172 173 if(!aRetval.isEmpty()) 174 { 175 // Calculate view-dependent hairline width 176 const basegfx::B2DVector aDiscreteSize(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)); 177 const double fDiscreteHalfLineWidth(aDiscreteSize.getLength() * 0.5); 178 179 if(basegfx::fTools::more(fDiscreteHalfLineWidth, 0.0)) 180 { 181 aRetval.grow(fDiscreteHalfLineWidth); 182 } 183 } 184 185 // return range 186 return aRetval; 187 } 188 189 Primitive2DSequence PolygonMarkerPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const 190 { 191 ::osl::MutexGuard aGuard( m_aMutex ); 192 bool bNeedNewDecomposition(false); 193 194 if(getBuffered2DDecomposition().hasElements()) 195 { 196 if(rViewInformation.getInverseObjectToViewTransformation() != maLastInverseObjectToViewTransformation) 197 { 198 bNeedNewDecomposition = true; 199 } 200 } 201 202 if(bNeedNewDecomposition) 203 { 204 // conditions of last local decomposition have changed, delete 205 const_cast< PolygonMarkerPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); 206 } 207 208 if(!getBuffered2DDecomposition().hasElements()) 209 { 210 // remember last used InverseObjectToViewTransformation 211 PolygonMarkerPrimitive2D* pThat = const_cast< PolygonMarkerPrimitive2D* >(this); 212 pThat->maLastInverseObjectToViewTransformation = rViewInformation.getInverseObjectToViewTransformation(); 213 } 214 215 // use parent implementation 216 return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); 217 } 218 219 // provide unique ID 220 ImplPrimitrive2DIDBlock(PolygonMarkerPrimitive2D, PRIMITIVE2D_ID_POLYGONMARKERPRIMITIVE2D) 221 222 } // end of namespace primitive2d 223 } // end of namespace drawinglayer 224 225 ////////////////////////////////////////////////////////////////////////////// 226 227 namespace drawinglayer 228 { 229 namespace primitive2d 230 { 231 Primitive2DSequence PolygonStrokePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 232 { 233 if(getB2DPolygon().count()) 234 { 235 // #i102241# try to simplify before usage 236 const basegfx::B2DPolygon aB2DPolygon(basegfx::tools::simplifyCurveSegments(getB2DPolygon())); 237 basegfx::B2DPolyPolygon aHairLinePolyPolygon; 238 239 if(getStrokeAttribute().isDefault() || 0.0 == getStrokeAttribute().getFullDotDashLen()) 240 { 241 // no line dashing, just copy 242 aHairLinePolyPolygon.append(aB2DPolygon); 243 } 244 else 245 { 246 // apply LineStyle 247 basegfx::tools::applyLineDashing( 248 aB2DPolygon, getStrokeAttribute().getDotDashArray(), 249 &aHairLinePolyPolygon, 0, getStrokeAttribute().getFullDotDashLen()); 250 } 251 252 const sal_uInt32 nCount(aHairLinePolyPolygon.count()); 253 254 if(!getLineAttribute().isDefault() && getLineAttribute().getWidth()) 255 { 256 // create fat line data 257 const double fHalfLineWidth(getLineAttribute().getWidth() / 2.0); 258 const basegfx::B2DLineJoin aLineJoin(getLineAttribute().getLineJoin()); 259 basegfx::B2DPolyPolygon aAreaPolyPolygon; 260 261 for(sal_uInt32 a(0L); a < nCount; a++) 262 { 263 // New version of createAreaGeometry; now creates bezier polygons 264 aAreaPolyPolygon.append(basegfx::tools::createAreaGeometry( 265 aHairLinePolyPolygon.getB2DPolygon(a), fHalfLineWidth, aLineJoin)); 266 } 267 268 // prepare return value 269 Primitive2DSequence aRetval(aAreaPolyPolygon.count()); 270 271 // create primitive 272 for(sal_uInt32 b(0L); b < aAreaPolyPolygon.count(); b++) 273 { 274 // put into single polyPolygon primitives to make clear that this is NOT meant 275 // to be painted as a single PolyPolygon (XORed as fill rule). Alternatively, a 276 // melting process may be used here one day. 277 const basegfx::B2DPolyPolygon aNewPolyPolygon(aAreaPolyPolygon.getB2DPolygon(b)); 278 static bool bTestByUsingRandomColor(false); 279 const basegfx::BColor aColor(bTestByUsingRandomColor 280 ? basegfx::BColor(rand() / 32767.0, rand() / 32767.0, rand() / 32767.0) 281 : getLineAttribute().getColor()); 282 const Primitive2DReference xRef(new PolyPolygonColorPrimitive2D(aNewPolyPolygon, aColor)); 283 aRetval[b] = xRef; 284 } 285 286 return aRetval; 287 } 288 else 289 { 290 // prepare return value 291 const Primitive2DReference xRef( 292 new PolyPolygonHairlinePrimitive2D( 293 aHairLinePolyPolygon, 294 getLineAttribute().getColor())); 295 296 return Primitive2DSequence(&xRef, 1); 297 } 298 } 299 else 300 { 301 return Primitive2DSequence(); 302 } 303 } 304 305 PolygonStrokePrimitive2D::PolygonStrokePrimitive2D( 306 const basegfx::B2DPolygon& rPolygon, 307 const attribute::LineAttribute& rLineAttribute, 308 const attribute::StrokeAttribute& rStrokeAttribute) 309 : BufferedDecompositionPrimitive2D(), 310 maPolygon(rPolygon), 311 maLineAttribute(rLineAttribute), 312 maStrokeAttribute(rStrokeAttribute) 313 { 314 } 315 316 PolygonStrokePrimitive2D::PolygonStrokePrimitive2D( 317 const basegfx::B2DPolygon& rPolygon, 318 const attribute::LineAttribute& rLineAttribute) 319 : BufferedDecompositionPrimitive2D(), 320 maPolygon(rPolygon), 321 maLineAttribute(rLineAttribute), 322 maStrokeAttribute() 323 { 324 } 325 326 bool PolygonStrokePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 327 { 328 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 329 { 330 const PolygonStrokePrimitive2D& rCompare = (PolygonStrokePrimitive2D&)rPrimitive; 331 332 return (getB2DPolygon() == rCompare.getB2DPolygon() 333 && getLineAttribute() == rCompare.getLineAttribute() 334 && getStrokeAttribute() == rCompare.getStrokeAttribute()); 335 } 336 337 return false; 338 } 339 340 basegfx::B2DRange PolygonStrokePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 341 { 342 basegfx::B2DRange aRetval; 343 344 if(getLineAttribute().getWidth()) 345 { 346 if(basegfx::B2DLINEJOIN_MITER == getLineAttribute().getLineJoin()) 347 { 348 // if line is mitered, use parent call since mitered line 349 // geometry may use more space than the geometry grown by half line width 350 aRetval = BufferedDecompositionPrimitive2D::getB2DRange(rViewInformation); 351 } 352 else 353 { 354 // for all other B2DLINEJOIN_* get the range from the base geometry 355 // and expand by half the line width 356 aRetval = getB2DPolygon().getB2DRange(); 357 aRetval.grow(getLineAttribute().getWidth() * 0.5); 358 } 359 } 360 else 361 { 362 // this is a hairline, thus the line width is view-dependent. Get range of polygon 363 // as base size 364 aRetval = getB2DPolygon().getB2DRange(); 365 366 if(!aRetval.isEmpty()) 367 { 368 // Calculate view-dependent hairline width 369 const basegfx::B2DVector aDiscreteSize(rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)); 370 const double fDiscreteHalfLineWidth(aDiscreteSize.getLength() * 0.5); 371 372 if(basegfx::fTools::more(fDiscreteHalfLineWidth, 0.0)) 373 { 374 aRetval.grow(fDiscreteHalfLineWidth); 375 } 376 } 377 } 378 379 return aRetval; 380 } 381 382 // provide unique ID 383 ImplPrimitrive2DIDBlock(PolygonStrokePrimitive2D, PRIMITIVE2D_ID_POLYGONSTROKEPRIMITIVE2D) 384 385 } // end of namespace primitive2d 386 } // end of namespace drawinglayer 387 388 ////////////////////////////////////////////////////////////////////////////// 389 390 namespace drawinglayer 391 { 392 namespace primitive2d 393 { 394 Primitive2DSequence PolygonWavePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 395 { 396 Primitive2DSequence aRetval; 397 398 if(getB2DPolygon().count()) 399 { 400 const bool bHasWidth(!basegfx::fTools::equalZero(getWaveWidth())); 401 const bool bHasHeight(!basegfx::fTools::equalZero(getWaveHeight())); 402 403 if(bHasWidth && bHasHeight) 404 { 405 // create waveline curve 406 const basegfx::B2DPolygon aWaveline(basegfx::tools::createWaveline(getB2DPolygon(), getWaveWidth(), getWaveHeight())); 407 const Primitive2DReference xRef(new PolygonStrokePrimitive2D(aWaveline, getLineAttribute(), getStrokeAttribute())); 408 aRetval = Primitive2DSequence(&xRef, 1); 409 } 410 else 411 { 412 // flat waveline, decompose to simple line primitive 413 const Primitive2DReference xRef(new PolygonStrokePrimitive2D(getB2DPolygon(), getLineAttribute(), getStrokeAttribute())); 414 aRetval = Primitive2DSequence(&xRef, 1); 415 } 416 } 417 418 return aRetval; 419 } 420 421 PolygonWavePrimitive2D::PolygonWavePrimitive2D( 422 const basegfx::B2DPolygon& rPolygon, 423 const attribute::LineAttribute& rLineAttribute, 424 const attribute::StrokeAttribute& rStrokeAttribute, 425 double fWaveWidth, 426 double fWaveHeight) 427 : PolygonStrokePrimitive2D(rPolygon, rLineAttribute, rStrokeAttribute), 428 mfWaveWidth(fWaveWidth), 429 mfWaveHeight(fWaveHeight) 430 { 431 if(mfWaveWidth < 0.0) 432 { 433 mfWaveWidth = 0.0; 434 } 435 436 if(mfWaveHeight < 0.0) 437 { 438 mfWaveHeight = 0.0; 439 } 440 } 441 442 PolygonWavePrimitive2D::PolygonWavePrimitive2D( 443 const basegfx::B2DPolygon& rPolygon, 444 const attribute::LineAttribute& rLineAttribute, 445 double fWaveWidth, 446 double fWaveHeight) 447 : PolygonStrokePrimitive2D(rPolygon, rLineAttribute), 448 mfWaveWidth(fWaveWidth), 449 mfWaveHeight(fWaveHeight) 450 { 451 if(mfWaveWidth < 0.0) 452 { 453 mfWaveWidth = 0.0; 454 } 455 456 if(mfWaveHeight < 0.0) 457 { 458 mfWaveHeight = 0.0; 459 } 460 } 461 462 bool PolygonWavePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 463 { 464 if(PolygonStrokePrimitive2D::operator==(rPrimitive)) 465 { 466 const PolygonWavePrimitive2D& rCompare = (PolygonWavePrimitive2D&)rPrimitive; 467 468 return (getWaveWidth() == rCompare.getWaveWidth() 469 && getWaveHeight() == rCompare.getWaveHeight()); 470 } 471 472 return false; 473 } 474 475 basegfx::B2DRange PolygonWavePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 476 { 477 // get range of parent 478 basegfx::B2DRange aRetval(PolygonStrokePrimitive2D::getB2DRange(rViewInformation)); 479 480 // if WaveHeight, grow by it 481 if(basegfx::fTools::more(getWaveHeight(), 0.0)) 482 { 483 aRetval.grow(getWaveHeight()); 484 } 485 486 // if line width, grow by it 487 if(basegfx::fTools::more(getLineAttribute().getWidth(), 0.0)) 488 { 489 aRetval.grow(getLineAttribute().getWidth() * 0.5); 490 } 491 492 return aRetval; 493 } 494 495 // provide unique ID 496 ImplPrimitrive2DIDBlock(PolygonWavePrimitive2D, PRIMITIVE2D_ID_POLYGONWAVEPRIMITIVE2D) 497 498 } // end of namespace primitive2d 499 } // end of namespace drawinglayer 500 501 ////////////////////////////////////////////////////////////////////////////// 502 503 namespace drawinglayer 504 { 505 namespace primitive2d 506 { 507 Primitive2DSequence PolygonStrokeArrowPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 508 { 509 // copy local polygon, it may be changed 510 basegfx::B2DPolygon aLocalPolygon(getB2DPolygon()); 511 basegfx::B2DPolyPolygon aArrowA; 512 basegfx::B2DPolyPolygon aArrowB; 513 514 if(!aLocalPolygon.isClosed()) 515 { 516 // apply arrows 517 const double fPolyLength(basegfx::tools::getLength(aLocalPolygon)); 518 double fStart(0.0); 519 double fEnd(0.0); 520 521 if(!getStart().isDefault() && getStart().isActive()) 522 { 523 // create start arrow primitive and consume 524 aArrowA = basegfx::tools::createAreaGeometryForLineStartEnd( 525 aLocalPolygon, getStart().getB2DPolyPolygon(), true, getStart().getWidth(), 526 fPolyLength, getStart().isCentered() ? 0.5 : 0.0, &fStart); 527 528 // create some overlapping 529 fStart *= 0.8; 530 } 531 532 if(!getEnd().isDefault() && getEnd().isActive()) 533 { 534 // create end arrow primitive and consume 535 aArrowB = basegfx::tools::createAreaGeometryForLineStartEnd( 536 aLocalPolygon, getEnd().getB2DPolyPolygon(), false, getEnd().getWidth(), 537 fPolyLength, getEnd().isCentered() ? 0.5 : 0.0, &fEnd); 538 539 // create some overlapping 540 fEnd *= 0.8; 541 } 542 543 if(0.0 != fStart || 0.0 != fEnd) 544 { 545 // build new poly, consume something from old poly 546 aLocalPolygon = basegfx::tools::getSnippetAbsolute(aLocalPolygon, fStart, fPolyLength - fEnd, fPolyLength); 547 } 548 } 549 550 // prepare return value 551 Primitive2DSequence aRetval(1L + (aArrowA.count() ? 1L : 0L) + (aArrowB.count() ? 1L : 0L)); 552 sal_uInt32 nInd(0L); 553 554 // add shaft 555 const Primitive2DReference xRefShaft(new 556 PolygonStrokePrimitive2D( 557 aLocalPolygon, getLineAttribute(), getStrokeAttribute())); 558 aRetval[nInd++] = xRefShaft; 559 560 if(aArrowA.count()) 561 { 562 const Primitive2DReference xRefA( 563 new PolyPolygonColorPrimitive2D( 564 aArrowA, getLineAttribute().getColor())); 565 aRetval[nInd++] = xRefA; 566 } 567 568 if(aArrowB.count()) 569 { 570 const Primitive2DReference xRefB( 571 new PolyPolygonColorPrimitive2D( 572 aArrowB, getLineAttribute().getColor())); 573 aRetval[nInd++] = xRefB; 574 } 575 576 return aRetval; 577 } 578 579 PolygonStrokeArrowPrimitive2D::PolygonStrokeArrowPrimitive2D( 580 const basegfx::B2DPolygon& rPolygon, 581 const attribute::LineAttribute& rLineAttribute, 582 const attribute::StrokeAttribute& rStrokeAttribute, 583 const attribute::LineStartEndAttribute& rStart, 584 const attribute::LineStartEndAttribute& rEnd) 585 : PolygonStrokePrimitive2D(rPolygon, rLineAttribute, rStrokeAttribute), 586 maStart(rStart), 587 maEnd(rEnd) 588 { 589 } 590 591 PolygonStrokeArrowPrimitive2D::PolygonStrokeArrowPrimitive2D( 592 const basegfx::B2DPolygon& rPolygon, 593 const attribute::LineAttribute& rLineAttribute, 594 const attribute::LineStartEndAttribute& rStart, 595 const attribute::LineStartEndAttribute& rEnd) 596 : PolygonStrokePrimitive2D(rPolygon, rLineAttribute), 597 maStart(rStart), 598 maEnd(rEnd) 599 { 600 } 601 602 bool PolygonStrokeArrowPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 603 { 604 if(PolygonStrokePrimitive2D::operator==(rPrimitive)) 605 { 606 const PolygonStrokeArrowPrimitive2D& rCompare = (PolygonStrokeArrowPrimitive2D&)rPrimitive; 607 608 return (getStart() == rCompare.getStart() 609 && getEnd() == rCompare.getEnd()); 610 } 611 612 return false; 613 } 614 615 basegfx::B2DRange PolygonStrokeArrowPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 616 { 617 basegfx::B2DRange aRetval; 618 619 if(getStart().isActive() || getEnd().isActive()) 620 { 621 // use decomposition when line start/end is used 622 return BufferedDecompositionPrimitive2D::getB2DRange(rViewInformation); 623 } 624 else 625 { 626 // get range from parent 627 return PolygonStrokePrimitive2D::getB2DRange(rViewInformation); 628 } 629 } 630 631 // provide unique ID 632 ImplPrimitrive2DIDBlock(PolygonStrokeArrowPrimitive2D, PRIMITIVE2D_ID_POLYGONSTROKEARROWPRIMITIVE2D) 633 634 } // end of namespace primitive2d 635 } // end of namespace drawinglayer 636 637 ////////////////////////////////////////////////////////////////////////////// 638 // eof 639