bump product version to 6.4.0.3
[LibreOffice.git] / vcl / source / treelist / imap.cxx
blob536c9c819a8f75aee06acfb2e0e5482d31182892
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 <tools/GenericTypeSerializer.hxx>
24 #include <vcl/outdev.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/mapmod.hxx>
27 #include <o3tl/numeric.hxx>
28 #include <svl/urihelper.hxx>
29 #include <vcl/imap.hxx>
30 #include <vcl/imapobj.hxx>
31 #include <vcl/imapcirc.hxx>
32 #include <vcl/imaprect.hxx>
33 #include <vcl/imappoly.hxx>
35 #include <string.h>
36 #include <math.h>
37 #include <memory>
38 #include <sal/log.hxx>
41 #define SCALEPOINT(aPT,aFracX,aFracY) (aPT).setX(long((aPT).X()*aFracX)); \
42 (aPT).setY(long((aPT).Y()*aFracY));
45 /******************************************************************************/
48 IMapObject::IMapObject()
49 : bActive( false )
50 , nReadVersion( 0 )
54 IMapObject::IMapObject( const OUString& rURL, const OUString& rAltText, const OUString& rDesc,
55 const OUString& rTarget, const OUString& rName, bool bURLActive )
56 : aURL( rURL )
57 , aAltText( rAltText )
58 , aDesc( rDesc )
59 , aTarget( rTarget )
60 , aName( rName )
61 , bActive( bURLActive )
62 , nReadVersion( 0 )
67 void IMapObject::Write( SvStream& rOStm ) const
69 const rtl_TextEncoding eEncoding = osl_getThreadTextEncoding();
71 rOStm.WriteUInt16( GetType() );
72 rOStm.WriteUInt16( IMAP_OBJ_VERSION );
73 rOStm.WriteUInt16( eEncoding );
75 const OString aRelURL = OUStringToOString(
76 URIHelper::simpleNormalizedMakeRelative("", aURL), eEncoding);
77 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStm, aRelURL);
78 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aAltText, eEncoding);
79 rOStm.WriteBool( bActive );
80 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aTarget, eEncoding);
82 std::unique_ptr<IMapCompat> pCompat(new IMapCompat( rOStm, StreamMode::WRITE ));
84 WriteIMapObject( rOStm );
85 aEventList.Write( rOStm ); // V4
86 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aName, eEncoding); // V5
90 /******************************************************************************
92 |* Binary import
94 \******************************************************************************/
96 void IMapObject::Read( SvStream& rIStm )
98 rtl_TextEncoding nTextEncoding;
100 // read on type and version
101 rIStm.SeekRel( 2 );
102 rIStm.ReadUInt16( nReadVersion );
103 rIStm.ReadUInt16( nTextEncoding );
104 aURL = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStm, nTextEncoding);
105 aAltText = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStm, nTextEncoding);
106 rIStm.ReadCharAsBool( bActive );
107 aTarget = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStm, nTextEncoding);
109 // make URL absolute
110 aURL = URIHelper::SmartRel2Abs( INetURLObject(""), aURL, URIHelper::GetMaybeFileHdl(), true, false, INetURLObject::EncodeMechanism::WasEncoded, INetURLObject::DecodeMechanism::Unambiguous );
111 std::unique_ptr<IMapCompat> pCompat(new IMapCompat( rIStm, StreamMode::READ ));
113 ReadIMapObject( rIStm );
115 // from version 4 onwards we read an eventlist
116 if ( nReadVersion >= 0x0004 )
118 aEventList.Read(rIStm);
120 // from version 5 onwards an objectname could be available
121 if ( nReadVersion >= 0x0005 )
122 aName = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStm, nTextEncoding);
126 bool IMapObject::IsEqual( const IMapObject& rEqObj )
128 return ( ( aURL == rEqObj.aURL ) &&
129 ( aAltText == rEqObj.aAltText ) &&
130 ( aDesc == rEqObj.aDesc ) &&
131 ( aTarget == rEqObj.aTarget ) &&
132 ( aName == rEqObj.aName ) &&
133 ( bActive == rEqObj.bActive ) );
136 IMapRectangleObject::IMapRectangleObject( const tools::Rectangle& rRect,
137 const OUString& rURL,
138 const OUString& rAltText,
139 const OUString& rDesc,
140 const OUString& rTarget,
141 const OUString& rName,
142 bool bURLActive,
143 bool bPixelCoords ) :
144 IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive )
146 ImpConstruct( rRect, bPixelCoords );
149 void IMapRectangleObject::ImpConstruct( const tools::Rectangle& rRect, bool bPixel )
151 if ( bPixel )
152 aRect = Application::GetDefaultDevice()->PixelToLogic( rRect, MapMode( MapUnit::Map100thMM ) );
153 else
154 aRect = rRect;
158 /******************************************************************************
160 |* Binary export
162 \******************************************************************************/
164 void IMapRectangleObject::WriteIMapObject( SvStream& rOStm ) const
166 tools::GenericTypeSerializer aSerializer(rOStm);
167 aSerializer.writeRectangle(aRect);
171 /******************************************************************************
173 |* Binary import
175 \******************************************************************************/
177 void IMapRectangleObject::ReadIMapObject( SvStream& rIStm )
179 tools::GenericTypeSerializer aSerializer(rIStm);
180 aSerializer.readRectangle(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 tools::Rectangle IMapRectangleObject::GetRectangle( bool bPixelCoords ) const
209 tools::Rectangle aNewRect;
211 if ( bPixelCoords )
212 aNewRect = Application::GetDefaultDevice()->LogicToPixel( aRect, MapMode( MapUnit::Map100thMM ) );
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 = tools::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( MapUnit::Map100thMM );
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;
277 tools::GenericTypeSerializer aSerializer(rOStm);
278 aSerializer.writePoint(aCenter);
279 rOStm.WriteUInt32( nTmp );
283 /******************************************************************************
285 |* Binary import
287 \******************************************************************************/
289 void IMapCircleObject::ReadIMapObject( SvStream& rIStm )
291 sal_uInt32 nTmp;
293 tools::GenericTypeSerializer aSerializer(rIStm);
294 aSerializer.readPoint(aCenter);
295 rIStm.ReadUInt32( nTmp );
297 nRadius = nTmp;
301 /******************************************************************************
303 |* return type
305 \******************************************************************************/
307 sal_uInt16 IMapCircleObject::GetType() const
309 return IMAP_OBJ_CIRCLE;
313 /******************************************************************************
315 |* Hit-Test
317 \******************************************************************************/
319 bool IMapCircleObject::IsHit( const Point& rPoint ) const
321 const Point aPoint( aCenter - rPoint );
322 bool bRet = false;
324 if ( static_cast<sal_Int32>(sqrt( static_cast<double>(aPoint.X()) * aPoint.X() +
325 aPoint.Y() * aPoint.Y() )) <= nRadius )
327 bRet = true;
330 return bRet;
333 Point IMapCircleObject::GetCenter( bool bPixelCoords ) const
335 Point aNewPoint;
337 if ( bPixelCoords )
338 aNewPoint = Application::GetDefaultDevice()->LogicToPixel( aCenter, MapMode( MapUnit::Map100thMM ) );
339 else
340 aNewPoint = aCenter;
342 return aNewPoint;
345 sal_uLong IMapCircleObject::GetRadius( bool bPixelCoords ) const
347 sal_uLong nNewRadius;
349 if ( bPixelCoords )
350 nNewRadius = Application::GetDefaultDevice()->LogicToPixel( Size( nRadius, 0 ), MapMode( MapUnit::Map100thMM ) ).Width();
351 else
352 nNewRadius = nRadius;
354 return nNewRadius;
357 void IMapCircleObject::Scale( const Fraction& rFracX, const Fraction& rFracY )
359 Fraction aAverage( rFracX );
361 aAverage += rFracY;
362 aAverage *= Fraction( 1, 2 );
364 if ( rFracX.GetDenominator() && rFracY.GetDenominator() )
366 SCALEPOINT( aCenter, rFracX, rFracY );
369 if (!aAverage.GetDenominator())
370 throw o3tl::divide_by_zero();
372 nRadius = double(nRadius * aAverage);
375 bool IMapCircleObject::IsEqual( const IMapCircleObject& rEqObj )
377 return ( IMapObject::IsEqual( rEqObj ) &&
378 ( aCenter == rEqObj.aCenter ) &&
379 ( nRadius == rEqObj.nRadius ) );
382 IMapPolygonObject::IMapPolygonObject( const tools::Polygon& rPoly,
383 const OUString& rURL,
384 const OUString& rAltText,
385 const OUString& rDesc,
386 const OUString& rTarget,
387 const OUString& rName,
388 bool bURLActive,
389 bool bPixelCoords ) :
390 IMapObject ( rURL, rAltText, rDesc, rTarget, rName, bURLActive ),
391 bEllipse ( false )
393 ImpConstruct( rPoly, bPixelCoords );
396 void IMapPolygonObject::ImpConstruct( const tools::Polygon& rPoly, bool bPixel )
398 if ( bPixel )
399 aPoly = Application::GetDefaultDevice()->PixelToLogic( rPoly, MapMode( MapUnit::Map100thMM ) );
400 else
401 aPoly = rPoly;
405 /******************************************************************************
407 |* Binary export
409 \******************************************************************************/
411 void IMapPolygonObject::WriteIMapObject( SvStream& rOStm ) const
413 tools::GenericTypeSerializer aSerializer(rOStm);
414 WritePolygon( rOStm, aPoly );
415 // Version 2
416 rOStm.WriteBool( bEllipse );
417 aSerializer.writeRectangle(aEllipse);
421 /******************************************************************************
423 |* Binary import
425 \******************************************************************************/
427 void IMapPolygonObject::ReadIMapObject( SvStream& rIStm )
429 ReadPolygon( rIStm, aPoly );
431 // Version >= 2 has additional ellipses information
432 if ( nReadVersion >= 2 )
434 rIStm.ReadCharAsBool( bEllipse );
435 tools::GenericTypeSerializer aSerializer(rIStm);
436 aSerializer.readRectangle(aEllipse);
441 /******************************************************************************
443 |* return type
445 \******************************************************************************/
447 sal_uInt16 IMapPolygonObject::GetType() const
449 return IMAP_OBJ_POLYGON;
453 /******************************************************************************
455 |* hit test
457 \******************************************************************************/
459 bool IMapPolygonObject::IsHit( const Point& rPoint ) const
461 return aPoly.IsInside( rPoint );
464 tools::Polygon IMapPolygonObject::GetPolygon( bool bPixelCoords ) const
466 tools::Polygon aNewPoly;
468 if ( bPixelCoords )
469 aNewPoly = Application::GetDefaultDevice()->LogicToPixel( aPoly, MapMode( MapUnit::Map100thMM ) );
470 else
471 aNewPoly = aPoly;
473 return aNewPoly;
476 void IMapPolygonObject::SetExtraEllipse( const tools::Rectangle& rEllipse )
478 if ( aPoly.GetSize() )
480 bEllipse = true;
481 aEllipse = rEllipse;
485 void IMapPolygonObject::Scale( const Fraction& rFracX, const Fraction& rFracY )
487 sal_uInt16 nCount = aPoly.GetSize();
489 for ( sal_uInt16 i = 0; i < nCount; i++ )
491 Point aScaledPt( aPoly[ i ] );
493 if ( rFracX.GetDenominator() && rFracY.GetDenominator() )
495 SCALEPOINT( aScaledPt, rFracX, rFracY );
498 aPoly[ i ] = aScaledPt;
501 if ( !bEllipse )
502 return;
504 Point aTL( aEllipse.TopLeft() );
505 Point aBR( aEllipse.BottomRight() );
507 if ( rFracX.GetDenominator() && rFracY.GetDenominator() )
509 SCALEPOINT( aTL, rFracX, rFracY );
510 SCALEPOINT( aBR, rFracX, rFracY );
513 aEllipse = tools::Rectangle( aTL, aBR );
516 bool IMapPolygonObject::IsEqual( const IMapPolygonObject& rEqObj )
518 bool bRet = false;
520 if ( IMapObject::IsEqual( rEqObj ) )
522 const tools::Polygon& rEqPoly = rEqObj.aPoly;
523 const sal_uInt16 nCount = aPoly.GetSize();
524 const sal_uInt16 nEqCount = rEqPoly.GetSize();
526 if ( nCount == nEqCount )
528 bool bDifferent = false;
530 for ( sal_uInt16 i = 0; i < nCount; i++ )
532 if ( aPoly[ i ] != rEqPoly[ i ] )
534 bDifferent = true;
535 break;
539 if ( !bDifferent )
540 bRet = true;
544 return bRet;
547 /******************************************************************************
549 |* Ctor
551 \******************************************************************************/
553 ImageMap::ImageMap( const OUString& rName )
554 : aName( rName )
559 /******************************************************************************
561 |* Copy-Ctor
563 \******************************************************************************/
565 ImageMap::ImageMap( const ImageMap& rImageMap )
568 size_t nCount = rImageMap.GetIMapObjectCount();
570 for ( size_t i = 0; i < nCount; i++ )
572 IMapObject* pCopyObj = rImageMap.GetIMapObject( i );
574 switch( pCopyObj->GetType() )
576 case IMAP_OBJ_RECTANGLE:
577 maList.emplace_back( new IMapRectangleObject( *static_cast<IMapRectangleObject*>( pCopyObj ) ) );
578 break;
580 case IMAP_OBJ_CIRCLE:
581 maList.emplace_back( new IMapCircleObject( *static_cast<IMapCircleObject*>( pCopyObj ) ) );
582 break;
584 case IMAP_OBJ_POLYGON:
585 maList.emplace_back( new IMapPolygonObject( *static_cast<IMapPolygonObject*>( pCopyObj ) ) );
586 break;
588 default:
589 break;
593 aName = rImageMap.aName;
597 /******************************************************************************
599 |* Dtor
601 \******************************************************************************/
603 ImageMap::~ImageMap()
608 /******************************************************************************
610 |* release internal memory
612 \******************************************************************************/
614 void ImageMap::ClearImageMap()
616 maList.clear();
618 aName.clear();
622 /******************************************************************************
624 |* assignment operator
626 \******************************************************************************/
628 ImageMap& ImageMap::operator=( const ImageMap& rImageMap )
630 if (this != &rImageMap)
632 size_t nCount = rImageMap.GetIMapObjectCount();
634 ClearImageMap();
636 for ( size_t i = 0; i < nCount; i++ )
638 IMapObject* pCopyObj = rImageMap.GetIMapObject( i );
640 switch( pCopyObj->GetType() )
642 case IMAP_OBJ_RECTANGLE:
643 maList.emplace_back( new IMapRectangleObject( *static_cast<IMapRectangleObject*>(pCopyObj) ) );
644 break;
646 case IMAP_OBJ_CIRCLE:
647 maList.emplace_back( new IMapCircleObject( *static_cast<IMapCircleObject*>(pCopyObj) ) );
648 break;
650 case IMAP_OBJ_POLYGON:
651 maList.emplace_back( new IMapPolygonObject( *static_cast<IMapPolygonObject*>(pCopyObj) ) );
652 break;
654 default:
655 break;
659 aName = rImageMap.aName;
661 return *this;
665 /******************************************************************************
667 |* compare operator I
669 \******************************************************************************/
671 bool ImageMap::operator==( const ImageMap& rImageMap )
673 const size_t nCount = maList.size();
674 const size_t nEqCount = rImageMap.GetIMapObjectCount();
675 bool bRet = false;
677 if ( nCount == nEqCount )
679 bool bDifferent = ( aName != rImageMap.aName );
681 for ( size_t i = 0; ( i < nCount ) && !bDifferent; i++ )
683 IMapObject* pObj = maList[ i ].get();
684 IMapObject* pEqObj = rImageMap.GetIMapObject( i );
686 if ( pObj->GetType() == pEqObj->GetType() )
688 switch( pObj->GetType() )
690 case IMAP_OBJ_RECTANGLE:
692 if ( ! static_cast<IMapRectangleObject*>(pObj)->IsEqual( *static_cast<IMapRectangleObject*>(pEqObj) ) )
693 bDifferent = true;
695 break;
697 case IMAP_OBJ_CIRCLE:
699 if ( ! static_cast<IMapCircleObject*>(pObj)->IsEqual( *static_cast<IMapCircleObject*>(pEqObj) ) )
700 bDifferent = true;
702 break;
704 case IMAP_OBJ_POLYGON:
706 if ( ! static_cast<IMapPolygonObject*>(pObj)->IsEqual( *static_cast<IMapPolygonObject*>(pEqObj) ) )
707 bDifferent = true;
709 break;
711 default:
712 break;
715 else
716 bDifferent = true;
719 if ( !bDifferent )
720 bRet = true;
723 return bRet;
727 /******************************************************************************
729 |* compare operator II
731 \******************************************************************************/
733 bool ImageMap::operator!=( const ImageMap& rImageMap )
735 return !( *this == rImageMap );
739 /******************************************************************************
741 |* insert new object
743 \******************************************************************************/
745 void ImageMap::InsertIMapObject( const IMapObject& rIMapObject )
747 switch( rIMapObject.GetType() )
749 case IMAP_OBJ_RECTANGLE:
750 maList.emplace_back( new IMapRectangleObject( static_cast<const IMapRectangleObject&>( rIMapObject ) ) );
751 break;
753 case IMAP_OBJ_CIRCLE:
754 maList.emplace_back( new IMapCircleObject( static_cast<const IMapCircleObject&>( rIMapObject ) ) );
755 break;
757 case IMAP_OBJ_POLYGON:
758 maList.emplace_back( new IMapPolygonObject( static_cast<const IMapPolygonObject&>( rIMapObject ) ) );
759 break;
761 default:
762 break;
766 void ImageMap::InsertIMapObject( std::unique_ptr<IMapObject> pNewObject )
768 maList.emplace_back( std::move(pNewObject) );
771 /******************************************************************************
773 |* hit test
775 \******************************************************************************/
777 IMapObject* ImageMap::GetHitIMapObject( const Size& rTotalSize,
778 const Size& rDisplaySize,
779 const Point& rRelHitPoint,
780 sal_uLong nFlags )
782 Point aRelPoint( rTotalSize.Width() * rRelHitPoint.X() / rDisplaySize.Width(),
783 rTotalSize.Height() * rRelHitPoint.Y() / rDisplaySize.Height() );
785 // transform point to check before checking if flags to mirror etc. are set,
786 if ( nFlags )
788 if ( nFlags & IMAP_MIRROR_HORZ )
789 aRelPoint.setX( rTotalSize.Width() - aRelPoint.X() );
791 if ( nFlags & IMAP_MIRROR_VERT )
792 aRelPoint.setY( rTotalSize.Height() - aRelPoint.Y() );
795 // walk over all objects and execute HitTest
796 IMapObject* pObj = nullptr;
797 for(const auto& i : maList) {
798 if ( i->IsHit( aRelPoint ) ) {
799 pObj = i.get();
800 break;
804 return( pObj ? ( pObj->IsActive() ? pObj : nullptr ) : nullptr );
807 void ImageMap::Scale( const Fraction& rFracX, const Fraction& rFracY )
809 size_t nCount = maList.size();
811 for ( size_t i = 0; i < nCount; i++ )
813 IMapObject* pObj = maList[ i ].get();
815 switch( pObj->GetType() )
817 case IMAP_OBJ_RECTANGLE:
818 static_cast<IMapRectangleObject*>( pObj )->Scale( rFracX, rFracY );
819 break;
821 case IMAP_OBJ_CIRCLE:
822 static_cast<IMapCircleObject*>( pObj )->Scale( rFracX, rFracY );
823 break;
825 case IMAP_OBJ_POLYGON:
826 static_cast<IMapPolygonObject*>( pObj )->Scale( rFracX, rFracY );
827 break;
829 default:
830 break;
836 /******************************************************************************
838 |* sequentially write objects
840 \******************************************************************************/
842 void ImageMap::ImpWriteImageMap( SvStream& rOStm ) const
844 size_t nCount = maList.size();
846 for ( size_t i = 0; i < nCount; i++ )
848 auto& pObj = maList[ i ];
849 pObj->Write( rOStm );
854 /******************************************************************************
856 |* sequentially read objects
858 \******************************************************************************/
860 void ImageMap::ImpReadImageMap( SvStream& rIStm, size_t nCount )
862 const size_t nMinRecordSize = 12; //circle, three 32bit numbers
863 const size_t nMaxRecords = rIStm.remainingSize() / nMinRecordSize;
865 if (nCount > nMaxRecords)
867 SAL_WARN("svtools.misc", "Parsing error: " << nMaxRecords << " max possible entries, but " <<
868 nCount << " claimed, truncating");
869 nCount = nMaxRecords;
872 // read new objects
873 for (size_t i = 0; i < nCount; ++i)
875 sal_uInt16 nType;
877 rIStm.ReadUInt16( nType );
878 rIStm.SeekRel( -2 );
880 switch( nType )
882 case IMAP_OBJ_RECTANGLE:
884 IMapRectangleObject* pObj = new IMapRectangleObject;
885 pObj->Read( rIStm );
886 maList.emplace_back( pObj );
888 break;
890 case IMAP_OBJ_CIRCLE:
892 IMapCircleObject* pObj = new IMapCircleObject;
893 pObj->Read( rIStm );
894 maList.emplace_back( pObj );
896 break;
898 case IMAP_OBJ_POLYGON:
900 IMapPolygonObject* pObj = new IMapPolygonObject;
901 pObj->Read( rIStm );
902 maList.emplace_back( pObj );
904 break;
906 default:
907 break;
913 /******************************************************************************
915 |* store binary
917 \******************************************************************************/
919 void ImageMap::Write( SvStream& rOStm ) const
921 IMapCompat* pCompat;
922 OUString aImageName( GetName() );
923 SvStreamEndian nOldFormat = rOStm.GetEndian();
924 sal_uInt16 nCount = static_cast<sal_uInt16>(GetIMapObjectCount());
925 const rtl_TextEncoding eEncoding = osl_getThreadTextEncoding(); //vomit!
927 rOStm.SetEndian( SvStreamEndian::LITTLE );
929 // write MagicCode
930 rOStm.WriteCharPtr( IMAPMAGIC );
931 rOStm.WriteUInt16( IMAGE_MAP_VERSION );
932 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aImageName, eEncoding);
933 write_uInt16_lenPrefixed_uInt8s_FromOString(rOStm, OString()); //dummy
934 rOStm.WriteUInt16( nCount );
935 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aImageName, eEncoding);
937 pCompat = new IMapCompat( rOStm, StreamMode::WRITE );
939 // here one can insert in newer versions
941 delete pCompat;
943 ImpWriteImageMap( rOStm );
945 rOStm.SetEndian( nOldFormat );
949 /******************************************************************************
951 |* load binary
953 \******************************************************************************/
955 void ImageMap::Read( SvStream& rIStm )
957 char cMagic[6];
958 SvStreamEndian nOldFormat = rIStm.GetEndian();
959 sal_uInt16 nCount;
961 rIStm.SetEndian( SvStreamEndian::LITTLE );
962 rIStm.ReadBytes(cMagic, sizeof(cMagic));
964 if ( !memcmp( cMagic, IMAPMAGIC, sizeof( cMagic ) ) )
966 IMapCompat* pCompat;
968 // delete old content
969 ClearImageMap();
971 // read on version
972 rIStm.SeekRel( 2 );
974 aName = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIStm, osl_getThreadTextEncoding());
975 read_uInt16_lenPrefixed_uInt8s_ToOString(rIStm); // Dummy
976 rIStm.ReadUInt16( nCount );
977 read_uInt16_lenPrefixed_uInt8s_ToOString(rIStm); // Dummy
979 pCompat = new IMapCompat( rIStm, StreamMode::READ );
981 // here one can read in newer versions
983 delete pCompat;
984 ImpReadImageMap( rIStm, nCount );
987 else
988 rIStm.SetError( SVSTREAM_GENERALERROR );
990 rIStm.SetEndian( nOldFormat );
994 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */