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_svtools.hxx" 26 27 #include <tools/urlobj.hxx> 28 #include <vcl/svapp.hxx> 29 #include <vcl/mapmod.hxx> 30 #include <vcl/window.hxx> 31 32 #include "svl/urihelper.hxx" 33 #include <svtools/imap.hxx> 34 #include <svtools/imapobj.hxx> 35 #include <svtools/imapcirc.hxx> 36 #include <svtools/imaprect.hxx> 37 #include <svtools/imappoly.hxx> 38 39 #include <string.h> 40 #include <math.h> 41 42 DBG_NAME( ImageMap ) 43 44 45 #define SCALEPOINT(aPT,aFracX,aFracY) (aPT).X()=((aPT).X()*(aFracX).GetNumerator())/(aFracX).GetDenominator(); \ 46 (aPT).Y()=((aPT).Y()*(aFracY).GetNumerator())/(aFracY).GetDenominator(); 47 48 49 /******************************************************************************/ 50 51 sal_uInt16 IMapObject::nActualTextEncoding = (sal_uInt16) RTL_TEXTENCODING_DONTKNOW; 52 53 /******************************************************************************/ 54 55 56 IMapObject::IMapObject() 57 : bActive( false ) 58 , nReadVersion( 0 ) 59 { 60 } 61 62 IMapObject::IMapObject( const String& rURL, const String& rAltText, const String& rDesc, 63 const String& rTarget, const String& rName, sal_Bool bURLActive ) 64 : aURL( rURL ) 65 , aAltText( rAltText ) 66 , aDesc( rDesc ) 67 , aTarget( rTarget ) 68 , aName( rName ) 69 , bActive( bURLActive ) 70 , nReadVersion( 0 ) 71 { 72 } 73 74 75 /****************************************************************************** 76 |* 77 |* Freigabe des internen Speichers 78 |* 79 \******************************************************************************/ 80 81 sal_uInt16 IMapObject::GetVersion() const 82 { 83 return IMAP_OBJ_VERSION; 84 } 85 86 87 /****************************************************************************** 88 |* 89 |* 90 |* 91 \******************************************************************************/ 92 93 void IMapObject::Write( SvStream& rOStm, const String& rBaseURL ) const 94 { 95 IMapCompat* pCompat; 96 const rtl_TextEncoding eEncoding = gsl_getSystemTextEncoding(); 97 98 rOStm << GetType(); 99 rOStm << GetVersion(); 100 rOStm << ( (sal_uInt16) eEncoding ); 101 102 const ByteString aRelURL = ByteString( String(URIHelper::simpleNormalizedMakeRelative( rBaseURL, aURL )), eEncoding ); 103 rOStm.WriteByteString( aRelURL ); 104 rOStm.WriteByteString( ByteString( aAltText, eEncoding ) ); 105 rOStm << bActive; 106 rOStm.WriteByteString( ByteString( aTarget, eEncoding ) ); 107 108 pCompat = new IMapCompat( rOStm, STREAM_WRITE ); 109 110 WriteIMapObject( rOStm ); 111 aEventList.Write( rOStm ); // V4 112 rOStm.WriteByteString( ByteString( aName, eEncoding ) ); // V5 113 114 delete pCompat; 115 } 116 117 118 /****************************************************************************** 119 |* 120 |* Binaer-Import 121 |* 122 \******************************************************************************/ 123 124 void IMapObject::Read( SvStream& rIStm, const String& rBaseURL ) 125 { 126 IMapCompat* pCompat; 127 rtl_TextEncoding nTextEncoding; 128 ByteString aString; 129 130 // Typ und Version ueberlesen wir 131 rIStm.SeekRel( 2 ); 132 rIStm >> nReadVersion; 133 rIStm >> nTextEncoding; 134 rIStm.ReadByteString( aString ); aURL = String( aString.GetBuffer(), nTextEncoding ); 135 rIStm.ReadByteString( aString ); aAltText = String( aString.GetBuffer(), nTextEncoding ); 136 rIStm >> bActive; 137 rIStm.ReadByteString( aString ); aTarget = String( aString.GetBuffer(), nTextEncoding ); 138 139 // URL absolut machen 140 aURL = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), aURL, URIHelper::GetMaybeFileHdl(), true, false, INetURLObject::WAS_ENCODED, INetURLObject::DECODE_UNAMBIGUOUS ); 141 pCompat = new IMapCompat( rIStm, STREAM_READ ); 142 143 ReadIMapObject( rIStm ); 144 145 // ab Version 4 lesen wir eine EventListe 146 if ( nReadVersion >= 0x0004 ) 147 { 148 aEventList.Read(rIStm); 149 150 // ab Version 5 kann ein Objektname vorhanden sein 151 if ( nReadVersion >= 0x0005 ) 152 { 153 rIStm.ReadByteString( aString ); aName = String( aString.GetBuffer(), nTextEncoding ); 154 } 155 } 156 157 delete pCompat; 158 } 159 160 161 /****************************************************************************** 162 |* 163 |* Konvertierung der logischen Koordianten in Pixel 164 |* 165 \******************************************************************************/ 166 167 Point IMapObject::GetPixelPoint( const Point& rLogPoint ) 168 { 169 return Application::GetDefaultDevice()->LogicToPixel( rLogPoint, MapMode( MAP_100TH_MM ) ); 170 } 171 172 173 /****************************************************************************** 174 |* 175 |* Konvertierung der logischen Koordianten in Pixel 176 |* 177 \******************************************************************************/ 178 179 Point IMapObject::GetLogPoint( const Point& rPixelPoint ) 180 { 181 return Application::GetDefaultDevice()->PixelToLogic( rPixelPoint, MapMode( MAP_100TH_MM ) ); 182 } 183 184 185 /****************************************************************************** 186 |* 187 |* 188 |* 189 \******************************************************************************/ 190 191 sal_Bool IMapObject::IsEqual( const IMapObject& rEqObj ) 192 { 193 return ( ( aURL == rEqObj.aURL ) && 194 ( aAltText == rEqObj.aAltText ) && 195 ( aDesc == rEqObj.aDesc ) && 196 ( aTarget == rEqObj.aTarget ) && 197 ( aName == rEqObj.aName ) && 198 ( bActive == rEqObj.bActive ) ); 199 } 200 201 202 /******************************************************************************/ 203 /******************************************************************************/ 204 /******************************************************************************/ 205 206 IMapRectangleObject::IMapRectangleObject( const Rectangle& rRect, 207 const String& rURL, 208 const String& rAltText, 209 const String& rDesc, 210 const String& rTarget, 211 const String& rName, 212 sal_Bool bURLActive, 213 sal_Bool bPixelCoords ) : 214 IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive ) 215 { 216 ImpConstruct( rRect, bPixelCoords ); 217 } 218 219 220 /****************************************************************************** 221 |* 222 |* 223 |* 224 \******************************************************************************/ 225 226 void IMapRectangleObject::ImpConstruct( const Rectangle& rRect, sal_Bool bPixel ) 227 { 228 if ( bPixel ) 229 aRect = Application::GetDefaultDevice()->PixelToLogic( rRect, MapMode( MAP_100TH_MM ) ); 230 else 231 aRect = rRect; 232 } 233 234 235 /****************************************************************************** 236 |* 237 |* Binaer-Export 238 |* 239 \******************************************************************************/ 240 241 void IMapRectangleObject::WriteIMapObject( SvStream& rOStm ) const 242 { 243 rOStm << aRect; 244 } 245 246 247 /****************************************************************************** 248 |* 249 |* Binaer-Import 250 |* 251 \******************************************************************************/ 252 253 void IMapRectangleObject::ReadIMapObject( SvStream& rIStm ) 254 { 255 rIStm >> aRect; 256 } 257 258 259 /****************************************************************************** 260 |* 261 |* Typ-Rueckgabe 262 |* 263 \******************************************************************************/ 264 265 sal_uInt16 IMapRectangleObject::GetType() const 266 { 267 return IMAP_OBJ_RECTANGLE; 268 } 269 270 271 /****************************************************************************** 272 |* 273 |* Hit-Test 274 |* 275 \******************************************************************************/ 276 277 sal_Bool IMapRectangleObject::IsHit( const Point& rPoint ) const 278 { 279 return aRect.IsInside( rPoint ); 280 } 281 282 283 /****************************************************************************** 284 |* 285 |* 286 |* 287 \******************************************************************************/ 288 289 Rectangle IMapRectangleObject::GetRectangle( sal_Bool bPixelCoords ) const 290 { 291 Rectangle aNewRect; 292 293 if ( bPixelCoords ) 294 aNewRect = Application::GetDefaultDevice()->LogicToPixel( aRect, MapMode( MAP_100TH_MM ) ); 295 else 296 aNewRect = aRect; 297 298 return aNewRect; 299 } 300 301 302 /****************************************************************************** 303 |* 304 |* 305 |* 306 \******************************************************************************/ 307 308 void IMapRectangleObject::Scale( const Fraction& rFracX, const Fraction& rFracY ) 309 { 310 Point aTL( aRect.TopLeft() ); 311 Point aBR( aRect.BottomRight() ); 312 313 if ( rFracX.GetDenominator() && rFracY.GetDenominator() ) 314 { 315 SCALEPOINT( aTL, rFracX, rFracY ); 316 SCALEPOINT( aBR, rFracX, rFracY ); 317 } 318 319 aRect = Rectangle( aTL, aBR ); 320 } 321 322 323 /****************************************************************************** 324 |* 325 |* 326 |* 327 \******************************************************************************/ 328 329 sal_Bool IMapRectangleObject::IsEqual( const IMapRectangleObject& rEqObj ) 330 { 331 return ( IMapObject::IsEqual( rEqObj ) && ( aRect == rEqObj.aRect ) ); 332 } 333 334 335 /******************************************************************************/ 336 /******************************************************************************/ 337 /******************************************************************************/ 338 339 IMapCircleObject::IMapCircleObject( const Point& rCenter, sal_uLong nCircleRadius, 340 const String& rURL, 341 const String& rAltText, 342 const String& rDesc, 343 const String& rTarget, 344 const String& rName, 345 sal_Bool bURLActive, 346 sal_Bool bPixelCoords ) : 347 IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive ) 348 { 349 ImpConstruct( rCenter, nCircleRadius, bPixelCoords ); 350 } 351 352 353 /****************************************************************************** 354 |* 355 |* 356 |* 357 \******************************************************************************/ 358 359 void IMapCircleObject::ImpConstruct( const Point& rCenter, sal_uLong nRad, sal_Bool bPixel ) 360 { 361 if ( bPixel ) 362 { 363 MapMode aMap100( MAP_100TH_MM ); 364 365 aCenter = Application::GetDefaultDevice()->PixelToLogic( rCenter, aMap100 ); 366 nRadius = Application::GetDefaultDevice()->PixelToLogic( Size( nRad, 0 ), aMap100 ).Width(); 367 } 368 else 369 { 370 aCenter = rCenter; 371 nRadius = nRad; 372 } 373 } 374 375 376 /****************************************************************************** 377 |* 378 |* Binaer-Export 379 |* 380 \******************************************************************************/ 381 382 void IMapCircleObject::WriteIMapObject( SvStream& rOStm ) const 383 { 384 sal_uInt32 nTmp = nRadius; 385 386 rOStm << aCenter; 387 rOStm << nTmp; 388 } 389 390 391 /****************************************************************************** 392 |* 393 |* Binaer-Import 394 |* 395 \******************************************************************************/ 396 397 void IMapCircleObject::ReadIMapObject( SvStream& rIStm ) 398 { 399 sal_uInt32 nTmp; 400 401 rIStm >> aCenter; 402 rIStm >> nTmp; 403 404 nRadius = nTmp; 405 } 406 407 408 /****************************************************************************** 409 |* 410 |* Typ-Rueckgabe 411 |* 412 \******************************************************************************/ 413 414 sal_uInt16 IMapCircleObject::GetType() const 415 { 416 return IMAP_OBJ_CIRCLE; 417 } 418 419 420 /****************************************************************************** 421 |* 422 |* Hit-Test 423 |* 424 \******************************************************************************/ 425 426 sal_Bool IMapCircleObject::IsHit( const Point& rPoint ) const 427 { 428 const Point aPoint( aCenter - rPoint ); 429 sal_Bool bRet = sal_False; 430 431 if ( (sal_uLong) sqrt( (double) aPoint.X() * aPoint.X() + 432 aPoint.Y() * aPoint.Y() ) <= nRadius ) 433 { 434 bRet = sal_True; 435 } 436 437 return bRet; 438 } 439 440 441 /****************************************************************************** 442 |* 443 |* 444 |* 445 \******************************************************************************/ 446 447 Point IMapCircleObject::GetCenter( sal_Bool bPixelCoords ) const 448 { 449 Point aNewPoint; 450 451 if ( bPixelCoords ) 452 aNewPoint = Application::GetDefaultDevice()->LogicToPixel( aCenter, MapMode( MAP_100TH_MM ) ); 453 else 454 aNewPoint = aCenter; 455 456 return aNewPoint; 457 } 458 459 460 /****************************************************************************** 461 |* 462 |* 463 |* 464 \******************************************************************************/ 465 466 sal_uLong IMapCircleObject::GetRadius( sal_Bool bPixelCoords ) const 467 { 468 sal_uLong nNewRadius; 469 470 if ( bPixelCoords ) 471 nNewRadius = Application::GetDefaultDevice()->LogicToPixel( Size( nRadius, 0 ), MapMode( MAP_100TH_MM ) ).Width(); 472 else 473 nNewRadius = nRadius; 474 475 return nNewRadius; 476 } 477 478 479 /****************************************************************************** 480 |* 481 |* 482 |* 483 \******************************************************************************/ 484 485 Rectangle IMapCircleObject::GetBoundRect() const 486 { 487 long nWidth = nRadius << 1; 488 489 return Rectangle( Point( aCenter.X() - nRadius, aCenter.Y() - nRadius ), 490 Size( nWidth, nWidth ) ); 491 } 492 493 494 /****************************************************************************** 495 |* 496 |* 497 |* 498 \******************************************************************************/ 499 500 void IMapCircleObject::Scale( const Fraction& rFracX, const Fraction& rFracY ) 501 { 502 Fraction aAverage( rFracX ); 503 504 aAverage += rFracY; 505 aAverage *= Fraction( 1, 2 ); 506 507 if ( rFracX.GetDenominator() && rFracY.GetDenominator() ) 508 { 509 SCALEPOINT( aCenter, rFracX, rFracY ); 510 } 511 512 nRadius = ( nRadius * aAverage.GetNumerator() ) / aAverage.GetDenominator(); 513 } 514 515 516 /****************************************************************************** 517 |* 518 |* 519 |* 520 \******************************************************************************/ 521 522 sal_Bool IMapCircleObject::IsEqual( const IMapCircleObject& rEqObj ) 523 { 524 return ( IMapObject::IsEqual( rEqObj ) && 525 ( aCenter == rEqObj.aCenter ) && 526 ( nRadius == rEqObj.nRadius ) ); 527 } 528 529 530 /******************************************************************************/ 531 /******************************************************************************/ 532 /******************************************************************************/ 533 IMapPolygonObject::IMapPolygonObject( const Polygon& rPoly, 534 const String& rURL, 535 const String& rAltText, 536 const String& rDesc, 537 const String& rTarget, 538 const String& rName, 539 sal_Bool bURLActive, 540 sal_Bool bPixelCoords ) : 541 IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive ), 542 bEllipse ( sal_False ) 543 { 544 ImpConstruct( rPoly, bPixelCoords ); 545 } 546 547 548 /****************************************************************************** 549 |* 550 |* 551 |* 552 \******************************************************************************/ 553 554 void IMapPolygonObject::ImpConstruct( const Polygon& rPoly, sal_Bool bPixel ) 555 { 556 if ( bPixel ) 557 aPoly = Application::GetDefaultDevice()->PixelToLogic( rPoly, MapMode( MAP_100TH_MM ) ); 558 else 559 aPoly = rPoly; 560 } 561 562 563 /****************************************************************************** 564 |* 565 |* Binaer-Export 566 |* 567 \******************************************************************************/ 568 569 void IMapPolygonObject::WriteIMapObject( SvStream& rOStm ) const 570 { 571 rOStm << aPoly; 572 rOStm << bEllipse; // >= Version 2 573 rOStm << aEllipse; // >= Version 2 574 } 575 576 577 /****************************************************************************** 578 |* 579 |* Binaer-Import 580 |* 581 \******************************************************************************/ 582 583 void IMapPolygonObject::ReadIMapObject( SvStream& rIStm ) 584 { 585 rIStm >> aPoly; 586 587 // Version >= 2 hat zusaetzlich Ellipsen-Information 588 if ( nReadVersion >= 2 ) 589 { 590 rIStm >> bEllipse; 591 rIStm >> aEllipse; 592 } 593 } 594 595 596 /****************************************************************************** 597 |* 598 |* Typ-Rueckgabe 599 |* 600 \******************************************************************************/ 601 602 sal_uInt16 IMapPolygonObject::GetType() const 603 { 604 return IMAP_OBJ_POLYGON; 605 } 606 607 608 /****************************************************************************** 609 |* 610 |* Hit-Test 611 |* 612 \******************************************************************************/ 613 614 sal_Bool IMapPolygonObject::IsHit( const Point& rPoint ) const 615 { 616 return aPoly.IsInside( rPoint ); 617 } 618 619 620 /****************************************************************************** 621 |* 622 |* 623 |* 624 \******************************************************************************/ 625 626 Polygon IMapPolygonObject::GetPolygon( sal_Bool bPixelCoords ) const 627 { 628 Polygon aNewPoly; 629 630 if ( bPixelCoords ) 631 aNewPoly = Application::GetDefaultDevice()->LogicToPixel( aPoly, MapMode( MAP_100TH_MM ) ); 632 else 633 aNewPoly = aPoly; 634 635 return aNewPoly; 636 } 637 638 639 /****************************************************************************** 640 |* 641 |* 642 |* 643 \******************************************************************************/ 644 645 void IMapPolygonObject::SetExtraEllipse( const Rectangle& rEllipse ) 646 { 647 if ( aPoly.GetSize() ) 648 { 649 bEllipse = sal_True; 650 aEllipse = rEllipse; 651 } 652 } 653 654 655 /****************************************************************************** 656 |* 657 |* 658 |* 659 \******************************************************************************/ 660 661 void IMapPolygonObject::Scale( const Fraction& rFracX, const Fraction& rFracY ) 662 { 663 sal_uInt16 nCount = aPoly.GetSize(); 664 665 for ( sal_uInt16 i = 0; i < nCount; i++ ) 666 { 667 Point aScaledPt( aPoly[ i ] ); 668 669 if ( rFracX.GetDenominator() && rFracY.GetDenominator() ) 670 { 671 SCALEPOINT( aScaledPt, rFracX, rFracY ); 672 } 673 674 aPoly[ i ] = aScaledPt; 675 } 676 677 if ( bEllipse ) 678 { 679 Point aTL( aEllipse.TopLeft() ); 680 Point aBR( aEllipse.BottomRight() ); 681 682 if ( rFracX.GetDenominator() && rFracY.GetDenominator() ) 683 { 684 SCALEPOINT( aTL, rFracX, rFracY ); 685 SCALEPOINT( aBR, rFracX, rFracY ); 686 } 687 688 aEllipse = Rectangle( aTL, aBR ); 689 } 690 } 691 692 693 /****************************************************************************** 694 |* 695 |* 696 |* 697 \******************************************************************************/ 698 699 sal_Bool IMapPolygonObject::IsEqual( const IMapPolygonObject& rEqObj ) 700 { 701 sal_Bool bRet = sal_False; 702 703 if ( IMapObject::IsEqual( rEqObj ) ) 704 { 705 const Polygon& rEqPoly = rEqObj.aPoly; 706 const sal_uInt16 nCount = aPoly.GetSize(); 707 const sal_uInt16 nEqCount = rEqPoly.GetSize(); 708 sal_Bool bDifferent = sal_False; 709 710 if ( nCount == nEqCount ) 711 { 712 for ( sal_uInt16 i = 0; i < nCount; i++ ) 713 { 714 if ( aPoly[ i ] != rEqPoly[ i ] ) 715 { 716 bDifferent = sal_True; 717 break; 718 } 719 } 720 721 if ( !bDifferent ) 722 bRet = sal_True; 723 } 724 } 725 726 return bRet; 727 } 728 729 730 /******************************************************************************/ 731 /******************************************************************************/ 732 /******************************************************************************/ 733 734 735 /****************************************************************************** 736 |* 737 |* Ctor 738 |* 739 \******************************************************************************/ 740 741 ImageMap::ImageMap( const String& rName ) : 742 aName ( rName ) 743 { 744 } 745 746 747 /****************************************************************************** 748 |* 749 |* Copy-Ctor 750 |* 751 \******************************************************************************/ 752 753 ImageMap::ImageMap( const ImageMap& rImageMap ) 754 { 755 DBG_CTOR( ImageMap, NULL ); 756 757 sal_uInt16 nCount = rImageMap.GetIMapObjectCount(); 758 759 for ( sal_uInt16 i = 0; i < nCount; i++ ) 760 { 761 IMapObject* pCopyObj = rImageMap.GetIMapObject( i ); 762 763 switch( pCopyObj->GetType() ) 764 { 765 case( IMAP_OBJ_RECTANGLE ): 766 maList.Insert( new IMapRectangleObject( *(IMapRectangleObject*) pCopyObj ), LIST_APPEND ); 767 break; 768 769 case( IMAP_OBJ_CIRCLE ): 770 maList.Insert( new IMapCircleObject( *(IMapCircleObject*) pCopyObj ), LIST_APPEND ); 771 break; 772 773 case( IMAP_OBJ_POLYGON ): 774 maList.Insert( new IMapPolygonObject( *(IMapPolygonObject*) pCopyObj ), LIST_APPEND ); 775 break; 776 777 default: 778 break; 779 } 780 } 781 782 aName = rImageMap.aName; 783 } 784 785 786 /****************************************************************************** 787 |* 788 |* Dtor 789 |* 790 \******************************************************************************/ 791 792 ImageMap::~ImageMap() 793 { 794 DBG_DTOR( ImageMap, NULL ); 795 796 ClearImageMap(); 797 } 798 799 800 /****************************************************************************** 801 |* 802 |* Freigabe des internen Speichers 803 |* 804 \******************************************************************************/ 805 806 void ImageMap::ClearImageMap() 807 { 808 IMapObject* pObj = (IMapObject*) maList.First(); 809 810 while ( pObj ) 811 { 812 delete pObj; 813 pObj = (IMapObject*) maList.Next(); 814 } 815 816 maList.Clear(); 817 818 aName = String(); 819 } 820 821 822 /****************************************************************************** 823 |* 824 |* Zuweisungsoperator 825 |* 826 \******************************************************************************/ 827 828 ImageMap& ImageMap::operator=( const ImageMap& rImageMap ) 829 { 830 sal_uInt16 nCount = rImageMap.GetIMapObjectCount(); 831 832 ClearImageMap(); 833 834 for ( sal_uInt16 i = 0; i < nCount; i++ ) 835 { 836 IMapObject* pCopyObj = rImageMap.GetIMapObject( i ); 837 838 switch( pCopyObj->GetType() ) 839 { 840 case( IMAP_OBJ_RECTANGLE ): 841 maList.Insert( new IMapRectangleObject( *(IMapRectangleObject*) pCopyObj ), LIST_APPEND ); 842 break; 843 844 case( IMAP_OBJ_CIRCLE ): 845 maList.Insert( new IMapCircleObject( *(IMapCircleObject*) pCopyObj ), LIST_APPEND ); 846 break; 847 848 case( IMAP_OBJ_POLYGON ): 849 maList.Insert( new IMapPolygonObject( *(IMapPolygonObject*) pCopyObj ), LIST_APPEND ); 850 break; 851 852 default: 853 break; 854 } 855 } 856 857 aName = rImageMap.aName; 858 859 return *this; 860 } 861 862 863 /****************************************************************************** 864 |* 865 |* Vergleichsoperator I 866 |* 867 \******************************************************************************/ 868 869 sal_Bool ImageMap::operator==( const ImageMap& rImageMap ) 870 { 871 const sal_uInt16 nCount = (sal_uInt16) maList.Count(); 872 const sal_uInt16 nEqCount = rImageMap.GetIMapObjectCount(); 873 sal_Bool bRet = sal_False; 874 875 if ( nCount == nEqCount ) 876 { 877 sal_Bool bDifferent = ( aName != rImageMap.aName ); 878 879 for ( sal_uInt16 i = 0; ( i < nCount ) && !bDifferent; i++ ) 880 { 881 IMapObject* pObj = (IMapObject*) maList.GetObject( i ); 882 IMapObject* pEqObj = rImageMap.GetIMapObject( i ); 883 884 if ( pObj->GetType() == pEqObj->GetType() ) 885 { 886 switch( pObj->GetType() ) 887 { 888 case( IMAP_OBJ_RECTANGLE ): 889 { 890 if ( !( (IMapRectangleObject*) pObj )->IsEqual( *(IMapRectangleObject*) pEqObj ) ) 891 bDifferent = sal_True; 892 } 893 break; 894 895 case( IMAP_OBJ_CIRCLE ): 896 { 897 if ( !( (IMapCircleObject*) pObj )->IsEqual( *(IMapCircleObject*) pEqObj ) ) 898 bDifferent = sal_True; 899 } 900 break; 901 902 case( IMAP_OBJ_POLYGON ): 903 { 904 if ( !( (IMapPolygonObject*) pObj )->IsEqual( *(IMapPolygonObject*) pEqObj ) ) 905 bDifferent = sal_True; 906 } 907 break; 908 909 default: 910 break; 911 } 912 } 913 else 914 bDifferent = sal_True; 915 } 916 917 if ( !bDifferent ) 918 bRet = sal_True; 919 } 920 921 return bRet; 922 } 923 924 925 /****************************************************************************** 926 |* 927 |* Vergleichsoperator II 928 |* 929 \******************************************************************************/ 930 931 sal_Bool ImageMap::operator!=( const ImageMap& rImageMap ) 932 { 933 return !( *this == rImageMap ); 934 } 935 936 937 /****************************************************************************** 938 |* 939 |* Freigabe des internen Speichers 940 |* 941 \******************************************************************************/ 942 943 sal_uInt16 ImageMap::GetVersion() const 944 { 945 return IMAGE_MAP_VERSION; 946 } 947 948 949 /****************************************************************************** 950 |* 951 |* Einfuegen eines neuen Objekts 952 |* 953 \******************************************************************************/ 954 955 void ImageMap::InsertIMapObject( const IMapObject& rIMapObject ) 956 { 957 switch( rIMapObject.GetType() ) 958 { 959 case( IMAP_OBJ_RECTANGLE ): 960 maList.Insert( new IMapRectangleObject( (IMapRectangleObject&) rIMapObject ), LIST_APPEND ); 961 break; 962 963 case( IMAP_OBJ_CIRCLE ): 964 maList.Insert( new IMapCircleObject( (IMapCircleObject&) rIMapObject ), LIST_APPEND ); 965 break; 966 967 case( IMAP_OBJ_POLYGON ): 968 maList.Insert( new IMapPolygonObject( (IMapPolygonObject&) rIMapObject ), LIST_APPEND ); 969 break; 970 971 default: 972 break; 973 } 974 } 975 976 977 /****************************************************************************** 978 |* 979 |* Hit-Test 980 |* 981 \******************************************************************************/ 982 983 IMapObject* ImageMap::GetHitIMapObject( const Size& rTotalSize, 984 const Size& rDisplaySize, 985 const Point& rRelHitPoint, 986 sal_uLong nFlags ) 987 { 988 Point aRelPoint( rTotalSize.Width() * rRelHitPoint.X() / rDisplaySize.Width(), 989 rTotalSize.Height() * rRelHitPoint.Y() / rDisplaySize.Height() ); 990 991 // Falls Flags zur Spiegelung etc. angegeben sind, wird 992 // der zu pruefende Punkt vor der Pruefung entspr. transformiert 993 if ( nFlags ) 994 { 995 if ( nFlags & IMAP_MIRROR_HORZ ) 996 aRelPoint.X() = rTotalSize.Width() - aRelPoint.X(); 997 998 if ( nFlags & IMAP_MIRROR_VERT ) 999 aRelPoint.Y() = rTotalSize.Height() - aRelPoint.Y(); 1000 } 1001 1002 // Alle Objekte durchlaufen und HitTest ausfuehren 1003 IMapObject* pObj = (IMapObject*) maList.First(); 1004 while ( pObj ) 1005 { 1006 if ( pObj->IsHit( aRelPoint ) ) 1007 break; 1008 1009 pObj = (IMapObject*) maList.Next(); 1010 } 1011 1012 return( pObj ? ( pObj->IsActive() ? pObj : NULL ) : NULL ); 1013 } 1014 1015 1016 /****************************************************************************** 1017 |* 1018 |* 1019 |* 1020 \******************************************************************************/ 1021 1022 Rectangle ImageMap::GetBoundRect() const 1023 { 1024 Rectangle aBoundRect; 1025 sal_uLong nCount = maList.Count(); 1026 1027 for ( sal_uLong i = 0; i < nCount; i++ ) 1028 aBoundRect.Union( ( (IMapObject*) maList.GetObject( i ) )->GetBoundRect() ); 1029 1030 return aBoundRect; 1031 } 1032 1033 1034 /****************************************************************************** 1035 |* 1036 |* 1037 |* 1038 \******************************************************************************/ 1039 1040 void ImageMap::Scale( const Fraction& rFracX, const Fraction& rFracY ) 1041 { 1042 sal_uInt16 nCount = (sal_uInt16) maList.Count(); 1043 1044 for ( sal_uInt16 i = 0; i < nCount; i++ ) 1045 { 1046 IMapObject* pObj = GetIMapObject( i ); 1047 1048 switch( pObj->GetType() ) 1049 { 1050 case( IMAP_OBJ_RECTANGLE ): 1051 ( (IMapRectangleObject*) pObj )->Scale( rFracX, rFracY ); 1052 break; 1053 1054 case( IMAP_OBJ_CIRCLE ): 1055 ( (IMapCircleObject*) pObj )->Scale( rFracX, rFracY ); 1056 break; 1057 1058 case( IMAP_OBJ_POLYGON ): 1059 ( (IMapPolygonObject*) pObj )->Scale( rFracX, rFracY ); 1060 break; 1061 1062 default: 1063 break; 1064 } 1065 } 1066 } 1067 1068 1069 /****************************************************************************** 1070 |* 1071 |* Objekte nacheinander wegschreiben 1072 |* 1073 \******************************************************************************/ 1074 1075 void ImageMap::ImpWriteImageMap( SvStream& rOStm, const String& rBaseURL ) const 1076 { 1077 IMapObject* pObj; 1078 sal_uInt16 nCount = (sal_uInt16) maList.Count(); 1079 1080 for ( sal_uInt16 i = 0; i < nCount; i++ ) 1081 { 1082 pObj = (IMapObject*) maList.GetObject( i ); 1083 pObj->Write( rOStm, rBaseURL ); 1084 } 1085 } 1086 1087 1088 /****************************************************************************** 1089 |* 1090 |* Objekte nacheinander lesen 1091 |* 1092 \******************************************************************************/ 1093 1094 void ImageMap::ImpReadImageMap( SvStream& rIStm, sal_uInt16 nCount, const String& rBaseURL ) 1095 { 1096 // neue Objekte einlesen 1097 for ( sal_uInt16 i = 0; i < nCount; i++ ) 1098 { 1099 sal_uInt16 nType; 1100 1101 rIStm >> nType; 1102 rIStm.SeekRel( -2 ); 1103 1104 switch( nType ) 1105 { 1106 case ( IMAP_OBJ_RECTANGLE ): 1107 { 1108 IMapRectangleObject* pObj = new IMapRectangleObject; 1109 pObj->Read( rIStm, rBaseURL ); 1110 maList.Insert( pObj, LIST_APPEND ); 1111 } 1112 break; 1113 1114 case ( IMAP_OBJ_CIRCLE ): 1115 { 1116 IMapCircleObject* pObj = new IMapCircleObject; 1117 pObj->Read( rIStm, rBaseURL ); 1118 maList.Insert( pObj, LIST_APPEND ); 1119 } 1120 break; 1121 1122 case ( IMAP_OBJ_POLYGON ): 1123 { 1124 IMapPolygonObject* pObj = new IMapPolygonObject; 1125 pObj->Read( rIStm, rBaseURL ); 1126 maList.Insert( pObj, LIST_APPEND ); 1127 } 1128 break; 1129 1130 default: 1131 break; 1132 } 1133 } 1134 } 1135 1136 1137 /****************************************************************************** 1138 |* 1139 |* Binaer speichern 1140 |* 1141 \******************************************************************************/ 1142 1143 void ImageMap::Write( SvStream& rOStm, const String& rBaseURL ) const 1144 { 1145 IMapCompat* pCompat; 1146 String aImageName( GetName() ); 1147 String aDummy; 1148 sal_uInt16 nOldFormat = rOStm.GetNumberFormatInt(); 1149 sal_uInt16 nCount = (sal_uInt16) GetIMapObjectCount(); 1150 const rtl_TextEncoding eEncoding = gsl_getSystemTextEncoding(); 1151 1152 rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); 1153 1154 // MagicCode schreiben 1155 rOStm << IMAPMAGIC; 1156 rOStm << GetVersion(); 1157 rOStm.WriteByteString( ByteString( aImageName, eEncoding ) ); 1158 rOStm.WriteByteString( ByteString( aDummy, eEncoding ) ); 1159 rOStm << nCount; 1160 rOStm.WriteByteString( ByteString( aImageName, eEncoding ) ); 1161 1162 pCompat = new IMapCompat( rOStm, STREAM_WRITE ); 1163 1164 // hier kann in neueren Versionen eingefuegt werden 1165 1166 delete pCompat; 1167 1168 ImpWriteImageMap( rOStm, rBaseURL ); 1169 1170 rOStm.SetNumberFormatInt( nOldFormat ); 1171 } 1172 1173 1174 /****************************************************************************** 1175 |* 1176 |* Binaer laden 1177 |* 1178 \******************************************************************************/ 1179 1180 void ImageMap::Read( SvStream& rIStm, const String& rBaseURL ) 1181 { 1182 ByteString aString; 1183 char cMagic[6]; 1184 sal_uInt16 nOldFormat = rIStm.GetNumberFormatInt(); 1185 sal_uInt16 nCount; 1186 1187 rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); 1188 rIStm.Read( cMagic, sizeof( cMagic ) ); 1189 1190 if ( !memcmp( cMagic, IMAPMAGIC, sizeof( cMagic ) ) ) 1191 { 1192 IMapCompat* pCompat; 1193 1194 // alten Inhalt loeschen 1195 ClearImageMap(); 1196 1197 // Version ueberlesen wir 1198 rIStm.SeekRel( 2 ); 1199 1200 rIStm.ReadByteString( aString ); aName = String( aString, gsl_getSystemTextEncoding() ); 1201 rIStm.ReadByteString( aString ); // Dummy 1202 rIStm >> nCount; 1203 rIStm.ReadByteString( aString ); // Dummy 1204 1205 pCompat = new IMapCompat( rIStm, STREAM_READ ); 1206 1207 // hier kann in neueren Versionen gelesen werden 1208 1209 delete pCompat; 1210 ImpReadImageMap( rIStm, nCount, rBaseURL ); 1211 1212 } 1213 else 1214 rIStm.SetError( SVSTREAM_GENERALERROR ); 1215 1216 rIStm.SetNumberFormatInt( nOldFormat ); 1217 } 1218 1219