1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: imap2.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
39 #include <vcl/svapp.hxx>
40 #include <tools/urlobj.hxx>
41 #ifndef _WRKWIN_HXX //autogen
42 #include <vcl/wrkwin.hxx>
44 #include <sot/formats.hxx>
46 #include "urihelper.hxx"
47 #include <svtools/imap.hxx>
48 #include <svtools/imap.hxx>
49 #include <svtools/imapobj.hxx>
50 #include <svtools/imaprect.hxx>
51 #include <svtools/imapcirc.hxx>
52 #include <svtools/imappoly.hxx>
60 #define NOTEOL(c) ((c)!='\0')
63 TYPEINIT0_AUTOFACTORY( ImageMap
);
66 /******************************************************************************/
67 /******************************************************************************/
70 /******************************************************************************
74 \******************************************************************************/
76 void IMapObject::AppendCERNCoords( const Point
& rPoint100
, ByteString
& rStr
) const
78 const Point
aPixPt( Application::GetDefaultDevice()->LogicToPixel( rPoint100
, MapMode( MAP_100TH_MM
) ) );
81 rStr
+= ByteString::CreateFromInt32( aPixPt
.X() );
83 rStr
+= ByteString::CreateFromInt32( aPixPt
.Y() );
88 /******************************************************************************
92 \******************************************************************************/
94 void IMapObject::AppendNCSACoords( const Point
& rPoint100
, ByteString
& rStr
) const
96 const Point
aPixPt( Application::GetDefaultDevice()->LogicToPixel( rPoint100
, MapMode( MAP_100TH_MM
) ) );
98 rStr
+= ByteString::CreateFromInt32( aPixPt
.X() );
100 rStr
+= ByteString::CreateFromInt32( aPixPt
.Y() );
105 /******************************************************************************
109 \******************************************************************************/
111 void IMapObject::AppendCERNURL( ByteString
& rStr
, const String
& rBaseURL
) const
113 rStr
+= ByteString( String(URIHelper::simpleNormalizedMakeRelative( rBaseURL
, aURL
)), gsl_getSystemTextEncoding() );
117 /******************************************************************************
121 \******************************************************************************/
123 void IMapObject::AppendNCSAURL( ByteString
& rStr
, const String
& rBaseURL
) const
125 rStr
+= ByteString( String(URIHelper::simpleNormalizedMakeRelative( rBaseURL
, aURL
)), gsl_getSystemTextEncoding() );
130 /******************************************************************************/
131 /******************************************************************************/
134 /******************************************************************************
138 \******************************************************************************/
140 void IMapRectangleObject::WriteCERN( SvStream
& rOStm
, const String
& rBaseURL
) const
142 ByteString
aStr( "rectangle " );
144 AppendCERNCoords( aRect
.TopLeft(), aStr
);
145 AppendCERNCoords( aRect
.BottomRight(), aStr
);
146 AppendCERNURL( aStr
, rBaseURL
);
148 rOStm
.WriteLine( aStr
);
152 /******************************************************************************
156 \******************************************************************************/
158 void IMapRectangleObject::WriteNCSA( SvStream
& rOStm
, const String
& rBaseURL
) const
160 ByteString
aStr( "rect " );
162 AppendNCSAURL( aStr
, rBaseURL
);
163 AppendNCSACoords( aRect
.TopLeft(), aStr
);
164 AppendNCSACoords( aRect
.BottomRight(), aStr
);
166 rOStm
.WriteLine( aStr
);
170 /******************************************************************************/
171 /******************************************************************************/
174 /******************************************************************************
178 \******************************************************************************/
180 void IMapCircleObject::WriteCERN( SvStream
& rOStm
, const String
& rBaseURL
) const
182 ByteString
aStr( "circle " );
184 AppendCERNCoords( aCenter
, aStr
);
185 aStr
+= ByteString::CreateFromInt32(nRadius
);
187 AppendCERNURL( aStr
, rBaseURL
);
189 rOStm
.WriteLine( aStr
);
193 /******************************************************************************
197 \******************************************************************************/
199 void IMapCircleObject::WriteNCSA( SvStream
& rOStm
, const String
& rBaseURL
) const
201 ByteString
aStr( "circle " );
203 AppendNCSAURL( aStr
, rBaseURL
);
204 AppendNCSACoords( aCenter
, aStr
);
205 AppendNCSACoords( aCenter
+ Point( nRadius
, 0 ), aStr
);
207 rOStm
.WriteLine( aStr
);
211 /******************************************************************************/
212 /******************************************************************************/
215 /******************************************************************************
219 \******************************************************************************/
221 void IMapPolygonObject::WriteCERN( SvStream
& rOStm
, const String
& rBaseURL
) const
223 ByteString
aStr( "polygon " );
224 const USHORT nCount
= aPoly
.GetSize();
226 for ( USHORT i
= 0; i
< nCount
; i
++ )
227 AppendCERNCoords( aPoly
[ i
], aStr
);
229 AppendCERNURL( aStr
, rBaseURL
);
231 rOStm
.WriteLine( aStr
);
235 /******************************************************************************
239 \******************************************************************************/
241 void IMapPolygonObject::WriteNCSA( SvStream
& rOStm
, const String
& rBaseURL
) const
243 ByteString
aStr( "poly " );
244 const USHORT nCount
= Min( aPoly
.GetSize(), (USHORT
) 100 );
246 AppendNCSAURL( aStr
, rBaseURL
);
248 for ( USHORT i
= 0; i
< nCount
; i
++ )
249 AppendNCSACoords( aPoly
[ i
], aStr
);
251 rOStm
.WriteLine( aStr
);
255 /******************************************************************************/
256 /******************************************************************************/
259 /******************************************************************************
263 \******************************************************************************/
265 void ImageMap::Write( SvStream
& rOStm
, ULONG nFormat
, const String
& rBaseURL
) const
269 case( IMAP_FORMAT_BIN
) : Write( rOStm
, rBaseURL
);
270 case( IMAP_FORMAT_CERN
) : ImpWriteCERN( rOStm
, rBaseURL
); break;
271 case( IMAP_FORMAT_NCSA
) : ImpWriteNCSA( rOStm
, rBaseURL
); break;
279 /******************************************************************************
283 \******************************************************************************/
285 void ImageMap::ImpWriteCERN( SvStream
& rOStm
, const String
& rBaseURL
) const
288 USHORT nCount
= (USHORT
) maList
.Count();
290 for ( USHORT i
= 0; i
< nCount
; i
++ )
292 pObj
= GetIMapObject( i
);
294 switch( pObj
->GetType() )
296 case( IMAP_OBJ_RECTANGLE
):
297 ( (IMapRectangleObject
*) pObj
)->WriteCERN( rOStm
, rBaseURL
);
300 case( IMAP_OBJ_CIRCLE
):
301 ( (IMapCircleObject
*) pObj
)->WriteCERN( rOStm
, rBaseURL
);
304 case( IMAP_OBJ_POLYGON
):
305 ( (IMapPolygonObject
*) pObj
)->WriteCERN( rOStm
, rBaseURL
);
315 /******************************************************************************
319 \******************************************************************************/
321 void ImageMap::ImpWriteNCSA( SvStream
& rOStm
, const String
& rBaseURL
) const
324 USHORT nCount
= (USHORT
) maList
.Count();
326 for ( USHORT i
= 0; i
< nCount
; i
++ )
328 pObj
= GetIMapObject( i
);
330 switch( pObj
->GetType() )
332 case( IMAP_OBJ_RECTANGLE
):
333 ( (IMapRectangleObject
*) pObj
)->WriteNCSA( rOStm
, rBaseURL
);
336 case( IMAP_OBJ_CIRCLE
):
337 ( (IMapCircleObject
*) pObj
)->WriteNCSA( rOStm
, rBaseURL
);
340 case( IMAP_OBJ_POLYGON
):
341 ( (IMapPolygonObject
*) pObj
)->WriteNCSA( rOStm
, rBaseURL
);
351 /******************************************************************************
355 \******************************************************************************/
357 ULONG
ImageMap::Read( SvStream
& rIStm
, ULONG nFormat
, const String
& rBaseURL
)
359 ULONG nRet
= IMAP_ERR_FORMAT
;
361 if ( nFormat
== IMAP_FORMAT_DETECT
)
362 nFormat
= ImpDetectFormat( rIStm
);
366 case ( IMAP_FORMAT_BIN
) : Read( rIStm
, rBaseURL
); break;
367 case ( IMAP_FORMAT_CERN
) : nRet
= ImpReadCERN( rIStm
, rBaseURL
); break;
368 case ( IMAP_FORMAT_NCSA
) : nRet
= ImpReadNCSA( rIStm
, rBaseURL
); break;
374 if ( !rIStm
.GetError() )
381 /******************************************************************************
385 \******************************************************************************/
387 ULONG
ImageMap::ImpReadCERN( SvStream
& rIStm
, const String
& rBaseURL
)
391 // alten Inhalt loeschen
394 while ( rIStm
.ReadLine( aStr
) )
395 ImpReadCERNLine( aStr
, rBaseURL
);
401 /******************************************************************************
405 \******************************************************************************/
407 void ImageMap::ImpReadCERNLine( const ByteString
& rLine
, const String
& rBaseURL
)
409 ByteString
aStr( rLine
);
412 aStr
.EraseLeadingChars( ' ' );
413 aStr
.EraseLeadingChars( '\t' );
414 aStr
.EraseAllChars( ';' );
417 const char* pStr
= aStr
.GetBuffer();
418 char cChar
= *pStr
++;
421 while( ( cChar
>= 'a' ) && ( cChar
<= 'z' ) && NOTEOL( cChar
) )
427 if ( NOTEOL( cChar
) )
429 if ( ( aToken
== "rectangle" ) || ( aToken
== "rect" ) )
431 const Point
aTopLeft( ImpReadCERNCoords( &pStr
) );
432 const Point
aBottomRight( ImpReadCERNCoords( &pStr
) );
433 const String
aURL( ImpReadCERNURL( &pStr
, rBaseURL
) );
434 const Rectangle
aRect( aTopLeft
, aBottomRight
);
436 IMapRectangleObject
* pObj
= new IMapRectangleObject( aRect
, aURL
, String(), String(), String(), String() );
437 maList
.Insert( pObj
, LIST_APPEND
);
439 else if ( ( aToken
== "circle" ) || ( aToken
== "circ" ) )
441 const Point
aCenter( ImpReadCERNCoords( &pStr
) );
442 const long nRadius
= ImpReadCERNRadius( &pStr
);
443 const String
aURL( ImpReadCERNURL( &pStr
, rBaseURL
) );
445 IMapCircleObject
* pObj
= new IMapCircleObject( aCenter
, nRadius
, aURL
, String(), String(), String(), String() );
446 maList
.Insert( pObj
, LIST_APPEND
);
448 else if ( ( aToken
== "polygon" ) || ( aToken
== "poly" ) )
450 const USHORT nCount
= aStr
.GetTokenCount( '(' ) - 1;
451 Polygon
aPoly( nCount
);
454 for ( USHORT i
= 0; i
< nCount
; i
++ )
455 aPoly
[ i
] = ImpReadCERNCoords( &pStr
);
457 aURL
= ImpReadCERNURL( &pStr
, rBaseURL
);
459 IMapPolygonObject
* pObj
= new IMapPolygonObject( aPoly
, aURL
, String(), String(), String(), String() );
460 maList
.Insert( pObj
, LIST_APPEND
);
466 /******************************************************************************
470 \******************************************************************************/
472 Point
ImageMap::ImpReadCERNCoords( const char** ppStr
)
477 char cChar
= *(*ppStr
)++;
479 while( NOTEOL( cChar
) && ( ( cChar
< '0' ) || ( cChar
> '9' ) ) )
482 if ( NOTEOL( cChar
) )
484 while( NOTEOL( cChar
) && ( cChar
>= '0' ) && ( cChar
<= '9' ) )
490 if ( NOTEOL( cChar
) )
492 while( NOTEOL( cChar
) && ( ( cChar
< '0' ) || ( cChar
> '9' ) ) )
495 while( NOTEOL( cChar
) && ( cChar
>= '0' ) && ( cChar
<= '9' ) )
501 if ( NOTEOL( cChar
) )
502 while( NOTEOL( cChar
) && ( cChar
!= ')' ) )
505 aPt
= Point( aStrX
.ToInt32(), aStrY
.ToInt32() );
513 /******************************************************************************
517 \******************************************************************************/
519 long ImageMap::ImpReadCERNRadius( const char** ppStr
)
522 char cChar
= *(*ppStr
)++;
524 while( NOTEOL( cChar
) && ( ( cChar
< '0' ) || ( cChar
> '9' ) ) )
527 if ( NOTEOL( cChar
) )
529 while( NOTEOL( cChar
) && ( cChar
>= '0' ) && ( cChar
<= '9' ) )
536 return aStr
.ToInt32();
540 /******************************************************************************
544 \******************************************************************************/
546 String
ImageMap::ImpReadCERNURL( const char** ppStr
, const String
& rBaseURL
)
548 String
aStr( String::CreateFromAscii( *ppStr
) );
550 aStr
.EraseLeadingChars( ' ' );
551 aStr
.EraseLeadingChars( '\t' );
552 aStr
.EraseTrailingChars( ' ' );
553 aStr
.EraseTrailingChars( '\t' );
555 return INetURLObject::GetAbsURL( rBaseURL
, aStr
);
559 /******************************************************************************
563 \******************************************************************************/
565 ULONG
ImageMap::ImpReadNCSA( SvStream
& rIStm
, const String
& rBaseURL
)
569 // alten Inhalt loeschen
572 while ( rIStm
.ReadLine( aStr
) )
573 ImpReadNCSALine( aStr
, rBaseURL
);
579 /******************************************************************************
583 \******************************************************************************/
585 void ImageMap::ImpReadNCSALine( const ByteString
& rLine
, const String
& rBaseURL
)
587 ByteString
aStr( rLine
);
590 aStr
.EraseLeadingChars( ' ' );
591 aStr
.EraseLeadingChars( '\t' );
592 aStr
.EraseAllChars( ';' );
595 const char* pStr
= aStr
.GetBuffer();
596 char cChar
= *pStr
++;
599 while( ( cChar
>= 'a' ) && ( cChar
<= 'z' ) && NOTEOL( cChar
) )
605 if ( NOTEOL( cChar
) )
607 if ( aToken
== "rect" )
609 const String
aURL( ImpReadNCSAURL( &pStr
, rBaseURL
) );
610 const Point
aTopLeft( ImpReadNCSACoords( &pStr
) );
611 const Point
aBottomRight( ImpReadNCSACoords( &pStr
) );
612 const Rectangle
aRect( aTopLeft
, aBottomRight
);
614 IMapRectangleObject
* pObj
= new IMapRectangleObject( aRect
, aURL
, String(), String(), String(), String() );
615 maList
.Insert( pObj
, LIST_APPEND
);
617 else if ( aToken
== "circle" )
619 const String
aURL( ImpReadNCSAURL( &pStr
, rBaseURL
) );
620 const Point
aCenter( ImpReadNCSACoords( &pStr
) );
621 const Point
aDX( aCenter
- ImpReadNCSACoords( &pStr
) );
622 long nRadius
= (long) sqrt( (double) aDX
.X() * aDX
.X() +
623 (double) aDX
.Y() * aDX
.Y() );
625 IMapCircleObject
* pObj
= new IMapCircleObject( aCenter
, nRadius
, aURL
, String(), String(), String(), String() );
626 maList
.Insert( pObj
, LIST_APPEND
);
628 else if ( aToken
== "poly" )
630 const USHORT nCount
= aStr
.GetTokenCount( ',' ) - 1;
631 const String
aURL( ImpReadNCSAURL( &pStr
, rBaseURL
) );
632 Polygon
aPoly( nCount
);
634 for ( USHORT i
= 0; i
< nCount
; i
++ )
635 aPoly
[ i
] = ImpReadNCSACoords( &pStr
);
637 IMapPolygonObject
* pObj
= new IMapPolygonObject( aPoly
, aURL
, String(), String(), String(), String() );
638 maList
.Insert( pObj
, LIST_APPEND
);
644 /******************************************************************************
648 \******************************************************************************/
650 String
ImageMap::ImpReadNCSAURL( const char** ppStr
, const String
& rBaseURL
)
653 char cChar
= *(*ppStr
)++;
655 while( NOTEOL( cChar
) && ( ( cChar
== ' ' ) || ( cChar
== '\t' ) ) )
658 if ( NOTEOL( cChar
) )
660 while( NOTEOL( cChar
) && ( cChar
!= ' ' ) && ( cChar
!= '\t' ) )
667 return INetURLObject::GetAbsURL( rBaseURL
, aStr
);
671 /******************************************************************************
675 \******************************************************************************/
677 Point
ImageMap::ImpReadNCSACoords( const char** ppStr
)
682 char cChar
= *(*ppStr
)++;
684 while( NOTEOL( cChar
) && ( ( cChar
< '0' ) || ( cChar
> '9' ) ) )
687 if ( NOTEOL( cChar
) )
689 while( NOTEOL( cChar
) && ( cChar
>= '0' ) && ( cChar
<= '9' ) )
695 if ( NOTEOL( cChar
) )
697 while( NOTEOL( cChar
) && ( ( cChar
< '0' ) || ( cChar
> '9' ) ) )
700 while( NOTEOL( cChar
) && ( cChar
>= '0' ) && ( cChar
<= '9' ) )
706 aPt
= Point( aStrX
.ToInt32(), aStrY
.ToInt32() );
714 /******************************************************************************
718 \******************************************************************************/
720 ULONG
ImageMap::ImpDetectFormat( SvStream
& rIStm
)
722 ULONG nPos
= rIStm
.Tell();
723 ULONG nRet
= IMAP_FORMAT_BIN
;
726 rIStm
.Read( cMagic
, sizeof( cMagic
) );
728 // Falls wir kein internes Format haben,
729 // untersuchen wir das Format
730 if ( memcmp( cMagic
, IMAPMAGIC
, sizeof( cMagic
) ) )
736 while ( rIStm
.ReadLine( aStr
) && nCount
-- )
740 if ( ( aStr
.Search( "rect" ) != STRING_NOTFOUND
) ||
741 ( aStr
.Search( "circ" ) != STRING_NOTFOUND
) ||
742 ( aStr
.Search( "poly" ) != STRING_NOTFOUND
) )
744 if ( ( aStr
.Search( '(' ) != STRING_NOTFOUND
) &&
745 ( aStr
.Search( ')' ) != STRING_NOTFOUND
) )
747 nRet
= IMAP_FORMAT_CERN
;
750 nRet
= IMAP_FORMAT_NCSA
;