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 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_basegfx.hxx" 24 25 #include <basegfx/polygon/b2dpolypolygontools.hxx> 26 #include <osl/diagnose.h> 27 #include <basegfx/polygon/b2dpolypolygon.hxx> 28 #include <basegfx/polygon/b2dpolygon.hxx> 29 #include <basegfx/polygon/b2dpolygontools.hxx> 30 #include <basegfx/numeric/ftools.hxx> 31 #include <basegfx/polygon/b2dpolypolygoncutter.hxx> 32 #include <numeric> 33 34 ////////////////////////////////////////////////////////////////////////////// 35 36 namespace basegfx 37 { 38 namespace tools 39 { correctOrientations(const B2DPolyPolygon & rCandidate)40 B2DPolyPolygon correctOrientations(const B2DPolyPolygon& rCandidate) 41 { 42 B2DPolyPolygon aRetval(rCandidate); 43 const sal_uInt32 nCount(aRetval.count()); 44 45 for(sal_uInt32 a(0L); a < nCount; a++) 46 { 47 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a)); 48 const B2VectorOrientation aOrientation(tools::getOrientation(aCandidate)); 49 sal_uInt32 nDepth(0L); 50 51 for(sal_uInt32 b(0L); b < nCount; b++) 52 { 53 if(b != a) 54 { 55 const B2DPolygon aCompare(rCandidate.getB2DPolygon(b)); 56 57 if(tools::isInside(aCompare, aCandidate, true)) 58 { 59 nDepth++; 60 } 61 } 62 } 63 64 const bool bShallBeHole(1L == (nDepth & 0x00000001)); 65 const bool bIsHole(ORIENTATION_NEGATIVE == aOrientation); 66 67 if(bShallBeHole != bIsHole && ORIENTATION_NEUTRAL != aOrientation) 68 { 69 B2DPolygon aFlipped(aCandidate); 70 aFlipped.flip(); 71 aRetval.setB2DPolygon(a, aFlipped); 72 } 73 } 74 75 return aRetval; 76 } 77 correctOutmostPolygon(const B2DPolyPolygon & rCandidate)78 B2DPolyPolygon correctOutmostPolygon(const B2DPolyPolygon& rCandidate) 79 { 80 const sal_uInt32 nCount(rCandidate.count()); 81 82 if(nCount > 1L) 83 { 84 for(sal_uInt32 a(0L); a < nCount; a++) 85 { 86 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a)); 87 sal_uInt32 nDepth(0L); 88 89 for(sal_uInt32 b(0L); b < nCount; b++) 90 { 91 if(b != a) 92 { 93 const B2DPolygon aCompare(rCandidate.getB2DPolygon(b)); 94 95 if(tools::isInside(aCompare, aCandidate, true)) 96 { 97 nDepth++; 98 } 99 } 100 } 101 102 if(!nDepth) 103 { 104 B2DPolyPolygon aRetval(rCandidate); 105 106 if(a != 0L) 107 { 108 // exchange polygon a and polygon 0L 109 aRetval.setB2DPolygon(0L, aCandidate); 110 aRetval.setB2DPolygon(a, rCandidate.getB2DPolygon(0L)); 111 } 112 113 // exit 114 return aRetval; 115 } 116 } 117 } 118 119 return rCandidate; 120 } 121 adaptiveSubdivideByDistance(const B2DPolyPolygon & rCandidate,double fDistanceBound)122 B2DPolyPolygon adaptiveSubdivideByDistance(const B2DPolyPolygon& rCandidate, double fDistanceBound) 123 { 124 if(rCandidate.areControlPointsUsed()) 125 { 126 const sal_uInt32 nPolygonCount(rCandidate.count()); 127 B2DPolyPolygon aRetval; 128 129 for(sal_uInt32 a(0L); a < nPolygonCount; a++) 130 { 131 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a)); 132 133 if(aCandidate.areControlPointsUsed()) 134 { 135 aRetval.append(tools::adaptiveSubdivideByDistance(aCandidate, fDistanceBound)); 136 } 137 else 138 { 139 aRetval.append(aCandidate); 140 } 141 } 142 143 return aRetval; 144 } 145 else 146 { 147 return rCandidate; 148 } 149 } 150 adaptiveSubdivideByAngle(const B2DPolyPolygon & rCandidate,double fAngleBound)151 B2DPolyPolygon adaptiveSubdivideByAngle(const B2DPolyPolygon& rCandidate, double fAngleBound) 152 { 153 if(rCandidate.areControlPointsUsed()) 154 { 155 const sal_uInt32 nPolygonCount(rCandidate.count()); 156 B2DPolyPolygon aRetval; 157 158 for(sal_uInt32 a(0L); a < nPolygonCount; a++) 159 { 160 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a)); 161 162 if(aCandidate.areControlPointsUsed()) 163 { 164 aRetval.append(tools::adaptiveSubdivideByAngle(aCandidate, fAngleBound)); 165 } 166 else 167 { 168 aRetval.append(aCandidate); 169 } 170 } 171 172 return aRetval; 173 } 174 else 175 { 176 return rCandidate; 177 } 178 } 179 adaptiveSubdivideByCount(const B2DPolyPolygon & rCandidate,sal_uInt32 nCount)180 B2DPolyPolygon adaptiveSubdivideByCount(const B2DPolyPolygon& rCandidate, sal_uInt32 nCount) 181 { 182 if(rCandidate.areControlPointsUsed()) 183 { 184 const sal_uInt32 nPolygonCount(rCandidate.count()); 185 B2DPolyPolygon aRetval; 186 187 for(sal_uInt32 a(0L); a < nPolygonCount; a++) 188 { 189 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a)); 190 191 if(aCandidate.areControlPointsUsed()) 192 { 193 aRetval.append(tools::adaptiveSubdivideByCount(aCandidate, nCount)); 194 } 195 else 196 { 197 aRetval.append(aCandidate); 198 } 199 } 200 201 return aRetval; 202 } 203 else 204 { 205 return rCandidate; 206 } 207 } 208 isInside(const B2DPolyPolygon & rCandidate,const B2DPoint & rPoint,bool bWithBorder)209 bool isInside(const B2DPolyPolygon& rCandidate, const B2DPoint& rPoint, bool bWithBorder) 210 { 211 const sal_uInt32 nPolygonCount(rCandidate.count()); 212 213 if(1L == nPolygonCount) 214 { 215 return isInside(rCandidate.getB2DPolygon(0L), rPoint, bWithBorder); 216 } 217 else 218 { 219 sal_Int32 nInsideCount(0L); 220 221 for(sal_uInt32 a(0L); a < nPolygonCount; a++) 222 { 223 const B2DPolygon aPolygon(rCandidate.getB2DPolygon(a)); 224 const bool bInside(isInside(aPolygon, rPoint, bWithBorder)); 225 226 if(bInside) 227 { 228 nInsideCount++; 229 } 230 } 231 232 return (nInsideCount % 2L); 233 } 234 } 235 getRangeWithControlPoints(const B2DPolyPolygon & rCandidate)236 B2DRange getRangeWithControlPoints(const B2DPolyPolygon& rCandidate) 237 { 238 B2DRange aRetval; 239 const sal_uInt32 nPolygonCount(rCandidate.count()); 240 241 for(sal_uInt32 a(0L); a < nPolygonCount; a++) 242 { 243 B2DPolygon aCandidate = rCandidate.getB2DPolygon(a); 244 aRetval.expand(tools::getRangeWithControlPoints(aCandidate)); 245 } 246 247 return aRetval; 248 } 249 getRange(const B2DPolyPolygon & rCandidate)250 B2DRange getRange(const B2DPolyPolygon& rCandidate) 251 { 252 B2DRange aRetval; 253 const sal_uInt32 nPolygonCount(rCandidate.count()); 254 255 for(sal_uInt32 a(0L); a < nPolygonCount; a++) 256 { 257 B2DPolygon aCandidate = rCandidate.getB2DPolygon(a); 258 aRetval.expand(tools::getRange(aCandidate)); 259 } 260 261 return aRetval; 262 } 263 getSignedArea(const B2DPolyPolygon & rCandidate)264 double getSignedArea(const B2DPolyPolygon& rCandidate) 265 { 266 double fRetval(0.0); 267 const sal_uInt32 nPolygonCount(rCandidate.count()); 268 269 for(sal_uInt32 a(0L); a < nPolygonCount; a++) 270 { 271 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a)); 272 273 fRetval += tools::getSignedArea(aCandidate); 274 } 275 276 return fRetval; 277 } 278 getArea(const B2DPolyPolygon & rCandidate)279 double getArea(const B2DPolyPolygon& rCandidate) 280 { 281 return fabs(getSignedArea(rCandidate)); 282 } 283 applyLineDashing(const B2DPolyPolygon & rCandidate,const::std::vector<double> & rDotDashArray,B2DPolyPolygon * pLineTarget,B2DPolyPolygon * pGapTarget,double fFullDashDotLen)284 void applyLineDashing(const B2DPolyPolygon& rCandidate, const ::std::vector<double>& rDotDashArray, B2DPolyPolygon* pLineTarget, B2DPolyPolygon* pGapTarget, double fFullDashDotLen) 285 { 286 if(0.0 == fFullDashDotLen && rDotDashArray.size()) 287 { 288 // calculate fFullDashDotLen from rDotDashArray 289 fFullDashDotLen = ::std::accumulate(rDotDashArray.begin(), rDotDashArray.end(), 0.0); 290 } 291 292 if(rCandidate.count() && fFullDashDotLen > 0.0) 293 { 294 B2DPolyPolygon aLineTarget, aGapTarget; 295 296 for(sal_uInt32 a(0L); a < rCandidate.count(); a++) 297 { 298 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a)); 299 300 applyLineDashing( 301 aCandidate, 302 rDotDashArray, 303 pLineTarget ? &aLineTarget : 0, 304 pGapTarget ? &aGapTarget : 0, 305 fFullDashDotLen); 306 307 if(pLineTarget) 308 { 309 pLineTarget->append(aLineTarget); 310 } 311 312 if(pGapTarget) 313 { 314 pGapTarget->append(aGapTarget); 315 } 316 } 317 } 318 } 319 isInEpsilonRange(const B2DPolyPolygon & rCandidate,const B2DPoint & rTestPosition,double fDistance)320 bool isInEpsilonRange(const B2DPolyPolygon& rCandidate, const B2DPoint& rTestPosition, double fDistance) 321 { 322 const sal_uInt32 nPolygonCount(rCandidate.count()); 323 324 for(sal_uInt32 a(0L); a < nPolygonCount; a++) 325 { 326 B2DPolygon aCandidate(rCandidate.getB2DPolygon(a)); 327 328 if(isInEpsilonRange(aCandidate, rTestPosition, fDistance)) 329 { 330 return true; 331 } 332 } 333 334 return false; 335 } 336 createB3DPolyPolygonFromB2DPolyPolygon(const B2DPolyPolygon & rCandidate,double fZCoordinate)337 B3DPolyPolygon createB3DPolyPolygonFromB2DPolyPolygon(const B2DPolyPolygon& rCandidate, double fZCoordinate) 338 { 339 const sal_uInt32 nPolygonCount(rCandidate.count()); 340 B3DPolyPolygon aRetval; 341 342 for(sal_uInt32 a(0L); a < nPolygonCount; a++) 343 { 344 B2DPolygon aCandidate(rCandidate.getB2DPolygon(a)); 345 346 aRetval.append(createB3DPolygonFromB2DPolygon(aCandidate, fZCoordinate)); 347 } 348 349 return aRetval; 350 } 351 createB2DPolyPolygonFromB3DPolyPolygon(const B3DPolyPolygon & rCandidate,const B3DHomMatrix & rMat)352 B2DPolyPolygon createB2DPolyPolygonFromB3DPolyPolygon(const B3DPolyPolygon& rCandidate, const B3DHomMatrix& rMat) 353 { 354 const sal_uInt32 nPolygonCount(rCandidate.count()); 355 B2DPolyPolygon aRetval; 356 357 for(sal_uInt32 a(0L); a < nPolygonCount; a++) 358 { 359 B3DPolygon aCandidate(rCandidate.getB3DPolygon(a)); 360 361 aRetval.append(createB2DPolygonFromB3DPolygon(aCandidate, rMat)); 362 } 363 364 return aRetval; 365 } 366 getSmallestDistancePointToPolyPolygon(const B2DPolyPolygon & rCandidate,const B2DPoint & rTestPoint,sal_uInt32 & rPolygonIndex,sal_uInt32 & rEdgeIndex,double & rCut)367 double getSmallestDistancePointToPolyPolygon(const B2DPolyPolygon& rCandidate, const B2DPoint& rTestPoint, sal_uInt32& rPolygonIndex, sal_uInt32& rEdgeIndex, double& rCut) 368 { 369 double fRetval(DBL_MAX); 370 const double fZero(0.0); 371 const sal_uInt32 nPolygonCount(rCandidate.count()); 372 373 for(sal_uInt32 a(0L); a < nPolygonCount; a++) 374 { 375 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a)); 376 sal_uInt32 nNewEdgeIndex; 377 double fNewCut; 378 const double fNewDistance(getSmallestDistancePointToPolygon(aCandidate, rTestPoint, nNewEdgeIndex, fNewCut)); 379 380 if(DBL_MAX == fRetval || fNewDistance < fRetval) 381 { 382 fRetval = fNewDistance; 383 rPolygonIndex = a; 384 rEdgeIndex = nNewEdgeIndex; 385 rCut = fNewCut; 386 387 if(fTools::equal(fRetval, fZero)) 388 { 389 // already found zero distance, cannot get better. Ensure numerical zero value and end loop. 390 fRetval = 0.0; 391 break; 392 } 393 } 394 } 395 396 return fRetval; 397 } 398 distort(const B2DPolyPolygon & rCandidate,const B2DRange & rOriginal,const B2DPoint & rTopLeft,const B2DPoint & rTopRight,const B2DPoint & rBottomLeft,const B2DPoint & rBottomRight)399 B2DPolyPolygon distort(const B2DPolyPolygon& rCandidate, const B2DRange& rOriginal, const B2DPoint& rTopLeft, const B2DPoint& rTopRight, const B2DPoint& rBottomLeft, const B2DPoint& rBottomRight) 400 { 401 const sal_uInt32 nPolygonCount(rCandidate.count()); 402 B2DPolyPolygon aRetval; 403 404 for(sal_uInt32 a(0L); a < nPolygonCount; a++) 405 { 406 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a)); 407 408 aRetval.append(distort(aCandidate, rOriginal, rTopLeft, rTopRight, rBottomLeft, rBottomRight)); 409 } 410 411 return aRetval; 412 } 413 rotateAroundPoint(const B2DPolyPolygon & rCandidate,const B2DPoint & rCenter,double fAngle)414 B2DPolyPolygon rotateAroundPoint(const B2DPolyPolygon& rCandidate, const B2DPoint& rCenter, double fAngle) 415 { 416 const sal_uInt32 nPolygonCount(rCandidate.count()); 417 B2DPolyPolygon aRetval; 418 419 for(sal_uInt32 a(0L); a < nPolygonCount; a++) 420 { 421 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a)); 422 423 aRetval.append(rotateAroundPoint(aCandidate, rCenter, fAngle)); 424 } 425 426 return aRetval; 427 } 428 expandToCurve(const B2DPolyPolygon & rCandidate)429 B2DPolyPolygon expandToCurve(const B2DPolyPolygon& rCandidate) 430 { 431 const sal_uInt32 nPolygonCount(rCandidate.count()); 432 B2DPolyPolygon aRetval; 433 434 for(sal_uInt32 a(0L); a < nPolygonCount; a++) 435 { 436 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a)); 437 438 aRetval.append(expandToCurve(aCandidate)); 439 } 440 441 return aRetval; 442 } 443 setContinuity(const B2DPolyPolygon & rCandidate,B2VectorContinuity eContinuity)444 B2DPolyPolygon setContinuity(const B2DPolyPolygon& rCandidate, B2VectorContinuity eContinuity) 445 { 446 if(rCandidate.areControlPointsUsed()) 447 { 448 const sal_uInt32 nPolygonCount(rCandidate.count()); 449 B2DPolyPolygon aRetval; 450 451 for(sal_uInt32 a(0L); a < nPolygonCount; a++) 452 { 453 const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a)); 454 455 aRetval.append(setContinuity(aCandidate, eContinuity)); 456 } 457 458 return aRetval; 459 } 460 else 461 { 462 return rCandidate; 463 } 464 } 465 growInNormalDirection(const B2DPolyPolygon & rCandidate,double fValue)466 B2DPolyPolygon growInNormalDirection(const B2DPolyPolygon& rCandidate, double fValue) 467 { 468 if(0.0 != fValue) 469 { 470 B2DPolyPolygon aRetval; 471 472 for(sal_uInt32 a(0L); a < rCandidate.count(); a++) 473 { 474 aRetval.append(growInNormalDirection(rCandidate.getB2DPolygon(a), fValue)); 475 } 476 477 return aRetval; 478 } 479 else 480 { 481 return rCandidate; 482 } 483 } 484 correctGrowShrinkPolygonPair(B2DPolyPolygon &,B2DPolyPolygon &)485 void correctGrowShrinkPolygonPair(B2DPolyPolygon& /*rOriginal*/, B2DPolyPolygon& /*rGrown*/) 486 { 487 } 488 reSegmentPolyPolygon(const B2DPolyPolygon & rCandidate,sal_uInt32 nSegments)489 B2DPolyPolygon reSegmentPolyPolygon(const B2DPolyPolygon& rCandidate, sal_uInt32 nSegments) 490 { 491 B2DPolyPolygon aRetval; 492 493 for(sal_uInt32 a(0L); a < rCandidate.count(); a++) 494 { 495 aRetval.append(reSegmentPolygon(rCandidate.getB2DPolygon(a), nSegments)); 496 } 497 498 return aRetval; 499 } 500 interpolate(const B2DPolyPolygon & rOld1,const B2DPolyPolygon & rOld2,double t)501 B2DPolyPolygon interpolate(const B2DPolyPolygon& rOld1, const B2DPolyPolygon& rOld2, double t) 502 { 503 OSL_ENSURE(rOld1.count() == rOld2.count(), "B2DPolyPolygon interpolate: Different geometry (!)"); 504 B2DPolyPolygon aRetval; 505 506 for(sal_uInt32 a(0L); a < rOld1.count(); a++) 507 { 508 aRetval.append(interpolate(rOld1.getB2DPolygon(a), rOld2.getB2DPolygon(a), t)); 509 } 510 511 return aRetval; 512 } 513 isRectangle(const B2DPolyPolygon & rPoly)514 bool isRectangle( const B2DPolyPolygon& rPoly ) 515 { 516 // exclude some cheap cases first 517 if( rPoly.count() != 1 ) 518 return false; 519 520 return isRectangle( rPoly.getB2DPolygon(0) ); 521 } 522 523 // #i76891# simplifyCurveSegments(const B2DPolyPolygon & rCandidate)524 B2DPolyPolygon simplifyCurveSegments(const B2DPolyPolygon& rCandidate) 525 { 526 if(rCandidate.areControlPointsUsed()) 527 { 528 B2DPolyPolygon aRetval; 529 530 for(sal_uInt32 a(0L); a < rCandidate.count(); a++) 531 { 532 aRetval.append(simplifyCurveSegments(rCandidate.getB2DPolygon(a))); 533 } 534 535 return aRetval; 536 } 537 else 538 { 539 return rCandidate; 540 } 541 } 542 reSegmentPolyPolygonEdges(const B2DPolyPolygon & rCandidate,sal_uInt32 nSubEdges,bool bHandleCurvedEdges,bool bHandleStraightEdges)543 B2DPolyPolygon reSegmentPolyPolygonEdges(const B2DPolyPolygon& rCandidate, sal_uInt32 nSubEdges, bool bHandleCurvedEdges, bool bHandleStraightEdges) 544 { 545 B2DPolyPolygon aRetval; 546 547 for(sal_uInt32 a(0L); a < rCandidate.count(); a++) 548 { 549 aRetval.append(reSegmentPolygonEdges(rCandidate.getB2DPolygon(a), nSubEdges, bHandleCurvedEdges, bHandleStraightEdges)); 550 } 551 552 return aRetval; 553 } 554 555 ////////////////////////////////////////////////////////////////////// 556 // comparators with tolerance for 2D PolyPolygons 557 equal(const B2DPolyPolygon & rCandidateA,const B2DPolyPolygon & rCandidateB,const double & rfSmallValue)558 bool equal(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB, const double& rfSmallValue) 559 { 560 const sal_uInt32 nPolygonCount(rCandidateA.count()); 561 562 if(nPolygonCount != rCandidateB.count()) 563 return false; 564 565 for(sal_uInt32 a(0); a < nPolygonCount; a++) 566 { 567 const B2DPolygon aCandidate(rCandidateA.getB2DPolygon(a)); 568 569 if(!equal(aCandidate, rCandidateB.getB2DPolygon(a), rfSmallValue)) 570 return false; 571 } 572 573 return true; 574 } 575 equal(const B2DPolyPolygon & rCandidateA,const B2DPolyPolygon & rCandidateB)576 bool equal(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB) 577 { 578 const double fSmallValue(fTools::getSmallValue()); 579 580 return equal(rCandidateA, rCandidateB, fSmallValue); 581 } 582 snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon & rCandidate)583 B2DPolyPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon& rCandidate) 584 { 585 B2DPolyPolygon aRetval; 586 587 for(sal_uInt32 a(0L); a < rCandidate.count(); a++) 588 { 589 aRetval.append(snapPointsOfHorizontalOrVerticalEdges(rCandidate.getB2DPolygon(a))); 590 } 591 592 return aRetval; 593 } 594 containsOnlyHorizontalAndVerticalEdges(const B2DPolyPolygon & rCandidate)595 bool containsOnlyHorizontalAndVerticalEdges(const B2DPolyPolygon& rCandidate) 596 { 597 if(rCandidate.areControlPointsUsed()) 598 { 599 return false; 600 } 601 602 for(sal_uInt32 a(0); a < rCandidate.count(); a++) 603 { 604 if(!containsOnlyHorizontalAndVerticalEdges(rCandidate.getB2DPolygon(a))) 605 { 606 return false; 607 } 608 } 609 610 return true; 611 } 612 613 ////////////////////////////////////////////////////////////////////////////// 614 // converters for com::sun::star::drawing::PointSequence 615 UnoPointSequenceSequenceToB2DPolyPolygon(const com::sun::star::drawing::PointSequenceSequence & rPointSequenceSequenceSource,bool bCheckClosed)616 B2DPolyPolygon UnoPointSequenceSequenceToB2DPolyPolygon( 617 const com::sun::star::drawing::PointSequenceSequence& rPointSequenceSequenceSource, 618 bool bCheckClosed) 619 { 620 B2DPolyPolygon aRetval; 621 const com::sun::star::drawing::PointSequence* pPointSequence = rPointSequenceSequenceSource.getConstArray(); 622 const com::sun::star::drawing::PointSequence* pPointSeqEnd = pPointSequence + rPointSequenceSequenceSource.getLength(); 623 624 for(;pPointSequence != pPointSeqEnd; pPointSequence++) 625 { 626 const B2DPolygon aNewPolygon = UnoPointSequenceToB2DPolygon(*pPointSequence, bCheckClosed); 627 aRetval.append(aNewPolygon); 628 } 629 630 return aRetval; 631 } 632 B2DPolyPolygonToUnoPointSequenceSequence(const B2DPolyPolygon & rPolyPolygon,com::sun::star::drawing::PointSequenceSequence & rPointSequenceSequenceRetval)633 void B2DPolyPolygonToUnoPointSequenceSequence( 634 const B2DPolyPolygon& rPolyPolygon, 635 com::sun::star::drawing::PointSequenceSequence& rPointSequenceSequenceRetval) 636 { 637 const sal_uInt32 nCount(rPolyPolygon.count()); 638 639 if(nCount) 640 { 641 rPointSequenceSequenceRetval.realloc(nCount); 642 com::sun::star::drawing::PointSequence* pPointSequence = rPointSequenceSequenceRetval.getArray(); 643 644 for(sal_uInt32 a(0); a < nCount; a++) 645 { 646 const B2DPolygon aPolygon(rPolyPolygon.getB2DPolygon(a)); 647 648 B2DPolygonToUnoPointSequence(aPolygon, *pPointSequence); 649 pPointSequence++; 650 } 651 } 652 else 653 { 654 rPointSequenceSequenceRetval.realloc(0); 655 } 656 } 657 658 ////////////////////////////////////////////////////////////////////////////// 659 // converters for com::sun::star::drawing::PolyPolygonBezierCoords (curved polygons) 660 UnoPolyPolygonBezierCoordsToB2DPolyPolygon(const com::sun::star::drawing::PolyPolygonBezierCoords & rPolyPolygonBezierCoordsSource,bool bCheckClosed)661 B2DPolyPolygon UnoPolyPolygonBezierCoordsToB2DPolyPolygon( 662 const com::sun::star::drawing::PolyPolygonBezierCoords& rPolyPolygonBezierCoordsSource, 663 bool bCheckClosed) 664 { 665 B2DPolyPolygon aRetval; 666 const sal_uInt32 nSequenceCount((sal_uInt32)rPolyPolygonBezierCoordsSource.Coordinates.getLength()); 667 668 if(nSequenceCount) 669 { 670 OSL_ENSURE(nSequenceCount == (sal_uInt32)rPolyPolygonBezierCoordsSource.Flags.getLength(), 671 "UnoPolyPolygonBezierCoordsToB2DPolyPolygon: unequal number of Points and Flags (!)"); 672 const com::sun::star::drawing::PointSequence* pPointSequence = rPolyPolygonBezierCoordsSource.Coordinates.getConstArray(); 673 const com::sun::star::drawing::FlagSequence* pFlagSequence = rPolyPolygonBezierCoordsSource.Flags.getConstArray(); 674 675 for(sal_uInt32 a(0); a < nSequenceCount; a++) 676 { 677 const B2DPolygon aNewPolygon(UnoPolygonBezierCoordsToB2DPolygon( 678 *pPointSequence, 679 *pFlagSequence, 680 bCheckClosed)); 681 682 pPointSequence++; 683 pFlagSequence++; 684 aRetval.append(aNewPolygon); 685 } 686 } 687 688 return aRetval; 689 } 690 B2DPolyPolygonToUnoPolyPolygonBezierCoords(const B2DPolyPolygon & rPolyPolygon,com::sun::star::drawing::PolyPolygonBezierCoords & rPolyPolygonBezierCoordsRetval)691 void B2DPolyPolygonToUnoPolyPolygonBezierCoords( 692 const B2DPolyPolygon& rPolyPolygon, 693 com::sun::star::drawing::PolyPolygonBezierCoords& rPolyPolygonBezierCoordsRetval) 694 { 695 const sal_uInt32 nCount(rPolyPolygon.count()); 696 697 if(nCount) 698 { 699 // prepare return value memory 700 rPolyPolygonBezierCoordsRetval.Coordinates.realloc((sal_Int32)nCount); 701 rPolyPolygonBezierCoordsRetval.Flags.realloc((sal_Int32)nCount); 702 703 // get pointers to arrays 704 com::sun::star::drawing::PointSequence* pPointSequence = rPolyPolygonBezierCoordsRetval.Coordinates.getArray(); 705 com::sun::star::drawing::FlagSequence* pFlagSequence = rPolyPolygonBezierCoordsRetval.Flags.getArray(); 706 707 for(sal_uInt32 a(0); a < nCount; a++) 708 { 709 const B2DPolygon aSource(rPolyPolygon.getB2DPolygon(a)); 710 711 B2DPolygonToUnoPolygonBezierCoords( 712 aSource, 713 *pPointSequence, 714 *pFlagSequence); 715 pPointSequence++; 716 pFlagSequence++; 717 } 718 } 719 else 720 { 721 rPolyPolygonBezierCoordsRetval.Coordinates.realloc(0); 722 rPolyPolygonBezierCoordsRetval.Flags.realloc(0); 723 } 724 } 725 726 } // end of namespace tools 727 } // end of namespace basegfx 728 729 ////////////////////////////////////////////////////////////////////////////// 730 // eof 731