Bump version to 5.0-14
[LibreOffice.git] / svtools / source / misc / imap.cxx
blobd005651a4213d09d5d59d68b232db2d1813fbad6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <tools/urlobj.hxx>
22 #include <tools/fract.hxx>
23 #include <vcl/svapp.hxx>
24 #include <vcl/mapmod.hxx>
25 #include <vcl/window.hxx>
26 #include <o3tl/numeric.hxx>
27 #include <svl/urihelper.hxx>
28 #include <svtools/imap.hxx>
29 #include <svtools/imapobj.hxx>
30 #include <svtools/imapcirc.hxx>
31 #include <svtools/imaprect.hxx>
32 #include <svtools/imappoly.hxx>
34 #include <string.h>
35 #include <math.h>
36 #include <boost/scoped_ptr.hpp>
39 #define SCALEPOINT(aPT,aFracX,aFracY) (aPT).X()=((aPT).X()*(aFracX).GetNumerator())/(aFracX).GetDenominator(); \
40 (aPT).Y()=((aPT).Y()*(aFracY).GetNumerator())/(aFracY).GetDenominator();
43 /******************************************************************************/
45 sal_uInt16 IMapObject::nActualTextEncoding = (sal_uInt16) RTL_TEXTENCODING_DONTKNOW;
47 /******************************************************************************/
50 IMapObject::IMapObject()
51 : bActive( false )
52 , nReadVersion( 0 )
56 IMapObject::IMapObject( const OUString& rURL, const OUString& rAltText, const OUString& rDesc,
57 const OUString& rTarget, const OUString& rName, bool bURLActive )
58 : aURL( rURL )
59 , aAltText( rAltText )
60 , aDesc( rDesc )
61 , aTarget( rTarget )
62 , aName( rName )
63 , bActive( bURLActive )
64 , nReadVersion( 0 )
69 void IMapObject::Write( SvStream& rOStm, const OUString& rBaseURL ) const
71 const rtl_TextEncoding eEncoding = osl_getThreadTextEncoding();
73 rOStm.WriteUInt16( GetType() );
74 rOStm.WriteUInt16( GetVersion() );
75 rOStm.WriteUInt16( eEncoding );
77 const OString aRelURL = OUStringToOString(
78 URIHelper::simpleNormalizedMakeRelative(rBaseURL, aURL), eEncoding);
79 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStm, aRelURL);
80 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aAltText, eEncoding);
81 rOStm.WriteBool( bActive );
82 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aTarget, eEncoding);
84 boost::scoped_ptr<IMapCompat> pCompat(new IMapCompat( rOStm, StreamMode::WRITE ));
86 WriteIMapObject( rOStm );
87 aEventList.Write( rOStm ); // V4
88 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aName, eEncoding); // V5
92 /******************************************************************************
94 |* Binary import
96 \******************************************************************************/
98 void IMapObject::Read( SvStream& rIStm, const OUString& rBaseURL )
100 rtl_TextEncoding nTextEncoding;
102 // read on type and version
103 rIStm.SeekRel( 2 );
104 rIStm.ReadUInt16( nReadVersion );
105 rIStm.ReadUInt16( nTextEncoding );
106 aURL = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStm, nTextEncoding);
107 aAltText = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStm, nTextEncoding);
108 rIStm.ReadCharAsBool( bActive );
109 aTarget = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStm, nTextEncoding);
111 // make URL absolute
112 aURL = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), aURL, URIHelper::GetMaybeFileHdl(), true, false, INetURLObject::WAS_ENCODED, INetURLObject::DECODE_UNAMBIGUOUS );
113 boost::scoped_ptr<IMapCompat> pCompat(new IMapCompat( rIStm, StreamMode::READ ));
115 ReadIMapObject( rIStm );
117 // from version 4 onwards we read a eventlist
118 if ( nReadVersion >= 0x0004 )
120 aEventList.Read(rIStm);
122 // from version 5 onwards an objectname could be available
123 if ( nReadVersion >= 0x0005 )
124 aName = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStm, nTextEncoding);
128 bool IMapObject::IsEqual( const IMapObject& rEqObj )
130 return ( ( aURL == rEqObj.aURL ) &&
131 ( aAltText == rEqObj.aAltText ) &&
132 ( aDesc == rEqObj.aDesc ) &&
133 ( aTarget == rEqObj.aTarget ) &&
134 ( aName == rEqObj.aName ) &&
135 ( bActive == rEqObj.bActive ) );
138 IMapRectangleObject::IMapRectangleObject( const Rectangle& rRect,
139 const OUString& rURL,
140 const OUString& rAltText,
141 const OUString& rDesc,
142 const OUString& rTarget,
143 const OUString& rName,
144 bool bURLActive,
145 bool bPixelCoords ) :
146 IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive )
148 ImpConstruct( rRect, bPixelCoords );
151 void IMapRectangleObject::ImpConstruct( const Rectangle& rRect, bool bPixel )
153 if ( bPixel )
154 aRect = Application::GetDefaultDevice()->PixelToLogic( rRect, MapMode( MAP_100TH_MM ) );
155 else
156 aRect = rRect;
160 /******************************************************************************
162 |* Binary export
164 \******************************************************************************/
166 void IMapRectangleObject::WriteIMapObject( SvStream& rOStm ) const
168 WriteRectangle( rOStm, aRect );
172 /******************************************************************************
174 |* Binary import
176 \******************************************************************************/
178 void IMapRectangleObject::ReadIMapObject( SvStream& rIStm )
180 ReadRectangle( rIStm, aRect );
184 /******************************************************************************
186 |* return type
188 \******************************************************************************/
190 sal_uInt16 IMapRectangleObject::GetType() const
192 return IMAP_OBJ_RECTANGLE;
196 /******************************************************************************
198 |* Hit test
200 \******************************************************************************/
202 bool IMapRectangleObject::IsHit( const Point& rPoint ) const
204 return aRect.IsInside( rPoint );
207 Rectangle IMapRectangleObject::GetRectangle( bool bPixelCoords ) const
209 Rectangle aNewRect;
211 if ( bPixelCoords )
212 aNewRect = Application::GetDefaultDevice()->LogicToPixel( aRect, MapMode( MAP_100TH_MM ) );
213 else
214 aNewRect = aRect;
216 return aNewRect;
219 void IMapRectangleObject::Scale( const Fraction& rFracX, const Fraction& rFracY )
221 Point aTL( aRect.TopLeft() );
222 Point aBR( aRect.BottomRight() );
224 if ( rFracX.GetDenominator() && rFracY.GetDenominator() )
226 SCALEPOINT( aTL, rFracX, rFracY );
227 SCALEPOINT( aBR, rFracX, rFracY );
230 aRect = Rectangle( aTL, aBR );
233 bool IMapRectangleObject::IsEqual( const IMapRectangleObject& rEqObj )
235 return ( IMapObject::IsEqual( rEqObj ) && ( aRect == rEqObj.aRect ) );
238 IMapCircleObject::IMapCircleObject( const Point& rCenter, sal_uLong nCircleRadius,
239 const OUString& rURL,
240 const OUString& rAltText,
241 const OUString& rDesc,
242 const OUString& rTarget,
243 const OUString& rName,
244 bool bURLActive,
245 bool bPixelCoords ) :
246 IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive )
248 ImpConstruct( rCenter, nCircleRadius, bPixelCoords );
251 void IMapCircleObject::ImpConstruct( const Point& rCenter, sal_uLong nRad, bool bPixel )
253 if ( bPixel )
255 MapMode aMap100( MAP_100TH_MM );
257 aCenter = Application::GetDefaultDevice()->PixelToLogic( rCenter, aMap100 );
258 nRadius = Application::GetDefaultDevice()->PixelToLogic( Size( nRad, 0 ), aMap100 ).Width();
260 else
262 aCenter = rCenter;
263 nRadius = nRad;
268 /******************************************************************************
270 |* Binary export
272 \******************************************************************************/
274 void IMapCircleObject::WriteIMapObject( SvStream& rOStm ) const
276 sal_uInt32 nTmp = nRadius;
278 WritePair( rOStm, aCenter );
279 rOStm.WriteUInt32( nTmp );
283 /******************************************************************************
285 |* Binary import
287 \******************************************************************************/
289 void IMapCircleObject::ReadIMapObject( SvStream& rIStm )
291 sal_uInt32 nTmp;
293 ReadPair( rIStm, aCenter );
294 rIStm.ReadUInt32( nTmp );
296 nRadius = nTmp;
300 /******************************************************************************
302 |* return type
304 \******************************************************************************/
306 sal_uInt16 IMapCircleObject::GetType() const
308 return IMAP_OBJ_CIRCLE;
312 /******************************************************************************
314 |* Hit-Test
316 \******************************************************************************/
318 bool IMapCircleObject::IsHit( const Point& rPoint ) const
320 const Point aPoint( aCenter - rPoint );
321 bool bRet = false;
323 if ( (sal_Int32) sqrt( (double) aPoint.X() * aPoint.X() +
324 aPoint.Y() * aPoint.Y() ) <= nRadius )
326 bRet = true;
329 return bRet;
332 Point IMapCircleObject::GetCenter( bool bPixelCoords ) const
334 Point aNewPoint;
336 if ( bPixelCoords )
337 aNewPoint = Application::GetDefaultDevice()->LogicToPixel( aCenter, MapMode( MAP_100TH_MM ) );
338 else
339 aNewPoint = aCenter;
341 return aNewPoint;
344 sal_uLong IMapCircleObject::GetRadius( bool bPixelCoords ) const
346 sal_uLong nNewRadius;
348 if ( bPixelCoords )
349 nNewRadius = Application::GetDefaultDevice()->LogicToPixel( Size( nRadius, 0 ), MapMode( MAP_100TH_MM ) ).Width();
350 else
351 nNewRadius = nRadius;
353 return nNewRadius;
356 Rectangle IMapCircleObject::GetBoundRect() const
358 long nWidth = nRadius << 1;
360 return Rectangle( Point( aCenter.X() - nRadius, aCenter.Y() - nRadius ),
361 Size( nWidth, nWidth ) );
364 void IMapCircleObject::Scale( const Fraction& rFracX, const Fraction& rFracY )
366 Fraction aAverage( rFracX );
368 aAverage += rFracY;
369 aAverage *= Fraction( 1, 2 );
371 if ( rFracX.GetDenominator() && rFracY.GetDenominator() )
373 SCALEPOINT( aCenter, rFracX, rFracY );
376 if (!aAverage.GetDenominator())
377 throw o3tl::divide_by_zero();
379 nRadius = ( nRadius * aAverage.GetNumerator() ) / aAverage.GetDenominator();
382 bool IMapCircleObject::IsEqual( const IMapCircleObject& rEqObj )
384 return ( IMapObject::IsEqual( rEqObj ) &&
385 ( aCenter == rEqObj.aCenter ) &&
386 ( nRadius == rEqObj.nRadius ) );
389 IMapPolygonObject::IMapPolygonObject( const Polygon& rPoly,
390 const OUString& rURL,
391 const OUString& rAltText,
392 const OUString& rDesc,
393 const OUString& rTarget,
394 const OUString& rName,
395 bool bURLActive,
396 bool bPixelCoords ) :
397 IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive ),
398 bEllipse ( false )
400 ImpConstruct( rPoly, bPixelCoords );
403 void IMapPolygonObject::ImpConstruct( const Polygon& rPoly, bool bPixel )
405 if ( bPixel )
406 aPoly = Application::GetDefaultDevice()->PixelToLogic( rPoly, MapMode( MAP_100TH_MM ) );
407 else
408 aPoly = rPoly;
412 /******************************************************************************
414 |* Binary export
416 \******************************************************************************/
418 void IMapPolygonObject::WriteIMapObject( SvStream& rOStm ) const
420 WritePolygon( rOStm, aPoly );
421 rOStm.WriteBool( bEllipse ); // >= Version 2
422 WriteRectangle( rOStm, aEllipse ); // >= Version 2
426 /******************************************************************************
428 |* Binary import
430 \******************************************************************************/
432 void IMapPolygonObject::ReadIMapObject( SvStream& rIStm )
434 ReadPolygon( rIStm, aPoly );
436 // Version >= 2 has additional ellipses information
437 if ( nReadVersion >= 2 )
439 rIStm.ReadCharAsBool( bEllipse );
440 ReadRectangle( rIStm, aEllipse );
445 /******************************************************************************
447 |* return type
449 \******************************************************************************/
451 sal_uInt16 IMapPolygonObject::GetType() const
453 return IMAP_OBJ_POLYGON;
457 /******************************************************************************
459 |* hit test
461 \******************************************************************************/
463 bool IMapPolygonObject::IsHit( const Point& rPoint ) const
465 return aPoly.IsInside( rPoint );
468 Polygon IMapPolygonObject::GetPolygon( bool bPixelCoords ) const
470 Polygon aNewPoly;
472 if ( bPixelCoords )
473 aNewPoly = Application::GetDefaultDevice()->LogicToPixel( aPoly, MapMode( MAP_100TH_MM ) );
474 else
475 aNewPoly = aPoly;
477 return aNewPoly;
480 void IMapPolygonObject::SetExtraEllipse( const Rectangle& rEllipse )
482 if ( aPoly.GetSize() )
484 bEllipse = true;
485 aEllipse = rEllipse;
489 void IMapPolygonObject::Scale( const Fraction& rFracX, const Fraction& rFracY )
491 sal_uInt16 nCount = aPoly.GetSize();
493 for ( sal_uInt16 i = 0; i < nCount; i++ )
495 Point aScaledPt( aPoly[ i ] );
497 if ( rFracX.GetDenominator() && rFracY.GetDenominator() )
499 SCALEPOINT( aScaledPt, rFracX, rFracY );
502 aPoly[ i ] = aScaledPt;
505 if ( bEllipse )
507 Point aTL( aEllipse.TopLeft() );
508 Point aBR( aEllipse.BottomRight() );
510 if ( rFracX.GetDenominator() && rFracY.GetDenominator() )
512 SCALEPOINT( aTL, rFracX, rFracY );
513 SCALEPOINT( aBR, rFracX, rFracY );
516 aEllipse = Rectangle( aTL, aBR );
520 bool IMapPolygonObject::IsEqual( const IMapPolygonObject& rEqObj )
522 bool bRet = false;
524 if ( IMapObject::IsEqual( rEqObj ) )
526 const Polygon& rEqPoly = rEqObj.aPoly;
527 const sal_uInt16 nCount = aPoly.GetSize();
528 const sal_uInt16 nEqCount = rEqPoly.GetSize();
530 if ( nCount == nEqCount )
532 bool bDifferent = false;
534 for ( sal_uInt16 i = 0; i < nCount; i++ )
536 if ( aPoly[ i ] != rEqPoly[ i ] )
538 bDifferent = true;
539 break;
543 if ( !bDifferent )
544 bRet = true;
548 return bRet;
551 /******************************************************************************
553 |* Ctor
555 \******************************************************************************/
557 ImageMap::ImageMap( const OUString& rName )
558 : aName( rName )
563 /******************************************************************************
565 |* Copy-Ctor
567 \******************************************************************************/
569 ImageMap::ImageMap( const ImageMap& rImageMap )
572 size_t nCount = rImageMap.GetIMapObjectCount();
574 for ( size_t i = 0; i < nCount; i++ )
576 IMapObject* pCopyObj = rImageMap.GetIMapObject( i );
578 switch( pCopyObj->GetType() )
580 case( IMAP_OBJ_RECTANGLE ):
581 maList.push_back( new IMapRectangleObject( *static_cast<IMapRectangleObject*>( pCopyObj ) ) );
582 break;
584 case( IMAP_OBJ_CIRCLE ):
585 maList.push_back( new IMapCircleObject( *static_cast<IMapCircleObject*>( pCopyObj ) ) );
586 break;
588 case( IMAP_OBJ_POLYGON ):
589 maList.push_back( new IMapPolygonObject( *static_cast<IMapPolygonObject*>( pCopyObj ) ) );
590 break;
592 default:
593 break;
597 aName = rImageMap.aName;
601 /******************************************************************************
603 |* Dtor
605 \******************************************************************************/
607 ImageMap::~ImageMap()
610 ClearImageMap();
614 /******************************************************************************
616 |* release internal memory
618 \******************************************************************************/
620 void ImageMap::ClearImageMap()
622 for( size_t i = 0, n = maList.size(); i < n; ++i )
623 delete maList[ i ];
624 maList.clear();
626 aName.clear();
630 /******************************************************************************
632 |* assignment operator
634 \******************************************************************************/
636 ImageMap& ImageMap::operator=( const ImageMap& rImageMap )
638 size_t nCount = rImageMap.GetIMapObjectCount();
640 ClearImageMap();
642 for ( size_t i = 0; i < nCount; i++ )
644 IMapObject* pCopyObj = rImageMap.GetIMapObject( i );
646 switch( pCopyObj->GetType() )
648 case( IMAP_OBJ_RECTANGLE ):
649 maList.push_back( new IMapRectangleObject( *static_cast<IMapRectangleObject*>(pCopyObj) ) );
650 break;
652 case( IMAP_OBJ_CIRCLE ):
653 maList.push_back( new IMapCircleObject( *static_cast<IMapCircleObject*>(pCopyObj) ) );
654 break;
656 case( IMAP_OBJ_POLYGON ):
657 maList.push_back( new IMapPolygonObject( *static_cast<IMapPolygonObject*>(pCopyObj) ) );
658 break;
660 default:
661 break;
665 aName = rImageMap.aName;
667 return *this;
671 /******************************************************************************
673 |* compare operator I
675 \******************************************************************************/
677 bool ImageMap::operator==( const ImageMap& rImageMap )
679 const size_t nCount = maList.size();
680 const size_t nEqCount = rImageMap.GetIMapObjectCount();
681 bool bRet = false;
683 if ( nCount == nEqCount )
685 bool bDifferent = ( aName != rImageMap.aName );
687 for ( size_t i = 0; ( i < nCount ) && !bDifferent; i++ )
689 IMapObject* pObj = maList[ i ];
690 IMapObject* pEqObj = rImageMap.GetIMapObject( i );
692 if ( pObj->GetType() == pEqObj->GetType() )
694 switch( pObj->GetType() )
696 case( IMAP_OBJ_RECTANGLE ):
698 if ( !( static_cast<IMapRectangleObject*>(pObj) )->IsEqual( *static_cast<IMapRectangleObject*>(pEqObj) ) )
699 bDifferent = true;
701 break;
703 case( IMAP_OBJ_CIRCLE ):
705 if ( !( static_cast<IMapCircleObject*>(pObj) )->IsEqual( *static_cast<IMapCircleObject*>(pEqObj) ) )
706 bDifferent = true;
708 break;
710 case( IMAP_OBJ_POLYGON ):
712 if ( !( static_cast<IMapPolygonObject*>(pObj) )->IsEqual( *static_cast<IMapPolygonObject*>(pEqObj) ) )
713 bDifferent = true;
715 break;
717 default:
718 break;
721 else
722 bDifferent = true;
725 if ( !bDifferent )
726 bRet = true;
729 return bRet;
733 /******************************************************************************
735 |* compare operator II
737 \******************************************************************************/
739 bool ImageMap::operator!=( const ImageMap& rImageMap )
741 return !( *this == rImageMap );
745 /******************************************************************************
747 |* insert new object
749 \******************************************************************************/
751 void ImageMap::InsertIMapObject( const IMapObject& rIMapObject )
753 switch( rIMapObject.GetType() )
755 case( IMAP_OBJ_RECTANGLE ):
756 maList.push_back( new IMapRectangleObject( static_cast<const IMapRectangleObject&>( rIMapObject ) ) );
757 break;
759 case( IMAP_OBJ_CIRCLE ):
760 maList.push_back( new IMapCircleObject( static_cast<const IMapCircleObject&>( rIMapObject ) ) );
761 break;
763 case( IMAP_OBJ_POLYGON ):
764 maList.push_back( new IMapPolygonObject( static_cast<const IMapPolygonObject&>( rIMapObject ) ) );
765 break;
767 default:
768 break;
773 /******************************************************************************
775 |* hit test
777 \******************************************************************************/
779 IMapObject* ImageMap::GetHitIMapObject( const Size& rTotalSize,
780 const Size& rDisplaySize,
781 const Point& rRelHitPoint,
782 sal_uLong nFlags )
784 Point aRelPoint( rTotalSize.Width() * rRelHitPoint.X() / rDisplaySize.Width(),
785 rTotalSize.Height() * rRelHitPoint.Y() / rDisplaySize.Height() );
787 // transform point to check before checking if flags to mirror etc. are set,
788 if ( nFlags )
790 if ( nFlags & IMAP_MIRROR_HORZ )
791 aRelPoint.X() = rTotalSize.Width() - aRelPoint.X();
793 if ( nFlags & IMAP_MIRROR_VERT )
794 aRelPoint.Y() = rTotalSize.Height() - aRelPoint.Y();
797 // walk over all objects and execute HitTest
798 IMapObject* pObj = NULL;
799 for( size_t i = 0, n = maList.size(); i < n; ++i ) {
800 if ( maList[ i ]->IsHit( aRelPoint ) ) {
801 pObj = maList[ i ];
802 break;
806 return( pObj ? ( pObj->IsActive() ? pObj : NULL ) : NULL );
809 void ImageMap::Scale( const Fraction& rFracX, const Fraction& rFracY )
811 size_t nCount = maList.size();
813 for ( size_t i = 0; i < nCount; i++ )
815 IMapObject* pObj = maList[ i ];
817 switch( pObj->GetType() )
819 case( IMAP_OBJ_RECTANGLE ):
820 static_cast<IMapRectangleObject*>( pObj )->Scale( rFracX, rFracY );
821 break;
823 case( IMAP_OBJ_CIRCLE ):
824 static_cast<IMapCircleObject*>( pObj )->Scale( rFracX, rFracY );
825 break;
827 case( IMAP_OBJ_POLYGON ):
828 static_cast<IMapPolygonObject*>( pObj )->Scale( rFracX, rFracY );
829 break;
831 default:
832 break;
838 /******************************************************************************
840 |* sequentially write objects
842 \******************************************************************************/
844 void ImageMap::ImpWriteImageMap( SvStream& rOStm, const OUString& rBaseURL ) const
846 size_t nCount = maList.size();
848 for ( size_t i = 0; i < nCount; i++ )
850 IMapObject* pObj = maList[ i ];
851 pObj->Write( rOStm, rBaseURL );
856 /******************************************************************************
858 |* sequentially read objects
860 \******************************************************************************/
862 void ImageMap::ImpReadImageMap( SvStream& rIStm, size_t nCount, const OUString& rBaseURL )
864 const size_t nMinRecordSize = 12; //circle, three 32bit numbers
865 const size_t nMaxRecords = rIStm.remainingSize() / nMinRecordSize;
867 if (nCount > nMaxRecords)
869 SAL_WARN("svtools.misc", "Parsing error: " << nMaxRecords << " max possible entries, but " <<
870 nCount << " claimed, truncating");
871 nCount = nMaxRecords;
874 // neue Objekte einlesen
875 for (size_t i = 0; i < nCount; ++i)
877 sal_uInt16 nType;
879 rIStm.ReadUInt16( nType );
880 rIStm.SeekRel( -2 );
882 switch( nType )
884 case ( IMAP_OBJ_RECTANGLE ):
886 IMapRectangleObject* pObj = new IMapRectangleObject;
887 pObj->Read( rIStm, rBaseURL );
888 maList.push_back( pObj );
890 break;
892 case ( IMAP_OBJ_CIRCLE ):
894 IMapCircleObject* pObj = new IMapCircleObject;
895 pObj->Read( rIStm, rBaseURL );
896 maList.push_back( pObj );
898 break;
900 case ( IMAP_OBJ_POLYGON ):
902 IMapPolygonObject* pObj = new IMapPolygonObject;
903 pObj->Read( rIStm, rBaseURL );
904 maList.push_back( pObj );
906 break;
908 default:
909 break;
915 /******************************************************************************
917 |* store binary
919 \******************************************************************************/
921 void ImageMap::Write( SvStream& rOStm, const OUString& rBaseURL ) const
923 IMapCompat* pCompat;
924 OUString aImageName( GetName() );
925 SvStreamEndian nOldFormat = rOStm.GetEndian();
926 sal_uInt16 nCount = (sal_uInt16) GetIMapObjectCount();
927 const rtl_TextEncoding eEncoding = osl_getThreadTextEncoding(); //vomit!
929 rOStm.SetEndian( SvStreamEndian::LITTLE );
931 // write MagicCode
932 rOStm.WriteCharPtr( IMAPMAGIC );
933 rOStm.WriteUInt16( GetVersion() );
934 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aImageName, eEncoding);
935 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStm, OString()); //dummy
936 rOStm.WriteUInt16( nCount );
937 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aImageName, eEncoding);
939 pCompat = new IMapCompat( rOStm, StreamMode::WRITE );
941 // here one can insert in newer versions
943 delete pCompat;
945 ImpWriteImageMap( rOStm, rBaseURL );
947 rOStm.SetEndian( nOldFormat );
951 /******************************************************************************
953 |* load binary
955 \******************************************************************************/
957 void ImageMap::Read( SvStream& rIStm, const OUString& rBaseURL )
959 char cMagic[6];
960 SvStreamEndian nOldFormat = rIStm.GetEndian();
961 sal_uInt16 nCount;
963 rIStm.SetEndian( SvStreamEndian::LITTLE );
964 rIStm.Read( cMagic, sizeof( cMagic ) );
966 if ( !memcmp( cMagic, IMAPMAGIC, sizeof( cMagic ) ) )
968 IMapCompat* pCompat;
970 // delete old content
971 ClearImageMap();
973 // read on version
974 rIStm.SeekRel( 2 );
976 aName = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStm, osl_getThreadTextEncoding());
977 read_uInt16_lenPrefixed_uInt8s_ToOString(rIStm); // Dummy
978 rIStm.ReadUInt16( nCount );
979 read_uInt16_lenPrefixed_uInt8s_ToOString(rIStm); // Dummy
981 pCompat = new IMapCompat( rIStm, StreamMode::READ );
983 // here one can read in newer versions
985 delete pCompat;
986 ImpReadImageMap( rIStm, nCount, rBaseURL );
989 else
990 rIStm.SetError( SVSTREAM_GENERALERROR );
992 rIStm.SetEndian( nOldFormat );
996 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */