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