Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <tools/urlobj.hxx>
22 : #include <vcl/svapp.hxx>
23 : #include <vcl/mapmod.hxx>
24 : #include <vcl/window.hxx>
25 :
26 : #include "svl/urihelper.hxx"
27 : #include <svtools/imap.hxx>
28 : #include <svtools/imapobj.hxx>
29 : #include <svtools/imapcirc.hxx>
30 : #include <svtools/imaprect.hxx>
31 : #include <svtools/imappoly.hxx>
32 :
33 : #include <string.h>
34 : #include <math.h>
35 :
36 : DBG_NAME( ImageMap )
37 :
38 :
39 : #define SCALEPOINT(aPT,aFracX,aFracY) (aPT).X()=((aPT).X()*(aFracX).GetNumerator())/(aFracX).GetDenominator(); \
40 : (aPT).Y()=((aPT).Y()*(aFracY).GetNumerator())/(aFracY).GetDenominator();
41 :
42 :
43 : /******************************************************************************/
44 :
45 : sal_uInt16 IMapObject::nActualTextEncoding = (sal_uInt16) RTL_TEXTENCODING_DONTKNOW;
46 :
47 : /******************************************************************************/
48 :
49 :
50 0 : IMapObject::IMapObject()
51 : : bActive( false )
52 0 : , nReadVersion( 0 )
53 : {
54 0 : }
55 :
56 0 : IMapObject::IMapObject( const String& rURL, const String& rAltText, const String& rDesc,
57 : const String& rTarget, const String& rName, sal_Bool bURLActive )
58 : : aURL( rURL )
59 : , aAltText( rAltText )
60 : , aDesc( rDesc )
61 : , aTarget( rTarget )
62 : , aName( rName )
63 : , bActive( bURLActive )
64 0 : , nReadVersion( 0 )
65 : {
66 0 : }
67 :
68 :
69 : /******************************************************************************
70 : |*
71 : |* Freigabe des internen Speichers
72 : |*
73 : \******************************************************************************/
74 :
75 0 : sal_uInt16 IMapObject::GetVersion() const
76 : {
77 0 : return IMAP_OBJ_VERSION;
78 : }
79 :
80 0 : void IMapObject::Write( SvStream& rOStm, const String& rBaseURL ) const
81 : {
82 : IMapCompat* pCompat;
83 0 : const rtl_TextEncoding eEncoding = osl_getThreadTextEncoding();
84 :
85 0 : rOStm << GetType();
86 0 : rOStm << GetVersion();
87 0 : rOStm << ( (sal_uInt16) eEncoding );
88 :
89 : const rtl::OString aRelURL = rtl::OUStringToOString(
90 0 : URIHelper::simpleNormalizedMakeRelative(rBaseURL, aURL), eEncoding);
91 0 : write_lenPrefixed_uInt8s_FromOString<sal_uInt16>(rOStm, aRelURL);
92 0 : write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rOStm, aAltText, eEncoding);
93 0 : rOStm << bActive;
94 0 : write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rOStm, aTarget, eEncoding);
95 :
96 0 : pCompat = new IMapCompat( rOStm, STREAM_WRITE );
97 :
98 0 : WriteIMapObject( rOStm );
99 0 : aEventList.Write( rOStm ); // V4
100 0 : write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rOStm, aName, eEncoding); // V5
101 :
102 0 : delete pCompat;
103 0 : }
104 :
105 :
106 : /******************************************************************************
107 : |*
108 : |* Binaer-Import
109 : |*
110 : \******************************************************************************/
111 :
112 0 : void IMapObject::Read( SvStream& rIStm, const String& rBaseURL )
113 : {
114 : IMapCompat* pCompat;
115 : rtl_TextEncoding nTextEncoding;
116 :
117 : // Typ und Version ueberlesen wir
118 0 : rIStm.SeekRel( 2 );
119 0 : rIStm >> nReadVersion;
120 0 : rIStm >> nTextEncoding;
121 0 : aURL = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(rIStm, nTextEncoding);
122 0 : aAltText = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(rIStm, nTextEncoding);
123 0 : rIStm >> bActive;
124 0 : aTarget = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(rIStm, nTextEncoding);
125 :
126 : // URL absolut machen
127 0 : aURL = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), aURL, URIHelper::GetMaybeFileHdl(), true, false, INetURLObject::WAS_ENCODED, INetURLObject::DECODE_UNAMBIGUOUS );
128 0 : pCompat = new IMapCompat( rIStm, STREAM_READ );
129 :
130 0 : ReadIMapObject( rIStm );
131 :
132 : // ab Version 4 lesen wir eine EventListe
133 0 : if ( nReadVersion >= 0x0004 )
134 : {
135 0 : aEventList.Read(rIStm);
136 :
137 : // ab Version 5 kann ein Objektname vorhanden sein
138 0 : if ( nReadVersion >= 0x0005 )
139 0 : aName = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(rIStm, nTextEncoding);
140 : }
141 :
142 0 : delete pCompat;
143 0 : }
144 :
145 0 : sal_Bool IMapObject::IsEqual( const IMapObject& rEqObj )
146 : {
147 0 : return ( ( aURL == rEqObj.aURL ) &&
148 0 : ( aAltText == rEqObj.aAltText ) &&
149 0 : ( aDesc == rEqObj.aDesc ) &&
150 0 : ( aTarget == rEqObj.aTarget ) &&
151 0 : ( aName == rEqObj.aName ) &&
152 0 : ( bActive == rEqObj.bActive ) );
153 : }
154 :
155 0 : IMapRectangleObject::IMapRectangleObject( const Rectangle& rRect,
156 : const String& rURL,
157 : const String& rAltText,
158 : const String& rDesc,
159 : const String& rTarget,
160 : const String& rName,
161 : sal_Bool bURLActive,
162 : sal_Bool bPixelCoords ) :
163 0 : IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive )
164 : {
165 0 : ImpConstruct( rRect, bPixelCoords );
166 0 : }
167 :
168 0 : void IMapRectangleObject::ImpConstruct( const Rectangle& rRect, sal_Bool bPixel )
169 : {
170 0 : if ( bPixel )
171 0 : aRect = Application::GetDefaultDevice()->PixelToLogic( rRect, MapMode( MAP_100TH_MM ) );
172 : else
173 0 : aRect = rRect;
174 0 : }
175 :
176 :
177 : /******************************************************************************
178 : |*
179 : |* Binaer-Export
180 : |*
181 : \******************************************************************************/
182 :
183 0 : void IMapRectangleObject::WriteIMapObject( SvStream& rOStm ) const
184 : {
185 0 : rOStm << aRect;
186 0 : }
187 :
188 :
189 : /******************************************************************************
190 : |*
191 : |* Binaer-Import
192 : |*
193 : \******************************************************************************/
194 :
195 0 : void IMapRectangleObject::ReadIMapObject( SvStream& rIStm )
196 : {
197 0 : rIStm >> aRect;
198 0 : }
199 :
200 :
201 : /******************************************************************************
202 : |*
203 : |* Typ-Rueckgabe
204 : |*
205 : \******************************************************************************/
206 :
207 0 : sal_uInt16 IMapRectangleObject::GetType() const
208 : {
209 0 : return IMAP_OBJ_RECTANGLE;
210 : }
211 :
212 :
213 : /******************************************************************************
214 : |*
215 : |* Hit-Test
216 : |*
217 : \******************************************************************************/
218 :
219 0 : sal_Bool IMapRectangleObject::IsHit( const Point& rPoint ) const
220 : {
221 0 : return aRect.IsInside( rPoint );
222 : }
223 :
224 0 : Rectangle IMapRectangleObject::GetRectangle( sal_Bool bPixelCoords ) const
225 : {
226 0 : Rectangle aNewRect;
227 :
228 0 : if ( bPixelCoords )
229 0 : aNewRect = Application::GetDefaultDevice()->LogicToPixel( aRect, MapMode( MAP_100TH_MM ) );
230 : else
231 0 : aNewRect = aRect;
232 :
233 0 : return aNewRect;
234 : }
235 :
236 0 : void IMapRectangleObject::Scale( const Fraction& rFracX, const Fraction& rFracY )
237 : {
238 0 : Point aTL( aRect.TopLeft() );
239 0 : Point aBR( aRect.BottomRight() );
240 :
241 0 : if ( rFracX.GetDenominator() && rFracY.GetDenominator() )
242 : {
243 0 : SCALEPOINT( aTL, rFracX, rFracY );
244 0 : SCALEPOINT( aBR, rFracX, rFracY );
245 : }
246 :
247 0 : aRect = Rectangle( aTL, aBR );
248 0 : }
249 :
250 0 : sal_Bool IMapRectangleObject::IsEqual( const IMapRectangleObject& rEqObj )
251 : {
252 0 : return ( IMapObject::IsEqual( rEqObj ) && ( aRect == rEqObj.aRect ) );
253 : }
254 :
255 0 : IMapCircleObject::IMapCircleObject( const Point& rCenter, sal_uLong nCircleRadius,
256 : const String& rURL,
257 : const String& rAltText,
258 : const String& rDesc,
259 : const String& rTarget,
260 : const String& rName,
261 : sal_Bool bURLActive,
262 : sal_Bool bPixelCoords ) :
263 0 : IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive )
264 : {
265 0 : ImpConstruct( rCenter, nCircleRadius, bPixelCoords );
266 0 : }
267 :
268 0 : void IMapCircleObject::ImpConstruct( const Point& rCenter, sal_uLong nRad, sal_Bool bPixel )
269 : {
270 0 : if ( bPixel )
271 : {
272 0 : MapMode aMap100( MAP_100TH_MM );
273 :
274 0 : aCenter = Application::GetDefaultDevice()->PixelToLogic( rCenter, aMap100 );
275 0 : nRadius = Application::GetDefaultDevice()->PixelToLogic( Size( nRad, 0 ), aMap100 ).Width();
276 : }
277 : else
278 : {
279 0 : aCenter = rCenter;
280 0 : nRadius = nRad;
281 : }
282 0 : }
283 :
284 :
285 : /******************************************************************************
286 : |*
287 : |* Binaer-Export
288 : |*
289 : \******************************************************************************/
290 :
291 0 : void IMapCircleObject::WriteIMapObject( SvStream& rOStm ) const
292 : {
293 0 : sal_uInt32 nTmp = nRadius;
294 :
295 0 : rOStm << aCenter;
296 0 : rOStm << nTmp;
297 0 : }
298 :
299 :
300 : /******************************************************************************
301 : |*
302 : |* Binaer-Import
303 : |*
304 : \******************************************************************************/
305 :
306 0 : void IMapCircleObject::ReadIMapObject( SvStream& rIStm )
307 : {
308 : sal_uInt32 nTmp;
309 :
310 0 : rIStm >> aCenter;
311 0 : rIStm >> nTmp;
312 :
313 0 : nRadius = nTmp;
314 0 : }
315 :
316 :
317 : /******************************************************************************
318 : |*
319 : |* Typ-Rueckgabe
320 : |*
321 : \******************************************************************************/
322 :
323 0 : sal_uInt16 IMapCircleObject::GetType() const
324 : {
325 0 : return IMAP_OBJ_CIRCLE;
326 : }
327 :
328 :
329 : /******************************************************************************
330 : |*
331 : |* Hit-Test
332 : |*
333 : \******************************************************************************/
334 :
335 0 : sal_Bool IMapCircleObject::IsHit( const Point& rPoint ) const
336 : {
337 0 : const Point aPoint( aCenter - rPoint );
338 0 : sal_Bool bRet = sal_False;
339 :
340 0 : if ( (sal_Int32) sqrt( (double) aPoint.X() * aPoint.X() +
341 0 : aPoint.Y() * aPoint.Y() ) <= nRadius )
342 : {
343 0 : bRet = sal_True;
344 : }
345 :
346 0 : return bRet;
347 : }
348 :
349 0 : Point IMapCircleObject::GetCenter( sal_Bool bPixelCoords ) const
350 : {
351 0 : Point aNewPoint;
352 :
353 0 : if ( bPixelCoords )
354 0 : aNewPoint = Application::GetDefaultDevice()->LogicToPixel( aCenter, MapMode( MAP_100TH_MM ) );
355 : else
356 0 : aNewPoint = aCenter;
357 :
358 0 : return aNewPoint;
359 : }
360 :
361 0 : sal_uLong IMapCircleObject::GetRadius( sal_Bool bPixelCoords ) const
362 : {
363 : sal_uLong nNewRadius;
364 :
365 0 : if ( bPixelCoords )
366 0 : nNewRadius = Application::GetDefaultDevice()->LogicToPixel( Size( nRadius, 0 ), MapMode( MAP_100TH_MM ) ).Width();
367 : else
368 0 : nNewRadius = nRadius;
369 :
370 0 : return nNewRadius;
371 : }
372 :
373 0 : Rectangle IMapCircleObject::GetBoundRect() const
374 : {
375 0 : long nWidth = nRadius << 1;
376 :
377 0 : return Rectangle( Point( aCenter.X() - nRadius, aCenter.Y() - nRadius ),
378 0 : Size( nWidth, nWidth ) );
379 : }
380 :
381 0 : void IMapCircleObject::Scale( const Fraction& rFracX, const Fraction& rFracY )
382 : {
383 0 : Fraction aAverage( rFracX );
384 :
385 0 : aAverage += rFracY;
386 0 : aAverage *= Fraction( 1, 2 );
387 :
388 0 : if ( rFracX.GetDenominator() && rFracY.GetDenominator() )
389 : {
390 0 : SCALEPOINT( aCenter, rFracX, rFracY );
391 : }
392 :
393 0 : nRadius = ( nRadius * aAverage.GetNumerator() ) / aAverage.GetDenominator();
394 0 : }
395 :
396 0 : sal_Bool IMapCircleObject::IsEqual( const IMapCircleObject& rEqObj )
397 : {
398 0 : return ( IMapObject::IsEqual( rEqObj ) &&
399 0 : ( aCenter == rEqObj.aCenter ) &&
400 0 : ( nRadius == rEqObj.nRadius ) );
401 : }
402 :
403 0 : IMapPolygonObject::IMapPolygonObject( const Polygon& rPoly,
404 : const String& rURL,
405 : const String& rAltText,
406 : const String& rDesc,
407 : const String& rTarget,
408 : const String& rName,
409 : sal_Bool bURLActive,
410 : sal_Bool bPixelCoords ) :
411 : IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive ),
412 0 : bEllipse ( sal_False )
413 : {
414 0 : ImpConstruct( rPoly, bPixelCoords );
415 0 : }
416 :
417 0 : void IMapPolygonObject::ImpConstruct( const Polygon& rPoly, sal_Bool bPixel )
418 : {
419 0 : if ( bPixel )
420 0 : aPoly = Application::GetDefaultDevice()->PixelToLogic( rPoly, MapMode( MAP_100TH_MM ) );
421 : else
422 0 : aPoly = rPoly;
423 0 : }
424 :
425 :
426 : /******************************************************************************
427 : |*
428 : |* Binaer-Export
429 : |*
430 : \******************************************************************************/
431 :
432 0 : void IMapPolygonObject::WriteIMapObject( SvStream& rOStm ) const
433 : {
434 0 : rOStm << aPoly;
435 0 : rOStm << bEllipse; // >= Version 2
436 0 : rOStm << aEllipse; // >= Version 2
437 0 : }
438 :
439 :
440 : /******************************************************************************
441 : |*
442 : |* Binaer-Import
443 : |*
444 : \******************************************************************************/
445 :
446 0 : void IMapPolygonObject::ReadIMapObject( SvStream& rIStm )
447 : {
448 0 : rIStm >> aPoly;
449 :
450 : // Version >= 2 hat zusaetzlich Ellipsen-Information
451 0 : if ( nReadVersion >= 2 )
452 : {
453 0 : rIStm >> bEllipse;
454 0 : rIStm >> aEllipse;
455 : }
456 0 : }
457 :
458 :
459 : /******************************************************************************
460 : |*
461 : |* Typ-Rueckgabe
462 : |*
463 : \******************************************************************************/
464 :
465 0 : sal_uInt16 IMapPolygonObject::GetType() const
466 : {
467 0 : return IMAP_OBJ_POLYGON;
468 : }
469 :
470 :
471 : /******************************************************************************
472 : |*
473 : |* Hit-Test
474 : |*
475 : \******************************************************************************/
476 :
477 0 : sal_Bool IMapPolygonObject::IsHit( const Point& rPoint ) const
478 : {
479 0 : return aPoly.IsInside( rPoint );
480 : }
481 :
482 0 : Polygon IMapPolygonObject::GetPolygon( sal_Bool bPixelCoords ) const
483 : {
484 0 : Polygon aNewPoly;
485 :
486 0 : if ( bPixelCoords )
487 0 : aNewPoly = Application::GetDefaultDevice()->LogicToPixel( aPoly, MapMode( MAP_100TH_MM ) );
488 : else
489 0 : aNewPoly = aPoly;
490 :
491 0 : return aNewPoly;
492 : }
493 :
494 0 : void IMapPolygonObject::SetExtraEllipse( const Rectangle& rEllipse )
495 : {
496 0 : if ( aPoly.GetSize() )
497 : {
498 0 : bEllipse = sal_True;
499 0 : aEllipse = rEllipse;
500 : }
501 0 : }
502 :
503 0 : void IMapPolygonObject::Scale( const Fraction& rFracX, const Fraction& rFracY )
504 : {
505 0 : sal_uInt16 nCount = aPoly.GetSize();
506 :
507 0 : for ( sal_uInt16 i = 0; i < nCount; i++ )
508 : {
509 0 : Point aScaledPt( aPoly[ i ] );
510 :
511 0 : if ( rFracX.GetDenominator() && rFracY.GetDenominator() )
512 : {
513 0 : SCALEPOINT( aScaledPt, rFracX, rFracY );
514 : }
515 :
516 0 : aPoly[ i ] = aScaledPt;
517 : }
518 :
519 0 : if ( bEllipse )
520 : {
521 0 : Point aTL( aEllipse.TopLeft() );
522 0 : Point aBR( aEllipse.BottomRight() );
523 :
524 0 : if ( rFracX.GetDenominator() && rFracY.GetDenominator() )
525 : {
526 0 : SCALEPOINT( aTL, rFracX, rFracY );
527 0 : SCALEPOINT( aBR, rFracX, rFracY );
528 : }
529 :
530 0 : aEllipse = Rectangle( aTL, aBR );
531 : }
532 0 : }
533 :
534 0 : sal_Bool IMapPolygonObject::IsEqual( const IMapPolygonObject& rEqObj )
535 : {
536 0 : sal_Bool bRet = sal_False;
537 :
538 0 : if ( IMapObject::IsEqual( rEqObj ) )
539 : {
540 0 : const Polygon& rEqPoly = rEqObj.aPoly;
541 0 : const sal_uInt16 nCount = aPoly.GetSize();
542 0 : const sal_uInt16 nEqCount = rEqPoly.GetSize();
543 0 : sal_Bool bDifferent = sal_False;
544 :
545 0 : if ( nCount == nEqCount )
546 : {
547 0 : for ( sal_uInt16 i = 0; i < nCount; i++ )
548 : {
549 0 : if ( aPoly[ i ] != rEqPoly[ i ] )
550 : {
551 0 : bDifferent = sal_True;
552 0 : break;
553 : }
554 : }
555 :
556 0 : if ( !bDifferent )
557 0 : bRet = sal_True;
558 : }
559 : }
560 :
561 0 : return bRet;
562 : }
563 :
564 : /******************************************************************************
565 : |*
566 : |* Ctor
567 : |*
568 : \******************************************************************************/
569 :
570 0 : ImageMap::ImageMap( const String& rName )
571 0 : : aName( rName )
572 : {
573 0 : }
574 :
575 :
576 : /******************************************************************************
577 : |*
578 : |* Copy-Ctor
579 : |*
580 : \******************************************************************************/
581 :
582 0 : ImageMap::ImageMap( const ImageMap& rImageMap )
583 : {
584 : DBG_CTOR( ImageMap, NULL );
585 :
586 0 : size_t nCount = rImageMap.GetIMapObjectCount();
587 :
588 0 : for ( size_t i = 0; i < nCount; i++ )
589 : {
590 0 : IMapObject* pCopyObj = rImageMap.GetIMapObject( i );
591 :
592 0 : switch( pCopyObj->GetType() )
593 : {
594 : case( IMAP_OBJ_RECTANGLE ):
595 0 : maList.push_back( new IMapRectangleObject( *(IMapRectangleObject*) pCopyObj ) );
596 0 : break;
597 :
598 : case( IMAP_OBJ_CIRCLE ):
599 0 : maList.push_back( new IMapCircleObject( *(IMapCircleObject*) pCopyObj ) );
600 0 : break;
601 :
602 : case( IMAP_OBJ_POLYGON ):
603 0 : maList.push_back( new IMapPolygonObject( *(IMapPolygonObject*) pCopyObj ) );
604 0 : break;
605 :
606 : default:
607 0 : break;
608 : }
609 : }
610 :
611 0 : aName = rImageMap.aName;
612 0 : }
613 :
614 :
615 : /******************************************************************************
616 : |*
617 : |* Dtor
618 : |*
619 : \******************************************************************************/
620 :
621 0 : ImageMap::~ImageMap()
622 : {
623 : DBG_DTOR( ImageMap, NULL );
624 :
625 0 : ClearImageMap();
626 0 : }
627 :
628 :
629 : /******************************************************************************
630 : |*
631 : |* Freigabe des internen Speichers
632 : |*
633 : \******************************************************************************/
634 :
635 0 : void ImageMap::ClearImageMap()
636 : {
637 0 : for( size_t i = 0, n = maList.size(); i < n; ++i )
638 0 : delete maList[ i ];
639 0 : maList.clear();
640 :
641 0 : aName = String();
642 0 : }
643 :
644 :
645 : /******************************************************************************
646 : |*
647 : |* Zuweisungsoperator
648 : |*
649 : \******************************************************************************/
650 :
651 0 : ImageMap& ImageMap::operator=( const ImageMap& rImageMap )
652 : {
653 0 : size_t nCount = rImageMap.GetIMapObjectCount();
654 :
655 0 : ClearImageMap();
656 :
657 0 : for ( size_t i = 0; i < nCount; i++ )
658 : {
659 0 : IMapObject* pCopyObj = rImageMap.GetIMapObject( i );
660 :
661 0 : switch( pCopyObj->GetType() )
662 : {
663 : case( IMAP_OBJ_RECTANGLE ):
664 0 : maList.push_back( new IMapRectangleObject( *(IMapRectangleObject*) pCopyObj ) );
665 0 : break;
666 :
667 : case( IMAP_OBJ_CIRCLE ):
668 0 : maList.push_back( new IMapCircleObject( *(IMapCircleObject*) pCopyObj ) );
669 0 : break;
670 :
671 : case( IMAP_OBJ_POLYGON ):
672 0 : maList.push_back( new IMapPolygonObject( *(IMapPolygonObject*) pCopyObj ) );
673 0 : break;
674 :
675 : default:
676 0 : break;
677 : }
678 : }
679 :
680 0 : aName = rImageMap.aName;
681 :
682 0 : return *this;
683 : }
684 :
685 :
686 : /******************************************************************************
687 : |*
688 : |* Vergleichsoperator I
689 : |*
690 : \******************************************************************************/
691 :
692 0 : sal_Bool ImageMap::operator==( const ImageMap& rImageMap )
693 : {
694 0 : const size_t nCount = maList.size();
695 0 : const size_t nEqCount = rImageMap.GetIMapObjectCount();
696 0 : sal_Bool bRet = sal_False;
697 :
698 0 : if ( nCount == nEqCount )
699 : {
700 0 : sal_Bool bDifferent = ( aName != rImageMap.aName );
701 :
702 0 : for ( size_t i = 0; ( i < nCount ) && !bDifferent; i++ )
703 : {
704 0 : IMapObject* pObj = maList[ i ];
705 0 : IMapObject* pEqObj = rImageMap.GetIMapObject( i );
706 :
707 0 : if ( pObj->GetType() == pEqObj->GetType() )
708 : {
709 0 : switch( pObj->GetType() )
710 : {
711 : case( IMAP_OBJ_RECTANGLE ):
712 : {
713 0 : if ( !( (IMapRectangleObject*) pObj )->IsEqual( *(IMapRectangleObject*) pEqObj ) )
714 0 : bDifferent = sal_True;
715 : }
716 0 : break;
717 :
718 : case( IMAP_OBJ_CIRCLE ):
719 : {
720 0 : if ( !( (IMapCircleObject*) pObj )->IsEqual( *(IMapCircleObject*) pEqObj ) )
721 0 : bDifferent = sal_True;
722 : }
723 0 : break;
724 :
725 : case( IMAP_OBJ_POLYGON ):
726 : {
727 0 : if ( !( (IMapPolygonObject*) pObj )->IsEqual( *(IMapPolygonObject*) pEqObj ) )
728 0 : bDifferent = sal_True;
729 : }
730 0 : break;
731 :
732 : default:
733 0 : break;
734 : }
735 : }
736 : else
737 0 : bDifferent = sal_True;
738 : }
739 :
740 0 : if ( !bDifferent )
741 0 : bRet = sal_True;
742 : }
743 :
744 0 : return bRet;
745 : }
746 :
747 :
748 : /******************************************************************************
749 : |*
750 : |* Vergleichsoperator II
751 : |*
752 : \******************************************************************************/
753 :
754 0 : sal_Bool ImageMap::operator!=( const ImageMap& rImageMap )
755 : {
756 0 : return !( *this == rImageMap );
757 : }
758 :
759 :
760 : /******************************************************************************
761 : |*
762 : |* Freigabe des internen Speichers
763 : |*
764 : \******************************************************************************/
765 :
766 0 : sal_uInt16 ImageMap::GetVersion() const
767 : {
768 0 : return IMAGE_MAP_VERSION;
769 : }
770 :
771 :
772 : /******************************************************************************
773 : |*
774 : |* Einfuegen eines neuen Objekts
775 : |*
776 : \******************************************************************************/
777 :
778 0 : void ImageMap::InsertIMapObject( const IMapObject& rIMapObject )
779 : {
780 0 : switch( rIMapObject.GetType() )
781 : {
782 : case( IMAP_OBJ_RECTANGLE ):
783 0 : maList.push_back( new IMapRectangleObject( (IMapRectangleObject&) rIMapObject ) );
784 0 : break;
785 :
786 : case( IMAP_OBJ_CIRCLE ):
787 0 : maList.push_back( new IMapCircleObject( (IMapCircleObject&) rIMapObject ) );
788 0 : break;
789 :
790 : case( IMAP_OBJ_POLYGON ):
791 0 : maList.push_back( new IMapPolygonObject( (IMapPolygonObject&) rIMapObject ) );
792 0 : break;
793 :
794 : default:
795 0 : break;
796 : }
797 0 : }
798 :
799 :
800 : /******************************************************************************
801 : |*
802 : |* Hit-Test
803 : |*
804 : \******************************************************************************/
805 :
806 0 : IMapObject* ImageMap::GetHitIMapObject( const Size& rTotalSize,
807 : const Size& rDisplaySize,
808 : const Point& rRelHitPoint,
809 : sal_uLong nFlags )
810 : {
811 0 : Point aRelPoint( rTotalSize.Width() * rRelHitPoint.X() / rDisplaySize.Width(),
812 0 : rTotalSize.Height() * rRelHitPoint.Y() / rDisplaySize.Height() );
813 :
814 : // Falls Flags zur Spiegelung etc. angegeben sind, wird
815 : // der zu pruefende Punkt vor der Pruefung entspr. transformiert
816 0 : if ( nFlags )
817 : {
818 0 : if ( nFlags & IMAP_MIRROR_HORZ )
819 0 : aRelPoint.X() = rTotalSize.Width() - aRelPoint.X();
820 :
821 0 : if ( nFlags & IMAP_MIRROR_VERT )
822 0 : aRelPoint.Y() = rTotalSize.Height() - aRelPoint.Y();
823 : }
824 :
825 : // Alle Objekte durchlaufen und HitTest ausfuehren
826 0 : IMapObject* pObj = NULL;
827 0 : for( size_t i = 0, n = maList.size(); i < n; ++i ) {
828 0 : if ( maList[ i ]->IsHit( aRelPoint ) ) {
829 0 : pObj = maList[ i ];
830 0 : break;
831 : }
832 : }
833 :
834 0 : return( pObj ? ( pObj->IsActive() ? pObj : NULL ) : NULL );
835 : }
836 :
837 0 : void ImageMap::Scale( const Fraction& rFracX, const Fraction& rFracY )
838 : {
839 0 : size_t nCount = maList.size();
840 :
841 0 : for ( size_t i = 0; i < nCount; i++ )
842 : {
843 0 : IMapObject* pObj = maList[ i ];
844 :
845 0 : switch( pObj->GetType() )
846 : {
847 : case( IMAP_OBJ_RECTANGLE ):
848 0 : ( (IMapRectangleObject*) pObj )->Scale( rFracX, rFracY );
849 0 : break;
850 :
851 : case( IMAP_OBJ_CIRCLE ):
852 0 : ( (IMapCircleObject*) pObj )->Scale( rFracX, rFracY );
853 0 : break;
854 :
855 : case( IMAP_OBJ_POLYGON ):
856 0 : ( (IMapPolygonObject*) pObj )->Scale( rFracX, rFracY );
857 0 : break;
858 :
859 : default:
860 0 : break;
861 : }
862 : }
863 0 : }
864 :
865 :
866 : /******************************************************************************
867 : |*
868 : |* Objekte nacheinander wegschreiben
869 : |*
870 : \******************************************************************************/
871 :
872 0 : void ImageMap::ImpWriteImageMap( SvStream& rOStm, const String& rBaseURL ) const
873 : {
874 : IMapObject* pObj;
875 0 : size_t nCount = maList.size();
876 :
877 0 : for ( size_t i = 0; i < nCount; i++ )
878 : {
879 0 : pObj = maList[ i ];
880 0 : pObj->Write( rOStm, rBaseURL );
881 : }
882 0 : }
883 :
884 :
885 : /******************************************************************************
886 : |*
887 : |* Objekte nacheinander lesen
888 : |*
889 : \******************************************************************************/
890 :
891 0 : void ImageMap::ImpReadImageMap( SvStream& rIStm, size_t nCount, const String& rBaseURL )
892 : {
893 : // neue Objekte einlesen
894 0 : for ( size_t i = 0; i < nCount; i++ )
895 : {
896 : sal_uInt16 nType;
897 :
898 0 : rIStm >> nType;
899 0 : rIStm.SeekRel( -2 );
900 :
901 0 : switch( nType )
902 : {
903 : case ( IMAP_OBJ_RECTANGLE ):
904 : {
905 0 : IMapRectangleObject* pObj = new IMapRectangleObject;
906 0 : pObj->Read( rIStm, rBaseURL );
907 0 : maList.push_back( pObj );
908 : }
909 0 : break;
910 :
911 : case ( IMAP_OBJ_CIRCLE ):
912 : {
913 0 : IMapCircleObject* pObj = new IMapCircleObject;
914 0 : pObj->Read( rIStm, rBaseURL );
915 0 : maList.push_back( pObj );
916 : }
917 0 : break;
918 :
919 : case ( IMAP_OBJ_POLYGON ):
920 : {
921 0 : IMapPolygonObject* pObj = new IMapPolygonObject;
922 0 : pObj->Read( rIStm, rBaseURL );
923 0 : maList.push_back( pObj );
924 : }
925 0 : break;
926 :
927 : default:
928 0 : break;
929 : }
930 : }
931 0 : }
932 :
933 :
934 : /******************************************************************************
935 : |*
936 : |* Binaer speichern
937 : |*
938 : \******************************************************************************/
939 :
940 0 : void ImageMap::Write( SvStream& rOStm, const String& rBaseURL ) const
941 : {
942 : IMapCompat* pCompat;
943 0 : String aImageName( GetName() );
944 0 : sal_uInt16 nOldFormat = rOStm.GetNumberFormatInt();
945 0 : sal_uInt16 nCount = (sal_uInt16) GetIMapObjectCount();
946 0 : const rtl_TextEncoding eEncoding = osl_getThreadTextEncoding(); //vomit!
947 :
948 0 : rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
949 :
950 : // MagicCode schreiben
951 0 : rOStm << IMAPMAGIC;
952 0 : rOStm << GetVersion();
953 0 : write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rOStm, aImageName, eEncoding);
954 0 : write_lenPrefixed_uInt8s_FromOString<sal_uInt16>(rOStm, rtl::OString()); //dummy
955 0 : rOStm << nCount;
956 0 : write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rOStm, aImageName, eEncoding);
957 :
958 0 : pCompat = new IMapCompat( rOStm, STREAM_WRITE );
959 :
960 : // hier kann in neueren Versionen eingefuegt werden
961 :
962 0 : delete pCompat;
963 :
964 0 : ImpWriteImageMap( rOStm, rBaseURL );
965 :
966 0 : rOStm.SetNumberFormatInt( nOldFormat );
967 0 : }
968 :
969 :
970 : /******************************************************************************
971 : |*
972 : |* Binaer laden
973 : |*
974 : \******************************************************************************/
975 :
976 0 : void ImageMap::Read( SvStream& rIStm, const String& rBaseURL )
977 : {
978 : char cMagic[6];
979 0 : sal_uInt16 nOldFormat = rIStm.GetNumberFormatInt();
980 : sal_uInt16 nCount;
981 :
982 0 : rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
983 0 : rIStm.Read( cMagic, sizeof( cMagic ) );
984 :
985 0 : if ( !memcmp( cMagic, IMAPMAGIC, sizeof( cMagic ) ) )
986 : {
987 : IMapCompat* pCompat;
988 :
989 : // alten Inhalt loeschen
990 0 : ClearImageMap();
991 :
992 : // Version ueberlesen wir
993 0 : rIStm.SeekRel( 2 );
994 :
995 0 : aName = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(rIStm, osl_getThreadTextEncoding());
996 0 : read_lenPrefixed_uInt8s_ToOString<sal_uInt16>(rIStm); // Dummy
997 0 : rIStm >> nCount;
998 0 : read_lenPrefixed_uInt8s_ToOString<sal_uInt16>(rIStm); // Dummy
999 :
1000 0 : pCompat = new IMapCompat( rIStm, STREAM_READ );
1001 :
1002 : // hier kann in neueren Versionen gelesen werden
1003 :
1004 0 : delete pCompat;
1005 0 : ImpReadImageMap( rIStm, nCount, rBaseURL );
1006 :
1007 : }
1008 : else
1009 0 : rIStm.SetError( SVSTREAM_GENERALERROR );
1010 :
1011 0 : rIStm.SetNumberFormatInt( nOldFormat );
1012 0 : }
1013 :
1014 :
1015 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|