xref: /aoo41x/main/svtools/source/misc/imap.cxx (revision 5900e8ec)
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