LCOV - code coverage report
Current view: top level - svtools/source/misc - imap.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 94 373 25.2 %
Date: 2015-06-13 12:38:46 Functions: 15 50 30.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11