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