xref: /AOO41X/main/svtools/source/misc/imap.cxx (revision 5900e8ec128faec89519683efce668ccd8cc6084)
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 
IMapObject()56 IMapObject::IMapObject()
57     : bActive( false )
58     , nReadVersion( 0 )
59 {
60 }
61 
IMapObject(const String & rURL,const String & rAltText,const String & rDesc,const String & rTarget,const String & rName,sal_Bool bURLActive)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 
GetVersion() const81 sal_uInt16 IMapObject::GetVersion() const
82 {
83     return IMAP_OBJ_VERSION;
84 }
85 
86 
87 /******************************************************************************
88 |*
89 |*
90 |*
91 \******************************************************************************/
92 
Write(SvStream & rOStm,const String & rBaseURL) const93 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 
Read(SvStream & rIStm,const String & rBaseURL)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 
GetPixelPoint(const Point & rLogPoint)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 
GetLogPoint(const Point & rPixelPoint)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 
IsEqual(const IMapObject & rEqObj)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 
IMapRectangleObject(const Rectangle & rRect,const String & rURL,const String & rAltText,const String & rDesc,const String & rTarget,const String & rName,sal_Bool bURLActive,sal_Bool bPixelCoords)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 
ImpConstruct(const Rectangle & rRect,sal_Bool bPixel)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 
WriteIMapObject(SvStream & rOStm) const241 void IMapRectangleObject::WriteIMapObject( SvStream& rOStm ) const
242 {
243     rOStm << aRect;
244 }
245 
246 
247 /******************************************************************************
248 |*
249 |* Binaer-Import
250 |*
251 \******************************************************************************/
252 
ReadIMapObject(SvStream & rIStm)253 void IMapRectangleObject::ReadIMapObject( SvStream& rIStm )
254 {
255     rIStm >> aRect;
256 }
257 
258 
259 /******************************************************************************
260 |*
261 |* Typ-Rueckgabe
262 |*
263 \******************************************************************************/
264 
GetType() const265 sal_uInt16 IMapRectangleObject::GetType() const
266 {
267     return IMAP_OBJ_RECTANGLE;
268 }
269 
270 
271 /******************************************************************************
272 |*
273 |* Hit-Test
274 |*
275 \******************************************************************************/
276 
IsHit(const Point & rPoint) const277 sal_Bool IMapRectangleObject::IsHit( const Point& rPoint ) const
278 {
279     return aRect.IsInside( rPoint );
280 }
281 
282 
283 /******************************************************************************
284 |*
285 |*
286 |*
287 \******************************************************************************/
288 
GetRectangle(sal_Bool bPixelCoords) const289 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 
Scale(const Fraction & rFracX,const Fraction & rFracY)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 
IsEqual(const IMapRectangleObject & rEqObj)329 sal_Bool IMapRectangleObject::IsEqual( const IMapRectangleObject& rEqObj )
330 {
331     return ( IMapObject::IsEqual( rEqObj ) && ( aRect == rEqObj.aRect ) );
332 }
333 
334 
335 /******************************************************************************/
336 /******************************************************************************/
337 /******************************************************************************/
338 
IMapCircleObject(const Point & rCenter,sal_uLong nCircleRadius,const String & rURL,const String & rAltText,const String & rDesc,const String & rTarget,const String & rName,sal_Bool bURLActive,sal_Bool bPixelCoords)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 
ImpConstruct(const Point & rCenter,sal_uLong nRad,sal_Bool bPixel)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 
WriteIMapObject(SvStream & rOStm) const382 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 
ReadIMapObject(SvStream & rIStm)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 
GetType() const414 sal_uInt16 IMapCircleObject::GetType() const
415 {
416     return IMAP_OBJ_CIRCLE;
417 }
418 
419 
420 /******************************************************************************
421 |*
422 |* Hit-Test
423 |*
424 \******************************************************************************/
425 
IsHit(const Point & rPoint) const426 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 
GetCenter(sal_Bool bPixelCoords) const447 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 
GetRadius(sal_Bool bPixelCoords) const466 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 
GetBoundRect() const485 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 
Scale(const Fraction & rFracX,const Fraction & rFracY)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 
IsEqual(const IMapCircleObject & rEqObj)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 /******************************************************************************/
IMapPolygonObject(const Polygon & rPoly,const String & rURL,const String & rAltText,const String & rDesc,const String & rTarget,const String & rName,sal_Bool bURLActive,sal_Bool bPixelCoords)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 
ImpConstruct(const Polygon & rPoly,sal_Bool bPixel)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 
WriteIMapObject(SvStream & rOStm) const569 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 
ReadIMapObject(SvStream & rIStm)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 
GetType() const602 sal_uInt16 IMapPolygonObject::GetType() const
603 {
604     return IMAP_OBJ_POLYGON;
605 }
606 
607 
608 /******************************************************************************
609 |*
610 |* Hit-Test
611 |*
612 \******************************************************************************/
613 
IsHit(const Point & rPoint) const614 sal_Bool IMapPolygonObject::IsHit( const Point& rPoint ) const
615 {
616     return aPoly.IsInside( rPoint );
617 }
618 
619 
620 /******************************************************************************
621 |*
622 |*
623 |*
624 \******************************************************************************/
625 
GetPolygon(sal_Bool bPixelCoords) const626 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 
SetExtraEllipse(const Rectangle & rEllipse)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 
Scale(const Fraction & rFracX,const Fraction & rFracY)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 
IsEqual(const IMapPolygonObject & rEqObj)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 
ImageMap(const String & rName)741 ImageMap::ImageMap( const String& rName ) :
742             aName   ( rName )
743 {
744 }
745 
746 
747 /******************************************************************************
748 |*
749 |* Copy-Ctor
750 |*
751 \******************************************************************************/
752 
ImageMap(const ImageMap & rImageMap)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 
~ImageMap()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 
ClearImageMap()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 
operator =(const ImageMap & rImageMap)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 
operator ==(const ImageMap & rImageMap)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 
operator !=(const ImageMap & rImageMap)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 
GetVersion() const943 sal_uInt16 ImageMap::GetVersion() const
944 {
945     return IMAGE_MAP_VERSION;
946 }
947 
948 
949 /******************************************************************************
950 |*
951 |* Einfuegen eines neuen Objekts
952 |*
953 \******************************************************************************/
954 
InsertIMapObject(const IMapObject & rIMapObject)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 
GetHitIMapObject(const Size & rTotalSize,const Size & rDisplaySize,const Point & rRelHitPoint,sal_uLong nFlags)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 
GetBoundRect() const1022 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 
Scale(const Fraction & rFracX,const Fraction & rFracY)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 
ImpWriteImageMap(SvStream & rOStm,const String & rBaseURL) const1075 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 
ImpReadImageMap(SvStream & rIStm,sal_uInt16 nCount,const String & rBaseURL)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 
Write(SvStream & rOStm,const String & rBaseURL) const1143 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 
Read(SvStream & rIStm,const String & rBaseURL)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