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_svx.hxx" 26 #include <osl/endian.h> 27 #include <tools/stream.hxx> 28 #include <tools/debug.hxx> 29 #include <tools/poly.hxx> 30 31 #include <svx/xpoly.hxx> 32 #include "xpolyimp.hxx" 33 #include <basegfx/polygon/b2dpolygon.hxx> 34 #include <basegfx/point/b2dpoint.hxx> 35 #include <basegfx/vector/b2dvector.hxx> 36 #include <basegfx/polygon/b2dpolygontools.hxx> 37 #include <vcl/salbtype.hxx> // FRound 38 #include <basegfx/range/b2drange.hxx> 39 #include <basegfx/numeric/ftools.hxx> 40 41 #define GLOBALOVERFLOW 42 43 DBG_NAME(XPolygon); 44 DBG_NAME(XPolyPolygon); 45 46 /************************************************************************* 47 |* 48 |* ImpXPolygon::ImpXPolygon() 49 |* 50 |* Beschreibung 51 |* Ersterstellung 08.11.94 52 |* Letzte Aenderung 12.01.95 ESO 53 |* 54 *************************************************************************/ 55 56 ImpXPolygon::ImpXPolygon( sal_uInt16 nInitSize, sal_uInt16 _nResize ) 57 { 58 pPointAry = NULL; 59 pFlagAry = NULL; 60 bDeleteOldPoints = sal_False; 61 nSize = 0; 62 nResize = _nResize; 63 nPoints = 0; 64 nRefCount = 1; 65 66 Resize( nInitSize ); 67 } 68 69 /************************************************************************* 70 |* 71 |* ImpXPolygon::ImpXPolygon() 72 |* 73 |* Beschreibung 74 |* Ersterstellung 08.11.94 75 |* Letzte Aenderung 12.01.95 ESO 76 |* 77 *************************************************************************/ 78 79 ImpXPolygon::ImpXPolygon( const ImpXPolygon& rImpXPoly ) 80 { 81 ( (ImpXPolygon&) rImpXPoly ).CheckPointDelete(); 82 83 pPointAry = NULL; 84 pFlagAry = NULL; 85 bDeleteOldPoints = sal_False; 86 nSize = 0; 87 ImpXPolygon::nResize = rImpXPoly.nResize; 88 nPoints = 0; 89 nRefCount = 1; 90 91 Resize( rImpXPoly.nSize ); 92 93 // Kopieren 94 nPoints = rImpXPoly.nPoints; 95 memcpy( pPointAry, rImpXPoly.pPointAry, nSize*sizeof( Point ) ); 96 memcpy( pFlagAry, rImpXPoly.pFlagAry, nSize ); 97 } 98 99 /************************************************************************* 100 |* 101 |* ImpXPolygon::~ImpXPolygon() 102 |* 103 |* Beschreibung 104 |* Ersterstellung 08.11.94 105 |* Letzte Aenderung 12.01.95 ESO 106 |* 107 *************************************************************************/ 108 109 ImpXPolygon::~ImpXPolygon() 110 { 111 delete[] (char*) pPointAry; 112 delete[] pFlagAry; 113 if ( bDeleteOldPoints ) 114 delete[] (char*) pOldPointAry; 115 } 116 117 /************************************************************************* 118 |* 119 |* ImpXPolygon::operator==() 120 |* 121 |* Ersterstellung Joe 26-09-95 122 |* Letzte Aenderung 123 |* 124 *************************************************************************/ 125 126 127 bool ImpXPolygon::operator==(const ImpXPolygon& rImpXPoly) const 128 { 129 return nPoints==rImpXPoly.nPoints && 130 (nPoints==0 || 131 (memcmp(pPointAry,rImpXPoly.pPointAry,nPoints*sizeof(Point))==0 && 132 memcmp(pFlagAry,rImpXPoly.pFlagAry,nPoints)==0)); 133 } 134 135 /************************************************************************* 136 |* 137 |* ImpXPolygon::Resize() 138 |* 139 |* !!! Polygongroesse aendern - wenn bDeletePoints sal_False, dann den 140 |* Point-Array nicht loeschen, sondern in pOldPointAry sichern und 141 |* das Flag bDeleteOldPoints setzen. Beim naechsten Zugriff wird 142 |* das Array dann geloescht. 143 |* Damit wird verhindert, dass bei XPoly[n] = XPoly[0] durch ein 144 |* Resize der fuer den rechten Ausdruck verwendete Point-Array 145 |* vorzeitig geloescht wird. 146 |* Ersterstellung 08.11.94 147 |* Letzte Aenderung 12.01.95 ESO 148 |* 149 *************************************************************************/ 150 151 void ImpXPolygon::Resize( sal_uInt16 nNewSize, sal_Bool bDeletePoints ) 152 { 153 if( nNewSize == nSize ) 154 return; 155 156 sal_uInt8* pOldFlagAry = pFlagAry; 157 sal_uInt16 nOldSize = nSize; 158 159 CheckPointDelete(); 160 pOldPointAry = pPointAry; 161 162 // Neue Groesse auf vielfaches von nResize runden, sofern Objekt 163 // nicht neu angelegt wurde (nSize != 0) 164 if ( nSize != 0 && nNewSize > nSize ) 165 { 166 DBG_ASSERT(nResize, "Resize-Versuch trotz nResize = 0 !"); 167 nNewSize = nSize + ((nNewSize-nSize-1) / nResize + 1) * nResize; 168 } 169 // Punkt Array erzeugen 170 nSize = nNewSize; 171 pPointAry = (Point*)new char[ nSize*sizeof( Point ) ]; 172 memset( pPointAry, 0, nSize*sizeof( Point ) ); 173 174 // Flag Array erzeugen 175 pFlagAry = new sal_uInt8[ nSize ]; 176 memset( pFlagAry, 0, nSize ); 177 178 // Eventuell umkopieren 179 if( nOldSize ) 180 { 181 if( nOldSize < nSize ) 182 { 183 memcpy( pPointAry, pOldPointAry, nOldSize*sizeof( Point ) ); 184 memcpy( pFlagAry, pOldFlagAry, nOldSize ); 185 } 186 else 187 { 188 memcpy( pPointAry, pOldPointAry, nSize*sizeof( Point ) ); 189 memcpy( pFlagAry, pOldFlagAry, nSize ); 190 191 // Anzahl der gueltigen Punkte anpassen 192 if( nPoints > nSize ) 193 nPoints = nSize; 194 } 195 if ( bDeletePoints ) delete[] (char*) pOldPointAry; 196 else bDeleteOldPoints = sal_True; 197 delete[] pOldFlagAry; 198 } 199 } 200 201 202 /************************************************************************* 203 |* 204 |* ImpXPolygon::InsertSpace() 205 |* 206 |* Beschreibung 207 |* Ersterstellung 08.11.94 208 |* Letzte Aenderung 29.03.95 ESO 209 |* 210 *************************************************************************/ 211 212 void ImpXPolygon::InsertSpace( sal_uInt16 nPos, sal_uInt16 nCount ) 213 { 214 CheckPointDelete(); 215 216 if ( nPos > nPoints ) 217 nPos = nPoints; 218 219 // Wenn Polygon zu klein dann groesser machen 220 if( (nPoints + nCount) > nSize ) 221 Resize( nPoints + nCount ); 222 223 // Wenn nicht hinter dem letzten Punkt eingefuegt wurde, 224 // den Rest nach hinten schieben 225 if( nPos < nPoints ) 226 { 227 sal_uInt16 nMove = nPoints - nPos; 228 memmove( &pPointAry[nPos+nCount], &pPointAry[nPos], 229 nMove * sizeof(Point) ); 230 memmove( &pFlagAry[nPos+nCount], &pFlagAry[nPos], nMove ); 231 } 232 memset( &pPointAry[nPos], 0, nCount * sizeof( Point ) ); 233 memset( &pFlagAry [nPos], 0, nCount ); 234 235 nPoints = nPoints + nCount; 236 } 237 238 239 /************************************************************************* 240 |* 241 |* ImpXPolygon::Remove() 242 |* 243 |* Beschreibung 244 |* Ersterstellung 08.11.94 245 |* Letzte Aenderung 12.01.94 ESO 246 |* 247 *************************************************************************/ 248 249 void ImpXPolygon::Remove( sal_uInt16 nPos, sal_uInt16 nCount ) 250 { 251 CheckPointDelete(); 252 253 if( (nPos + nCount) <= nPoints ) 254 { 255 sal_uInt16 nMove = nPoints - nPos - nCount; 256 257 if( nMove ) 258 { 259 memmove( &pPointAry[nPos], &pPointAry[nPos+nCount], 260 nMove * sizeof(Point) ); 261 memmove( &pFlagAry[nPos], &pFlagAry[nPos+nCount], nMove ); 262 } 263 memset( &pPointAry[nPoints - nCount], 0, nCount * sizeof( Point ) ); 264 memset( &pFlagAry [nPoints - nCount], 0, nCount ); 265 nPoints = nPoints - nCount; 266 } 267 } 268 269 270 /************************************************************************* 271 |* 272 |* XPolygon::XPolygon() 273 |* 274 |* Beschreibung 275 |* Ersterstellung 08.11.94 276 |* Letzte Aenderung 08.11.94 277 |* 278 *************************************************************************/ 279 280 XPolygon::XPolygon( sal_uInt16 nSize, sal_uInt16 nResize ) 281 { 282 DBG_CTOR(XPolygon,NULL); 283 pImpXPolygon = new ImpXPolygon( nSize, nResize ); 284 } 285 286 /************************************************************************* 287 |* 288 |* XPolygon::XPolygon() 289 |* 290 |* Beschreibung 291 |* Ersterstellung 08.11.94 292 |* Letzte Aenderung 08.11.94 293 |* 294 *************************************************************************/ 295 296 XPolygon::XPolygon( const XPolygon& rXPoly ) 297 { 298 DBG_CTOR(XPolygon,NULL); 299 pImpXPolygon = rXPoly.pImpXPolygon; 300 pImpXPolygon->nRefCount++; 301 } 302 303 /************************************************************************* 304 |* 305 |* XPolygon::XPolygon() 306 |* 307 |* XPolygon aus einem Standardpolygon erstellen 308 |* Ersterstellung 18.01.95 ESO 309 |* Letzte Aenderung 18.01.95 ESO 310 |* 311 *************************************************************************/ 312 313 XPolygon::XPolygon( const Polygon& rPoly ) 314 { 315 DBG_CTOR(XPolygon,NULL); 316 317 sal_uInt16 nSize = rPoly.GetSize(); 318 pImpXPolygon = new ImpXPolygon( nSize ); 319 pImpXPolygon->nPoints = nSize; 320 321 for( sal_uInt16 i = 0; i < nSize; i++ ) 322 { 323 pImpXPolygon->pPointAry[i] = rPoly[i]; 324 pImpXPolygon->pFlagAry[i] = (sal_uInt8) rPoly.GetFlags( i ); 325 } 326 } 327 328 /************************************************************************* 329 |* 330 |* XPolygon::XPolygon() 331 |* 332 |* Rechteck (auch mit abgerundeten Ecken) als Bezierpolygon erzeugen 333 |* Ersterstellung 09.01.95 ESO 334 |* Letzte Aenderung 09.01.95 ESO 335 |* 336 *************************************************************************/ 337 338 XPolygon::XPolygon(const Rectangle& rRect, long nRx, long nRy) 339 { 340 DBG_CTOR(XPolygon,NULL); 341 pImpXPolygon = new ImpXPolygon(17); 342 long nWh = (rRect.GetWidth() - 1) / 2; 343 long nHh = (rRect.GetHeight() - 1) / 2; 344 345 if ( nRx > nWh ) nRx = nWh; 346 if ( nRy > nHh ) nRy = nHh; 347 348 // Rx negativ, damit Umlauf im Uhrzeigersinn erfolgt 349 nRx = -nRx; 350 351 // Faktor fuer Kontrollpunkte der Bezierkurven: 8/3 * (sin(45g) - 0.5) 352 long nXHdl = (long)(0.552284749 * nRx); 353 long nYHdl = (long)(0.552284749 * nRy); 354 sal_uInt16 nPos = 0; 355 356 if ( nRx && nRy ) 357 { 358 Point aCenter; 359 360 for (sal_uInt16 nQuad = 0; nQuad < 4; nQuad++) 361 { 362 switch ( nQuad ) 363 { 364 case 0: aCenter = rRect.TopLeft(); 365 aCenter.X() -= nRx; 366 aCenter.Y() += nRy; 367 break; 368 case 1: aCenter = rRect.TopRight(); 369 aCenter.X() += nRx; 370 aCenter.Y() += nRy; 371 break; 372 case 2: aCenter = rRect.BottomRight(); 373 aCenter.X() += nRx; 374 aCenter.Y() -= nRy; 375 break; 376 case 3: aCenter = rRect.BottomLeft(); 377 aCenter.X() -= nRx; 378 aCenter.Y() -= nRy; 379 break; 380 } 381 GenBezArc(aCenter, nRx, nRy, nXHdl, nYHdl, 0, 900, nQuad, nPos); 382 pImpXPolygon->pFlagAry[nPos ] = (sal_uInt8) XPOLY_SMOOTH; 383 pImpXPolygon->pFlagAry[nPos+3] = (sal_uInt8) XPOLY_SMOOTH; 384 nPos += 4; 385 } 386 } 387 else 388 { 389 pImpXPolygon->pPointAry[nPos++] = rRect.TopLeft(); 390 pImpXPolygon->pPointAry[nPos++] = rRect.TopRight(); 391 pImpXPolygon->pPointAry[nPos++] = rRect.BottomRight(); 392 pImpXPolygon->pPointAry[nPos++] = rRect.BottomLeft(); 393 } 394 pImpXPolygon->pPointAry[nPos] = pImpXPolygon->pPointAry[0]; 395 pImpXPolygon->nPoints = nPos + 1; 396 } 397 398 /************************************************************************* 399 |* 400 |* XPolygon::XPolygon() 401 |* 402 |* Ellipsen(bogen) als Bezierpolygon erzeugen 403 |* Ersterstellung 09.01.95 404 |* Letzte Aenderung 09.01.95 405 |* 406 *************************************************************************/ 407 408 XPolygon::XPolygon(const Point& rCenter, long nRx, long nRy, 409 sal_uInt16 nStartAngle, sal_uInt16 nEndAngle, sal_Bool bClose) 410 { 411 DBG_CTOR(XPolygon,NULL); 412 pImpXPolygon = new ImpXPolygon(17); 413 414 nStartAngle %= 3600; 415 if ( nEndAngle > 3600 ) nEndAngle %= 3600; 416 sal_Bool bFull = (nStartAngle == 0 && nEndAngle == 3600); 417 418 // Faktor fuer Kontrollpunkte der Bezierkurven: 8/3 * (sin(45g) - 0.5) 419 long nXHdl = (long)(0.552284749 * nRx); 420 long nYHdl = (long)(0.552284749 * nRy); 421 sal_uInt16 nPos = 0; 422 sal_Bool bLoopEnd = sal_False; 423 424 do 425 { 426 sal_uInt16 nA1, nA2; 427 sal_uInt16 nQuad = nStartAngle / 900; 428 if ( nQuad == 4 ) nQuad = 0; 429 bLoopEnd = CheckAngles(nStartAngle, nEndAngle, nA1, nA2); 430 GenBezArc(rCenter, nRx, nRy, nXHdl, nYHdl, nA1, nA2, nQuad, nPos); 431 nPos += 3; 432 if ( !bLoopEnd ) 433 pImpXPolygon->pFlagAry[nPos] = (sal_uInt8) XPOLY_SMOOTH; 434 435 } while ( !bLoopEnd ); 436 437 // Wenn kein Vollkreis, dann ggf. Enden mit Mittelpunkt verbinden 438 if ( !bFull && bClose ) 439 pImpXPolygon->pPointAry[++nPos] = rCenter; 440 441 if ( bFull ) 442 { 443 pImpXPolygon->pFlagAry[0 ] = (sal_uInt8) XPOLY_SMOOTH; 444 pImpXPolygon->pFlagAry[nPos] = (sal_uInt8) XPOLY_SMOOTH; 445 } 446 pImpXPolygon->nPoints = nPos + 1; 447 } 448 449 /************************************************************************* 450 |* 451 |* XPolygon::~XPolygon() 452 |* 453 |* Beschreibung 454 |* Ersterstellung 08.11.94 455 |* Letzte Aenderung 08.11.94 456 |* 457 *************************************************************************/ 458 459 XPolygon::~XPolygon() 460 { 461 DBG_DTOR(XPolygon,NULL); 462 if( pImpXPolygon->nRefCount > 1 ) 463 pImpXPolygon->nRefCount--; 464 else 465 delete pImpXPolygon; 466 } 467 468 /************************************************************************* 469 |* 470 |* XPolygon::CheckReference() 471 |* 472 |* Referenzzaehler desImpXPoly pruefen und ggf. von diesem abkoppeln 473 |* Ersterstellung 17.01.95 ESO 474 |* Letzte Aenderung 17.01.95 ESO 475 |* 476 *************************************************************************/ 477 478 void XPolygon::CheckReference() 479 { 480 if( pImpXPolygon->nRefCount > 1 ) 481 { 482 pImpXPolygon->nRefCount--; 483 pImpXPolygon = new ImpXPolygon( *pImpXPolygon ); 484 } 485 } 486 487 /************************************************************************* 488 |* 489 |* XPolygon::SetSize() 490 |* 491 |* Beschreibung 492 |* Ersterstellung 08.11.94 493 |* Letzte Aenderung 08.11.94 494 |* 495 *************************************************************************/ 496 497 void XPolygon::SetSize( sal_uInt16 nNewSize ) 498 { 499 CheckReference(); 500 pImpXPolygon->Resize( nNewSize ); 501 } 502 503 /************************************************************************* 504 |* 505 |* XPolygon::GetSize() 506 |* 507 |* Beschreibung 508 |* Ersterstellung 08.11.94 509 |* Letzte Aenderung 12.01.95 ESO 510 |* 511 *************************************************************************/ 512 513 sal_uInt16 XPolygon::GetSize() const 514 { 515 pImpXPolygon->CheckPointDelete(); 516 return pImpXPolygon->nSize; 517 } 518 519 /************************************************************************* 520 |* 521 |* XPolygon::SetPointCount() 522 |* 523 |* Beschreibung 524 |* Ersterstellung 08.11.94 525 |* Letzte Aenderung 12.01.95 ESO 526 |* 527 *************************************************************************/ 528 529 void XPolygon::SetPointCount( sal_uInt16 nPoints ) 530 { 531 pImpXPolygon->CheckPointDelete(); 532 CheckReference(); 533 534 if( pImpXPolygon->nSize < nPoints ) 535 pImpXPolygon->Resize( nPoints ); 536 537 if ( nPoints < pImpXPolygon->nPoints ) 538 { 539 sal_uInt16 nSize = pImpXPolygon->nPoints - nPoints; 540 memset( &pImpXPolygon->pPointAry[nPoints], 0, nSize * sizeof( Point ) ); 541 memset( &pImpXPolygon->pFlagAry [nPoints], 0, nSize ); 542 } 543 pImpXPolygon->nPoints = nPoints; 544 } 545 546 /************************************************************************* 547 |* 548 |* XPolygon::GetPointCount() 549 |* 550 |* Beschreibung 551 |* Ersterstellung 08.11.94 552 |* Letzte Aenderung 12.01.95 ESO 553 |* 554 *************************************************************************/ 555 556 sal_uInt16 XPolygon::GetPointCount() const 557 { 558 pImpXPolygon->CheckPointDelete(); 559 return pImpXPolygon->nPoints; 560 } 561 562 /************************************************************************* 563 |* 564 |* XPolygon::Insert() 565 |* 566 |* Beschreibung 567 |* Ersterstellung 08.11.94 568 |* Letzte Aenderung 08.11.94 569 |* 570 *************************************************************************/ 571 572 void XPolygon::Insert( sal_uInt16 nPos, const Point& rPt, XPolyFlags eFlags ) 573 { 574 CheckReference(); 575 if (nPos>pImpXPolygon->nPoints) nPos=pImpXPolygon->nPoints; 576 pImpXPolygon->InsertSpace( nPos, 1 ); 577 pImpXPolygon->pPointAry[nPos] = rPt; 578 pImpXPolygon->pFlagAry[nPos] = (sal_uInt8)eFlags; 579 } 580 581 /************************************************************************* 582 |* 583 |* XPolygon::Insert() 584 |* 585 |* Beschreibung 586 |* Ersterstellung 08.11.94 587 |* Letzte Aenderung 08.11.94 588 |* 589 *************************************************************************/ 590 591 void XPolygon::Insert( sal_uInt16 nPos, const XPolygon& rXPoly ) 592 { 593 CheckReference(); 594 if (nPos>pImpXPolygon->nPoints) nPos=pImpXPolygon->nPoints; 595 596 sal_uInt16 nPoints = rXPoly.GetPointCount(); 597 598 pImpXPolygon->InsertSpace( nPos, nPoints ); 599 600 memcpy( &(pImpXPolygon->pPointAry[nPos]), 601 rXPoly.pImpXPolygon->pPointAry, 602 nPoints*sizeof( Point ) ); 603 memcpy( &(pImpXPolygon->pFlagAry[nPos]), 604 rXPoly.pImpXPolygon->pFlagAry, 605 nPoints ); 606 } 607 608 /************************************************************************* 609 |* 610 |* XPolygon::Insert() 611 |* 612 |* Beschreibung 613 |* Ersterstellung 08.11.94 614 |* Letzte Aenderung 08.11.94 615 |* 616 *************************************************************************/ 617 618 void XPolygon::Insert( sal_uInt16 nPos, const Polygon& rPoly ) 619 { 620 CheckReference(); 621 if (nPos>pImpXPolygon->nPoints) nPos=pImpXPolygon->nPoints; 622 623 sal_uInt16 nPoints = rPoly.GetSize(); 624 625 pImpXPolygon->InsertSpace( nPos, nPoints ); 626 627 sal_uInt16 i; 628 for( i=0; i < nPoints; i++ ) 629 pImpXPolygon->pPointAry[i] = rPoly[i]; 630 631 // Die Flags sind durch das InsertSpace bereits auf 0 gesetzt 632 } 633 634 /************************************************************************* 635 |* 636 |* XPolygon::Remove() 637 |* 638 |* Beschreibung 639 |* Ersterstellung 08.11.94 640 |* Letzte Aenderung 08.11.94 641 |* 642 *************************************************************************/ 643 644 void XPolygon::Remove( sal_uInt16 nPos, sal_uInt16 nCount ) 645 { 646 CheckReference(); 647 pImpXPolygon->Remove( nPos, nCount ); 648 } 649 650 /************************************************************************* 651 |* 652 |* XPolygon::Move() 653 |* 654 |* Beschreibung 655 |* Ersterstellung 09.11.94 656 |* Letzte Aenderung 09.11.94 657 |* 658 *************************************************************************/ 659 660 void XPolygon::Move( long nHorzMove, long nVertMove ) 661 { 662 if ( !nHorzMove && !nVertMove ) 663 return; 664 665 CheckReference(); 666 667 // Punkte verschieben 668 sal_uInt16 nCount = pImpXPolygon->nPoints; 669 for ( sal_uInt16 i = 0; i < nCount; i++ ) 670 { 671 Point* pPt = &(pImpXPolygon->pPointAry[i]); 672 pPt->X() += nHorzMove; 673 pPt->Y() += nVertMove; 674 } 675 } 676 677 /************************************************************************* 678 |* 679 |* XPolygon::GetBoundRect() 680 |* 681 |* Beschreibung 682 |* Ersterstellung 09.11.94 683 |* Letzte Aenderung 12.01.95 ESO 684 |* 685 *************************************************************************/ 686 687 Rectangle XPolygon::GetBoundRect() const 688 { 689 pImpXPolygon->CheckPointDelete(); 690 Rectangle aRetval; 691 692 if(pImpXPolygon->nPoints) 693 { 694 // #i37709# 695 // For historical reasons the control points are not part of the 696 // BoundRect. This makes it necessary to subdivide the polygon to 697 // get a relatively correct BoundRect. Numerically, this is not 698 // correct and never was. 699 700 const basegfx::B2DRange aPolygonRange(basegfx::tools::getRange(getB2DPolygon())); 701 aRetval = Rectangle( 702 FRound(aPolygonRange.getMinX()), FRound(aPolygonRange.getMinY()), 703 FRound(aPolygonRange.getMaxX()), FRound(aPolygonRange.getMaxY())); 704 } 705 706 return aRetval; 707 } 708 709 /************************************************************************* 710 |* 711 |* XPolygon::operator[]() 712 |* 713 |* Beschreibung 714 |* Ersterstellung 08.11.94 715 |* Letzte Aenderung 12.01.95 716 |* 717 *************************************************************************/ 718 719 const Point& XPolygon::operator[]( sal_uInt16 nPos ) const 720 { 721 DBG_ASSERT(nPos < pImpXPolygon->nPoints, "Ungueltiger Index bei const-Arrayzugriff auf XPolygon"); 722 723 pImpXPolygon->CheckPointDelete(); 724 return pImpXPolygon->pPointAry[nPos]; 725 } 726 727 /************************************************************************* 728 |* 729 |* XPolygon::operator[]() 730 |* 731 |* Beschreibung 732 |* Ersterstellung 08.11.94 733 |* Letzte Aenderung 12.01.95 ESO 734 |* 735 *************************************************************************/ 736 737 Point& XPolygon::operator[]( sal_uInt16 nPos ) 738 { 739 pImpXPolygon->CheckPointDelete(); 740 CheckReference(); 741 742 if( nPos >= pImpXPolygon->nSize ) 743 { 744 DBG_ASSERT(pImpXPolygon->nResize, "Ungueltiger Index bei Arrayzugriff auf XPolygon"); 745 pImpXPolygon->Resize(nPos + 1, sal_False); 746 } 747 if( nPos >= pImpXPolygon->nPoints ) 748 pImpXPolygon->nPoints = nPos + 1; 749 750 return pImpXPolygon->pPointAry[nPos]; 751 } 752 753 /************************************************************************* 754 |* 755 |* XPolygon::operator=() 756 |* 757 |* Beschreibung Zuweisungsoperator 758 |* Ersterstellung ESO 22.11.94 759 |* Letzte Aenderung ESO 12.01.95 760 |* 761 *************************************************************************/ 762 763 XPolygon& XPolygon::operator=( const XPolygon& rXPoly ) 764 { 765 pImpXPolygon->CheckPointDelete(); 766 767 rXPoly.pImpXPolygon->nRefCount++; 768 769 if( pImpXPolygon->nRefCount > 1 ) 770 pImpXPolygon->nRefCount--; 771 else 772 delete pImpXPolygon; 773 774 pImpXPolygon = rXPoly.pImpXPolygon; 775 return *this; 776 } 777 778 /************************************************************************* 779 |* 780 |* XPolygon::operator==() 781 |* 782 |* Beschreibung Gleichheitsoperator 783 |* Ersterstellung ESO 22.11.94 784 |* Letzte Aenderung Joe 26.09.95 785 |* 786 *************************************************************************/ 787 788 sal_Bool XPolygon::operator==( const XPolygon& rXPoly ) const 789 { 790 pImpXPolygon->CheckPointDelete(); 791 if (rXPoly.pImpXPolygon==pImpXPolygon) return sal_True; 792 return *rXPoly.pImpXPolygon == *pImpXPolygon; 793 } 794 795 /************************************************************************* 796 |* 797 |* XPolygon::operator!=() 798 |* 799 |* Beschreibung Ungleichheitsoperator 800 |* Ersterstellung ESO 22.11.94 801 |* Letzte Aenderung Joe 26.09.95 802 |* 803 *************************************************************************/ 804 805 sal_Bool XPolygon::operator!=( const XPolygon& rXPoly ) const 806 { 807 pImpXPolygon->CheckPointDelete(); 808 if (rXPoly.pImpXPolygon==pImpXPolygon) return sal_False; 809 return *rXPoly.pImpXPolygon != *pImpXPolygon; 810 } 811 812 /************************************************************************* 813 |* 814 |* XPolygon::GetFlags() 815 |* 816 |* Flags fuer den Punkt an der Position nPos zurueckgeben 817 |* Ersterstellung ESO 11.11.94 818 |* Letzte Aenderung ESO 12.01.95 819 |* 820 *************************************************************************/ 821 822 XPolyFlags XPolygon::GetFlags( sal_uInt16 nPos ) const 823 { 824 pImpXPolygon->CheckPointDelete(); 825 return (XPolyFlags) pImpXPolygon->pFlagAry[nPos]; 826 } 827 828 /************************************************************************* 829 |* 830 |* XPolygon::SetFlags() 831 |* 832 |* Flags fuer den Punkt an der Position nPos setzen 833 |* Ersterstellung ESO 11.11.94 834 |* Letzte Aenderung ESO 12.01.95 835 |* 836 *************************************************************************/ 837 838 void XPolygon::SetFlags( sal_uInt16 nPos, XPolyFlags eFlags ) 839 { 840 pImpXPolygon->CheckPointDelete(); 841 CheckReference(); 842 pImpXPolygon->pFlagAry[nPos] = (sal_uInt8) eFlags; 843 } 844 845 /************************************************************************* 846 |* 847 |* XPolygon::IsControl() 848 |* 849 |* Kurzform zur Abfrage des CONTROL-Flags 850 |* Ersterstellung ESO 09.01.95 851 |* Letzte Aenderung ESO 12.01.95 852 |* 853 *************************************************************************/ 854 855 sal_Bool XPolygon::IsControl(sal_uInt16 nPos) const 856 { 857 return ( (XPolyFlags) pImpXPolygon->pFlagAry[nPos] == XPOLY_CONTROL ); 858 } 859 860 /************************************************************************* 861 |* 862 |* XPolygon::IsSmooth() 863 |* 864 |* Kurzform zur Abfrage von SMOOTH- und SYMMTR-Flag 865 |* Ersterstellung ESO 18.04.95 866 |* Letzte Aenderung ESO 18.04.95 867 |* 868 *************************************************************************/ 869 870 sal_Bool XPolygon::IsSmooth(sal_uInt16 nPos) const 871 { 872 XPolyFlags eFlag = (XPolyFlags) pImpXPolygon->pFlagAry[nPos]; 873 return ( eFlag == XPOLY_SMOOTH || eFlag == XPOLY_SYMMTR ); 874 } 875 876 /************************************************************************* 877 |* 878 |* XPolygon::CalcDistance() 879 |* 880 |* Abstand zwischen zwei Punkten berechnen 881 |* Ersterstellung ESO 09.01.95 882 |* Letzte Aenderung ESO 09.01.95 883 |* 884 *************************************************************************/ 885 886 double XPolygon::CalcDistance(sal_uInt16 nP1, sal_uInt16 nP2) 887 { 888 const Point& rP1 = pImpXPolygon->pPointAry[nP1]; 889 const Point& rP2 = pImpXPolygon->pPointAry[nP2]; 890 double fDx = rP2.X() - rP1.X(); 891 double fDy = rP2.Y() - rP1.Y(); 892 return sqrt(fDx * fDx + fDy * fDy); 893 } 894 895 /************************************************************************* 896 |* 897 |* XPolygon::SubdivideBezier() 898 |* 899 |* Bezierkurve unterteilen 900 |* Ersterstellung ESO 09.01.95 901 |* Letzte Aenderung ESO 09.01.95 902 |* 903 *************************************************************************/ 904 905 void XPolygon::SubdivideBezier(sal_uInt16 nPos, sal_Bool bCalcFirst, double fT) 906 { 907 Point* pPoints = pImpXPolygon->pPointAry; 908 double fT2 = fT * fT; 909 double fT3 = fT * fT2; 910 double fU = 1.0 - fT; 911 double fU2 = fU * fU; 912 double fU3 = fU * fU2; 913 sal_uInt16 nIdx = nPos; 914 short nPosInc, nIdxInc; 915 916 if ( bCalcFirst ) 917 { 918 nPos += 3; 919 nPosInc = -1; 920 nIdxInc = 0; 921 } 922 else 923 { 924 nPosInc = 1; 925 nIdxInc = 1; 926 } 927 pPoints[nPos].X() = (long) (fU3 * pPoints[nIdx ].X() + 928 fT * fU2 * pPoints[nIdx+1].X() * 3 + 929 fT2 * fU * pPoints[nIdx+2].X() * 3 + 930 fT3 * pPoints[nIdx+3].X()); 931 pPoints[nPos].Y() = (long) (fU3 * pPoints[nIdx ].Y() + 932 fT * fU2 * pPoints[nIdx+1].Y() * 3 + 933 fT2 * fU * pPoints[nIdx+2].Y() * 3 + 934 fT3 * pPoints[nIdx+3].Y()); 935 nPos = nPos + nPosInc; 936 nIdx = nIdx + nIdxInc; 937 pPoints[nPos].X() = (long) (fU2 * pPoints[nIdx ].X() + 938 fT * fU * pPoints[nIdx+1].X() * 2 + 939 fT2 * pPoints[nIdx+2].X()); 940 pPoints[nPos].Y() = (long) (fU2 * pPoints[nIdx ].Y() + 941 fT * fU * pPoints[nIdx+1].Y() * 2 + 942 fT2 * pPoints[nIdx+2].Y()); 943 nPos = nPos + nPosInc; 944 nIdx = nIdx + nIdxInc; 945 pPoints[nPos].X() = (long) (fU * pPoints[nIdx ].X() + 946 fT * pPoints[nIdx+1].X()); 947 pPoints[nPos].Y() = (long) (fU * pPoints[nIdx ].Y() + 948 fT * pPoints[nIdx+1].Y()); 949 } 950 951 /************************************************************************/ 952 953 void XPolygon::GenBezArc(const Point& rCenter, long nRx, long nRy, 954 long nXHdl, long nYHdl, sal_uInt16 nStart, sal_uInt16 nEnd, 955 sal_uInt16 nQuad, sal_uInt16 nFirst) 956 { 957 Point* pPoints = pImpXPolygon->pPointAry; 958 pPoints[nFirst ] = rCenter; 959 pPoints[nFirst+3] = rCenter; 960 961 if ( nQuad == 1 || nQuad == 2 ) 962 { 963 nRx = -nRx; nXHdl = -nXHdl; 964 } 965 if ( nQuad == 0 || nQuad == 1 ) 966 { 967 nRy = -nRy; nYHdl = -nYHdl; 968 } 969 970 if ( nQuad == 0 || nQuad == 2 ) 971 { 972 pPoints[nFirst].X() += nRx; pPoints[nFirst+3].Y() += nRy; 973 } 974 else 975 { 976 pPoints[nFirst].Y() += nRy; pPoints[nFirst+3].X() += nRx; 977 } 978 pPoints[nFirst+1] = pPoints[nFirst]; 979 pPoints[nFirst+2] = pPoints[nFirst+3]; 980 981 if ( nQuad == 0 || nQuad == 2 ) 982 { 983 pPoints[nFirst+1].Y() += nYHdl; pPoints[nFirst+2].X() += nXHdl; 984 } 985 else 986 { 987 pPoints[nFirst+1].X() += nXHdl; pPoints[nFirst+2].Y() += nYHdl; 988 } 989 if ( nStart > 0 ) 990 SubdivideBezier(nFirst, sal_False, (double)nStart / 900); 991 if ( nEnd < 900 ) 992 SubdivideBezier(nFirst, sal_True, (double)(nEnd-nStart) / (900-nStart)); 993 SetFlags(nFirst+1, XPOLY_CONTROL); 994 SetFlags(nFirst+2, XPOLY_CONTROL); 995 } 996 997 /************************************************************************/ 998 999 sal_Bool XPolygon::CheckAngles(sal_uInt16& nStart, sal_uInt16 nEnd, sal_uInt16& nA1, sal_uInt16& nA2) 1000 { 1001 if ( nStart == 3600 ) nStart = 0; 1002 if ( nEnd == 0 ) nEnd = 3600; 1003 sal_uInt16 nStPrev = nStart; 1004 sal_uInt16 nMax = (nStart / 900 + 1) * 900; 1005 sal_uInt16 nMin = nMax - 900; 1006 1007 if ( nEnd >= nMax || nEnd <= nStart ) nA2 = 900; 1008 else nA2 = nEnd - nMin; 1009 nA1 = nStart - nMin; 1010 nStart = nMax; 1011 1012 // sal_True zurueck, falls letztes Segment berechnet wurde 1013 return (nStPrev < nEnd && nStart >= nEnd); 1014 } 1015 1016 /************************************************************************* 1017 |* 1018 |* XPolygon::CalcSmoothJoin() 1019 |* 1020 |* glatten Uebergang zu einer Bezierkurve berechnen, indem der 1021 |* entsprechende Punkt auf die Verbindungslinie von zwei anderen 1022 |* Punkten projiziert wird 1023 |* Center = End- bzw. Anfangspunkt der Bezierkurve 1024 |* Drag = der bewegte Punkt, der die Verschiebung von Pnt vorgibt 1025 |* Pnt = der zu modifizierende Punkt 1026 |* Wenn Center am Anfang bzw. Ende des Polygons liegt, wird Pnt 1027 |* auf die entgegengesetzte Seite verlegt 1028 |* Ersterstellung ESO 09.01.95 1029 |* Letzte Aenderung ESO 18.04.95 1030 |* 1031 \************************************************************************/ 1032 1033 void XPolygon::CalcSmoothJoin(sal_uInt16 nCenter, sal_uInt16 nDrag, sal_uInt16 nPnt) 1034 { 1035 CheckReference(); 1036 1037 // sal_uInt16 nMaxPnt = pImpXPolygon->nPoints - 1; 1038 1039 // if ( nCenter == nMaxPnt ) nPnt = 1; 1040 // else if ( nCenter == 0 ) nPnt = nMaxPnt - 1; 1041 1042 // Wenn nPnt kein Control-Punkt, d.h. nicht verschiebbar, dann 1043 // statt dessen nDrag auf der Achse nCenter-nPnt verschieben 1044 if ( !IsControl(nPnt) ) 1045 { 1046 sal_uInt16 nTmp = nDrag; 1047 nDrag = nPnt; 1048 nPnt = nTmp; 1049 } 1050 Point* pPoints = pImpXPolygon->pPointAry; 1051 Point aDiff = pPoints[nDrag] - pPoints[nCenter]; 1052 double fDiv = CalcDistance(nCenter, nDrag); 1053 1054 if ( fDiv ) 1055 { 1056 double fRatio = CalcDistance(nCenter, nPnt) / fDiv; 1057 // bei SMOOTH bisherige Laenge beibehalten 1058 if ( GetFlags(nCenter) == XPOLY_SMOOTH || !IsControl(nDrag) ) 1059 { 1060 aDiff.X() = (long) (fRatio * aDiff.X()); 1061 aDiff.Y() = (long) (fRatio * aDiff.Y()); 1062 } 1063 pPoints[nPnt] = pPoints[nCenter] - aDiff; 1064 } 1065 } 1066 1067 /************************************************************************* 1068 |* 1069 |* XPolygon::CalcTangent() 1070 |* 1071 |* Tangente fuer den Uebergang zwischen zwei Bezierkurven berechnen 1072 |* Center = End- bzw. Anfangspunkt der Bezierkurven 1073 |* Prev = vorheriger Zugpunkt 1074 |* Next = naechster Zugpunkt 1075 |* Ersterstellung ESO 09.01.95 1076 |* Letzte Aenderung ESO 18.04.95 1077 |* 1078 \************************************************************************/ 1079 1080 void XPolygon::CalcTangent(sal_uInt16 nCenter, sal_uInt16 nPrev, sal_uInt16 nNext) 1081 { 1082 CheckReference(); 1083 1084 double fAbsLen = CalcDistance(nNext, nPrev); 1085 1086 if ( fAbsLen ) 1087 { 1088 const Point& rCenter = pImpXPolygon->pPointAry[nCenter]; 1089 Point& rNext = pImpXPolygon->pPointAry[nNext]; 1090 Point& rPrev = pImpXPolygon->pPointAry[nPrev]; 1091 Point aDiff = rNext - rPrev; 1092 double fNextLen = CalcDistance(nCenter, nNext) / fAbsLen; 1093 double fPrevLen = CalcDistance(nCenter, nPrev) / fAbsLen; 1094 1095 // bei SYMMTR gleiche Laenge fuer beide Seiten 1096 if ( GetFlags(nCenter) == XPOLY_SYMMTR ) 1097 { 1098 fPrevLen = (fNextLen + fPrevLen) / 2; 1099 fNextLen = fPrevLen; 1100 } 1101 rNext.X() = rCenter.X() + (long) (fNextLen * aDiff.X()); 1102 rNext.Y() = rCenter.Y() + (long) (fNextLen * aDiff.Y()); 1103 rPrev.X() = rCenter.X() - (long) (fPrevLen * aDiff.X()); 1104 rPrev.Y() = rCenter.Y() - (long) (fPrevLen * aDiff.Y()); 1105 } 1106 } 1107 1108 /************************************************************************* 1109 |* 1110 |* XPolygon::PointsToBezier() 1111 |* 1112 |* wandelt vier Polygonpunkte in eine Bezierkurve durch diese Punkte um 1113 |* Ersterstellung ESO 09.01.95 1114 |* Letzte Aenderung ESO 09.01.95 1115 |* 1116 \************************************************************************/ 1117 1118 void XPolygon::PointsToBezier(sal_uInt16 nFirst) 1119 { 1120 double nFullLength, nPart1Length, nPart2Length; 1121 double fX0, fY0, fX1, fY1, fX2, fY2, fX3, fY3; 1122 double fTx1, fTx2, fTy1, fTy2; 1123 double fT1, fU1, fT2, fU2, fV; 1124 Point* pPoints = pImpXPolygon->pPointAry; 1125 1126 if ( nFirst > pImpXPolygon->nPoints - 4 || IsControl(nFirst) || 1127 IsControl(nFirst+1) || IsControl(nFirst+2) || IsControl(nFirst+3) ) 1128 return; 1129 1130 CheckReference(); 1131 1132 fTx1 = pPoints[nFirst+1].X(); 1133 fTy1 = pPoints[nFirst+1].Y(); 1134 fTx2 = pPoints[nFirst+2].X(); 1135 fTy2 = pPoints[nFirst+2].Y(); 1136 fX0 = pPoints[nFirst ].X(); 1137 fY0 = pPoints[nFirst ].Y(); 1138 fX3 = pPoints[nFirst+3].X(); 1139 fY3 = pPoints[nFirst+3].Y(); 1140 1141 nPart1Length = CalcDistance(nFirst, nFirst+1); 1142 nPart2Length = nPart1Length + CalcDistance(nFirst+1, nFirst+2); 1143 nFullLength = nPart2Length + CalcDistance(nFirst+2, nFirst+3); 1144 if ( nFullLength < 20 ) 1145 return; 1146 1147 if ( nPart2Length == nFullLength ) 1148 nPart2Length -= 1; 1149 if ( nPart1Length == nFullLength ) 1150 nPart1Length = nPart2Length - 1; 1151 if ( nPart1Length <= 0 ) 1152 nPart1Length = 1; 1153 if ( nPart2Length <= 0 || nPart2Length == nPart1Length ) 1154 nPart2Length = nPart1Length + 1; 1155 1156 fT1 = nPart1Length / nFullLength; 1157 fU1 = 1.0 - fT1; 1158 fT2 = nPart2Length / nFullLength; 1159 fU2 = 1.0 - fT2; 1160 fV = 3 * (1.0 - (fT1 * fU2) / (fT2 * fU1)); 1161 1162 fX1 = fTx1 / (fT1 * fU1 * fU1) - fTx2 * fT1 / (fT2 * fT2 * fU1 * fU2); 1163 fX1 /= fV; 1164 fX1 -= fX0 * ( fU1 / fT1 + fU2 / fT2) / 3; 1165 fX1 += fX3 * ( fT1 * fT2 / (fU1 * fU2)) / 3; 1166 1167 fY1 = fTy1 / (fT1 * fU1 * fU1) - fTy2 * fT1 / (fT2 * fT2 * fU1 * fU2); 1168 fY1 /= fV; 1169 fY1 -= fY0 * ( fU1 / fT1 + fU2 / fT2) / 3; 1170 fY1 += fY3 * ( fT1 * fT2 / (fU1 * fU2)) / 3; 1171 1172 fX2 = fTx2 / (fT2 * fT2 * fU2 * 3) - fX0 * fU2 * fU2 / ( fT2 * fT2 * 3); 1173 fX2 -= fX1 * fU2 / fT2; 1174 fX2 -= fX3 * fT2 / (fU2 * 3); 1175 1176 fY2 = fTy2 / (fT2 * fT2 * fU2 * 3) - fY0 * fU2 * fU2 / ( fT2 * fT2 * 3); 1177 fY2 -= fY1 * fU2 / fT2; 1178 fY2 -= fY3 * fT2 / (fU2 * 3); 1179 1180 pPoints[nFirst+1] = Point((long) fX1, (long) fY1); 1181 pPoints[nFirst+2] = Point((long) fX2, (long) fY2); 1182 SetFlags(nFirst+1, XPOLY_CONTROL); 1183 SetFlags(nFirst+2, XPOLY_CONTROL); 1184 } 1185 1186 /************************************************************************* 1187 |* 1188 |* XPolygon::Translate() 1189 |* 1190 |* Polygon auf den uebergebenen Punkt verschieben 1191 |* Ersterstellung ESO 17.01.95 1192 |* Letzte Aenderung ESO 17.01.95 1193 |* 1194 *************************************************************************/ 1195 1196 void XPolygon::Translate(const Point& rTrans) 1197 { 1198 pImpXPolygon->CheckPointDelete(); 1199 CheckReference(); 1200 1201 sal_uInt16 nPntCnt = pImpXPolygon->nPoints; 1202 1203 for (sal_uInt16 i = 0; i < nPntCnt; i++) 1204 pImpXPolygon->pPointAry[i] += rTrans; 1205 } 1206 1207 /************************************************************************* 1208 |* 1209 |* XPolygon::Rotate() 1210 |* 1211 |* Alle Punkte um den Punkt rCenter drehen, Sinus und Cosinus 1212 |* muessen uebergeben werden 1213 |* Ersterstellung ESO 09.01.95 1214 |* Letzte Aenderung ESO 17.01.95 1215 |* 1216 *************************************************************************/ 1217 1218 void XPolygon::Rotate(const Point& rCenter, double fSin, double fCos) 1219 { 1220 pImpXPolygon->CheckPointDelete(); 1221 CheckReference(); 1222 1223 long nX; 1224 long nY; 1225 long nNewX; 1226 long nNewY; 1227 long nCenterX = rCenter.X(); 1228 long nCenterY = rCenter.Y(); 1229 1230 sal_uInt16 nPntCnt = pImpXPolygon->nPoints; 1231 1232 for (sal_uInt16 i = 0; i < nPntCnt; i++) 1233 { 1234 Point *pPt = &(pImpXPolygon->pPointAry[i]); 1235 nX = pPt->X()-nCenterX; 1236 nY = pPt->Y()-nCenterY; 1237 nNewX = (long)floor(fCos * nX + fSin * nY + 0.5); 1238 nNewY = -(long)floor(fSin * nX - fCos * nY + 0.5); 1239 pPt->X() = nNewX + nCenterX; 1240 pPt->Y() = nNewY + nCenterY; 1241 1242 /* und so stand das in einem anderen File auf T: 1243 dass ich am 29-11-1995 gegettet habe. Joe M. 1244 sal_uInt16 nPntCnt = pImpXPolygon->nPoints; 1245 1246 for (sal_uInt16 i = 0; i < nPntCnt; i++) 1247 { 1248 Point P = pImpXPolygon->pPointAry[i] - rCenter; 1249 long X = P.X(); 1250 long Y = P.Y(); 1251 P.X() = (long)floor(fCos * X + fSin * Y + 0.5); 1252 P.Y() = -(long)floor(fSin * X - fCos * Y + 0.5); 1253 pImpXPolygon->pPointAry[i] = P + rCenter; 1254 */ 1255 } 1256 } 1257 1258 /************************************************************************* 1259 |* 1260 |* XPolygon::Rotate() 1261 |* 1262 |* Alle Punkte um den Punkt rCenter mit dem Winkel nAngle drehen 1263 |* Winkel in 10tel Grad, Wertebereich 0 - 3600 1264 |* Ersterstellung ESO 17.01.95 1265 |* Letzte Aenderung ESO 17.01.95 1266 |* 1267 *************************************************************************/ 1268 1269 void XPolygon::Rotate(const Point& rCenter, sal_uInt16 nAngle) 1270 { 1271 nAngle %= 3600; 1272 1273 if ( nAngle != 0 ) 1274 { 1275 double fAngle = F_PI * nAngle / 1800; 1276 double fSin = sin(fAngle); 1277 double fCos = cos(fAngle); 1278 Rotate(rCenter, fSin, fCos); 1279 } 1280 } 1281 1282 /************************************************************************* 1283 |* 1284 |* XPolygon::Scale() 1285 |* 1286 |* XPolygon in X- und/oder Y-Richtung skalieren 1287 |* Ersterstellung ESO 01.02.95 1288 |* Letzte Aenderung ESO 01.02.95 1289 |* 1290 *************************************************************************/ 1291 1292 void XPolygon::Scale(double fSx, double fSy) 1293 { 1294 pImpXPolygon->CheckPointDelete(); 1295 CheckReference(); 1296 1297 sal_uInt16 nPntCnt = pImpXPolygon->nPoints; 1298 1299 for (sal_uInt16 i = 0; i < nPntCnt; i++) 1300 { 1301 Point& rPnt = pImpXPolygon->pPointAry[i]; 1302 rPnt.X() = (long)(fSx * rPnt.X()); 1303 rPnt.Y() = (long)(fSy * rPnt.Y()); 1304 } 1305 } 1306 1307 /************************************************************************* 1308 |* 1309 |* XPolygon::SlantX() 1310 |* 1311 |* XPolygon in X-Richtung um einen beliebigen Winkel kippen, 1312 |* bezogen auf eine Referenz-Y-Koordinate 1313 |* Ersterstellung ESO 01.02.95 1314 |* Letzte Aenderung ESO 01.02.95 1315 |* 1316 *************************************************************************/ 1317 1318 void XPolygon::SlantX(long nYRef, double fSin, double fCos) 1319 { 1320 pImpXPolygon->CheckPointDelete(); 1321 CheckReference(); 1322 1323 sal_uInt16 nPntCnt = pImpXPolygon->nPoints; 1324 1325 for (sal_uInt16 i = 0; i < nPntCnt; i++) 1326 { 1327 Point& rPnt = pImpXPolygon->pPointAry[i]; 1328 long nDy = rPnt.Y() - nYRef; 1329 rPnt.X() += (long)(fSin * nDy); 1330 rPnt.Y() = nYRef + (long)(fCos * nDy); 1331 } 1332 } 1333 1334 /************************************************************************* 1335 |* 1336 |* XPolygon::SlantY() 1337 |* 1338 |* XPolygon in Y-Richtung um einen beliebigen Winkel kippen, 1339 |* bezogen auf eine Referenz-X-Koordinate 1340 |* Ersterstellung ESO 01.02.95 1341 |* Letzte Aenderung ESO 01.02.95 1342 |* 1343 *************************************************************************/ 1344 1345 void XPolygon::SlantY(long nXRef, double fSin, double fCos) 1346 { 1347 pImpXPolygon->CheckPointDelete(); 1348 CheckReference(); 1349 1350 sal_uInt16 nPntCnt = pImpXPolygon->nPoints; 1351 1352 for (sal_uInt16 i = 0; i < nPntCnt; i++) 1353 { 1354 Point& rPnt = pImpXPolygon->pPointAry[i]; 1355 long nDx = rPnt.X() - nXRef; 1356 rPnt.X() = nXRef + (long)(fCos * nDx); 1357 rPnt.Y() -= (long)(fSin * nDx); 1358 } 1359 } 1360 1361 /************************************************************************* 1362 |* 1363 |* XPolygon::Distort() 1364 |* 1365 |* XPolygon verzerren, indem die Koordinaten relativ zu einem 1366 |* Referenzrechteck in ein beliebiges Viereck skaliert werden 1367 |* Zuordnung der Viereck-Punkte im Polygon zum Referenzrechteck: 1368 |* 0: links oben 0----1 1369 |* 1: rechts oben | | 1370 |* 2: rechts unten 3----2 1371 |* 3: links unten 1372 |* Ersterstellung ESO 07.07.95 1373 |* Letzte Aenderung ESO 07.07.95 1374 |* 1375 *************************************************************************/ 1376 1377 void XPolygon::Distort(const Rectangle& rRefRect, 1378 const XPolygon& rDistortedRect) 1379 { 1380 pImpXPolygon->CheckPointDelete(); 1381 CheckReference(); 1382 1383 long Xr, Wr, X1, X2, X3, X4; 1384 long Yr, Hr, Y1, Y2, Y3, Y4; 1385 double fTx, fTy, fUx, fUy; 1386 1387 Xr = rRefRect.Left(); 1388 Yr = rRefRect.Top(); 1389 Wr = rRefRect.GetWidth(); 1390 Hr = rRefRect.GetHeight(); 1391 1392 if ( Wr && Hr ) 1393 { 1394 DBG_ASSERT(rDistortedRect.pImpXPolygon->nPoints >= 4, 1395 "Distort-Rechteck zu klein"); 1396 1397 X1 = rDistortedRect[0].X(); 1398 Y1 = rDistortedRect[0].Y(); 1399 X2 = rDistortedRect[1].X(); 1400 Y2 = rDistortedRect[1].Y(); 1401 X3 = rDistortedRect[3].X(); 1402 Y3 = rDistortedRect[3].Y(); 1403 X4 = rDistortedRect[2].X(); 1404 Y4 = rDistortedRect[2].Y(); 1405 1406 sal_uInt16 nPntCnt = pImpXPolygon->nPoints; 1407 1408 for (sal_uInt16 i = 0; i < nPntCnt; i++) 1409 { 1410 Point& rPnt = pImpXPolygon->pPointAry[i]; 1411 1412 fTx = (double)(rPnt.X() - Xr) / Wr; 1413 fTy = (double)(rPnt.Y() - Yr) / Hr; 1414 fUx = 1.0 - fTx; 1415 fUy = 1.0 - fTy; 1416 1417 rPnt.X() = (long) ( fUy * (fUx * X1 + fTx * X2) + 1418 fTy * (fUx * X3 + fTx * X4) ); 1419 rPnt.Y() = (long) ( fUx * (fUy * Y1 + fTy * Y3) + 1420 fTx * (fUy * Y2 + fTy * Y4) ); 1421 } 1422 } 1423 } 1424 1425 /************************************************************************* 1426 |* 1427 |* Bestimme den linken, unteren Punkt des Polygons und richte das 1428 |* Polygon so aus, dass dieser Punkt auf dem Index 0 liegt 1429 |* 1430 \************************************************************************/ 1431 1432 void XPolygon::Rotate20() 1433 { 1434 pImpXPolygon->CheckPointDelete(); 1435 CheckReference(); 1436 1437 double fMinY = pImpXPolygon->pPointAry->Y(); 1438 double fMinX = pImpXPolygon->pPointAry->X(); 1439 long nPntCnt = pImpXPolygon->nPoints; 1440 long nIndex0 = 0; 1441 1442 for (long nPoints = 1; 1443 nPoints < nPntCnt; 1444 nPoints ++) 1445 { 1446 Point &rPnt = pImpXPolygon->pPointAry[nPoints]; 1447 1448 if ((rPnt.X () < fMinX) || (fMinX == rPnt.X ()) && 1449 (fMinY >= rPnt.Y ())) 1450 { 1451 fMinX = rPnt.X (); 1452 fMinY = rPnt.Y (); 1453 nIndex0 = nPoints; 1454 } 1455 } 1456 1457 if (nIndex0 < nPntCnt) 1458 { 1459 Point *pTemp = new Point [nIndex0]; 1460 memcpy (pTemp, pImpXPolygon->pPointAry, nIndex0 * sizeof (Point)); 1461 memcpy (pImpXPolygon->pPointAry, &pImpXPolygon->pPointAry [nIndex0], (nPntCnt - nIndex0) * sizeof (Point)); 1462 memcpy (&pImpXPolygon->pPointAry [nIndex0], pTemp, nIndex0 * sizeof (Point)); 1463 delete[] pTemp; 1464 } 1465 } 1466 1467 basegfx::B2DPolygon XPolygon::getB2DPolygon() const 1468 { 1469 // #i74631# use tools Polygon class for conversion to not have the code doubled 1470 // here. This needs one more conversion but avoids different convertors in 1471 // the long run 1472 DBG_ASSERT(pImpXPolygon != 0, "XPolygon::getB2DPolygon(): XPolygon has no implementation incarnated (!)"); 1473 const Polygon aSource(GetPointCount(), pImpXPolygon->pPointAry, pImpXPolygon->pFlagAry); 1474 1475 return aSource.getB2DPolygon(); 1476 } 1477 1478 XPolygon::XPolygon(const basegfx::B2DPolygon& rPolygon) 1479 { 1480 // #i74631# use tools Polygon class for conversion to not have the code doubled 1481 // here. This needs one more conversion but avoids different convertors in 1482 // the long run 1483 DBG_CTOR(XPolygon,NULL); 1484 1485 const Polygon aSource(rPolygon); 1486 sal_uInt16 nSize = aSource.GetSize(); 1487 pImpXPolygon = new ImpXPolygon( nSize ); 1488 pImpXPolygon->nPoints = nSize; 1489 1490 for( sal_uInt16 i = 0; i < nSize; i++ ) 1491 { 1492 pImpXPolygon->pPointAry[i] = aSource[i]; 1493 pImpXPolygon->pFlagAry[i] = (sal_uInt8) aSource.GetFlags( i ); 1494 } 1495 } 1496 1497 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1498 //+--------------- XPolyPolygon -----------------------------------------+ 1499 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1500 1501 /************************************************************************* 1502 |* 1503 |* ImpXPolyPolygon::ImpXPolyPolygon() 1504 |* 1505 |* Beschreibung Erzeugt das XPolygon-Array 1506 |* Ersterstellung CL 09.11.94 1507 |* Letzte Aenderung MM 09.11.94 1508 |* 1509 *************************************************************************/ 1510 1511 ImpXPolyPolygon::ImpXPolyPolygon( const ImpXPolyPolygon& rImpXPolyPoly ) : 1512 aXPolyList( rImpXPolyPoly.aXPolyList ) 1513 { 1514 nRefCount = 1; 1515 1516 // Einzelne Elemente duplizieren 1517 XPolygon* pXPoly = aXPolyList.First(); 1518 while ( pXPoly ) 1519 { 1520 aXPolyList.Replace( new XPolygon( *(aXPolyList.GetCurObject()) ) ); 1521 pXPoly = aXPolyList.Next(); 1522 } 1523 } 1524 1525 1526 /************************************************************************* 1527 |* 1528 |* ImpXPolyPolygon::~ImpXPolyPolygon() 1529 |* 1530 |* Beschreibung Loescht das Polygon-Array 1531 |* Ersterstellung CL 09.06.93 1532 |* Letzte Aenderung CL 09.06.93 1533 |* 1534 *************************************************************************/ 1535 1536 ImpXPolyPolygon::~ImpXPolyPolygon() 1537 { 1538 XPolygon* pXPoly = aXPolyList.First(); 1539 while( pXPoly ) 1540 { 1541 delete pXPoly; 1542 pXPoly = aXPolyList.Next(); 1543 } 1544 } 1545 1546 /************************************************************************* 1547 |* 1548 |* ImpXPolyPolygon::operator==() 1549 |* 1550 |* Ersterstellung Joe 26-09-95 1551 |* Letzte Aenderung 1552 |* 1553 *************************************************************************/ 1554 1555 1556 bool ImpXPolyPolygon::operator==(const ImpXPolyPolygon& rImpXPolyPoly) const 1557 { 1558 sal_uInt16 nAnz=(sal_uInt16)aXPolyList.Count(); 1559 const XPolygonList& rCmpList=rImpXPolyPoly.aXPolyList; 1560 if (nAnz!=(sal_uInt16)rCmpList.Count()) return sal_False; 1561 bool bEq=true; 1562 for (sal_uInt16 i=nAnz; i>0 && bEq;) { 1563 i--; 1564 bEq= *aXPolyList.GetObject(i) == *rCmpList.GetObject(i); 1565 } 1566 return bEq; 1567 } 1568 1569 /************************************************************************* 1570 |* 1571 |* XPolyPolygon::XPolyPolygon() 1572 |* 1573 |* Beschreibung POLY.SDW 1574 |* Ersterstellung CL 27.01.93 1575 |* Letzte Aenderung CL 27.01.93 1576 |* 1577 *************************************************************************/ 1578 1579 XPolyPolygon::XPolyPolygon( sal_uInt16 nInitSize, sal_uInt16 nResize ) 1580 { 1581 DBG_CTOR(XPolyPolygon,NULL); 1582 pImpXPolyPolygon = new ImpXPolyPolygon( nInitSize, nResize ); 1583 } 1584 1585 1586 /************************************************************************* 1587 |* 1588 |* XPolyPolygon::XPolyPolygon() 1589 |* 1590 |* Beschreibung POLY.SDW 1591 |* Ersterstellung CL 27.01.93 1592 |* Letzte Aenderung CL 27.01.93 1593 |* 1594 *************************************************************************/ 1595 1596 XPolyPolygon::XPolyPolygon( const XPolygon& rXPoly ) 1597 { 1598 DBG_CTOR(XPolyPolygon,NULL); 1599 pImpXPolyPolygon = new ImpXPolyPolygon; 1600 pImpXPolyPolygon->aXPolyList.Insert( new XPolygon( rXPoly ) ); 1601 } 1602 1603 /************************************************************************* 1604 |* 1605 |* XPolyPolygon::XPolyPolygon() 1606 |* 1607 |* Beschreibung POLY.SDW 1608 |* Ersterstellung CL 27.01.93 1609 |* Letzte Aenderung CL 27.01.93 1610 |* 1611 *************************************************************************/ 1612 1613 XPolyPolygon::XPolyPolygon( const XPolyPolygon& rXPolyPoly ) 1614 { 1615 DBG_CTOR(XPolyPolygon,NULL); 1616 pImpXPolyPolygon = rXPolyPoly.pImpXPolyPolygon; 1617 pImpXPolyPolygon->nRefCount++; 1618 } 1619 1620 /************************************************************************* 1621 |* 1622 |* XPolyPolygon::XPolyPolygon() 1623 |* 1624 |* XPolyPolygon aus einen Standard-PolyPolygon erzeugen 1625 |* Ersterstellung 18.01.95 ESO 1626 |* Letzte Aenderung 18.01.95 ESO 1627 |* 1628 *************************************************************************/ 1629 1630 XPolyPolygon::XPolyPolygon( const PolyPolygon& rPolyPoly ) 1631 { 1632 DBG_CTOR(XPolyPolygon,NULL); 1633 pImpXPolyPolygon = new ImpXPolyPolygon; 1634 1635 for (sal_uInt16 i = 0; i < rPolyPoly.Count(); i++) 1636 pImpXPolyPolygon->aXPolyList.Insert( 1637 new XPolygon(rPolyPoly.GetObject(i)) ); 1638 } 1639 1640 /************************************************************************* 1641 |* 1642 |* XPolyPolygon::~XPolyPolygon() 1643 |* 1644 |* Beschreibung POLY.SDW 1645 |* Ersterstellung CL 27.01.93 1646 |* Letzte Aenderung CL 27.01.93 1647 |* 1648 *************************************************************************/ 1649 1650 XPolyPolygon::~XPolyPolygon() 1651 { 1652 DBG_DTOR(XPolyPolygon,NULL); 1653 if( pImpXPolyPolygon->nRefCount > 1 ) 1654 pImpXPolyPolygon->nRefCount--; 1655 else 1656 delete pImpXPolyPolygon; 1657 } 1658 1659 /************************************************************************* 1660 |* 1661 |* XPolygon::CheckReference() 1662 |* 1663 |* Referenzzaehler desImpXPolyPoly pruefen und ggf. von diesem abkoppeln 1664 |* Ersterstellung 18.01.95 ESO 1665 |* Letzte Aenderung 18.01.95 ESO 1666 |* 1667 *************************************************************************/ 1668 1669 void XPolyPolygon::CheckReference() 1670 { 1671 if( pImpXPolyPolygon->nRefCount > 1 ) 1672 { 1673 pImpXPolyPolygon->nRefCount--; 1674 pImpXPolyPolygon = new ImpXPolyPolygon( *pImpXPolyPolygon ); 1675 } 1676 } 1677 1678 /************************************************************************* 1679 |* 1680 |* XPolyPolygon::Insert() 1681 |* 1682 |* Beschreibung POLY.SDW 1683 |* Ersterstellung CL 27.01.93 1684 |* Letzte Aenderung CL 27.01.93 1685 |* 1686 *************************************************************************/ 1687 1688 void XPolyPolygon::Insert( const XPolygon& rXPoly, sal_uInt16 nPos ) 1689 { 1690 CheckReference(); 1691 XPolygon* pXPoly = new XPolygon( rXPoly ); 1692 pImpXPolyPolygon->aXPolyList.Insert( pXPoly, nPos ); 1693 } 1694 1695 /************************************************************************* 1696 |* 1697 |* XPolyPolygon::Insert() 1698 |* 1699 |* saemtliche XPolygone aus einem XPolyPolygon einfuegen 1700 |* Ersterstellung 18.01.95 ESO 1701 |* Letzte Aenderung 18.01.95 ESO 1702 |* 1703 *************************************************************************/ 1704 1705 void XPolyPolygon::Insert( const XPolyPolygon& rXPolyPoly, sal_uInt16 nPos ) 1706 { 1707 CheckReference(); 1708 1709 for (sal_uInt16 i = 0; i < rXPolyPoly.Count(); i++) 1710 { 1711 XPolygon* pXPoly = new XPolygon(rXPolyPoly[i]); 1712 pImpXPolyPolygon->aXPolyList.Insert(pXPoly, nPos); 1713 if ( nPos != XPOLYPOLY_APPEND ) 1714 nPos++; 1715 } 1716 } 1717 1718 /************************************************************************* 1719 |* 1720 |* XPolyPolygon::Remove() 1721 |* 1722 |* Beschreibung POLY.SDW 1723 |* Ersterstellung CL 27.01.93 1724 |* Letzte Aenderung CL 27.01.93 1725 |* 1726 *************************************************************************/ 1727 1728 XPolygon XPolyPolygon::Remove( sal_uInt16 nPos ) 1729 { 1730 CheckReference(); 1731 XPolygon* pTmpXPoly = pImpXPolyPolygon->aXPolyList.Remove( nPos ); 1732 XPolygon aXPoly( *pTmpXPoly ); 1733 delete pTmpXPoly; 1734 return aXPoly; 1735 } 1736 1737 1738 /************************************************************************* 1739 |* 1740 |* XPolyPolygon::Replace() 1741 |* 1742 |* Beschreibung POLY.SDW 1743 |* Ersterstellung CL 27.01.93 1744 |* Letzte Aenderung CL 27.01.93 1745 |* 1746 *************************************************************************/ 1747 1748 XPolygon XPolyPolygon::Replace( const XPolygon& rXPoly, sal_uInt16 nPos ) 1749 { 1750 CheckReference(); 1751 XPolygon* pXPoly = new XPolygon( rXPoly ); 1752 XPolygon* pTmpXPoly = pImpXPolyPolygon->aXPolyList.Replace( pXPoly, nPos ); 1753 XPolygon aXPoly( *pTmpXPoly ); 1754 delete pTmpXPoly; 1755 return aXPoly; 1756 } 1757 1758 1759 /************************************************************************* 1760 |* 1761 |* XPolyPolygon::GetObject() 1762 |* 1763 |* Beschreibung POLY.SDW 1764 |* Ersterstellung CL 27.01.93 1765 |* Letzte Aenderung CL 27.01.93 1766 |* 1767 *************************************************************************/ 1768 1769 const XPolygon& XPolyPolygon::GetObject( sal_uInt16 nPos ) const 1770 { 1771 return *(pImpXPolyPolygon->aXPolyList.GetObject( nPos )); 1772 } 1773 1774 1775 /************************************************************************* 1776 |* 1777 |* XPolyPolygon::Clear() 1778 |* 1779 |* Beschreibung POLY.SDW 1780 |* Ersterstellung CL 27.01.93 1781 |* Letzte Aenderung TH 17.10.94 1782 |* 1783 *************************************************************************/ 1784 1785 void XPolyPolygon::Clear() 1786 { 1787 if ( pImpXPolyPolygon->nRefCount > 1 ) 1788 { 1789 pImpXPolyPolygon->nRefCount--; 1790 pImpXPolyPolygon = new ImpXPolyPolygon(); 1791 } 1792 else 1793 { 1794 XPolygon* pXPoly = pImpXPolyPolygon->aXPolyList.First(); 1795 while( pXPoly ) 1796 { 1797 delete pXPoly; 1798 pXPoly = pImpXPolyPolygon->aXPolyList.Next(); 1799 } 1800 pImpXPolyPolygon->aXPolyList.Clear(); 1801 } 1802 } 1803 1804 1805 /************************************************************************* 1806 |* 1807 |* XPolyPolygon::Count() 1808 |* 1809 |* Beschreibung 1810 |* Ersterstellung CL 27.01.93 1811 |* Letzte Aenderung CL 27.01.93 1812 |* 1813 *************************************************************************/ 1814 1815 sal_uInt16 XPolyPolygon::Count() const 1816 { 1817 return (sal_uInt16)(pImpXPolyPolygon->aXPolyList.Count()); 1818 } 1819 1820 1821 /************************************************************************* 1822 |* 1823 |* XPolyPolygon::Move() 1824 |* 1825 |* Beschreibung POLY.SDW 1826 |* Ersterstellung TH 04.10.94 1827 |* Letzte Aenderung TH 04.10.94 1828 |* 1829 *************************************************************************/ 1830 1831 void XPolyPolygon::Move( long nHorzMove, long nVertMove ) 1832 { 1833 // Diese Abfrage sollte man fuer die DrawEngine durchfuehren 1834 if ( !nHorzMove && !nVertMove ) 1835 return; 1836 1837 // Referenzcounter beruecksichtigen 1838 CheckReference(); 1839 1840 // Punkte verschieben 1841 XPolygon* pXPoly = pImpXPolyPolygon->aXPolyList.First(); 1842 while( pXPoly ) 1843 { 1844 pXPoly->Move( nHorzMove, nVertMove ); 1845 pXPoly = pImpXPolyPolygon->aXPolyList.Next(); 1846 } 1847 } 1848 1849 /************************************************************************* 1850 |* 1851 |* XPolyPolygon::GetBoundRect() 1852 |* 1853 |* Beschreibung POLY.SDW 1854 |* Ersterstellung TH 04.10.94 1855 |* Letzte Aenderung TH 04.10.94 1856 |* 1857 *************************************************************************/ 1858 1859 Rectangle XPolyPolygon::GetBoundRect() const 1860 { 1861 sal_uInt16 nXPoly = (sal_uInt16)pImpXPolyPolygon->aXPolyList.Count(); 1862 Rectangle aRect; 1863 1864 for ( sal_uInt16 n = 0; n < nXPoly; n++ ) 1865 { 1866 const XPolygon* pXPoly = pImpXPolyPolygon->aXPolyList.GetObject( n ); 1867 aRect.Union( pXPoly->GetBoundRect() ); 1868 } 1869 1870 return aRect; 1871 } 1872 1873 1874 /************************************************************************* 1875 |* 1876 |* XPolyPolygon::operator[]() 1877 |* 1878 |* Beschreibung POLY.SDW 1879 |* Ersterstellung TH 28.10.94 1880 |* Letzte Aenderung TH 28.10.94 1881 |* 1882 *************************************************************************/ 1883 1884 XPolygon& XPolyPolygon::operator[]( sal_uInt16 nPos ) 1885 { 1886 CheckReference(); 1887 return *(pImpXPolyPolygon->aXPolyList.GetObject( nPos )); 1888 } 1889 1890 /************************************************************************* 1891 |* 1892 |* XPolyPolygon::operator=() 1893 |* 1894 |* Beschreibung POLY.SDW 1895 |* Ersterstellung CL 27.01.93 1896 |* Letzte Aenderung CL 27.01.93 1897 |* 1898 *************************************************************************/ 1899 1900 XPolyPolygon& XPolyPolygon::operator=( const XPolyPolygon& rXPolyPoly ) 1901 { 1902 rXPolyPoly.pImpXPolyPolygon->nRefCount++; 1903 1904 if( pImpXPolyPolygon->nRefCount > 1 ) 1905 pImpXPolyPolygon->nRefCount--; 1906 else 1907 delete pImpXPolyPolygon; 1908 1909 pImpXPolyPolygon = rXPolyPoly.pImpXPolyPolygon; 1910 return *this; 1911 } 1912 1913 1914 /************************************************************************* 1915 |* 1916 |* XPolyPolygon::operator==() 1917 |* 1918 |* Beschreibung POLY.SDW 1919 |* Ersterstellung CL 27.01.93 1920 |* Letzte Aenderung Joe 27.01.93 1921 |* 1922 *************************************************************************/ 1923 1924 sal_Bool XPolyPolygon::operator==( const XPolyPolygon& rXPolyPoly ) const 1925 { 1926 if (pImpXPolyPolygon==rXPolyPoly.pImpXPolyPolygon) return sal_True; 1927 return *pImpXPolyPolygon == *rXPolyPoly.pImpXPolyPolygon; 1928 } 1929 1930 1931 /************************************************************************* 1932 |* 1933 |* XPolyPolygon::operator!=() 1934 |* 1935 |* Beschreibung POLY.SDW 1936 |* Ersterstellung CL 27.01.93 1937 |* Letzte Aenderung Joe 27.01.93 1938 |* 1939 *************************************************************************/ 1940 1941 sal_Bool XPolyPolygon::operator!=( const XPolyPolygon& rXPolyPoly ) const 1942 { 1943 if (pImpXPolyPolygon==rXPolyPoly.pImpXPolyPolygon) return sal_False; 1944 return *pImpXPolyPolygon != *rXPolyPoly.pImpXPolyPolygon; 1945 } 1946 1947 /************************************************************************* 1948 |* 1949 |* XPolyPolygon::Translate() 1950 |* 1951 |* Alle Polygone auf den uebergebenen Punkt verschieben 1952 |* Ersterstellung ESO 25.01.95 1953 |* Letzte Aenderung ESO 25.01.95 1954 |* 1955 *************************************************************************/ 1956 1957 void XPolyPolygon::Translate(const Point& rTrans) 1958 { 1959 CheckReference(); 1960 1961 for (sal_uInt16 i = 0; i < Count(); i++) 1962 pImpXPolyPolygon->aXPolyList.GetObject(i)->Translate(rTrans); 1963 } 1964 1965 /************************************************************************* 1966 |* 1967 |* XPolyPolygon::Rotate() 1968 |* 1969 |* Alle Polygone um den Punkt rCenter drehen, Sinus und Cosinus 1970 |* muessen uebergeben werden 1971 |* Ersterstellung ESO 25.01.95 1972 |* Letzte Aenderung ESO 25.01.95 1973 |* 1974 *************************************************************************/ 1975 1976 void XPolyPolygon::Rotate(const Point& rCenter, double fSin, double fCos) 1977 { 1978 CheckReference(); 1979 1980 for (sal_uInt16 i = 0; i < Count(); i++) 1981 pImpXPolyPolygon->aXPolyList.GetObject(i)->Rotate(rCenter, fSin, fCos); 1982 } 1983 1984 /************************************************************************* 1985 |* 1986 |* Bestimme den linken, unteren Punkt des Polygons und richte das 1987 |* Polygon so aus, dass dieser Punkt auf dem Index 0 liegt 1988 |* 1989 \************************************************************************/ 1990 1991 void XPolyPolygon::Rotate20() 1992 { 1993 CheckReference(); 1994 1995 for (sal_uInt16 i = 0; i < Count(); i++) 1996 pImpXPolyPolygon->aXPolyList.GetObject(i)->Rotate20(); 1997 } 1998 1999 /************************************************************************* 2000 |* 2001 |* XPolyPolygon::Rotate() 2002 |* 2003 |* Alle Poylgone um den Punkt rCenter mit dem Winkel nAngle drehen 2004 |* Winkel in 10tel Grad, Wertebereich 0 - 3600 2005 |* Ersterstellung ESO 25.01.95 2006 |* Letzte Aenderung ESO 25.01.95 2007 |* 2008 *************************************************************************/ 2009 2010 void XPolyPolygon::Rotate(const Point& rCenter, sal_uInt16 nAngle) 2011 { 2012 nAngle %= 3600; 2013 2014 if ( nAngle != 0 ) 2015 { 2016 double fAngle = F_PI * nAngle / 1800; 2017 double fSin = sin(fAngle); 2018 double fCos = cos(fAngle); 2019 Rotate(rCenter, fSin, fCos); 2020 } 2021 } 2022 2023 /************************************************************************* 2024 |* 2025 |* XPolyPolygon::Scale() 2026 |* 2027 |* Alle Polygone in X- und/oder Y-Richtung skalieren 2028 |* Ersterstellung ESO 01.02.95 2029 |* Letzte Aenderung ESO 01.02.95 2030 |* 2031 *************************************************************************/ 2032 2033 void XPolyPolygon::Scale(double fSx, double fSy) 2034 { 2035 CheckReference(); 2036 2037 for (sal_uInt16 i = 0; i < Count(); i++) 2038 pImpXPolyPolygon->aXPolyList.GetObject(i)->Scale(fSx, fSy); 2039 } 2040 2041 /************************************************************************* 2042 |* 2043 |* XPolyPolygon::SlantX() 2044 |* 2045 |* Alle Polygone in X-Richtung um einen beliebigen Winkel kippen, 2046 |* bezogen auf eine Referenz-Y-Koordinate 2047 |* Ersterstellung ESO 01.02.95 2048 |* Letzte Aenderung ESO 01.02.95 2049 |* 2050 *************************************************************************/ 2051 2052 void XPolyPolygon::SlantX(long nYRef, double fSin, double fCos) 2053 { 2054 CheckReference(); 2055 2056 for (sal_uInt16 i = 0; i < Count(); i++) 2057 pImpXPolyPolygon->aXPolyList.GetObject(i)->SlantX(nYRef, fSin, fCos); 2058 } 2059 2060 /************************************************************************* 2061 |* 2062 |* XPolyPolygon::SlantY() 2063 |* 2064 |* Alle Polygone in Y-Richtung um einen beliebigen Winkel kippen, 2065 |* bezogen auf eine Referenz-X-Koordinate 2066 |* Ersterstellung ESO 01.02.95 2067 |* Letzte Aenderung ESO 01.02.95 2068 |* 2069 *************************************************************************/ 2070 2071 void XPolyPolygon::SlantY(long nXRef, double fSin, double fCos) 2072 { 2073 CheckReference(); 2074 2075 for (sal_uInt16 i = 0; i < Count(); i++) 2076 pImpXPolyPolygon->aXPolyList.GetObject(i)->SlantY(nXRef, fSin, fCos); 2077 } 2078 2079 /************************************************************************* 2080 |* 2081 |* XPolygon::Distort() 2082 |* 2083 |* XPolygon verzerren, indem die Koordinaten relativ zu einem 2084 |* Referenzrechteck in ein beliebiges Viereck skaliert werden 2085 |* Zuordnung der Viereck-Punkte im Polygon zum Referenzrechteck: 2086 |* 0: links oben 0----1 2087 |* 1: rechts oben | | 2088 |* 2: rechts unten 3----2 2089 |* 3: links unten 2090 |* Ersterstellung ESO 07.07.95 2091 |* Letzte Aenderung ESO 07.07.95 2092 |* 2093 *************************************************************************/ 2094 2095 void XPolyPolygon::Distort(const Rectangle& rRefRect, 2096 const XPolygon& rDistortedRect) 2097 { 2098 CheckReference(); 2099 2100 for (sal_uInt16 i = 0; i < Count(); i++) 2101 pImpXPolyPolygon->aXPolyList.GetObject(i)->Distort(rRefRect, 2102 rDistortedRect); 2103 } 2104 2105 basegfx::B2DPolyPolygon XPolyPolygon::getB2DPolyPolygon() const 2106 { 2107 basegfx::B2DPolyPolygon aRetval; 2108 2109 for(sal_uInt16 a(0L); a < Count(); a++) 2110 { 2111 const XPolygon& rPoly = (*this)[a]; 2112 aRetval.append(rPoly.getB2DPolygon()); 2113 } 2114 2115 return aRetval; 2116 } 2117 2118 XPolyPolygon::XPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPolygon) 2119 { 2120 DBG_CTOR(XPolyPolygon,NULL); 2121 pImpXPolyPolygon = new ImpXPolyPolygon( 16, 16 ); 2122 2123 for(sal_uInt32 a(0L); a < rPolyPolygon.count(); a++) 2124 { 2125 basegfx::B2DPolygon aCandidate = rPolyPolygon.getB2DPolygon(a); 2126 XPolygon aNewPoly(aCandidate); 2127 Insert(aNewPoly); 2128 } 2129 } 2130 2131 // eof 2132