LCOV - code coverage report
Current view: top level - vcl/source/gdi - impgraph.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 526 750 70.1 %
Date: 2014-11-03 Functions: 53 61 86.9 %
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             : #include "sal/config.h"
      21             : 
      22             : #include <comphelper/processfactory.hxx>
      23             : #include <tools/vcompat.hxx>
      24             : #include <tools/urlobj.hxx>
      25             : #include <tools/debug.hxx>
      26             : #include <tools/stream.hxx>
      27             : #include <tools/helpers.hxx>
      28             : #include <ucbhelper/content.hxx>
      29             : #include <unotools/ucbstreamhelper.hxx>
      30             : #include <unotools/tempfile.hxx>
      31             : #include <vcl/outdev.hxx>
      32             : #include <vcl/virdev.hxx>
      33             : #include <vcl/gfxlink.hxx>
      34             : #include <vcl/cvtgrf.hxx>
      35             : #include <vcl/graph.hxx>
      36             : #include <vcl/metaact.hxx>
      37             : #include <impgraph.hxx>
      38             : #include <com/sun/star/ucb/CommandAbortedException.hpp>
      39             : #include <vcl/dibtools.hxx>
      40             : #include <boost/scoped_ptr.hpp>
      41             : 
      42             : #define GRAPHIC_MAXPARTLEN          256000L
      43             : #define GRAPHIC_MTFTOBMP_MAXEXT     2048
      44             : #define GRAPHIC_STREAMBUFSIZE       8192UL
      45             : 
      46             : #define SYS_WINMETAFILE             0x00000003L
      47             : #define SYS_WNTMETAFILE             0x00000004L
      48             : #define SYS_OS2METAFILE             0x00000005L
      49             : #define SYS_MACMETAFILE             0x00000006L
      50             : 
      51             : #define GRAPHIC_FORMAT_50           static_cast<sal_uInt32>(COMPAT_FORMAT( 'G', 'R', 'F', '5' ))
      52             : #define NATIVE_FORMAT_50            static_cast<sal_uInt32>(COMPAT_FORMAT( 'N', 'A', 'T', '5' ))
      53             : 
      54         136 : struct ImpSwapFile
      55             : {
      56             :     INetURLObject   aSwapURL;
      57             :     sal_uLong           nRefCount;
      58             : };
      59             : 
      60           0 : class ReaderData
      61             : {
      62             : public:
      63             :     Size    maPreviewSize;
      64             : };
      65             : 
      66        1082 : GraphicReader::~GraphicReader()
      67             : {
      68         541 :     delete mpReaderData;
      69         541 : }
      70             : 
      71         411 : void GraphicReader::DisablePreviewMode()
      72             : {
      73         411 :     if( mpReaderData )
      74           0 :         mpReaderData->maPreviewSize = Size( 0, 0 );
      75         411 : }
      76             : 
      77           0 : void GraphicReader::SetPreviewSize( const Size& rSize )
      78             : {
      79           0 :     if( !mpReaderData )
      80           0 :         mpReaderData = new ReaderData;
      81           0 :     mpReaderData->maPreviewSize = rSize;
      82           0 : }
      83             : 
      84         411 : Size GraphicReader::GetPreviewSize() const
      85             : {
      86         411 :     Size aSize( 0, 0 );
      87         411 :     if( mpReaderData )
      88           0 :         aSize = mpReaderData->maPreviewSize;
      89         411 :     return aSize;
      90             : }
      91             : 
      92      247513 : ImpGraphic::ImpGraphic() :
      93             :         mpAnimation     ( NULL ),
      94             :         mpContext       ( NULL ),
      95             :         mpSwapFile      ( NULL ),
      96             :         mpGfxLink       ( NULL ),
      97             :         meType          ( GRAPHIC_NONE ),
      98             :         mnDocFilePos    ( 0UL ),
      99             :         mnSizeBytes     ( 0UL ),
     100             :         mnRefCount      ( 1UL ),
     101             :         mbSwapOut       ( false ),
     102      247513 :         mbSwapUnderway  ( false )
     103             : {
     104      247513 : }
     105             : 
     106          32 : ImpGraphic::ImpGraphic( const ImpGraphic& rImpGraphic ) :
     107             :         maMetaFile      ( rImpGraphic.maMetaFile ),
     108             :         maEx            ( rImpGraphic.maEx ),
     109             :         mpContext       ( NULL ),
     110             :         mpSwapFile      ( rImpGraphic.mpSwapFile ),
     111             :         meType          ( rImpGraphic.meType ),
     112             :         maDocFileURLStr ( rImpGraphic.maDocFileURLStr ),
     113             :         mnDocFilePos    ( rImpGraphic.mnDocFilePos ),
     114             :         mnSizeBytes     ( rImpGraphic.mnSizeBytes ),
     115             :         mnRefCount      ( 1UL ),
     116             :         mbSwapOut       ( rImpGraphic.mbSwapOut ),
     117          32 :         mbSwapUnderway  ( false )
     118             : {
     119          32 :     if( mpSwapFile )
     120           0 :         mpSwapFile->nRefCount++;
     121             : 
     122          32 :     if( rImpGraphic.mpGfxLink )
     123           0 :         mpGfxLink = new GfxLink( *rImpGraphic.mpGfxLink );
     124             :     else
     125          32 :         mpGfxLink = NULL;
     126             : 
     127          32 :     if( rImpGraphic.mpAnimation )
     128             :     {
     129          16 :         mpAnimation = new Animation( *rImpGraphic.mpAnimation );
     130          16 :         maEx = mpAnimation->GetBitmapEx();
     131             :     }
     132             :     else
     133          16 :         mpAnimation = NULL;
     134             : 
     135          32 :     maSvgData = rImpGraphic.maSvgData;
     136          32 : }
     137             : 
     138         909 : ImpGraphic::ImpGraphic( const Bitmap& rBitmap ) :
     139             :         maEx            ( rBitmap ),
     140             :         mpAnimation     ( NULL ),
     141             :         mpContext       ( NULL ),
     142             :         mpSwapFile      ( NULL ),
     143             :         mpGfxLink       ( NULL ),
     144         909 :         meType          ( !rBitmap ? GRAPHIC_NONE : GRAPHIC_BITMAP ),
     145             :         mnDocFilePos    ( 0UL ),
     146             :         mnSizeBytes     ( 0UL ),
     147             :         mnRefCount      ( 1UL ),
     148             :         mbSwapOut       ( false ),
     149        1818 :         mbSwapUnderway  ( false )
     150             : {
     151         909 : }
     152             : 
     153      360319 : ImpGraphic::ImpGraphic( const BitmapEx& rBitmapEx ) :
     154             :         maEx            ( rBitmapEx ),
     155             :         mpAnimation     ( NULL ),
     156             :         mpContext       ( NULL ),
     157             :         mpSwapFile      ( NULL ),
     158             :         mpGfxLink       ( NULL ),
     159      360319 :         meType          ( !rBitmapEx ? GRAPHIC_NONE : GRAPHIC_BITMAP ),
     160             :         mnDocFilePos    ( 0UL ),
     161             :         mnSizeBytes     ( 0UL ),
     162             :         mnRefCount      ( 1UL ),
     163             :         mbSwapOut       ( false ),
     164      720638 :         mbSwapUnderway  ( false )
     165             : {
     166      360319 : }
     167             : 
     168         302 : ImpGraphic::ImpGraphic(const SvgDataPtr& rSvgDataPtr)
     169             : :   mpAnimation( NULL ),
     170             :     mpContext( NULL ),
     171             :     mpSwapFile( NULL ),
     172             :     mpGfxLink( NULL ),
     173         302 :     meType( rSvgDataPtr.get() ? GRAPHIC_BITMAP : GRAPHIC_NONE ),
     174             :     mnDocFilePos( 0UL ),
     175             :     mnSizeBytes( 0UL ),
     176             :     mnRefCount( 1UL ),
     177             :     mbSwapOut( false ),
     178             :     mbSwapUnderway( false ),
     179         604 :     maSvgData(rSvgDataPtr)
     180             : {
     181         302 : }
     182             : 
     183          16 : ImpGraphic::ImpGraphic( const Animation& rAnimation ) :
     184          16 :         maEx            ( rAnimation.GetBitmapEx() ),
     185          16 :         mpAnimation     ( new Animation( rAnimation ) ),
     186             :         mpContext       ( NULL ),
     187             :         mpSwapFile      ( NULL ),
     188             :         mpGfxLink       ( NULL ),
     189             :         meType          ( GRAPHIC_BITMAP ),
     190             :         mnDocFilePos    ( 0UL ),
     191             :         mnSizeBytes     ( 0UL ),
     192             :         mnRefCount      ( 1UL ),
     193             :         mbSwapOut       ( false ),
     194          48 :         mbSwapUnderway  ( false )
     195             : {
     196          16 : }
     197             : 
     198       13630 : ImpGraphic::ImpGraphic( const GDIMetaFile& rMtf ) :
     199             :         maMetaFile      ( rMtf ),
     200             :         mpAnimation     ( NULL ),
     201             :         mpContext       ( NULL ),
     202             :         mpSwapFile      ( NULL ),
     203             :         mpGfxLink       ( NULL ),
     204             :         meType          ( GRAPHIC_GDIMETAFILE ),
     205             :         mnDocFilePos    ( 0UL ),
     206             :         mnSizeBytes     ( 0UL ),
     207             :         mnRefCount      ( 1UL ),
     208             :         mbSwapOut       ( false ),
     209       13630 :         mbSwapUnderway  ( false )
     210             : {
     211       13630 : }
     212             : 
     213     1857467 : ImpGraphic::~ImpGraphic()
     214             : {
     215      622488 :     ImplClear();
     216             : 
     217      622488 :     if( reinterpret_cast<sal_uLong>(mpContext) > 1UL )
     218           0 :         delete mpContext;
     219     1234979 : }
     220             : 
     221        9942 : ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic )
     222             : {
     223        9942 :     if( &rImpGraphic != this )
     224             :     {
     225        9942 :         if( !mbSwapUnderway )
     226        9912 :             ImplClear();
     227             : 
     228        9942 :         maMetaFile = rImpGraphic.maMetaFile;
     229        9942 :         meType = rImpGraphic.meType;
     230        9942 :         mnSizeBytes = rImpGraphic.mnSizeBytes;
     231             : 
     232        9942 :         delete mpAnimation;
     233             : 
     234        9942 :         if ( rImpGraphic.mpAnimation )
     235             :         {
     236           0 :             mpAnimation = new Animation( *rImpGraphic.mpAnimation );
     237           0 :             maEx = mpAnimation->GetBitmapEx();
     238             :         }
     239             :         else
     240             :         {
     241        9942 :             mpAnimation = NULL;
     242        9942 :             maEx = rImpGraphic.maEx;
     243             :         }
     244             : 
     245        9942 :         if( !mbSwapUnderway )
     246             :         {
     247        9912 :             maDocFileURLStr = rImpGraphic.maDocFileURLStr;
     248        9912 :             mnDocFilePos = rImpGraphic.mnDocFilePos;
     249        9912 :             mbSwapOut = rImpGraphic.mbSwapOut;
     250        9912 :             mpSwapFile = rImpGraphic.mpSwapFile;
     251             : 
     252        9912 :             if( mpSwapFile )
     253           0 :                 mpSwapFile->nRefCount++;
     254             :         }
     255             : 
     256        9942 :         delete mpGfxLink;
     257             : 
     258        9942 :         if( rImpGraphic.mpGfxLink )
     259           0 :             mpGfxLink = new GfxLink( *rImpGraphic.mpGfxLink );
     260             :         else
     261        9942 :             mpGfxLink = NULL;
     262             : 
     263        9942 :         maSvgData = rImpGraphic.maSvgData;
     264             :     }
     265             : 
     266        9942 :     return *this;
     267             : }
     268             : 
     269        3827 : bool ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const
     270             : {
     271        3827 :     bool bRet = false;
     272             : 
     273        3827 :     if( this == &rImpGraphic )
     274        1953 :         bRet = true;
     275        1874 :     else if( !ImplIsSwapOut() && ( rImpGraphic.meType == meType ) )
     276             :     {
     277        1812 :         switch( meType )
     278             :         {
     279             :             case( GRAPHIC_NONE ):
     280          16 :                 bRet = true;
     281          16 :             break;
     282             : 
     283             :             case( GRAPHIC_GDIMETAFILE ):
     284             :             {
     285         190 :                 if( rImpGraphic.maMetaFile == maMetaFile )
     286         190 :                     bRet = true;
     287             :             }
     288         190 :             break;
     289             : 
     290             :             case( GRAPHIC_BITMAP ):
     291             :             {
     292        1606 :                 if(maSvgData.get())
     293             :                 {
     294           0 :                     if(maSvgData == rImpGraphic.maSvgData)
     295             :                     {
     296           0 :                         bRet = true;
     297             :                     }
     298           0 :                     else if(rImpGraphic.maSvgData)
     299             :                     {
     300           0 :                         if(maSvgData->getSvgDataArrayLength() == rImpGraphic.maSvgData->getSvgDataArrayLength())
     301             :                         {
     302           0 :                             if(0 == memcmp(
     303           0 :                                 maSvgData->getSvgDataArray().get(),
     304           0 :                                 rImpGraphic.maSvgData->getSvgDataArray().get(),
     305           0 :                                 maSvgData->getSvgDataArrayLength()))
     306             :                             {
     307           0 :                                 bRet = true;
     308             :                             }
     309             :                         }
     310             :                     }
     311             :                 }
     312        1606 :                 else if( mpAnimation )
     313             :                 {
     314           0 :                     if( rImpGraphic.mpAnimation && ( *rImpGraphic.mpAnimation == *mpAnimation ) )
     315           0 :                         bRet = true;
     316             :                 }
     317        1606 :                 else if( !rImpGraphic.mpAnimation && ( rImpGraphic.maEx == maEx ) )
     318             :                 {
     319        1576 :                     bRet = true;
     320             :                 }
     321             :             }
     322        1606 :             break;
     323             : 
     324             :             default:
     325           0 :             break;
     326             :         }
     327             :     }
     328             : 
     329        3827 :     return bRet;
     330             : }
     331             : 
     332      642600 : void ImpGraphic::ImplClearGraphics( bool bCreateSwapInfo )
     333             : {
     334      642600 :     if( bCreateSwapInfo && !ImplIsSwapOut() )
     335             :     {
     336          72 :         maSwapInfo.maPrefMapMode = ImplGetPrefMapMode();
     337          72 :         maSwapInfo.maPrefSize = ImplGetPrefSize();
     338             :     }
     339             : 
     340      642600 :     maEx.Clear();
     341      642600 :     maMetaFile.Clear();
     342             : 
     343      642600 :     if( mpAnimation )
     344             :     {
     345          32 :         mpAnimation->Clear();
     346          32 :         delete mpAnimation;
     347          32 :         mpAnimation = NULL;
     348             :     }
     349             : 
     350      642600 :     if( mpGfxLink )
     351             :     {
     352       10971 :         delete mpGfxLink;
     353       10971 :         mpGfxLink = NULL;
     354             :     }
     355             : 
     356      642600 :     maSvgData.reset();
     357      642600 : }
     358             : 
     359      642528 : void ImpGraphic::ImplClear()
     360             : {
     361      642528 :     if( mpSwapFile )
     362             :     {
     363          38 :         if( mpSwapFile->nRefCount > 1 )
     364           0 :             mpSwapFile->nRefCount--;
     365             :         else
     366             :         {
     367             :             try
     368             :             {
     369             :                 ::ucbhelper::Content aCnt( mpSwapFile->aSwapURL.GetMainURL( INetURLObject::NO_DECODE ),
     370             :                                      ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(),
     371          38 :                                      comphelper::getProcessComponentContext() );
     372             : 
     373             :                 aCnt.executeCommand( OUString("delete"),
     374          38 :                                      ::com::sun::star::uno::makeAny( true ) );
     375             :             }
     376           0 :             catch( const ::com::sun::star::ucb::ContentCreationException& )
     377             :             {
     378             :             }
     379           0 :             catch( const ::com::sun::star::uno::RuntimeException& )
     380             :             {
     381             :             }
     382           0 :             catch( const ::com::sun::star::ucb::CommandAbortedException& )
     383             :             {
     384             :             }
     385           0 :             catch( const ::com::sun::star::uno::Exception& )
     386             :             {
     387             :             }
     388             : 
     389          38 :             delete mpSwapFile;
     390             :         }
     391             : 
     392          38 :         mpSwapFile = NULL;
     393             :     }
     394             : 
     395      642528 :     mbSwapOut = false;
     396      642528 :     mnDocFilePos = 0UL;
     397      642528 :     maDocFileURLStr = OUString();
     398             : 
     399             :     // cleanup
     400      642528 :     ImplClearGraphics( false );
     401      642528 :     meType = GRAPHIC_NONE;
     402      642528 :     mnSizeBytes = 0;
     403      642528 : }
     404             : 
     405             : 
     406          56 : void ImpGraphic::ImplSetDefaultType()
     407             : {
     408          56 :     ImplClear();
     409          56 :     meType = GRAPHIC_DEFAULT;
     410          56 : }
     411             : 
     412      240019 : bool ImpGraphic::ImplIsSupportedGraphic() const
     413             : {
     414      240019 :     return( meType != GRAPHIC_NONE );
     415             : }
     416             : 
     417       38067 : bool ImpGraphic::ImplIsTransparent() const
     418             : {
     419       38067 :     bool bRet(true);
     420             : 
     421       38067 :     if( meType == GRAPHIC_BITMAP && !maSvgData.get())
     422             :     {
     423        9957 :         bRet = ( mpAnimation ? mpAnimation->IsTransparent() : maEx.IsTransparent() );
     424             :     }
     425             : 
     426       38067 :     return bRet;
     427             : }
     428             : 
     429       38063 : bool ImpGraphic::ImplIsAlpha() const
     430             : {
     431       38063 :     bool bRet(false);
     432             : 
     433       38063 :     if(maSvgData.get())
     434             :     {
     435          10 :         bRet = true;
     436             :     }
     437       38053 :     else if( meType == GRAPHIC_BITMAP )
     438             :     {
     439        9953 :         bRet = ( NULL == mpAnimation ) && maEx.IsAlpha();
     440             :     }
     441             : 
     442       38063 :     return bRet;
     443             : }
     444             : 
     445      392281 : bool ImpGraphic::ImplIsAnimated() const
     446             : {
     447      392281 :     return( mpAnimation != NULL );
     448             : }
     449             : 
     450       37977 : bool ImpGraphic::ImplIsEPS() const
     451             : {
     452       41121 :     return( ( meType == GRAPHIC_GDIMETAFILE ) &&
     453       41121 :             ( maMetaFile.GetActionSize() > 0 ) &&
     454       41121 :             ( maMetaFile.GetAction( 0 )->GetType() == META_EPS_ACTION ) );
     455             : }
     456             : 
     457         166 : Bitmap ImpGraphic::ImplGetBitmap(const GraphicConversionParameters& rParameters) const
     458             : {
     459         166 :     Bitmap aRetBmp;
     460             : 
     461         166 :     if( meType == GRAPHIC_BITMAP )
     462             :     {
     463           8 :         if(maSvgData.get() && maEx.IsEmpty())
     464             :         {
     465             :             // use maEx as local buffer for rendered svg
     466           0 :             const_cast< ImpGraphic* >(this)->maEx = maSvgData->getReplacement();
     467             :         }
     468             : 
     469           8 :         const BitmapEx& rRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx );
     470           8 :         const Color     aReplaceColor( COL_WHITE );
     471             : 
     472           8 :         aRetBmp = rRetBmpEx.GetBitmap( &aReplaceColor );
     473             : 
     474           8 :         if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height())
     475           0 :             aRetBmp.Scale(rParameters.getSizePixel());
     476             :     }
     477         158 :     else if( ( meType != GRAPHIC_DEFAULT ) && ImplIsSupportedGraphic() )
     478             :     {
     479         158 :         if(maEx.IsEmpty())
     480             :         {
     481             :             // calculate size
     482         158 :             VirtualDevice aVDev;
     483         158 :             Size aDrawSize(aVDev.LogicToPixel(maMetaFile.GetPrefSize(), maMetaFile.GetPrefMapMode()));
     484             : 
     485         158 :             if(rParameters.getSizePixel().Width() && rParameters.getSizePixel().Height())
     486             :             {
     487             :                 // apply given size if exists
     488           2 :                 aDrawSize = rParameters.getSizePixel();
     489             :             }
     490             : 
     491         394 :             if(aDrawSize.Width() && aDrawSize.Height() && !rParameters.getUnlimitedSize()
     492         236 :                 && (aDrawSize.Width() > GRAPHIC_MTFTOBMP_MAXEXT || aDrawSize.Height() > GRAPHIC_MTFTOBMP_MAXEXT))
     493             :             {
     494             :                 // limit bitmap size to a maximum of GRAPHIC_MTFTOBMP_MAXEXT x GRAPHIC_MTFTOBMP_MAXEXT
     495           0 :                 double fWH((double)aDrawSize.Width() / (double)aDrawSize.Height());
     496             : 
     497           0 :                 if(fWH <= 1.0)
     498             :                 {
     499           0 :                     aDrawSize.setWidth(basegfx::fround(GRAPHIC_MTFTOBMP_MAXEXT * fWH));
     500           0 :                     aDrawSize.setHeight(GRAPHIC_MTFTOBMP_MAXEXT);
     501             :                 }
     502             :                 else
     503             :                 {
     504           0 :                     aDrawSize.setWidth(GRAPHIC_MTFTOBMP_MAXEXT);
     505           0 :                     aDrawSize.setHeight(basegfx::fround(GRAPHIC_MTFTOBMP_MAXEXT / fWH));
     506             :                 }
     507             :             }
     508             : 
     509             :             // calculate pixel size. Normally, it's the same as aDrawSize, but may
     510             :             // need to be extended when hairlines are on the right or bottom edge
     511         158 :             Size aPixelSize(aDrawSize);
     512             : 
     513         158 :             if(GRAPHIC_GDIMETAFILE == ImplGetType())
     514             :             {
     515             :                 // get hairline and full bound rect
     516         158 :                 Rectangle aHairlineRect;
     517         158 :                 const Rectangle aRect(maMetaFile.GetBoundRect(aVDev, &aHairlineRect));
     518             : 
     519         158 :                 if(!aRect.IsEmpty() && !aHairlineRect.IsEmpty())
     520             :                 {
     521             :                     // expand if needed to allow bottom and right hairlines to be added
     522           0 :                     if(aRect.Right() == aHairlineRect.Right())
     523             :                     {
     524           0 :                         aPixelSize.setWidth(aPixelSize.getWidth() + 1);
     525             :                     }
     526             : 
     527           0 :                     if(aRect.Bottom() == aHairlineRect.Bottom())
     528             :                     {
     529           0 :                         aPixelSize.setHeight(aPixelSize.getHeight() + 1);
     530             :                     }
     531             :                 }
     532             :             }
     533             : 
     534         158 :             if(aVDev.SetOutputSizePixel(aPixelSize))
     535             :             {
     536         158 :                 if(rParameters.getAntiAliase())
     537             :                 {
     538           2 :                     aVDev.SetAntialiasing(aVDev.GetAntialiasing() | ANTIALIASING_ENABLE_B2DDRAW);
     539             :                 }
     540             : 
     541         158 :                 if(rParameters.getSnapHorVerLines())
     542             :                 {
     543           2 :                     aVDev.SetAntialiasing(aVDev.GetAntialiasing() | ANTIALIASING_PIXELSNAPHAIRLINE);
     544             :                 }
     545             : 
     546         158 :                 ImplDraw( &aVDev, Point(), aDrawSize );
     547             : 
     548             :                 // use maEx as local buffer for rendered metafile
     549         158 :                 const_cast< ImpGraphic* >(this)->maEx = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() );
     550         158 :             }
     551             :         }
     552             : 
     553         158 :         aRetBmp = maEx.GetBitmap();
     554             :     }
     555             : 
     556         166 :     if( !!aRetBmp )
     557             :     {
     558          86 :         aRetBmp.SetPrefMapMode( ImplGetPrefMapMode() );
     559          86 :         aRetBmp.SetPrefSize( ImplGetPrefSize() );
     560             :     }
     561             : 
     562         166 :     return aRetBmp;
     563             : }
     564             : 
     565      356896 : BitmapEx ImpGraphic::ImplGetBitmapEx(const GraphicConversionParameters& rParameters) const
     566             : {
     567      356896 :     BitmapEx aRetBmpEx;
     568             : 
     569      356896 :     if( meType == GRAPHIC_BITMAP )
     570             :     {
     571      143398 :         if(maSvgData.get() && maEx.IsEmpty())
     572             :         {
     573             :             // use maEx as local buffer for rendered svg
     574         294 :             const_cast< ImpGraphic* >(this)->maEx = maSvgData->getReplacement();
     575             :         }
     576             : 
     577      143398 :         aRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx );
     578             : 
     579      143398 :         if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height())
     580             :         {
     581             :             aRetBmpEx.Scale(
     582             :                 rParameters.getSizePixel(),
     583           0 :                 rParameters.getScaleHighQuality() ? BMP_SCALE_INTERPOLATE : BMP_SCALE_FAST);
     584             :         }
     585             :     }
     586      213498 :     else if( ( meType != GRAPHIC_DEFAULT ) && ImplIsSupportedGraphic() )
     587             :     {
     588          79 :         if(maEx.IsEmpty())
     589             :         {
     590          79 :             const ImpGraphic aMonoMask( maMetaFile.GetMonochromeMtf( COL_BLACK ) );
     591             : 
     592             :             // use maEx as local buffer for rendered metafile
     593          79 :             const_cast< ImpGraphic* >(this)->maEx = BitmapEx(ImplGetBitmap(rParameters), aMonoMask.ImplGetBitmap(rParameters));
     594             :         }
     595             : 
     596          79 :         aRetBmpEx = maEx;
     597             :     }
     598             : 
     599      356896 :     return aRetBmpEx;
     600             : }
     601             : 
     602           0 : Animation ImpGraphic::ImplGetAnimation() const
     603             : {
     604           0 :     Animation aAnimation;
     605             : 
     606           0 :     if( mpAnimation )
     607           0 :         aAnimation = *mpAnimation;
     608             : 
     609           0 :     return aAnimation;
     610             : }
     611             : 
     612        2856 : const GDIMetaFile& ImpGraphic::ImplGetGDIMetaFile() const
     613             : {
     614        2856 :     if (GRAPHIC_BITMAP == meType && !maMetaFile.GetActionSize())
     615             :     {
     616             :         // #i119735#
     617             :         // Use the local maMetaFile as container for a metafile-representation
     618             :         // of the bitmap graphic. This will be done only once, thus be buffered.
     619             :         // I checked all usages of maMetaFile, it is only used when type is not
     620             :         // GRAPHIC_BITMAP. In operator= it will get copied, thus buffering will
     621             :         // survive copying (change this if not wanted)
     622           8 :         ImpGraphic* pThat = const_cast< ImpGraphic* >(this);
     623             : 
     624           8 :         if(maSvgData.get() && !maEx)
     625             :         {
     626             :             // use maEx as local buffer for rendered svg
     627           2 :             pThat->maEx = maSvgData->getReplacement();
     628             :         }
     629             : 
     630             :         // #123983# directly create a metafile with the same PrefSize and PrefMapMode
     631             :         // the bitmap has, this will be an always correct metafile
     632           8 :         if(maEx.IsTransparent())
     633             :         {
     634           6 :             pThat->maMetaFile.AddAction(new MetaBmpExScaleAction(Point(), maEx.GetPrefSize(), maEx));
     635             :         }
     636             :         else
     637             :         {
     638           2 :             pThat->maMetaFile.AddAction(new MetaBmpScaleAction(Point(), maEx.GetPrefSize(), maEx.GetBitmap()));
     639             :         }
     640             : 
     641           8 :         pThat->maMetaFile.Stop();
     642           8 :         pThat->maMetaFile.WindStart();
     643           8 :         pThat->maMetaFile.SetPrefSize(maEx.GetPrefSize());
     644           8 :         pThat->maMetaFile.SetPrefMapMode(maEx.GetPrefMapMode());
     645             :     }
     646             : 
     647        2856 :     return maMetaFile;
     648             : }
     649             : 
     650       53122 : Size ImpGraphic::ImplGetPrefSize() const
     651             : {
     652       53122 :     Size aSize;
     653             : 
     654       53122 :     if( ImplIsSwapOut() )
     655           2 :         aSize = maSwapInfo.maPrefSize;
     656             :     else
     657             :     {
     658       53120 :         switch( meType )
     659             :         {
     660             :             case( GRAPHIC_NONE ):
     661             :             case( GRAPHIC_DEFAULT ):
     662       27858 :             break;
     663             : 
     664             :             case( GRAPHIC_BITMAP ):
     665             :             {
     666       19539 :                 if(maSvgData.get() && maEx.IsEmpty())
     667             :                 {
     668             :                     // svg not yet buffered in maEx, return size derived from range
     669          26 :                     const basegfx::B2DRange& rRange = maSvgData->getRange();
     670             : 
     671          26 :                     aSize = Size(basegfx::fround(rRange.getWidth()), basegfx::fround(rRange.getHeight()));
     672             :                 }
     673             :                 else
     674             :                 {
     675       19513 :                     aSize = maEx.GetPrefSize();
     676             : 
     677       19513 :                     if( !aSize.Width() || !aSize.Height() )
     678             :                     {
     679        5339 :                         aSize = maEx.GetSizePixel();
     680             :                     }
     681             :                 }
     682             :             }
     683       19539 :             break;
     684             : 
     685             :             default:
     686             :             {
     687        5723 :                 if( ImplIsSupportedGraphic() )
     688        5723 :                   aSize = maMetaFile.GetPrefSize();
     689             :             }
     690        5723 :             break;
     691             :         }
     692             :     }
     693             : 
     694       53122 :     return aSize;
     695             : }
     696             : 
     697        8752 : void ImpGraphic::ImplSetPrefSize( const Size& rPrefSize )
     698             : {
     699        8752 :     switch( meType )
     700             :     {
     701             :         case( GRAPHIC_NONE ):
     702             :         case( GRAPHIC_DEFAULT ):
     703           6 :         break;
     704             : 
     705             :         case( GRAPHIC_BITMAP ):
     706             :         {
     707             :             //UUUU used when importing a writer FlyFrame with SVG as graphic, added conversion
     708             :             // to allow setting the PrefSize at the BitmapEx to hold it
     709        6462 :             if(maSvgData.get() && maEx.IsEmpty())
     710             :             {
     711             :                 // use maEx as local buffer for rendered svg
     712           4 :                 const_cast< ImpGraphic* >(this)->maEx = maSvgData->getReplacement();
     713             :             }
     714             : 
     715             :             // #108077# Push through pref size to animation object,
     716             :             // will be lost on copy otherwise
     717        6462 :             if( ImplIsAnimated() )
     718             :             {
     719           0 :                 const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefSize( rPrefSize );
     720             :             }
     721             : 
     722        6462 :             maEx.SetPrefSize( rPrefSize );
     723             :         }
     724        6462 :         break;
     725             : 
     726             :         default:
     727             :         {
     728        2284 :             if( ImplIsSupportedGraphic() )
     729        2284 :                 maMetaFile.SetPrefSize( rPrefSize );
     730             :         }
     731        2284 :         break;
     732             :     }
     733        8752 : }
     734             : 
     735       52729 : MapMode ImpGraphic::ImplGetPrefMapMode() const
     736             : {
     737       52729 :     MapMode aMapMode;
     738             : 
     739       52729 :     if( ImplIsSwapOut() )
     740           2 :         aMapMode = maSwapInfo.maPrefMapMode;
     741             :     else
     742             :     {
     743       52727 :         switch( meType )
     744             :         {
     745             :             case( GRAPHIC_NONE ):
     746             :             case( GRAPHIC_DEFAULT ):
     747       27848 :             break;
     748             : 
     749             :             case( GRAPHIC_BITMAP ):
     750             :             {
     751       19237 :                 if(maSvgData.get() && maEx.IsEmpty())
     752             :                 {
     753             :                     // svg not yet buffered in maEx, return default PrefMapMode
     754          34 :                     aMapMode = MapMode(MAP_100TH_MM);
     755             :                 }
     756             :                 else
     757             :                 {
     758       19203 :                     const Size aSize( maEx.GetPrefSize() );
     759             : 
     760       19203 :                     if ( aSize.Width() && aSize.Height() )
     761       13766 :                         aMapMode = maEx.GetPrefMapMode();
     762             :                 }
     763             :             }
     764       19237 :             break;
     765             : 
     766             :             default:
     767             :             {
     768        5642 :                 if( ImplIsSupportedGraphic() )
     769        5642 :                     return maMetaFile.GetPrefMapMode();
     770             :             }
     771           0 :             break;
     772             :         }
     773             :     }
     774             : 
     775       47087 :     return aMapMode;
     776             : }
     777             : 
     778        8752 : void ImpGraphic::ImplSetPrefMapMode( const MapMode& rPrefMapMode )
     779             : {
     780        8752 :     switch( meType )
     781             :     {
     782             :         case( GRAPHIC_NONE ):
     783             :         case( GRAPHIC_DEFAULT ):
     784           6 :         break;
     785             : 
     786             :         case( GRAPHIC_BITMAP ):
     787             :         {
     788        6462 :             if(maSvgData.get())
     789             :             {
     790             :                 // ignore for Svg. If this is really used (except the grfcache)
     791             :                 // it can be extended by using maEx as buffer for maSvgData->getReplacement()
     792             :             }
     793             :             else
     794             :             {
     795             :                 // #108077# Push through pref mapmode to animation object,
     796             :                 // will be lost on copy otherwise
     797        6458 :                 if( ImplIsAnimated() )
     798             :                 {
     799           0 :                     const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefMapMode( rPrefMapMode );
     800             :                 }
     801             : 
     802        6458 :                 maEx.SetPrefMapMode( rPrefMapMode );
     803             :             }
     804             :         }
     805        6462 :         break;
     806             : 
     807             :         default:
     808             :         {
     809        2284 :             if( ImplIsSupportedGraphic() )
     810        2284 :                 maMetaFile.SetPrefMapMode( rPrefMapMode );
     811             :         }
     812        2284 :         break;
     813             :     }
     814        8752 : }
     815             : 
     816       40407 : sal_uLong ImpGraphic::ImplGetSizeBytes() const
     817             : {
     818       40407 :     if( 0 == mnSizeBytes )
     819             :     {
     820       32946 :         if( meType == GRAPHIC_BITMAP )
     821             :         {
     822        6048 :             if(maSvgData.get())
     823             :             {
     824           8 :                 mnSizeBytes = maSvgData->getSvgDataArrayLength();
     825             :             }
     826             :             else
     827             :             {
     828        6040 :                 mnSizeBytes = mpAnimation ? mpAnimation->GetSizeBytes() : maEx.GetSizeBytes();
     829             :             }
     830             :         }
     831       26898 :         else if( meType == GRAPHIC_GDIMETAFILE )
     832             :         {
     833        1942 :             mnSizeBytes = maMetaFile.GetSizeBytes();
     834             :         }
     835             :     }
     836             : 
     837       40407 :     return( mnSizeBytes );
     838             : }
     839             : 
     840           0 : void ImpGraphic::ImplDraw( OutputDevice* pOutDev, const Point& rDestPt ) const
     841             : {
     842           0 :     if( ImplIsSupportedGraphic() && !ImplIsSwapOut() )
     843             :     {
     844           0 :         switch( meType )
     845             :         {
     846             :             case( GRAPHIC_DEFAULT ):
     847           0 :             break;
     848             : 
     849             :             case( GRAPHIC_BITMAP ):
     850             :             {
     851           0 :                 if(maSvgData.get() && !maEx)
     852             :                 {
     853             :                     // use maEx as local buffer for rendered svg
     854           0 :                     const_cast< ImpGraphic* >(this)->maEx = maSvgData->getReplacement();
     855             :                 }
     856             : 
     857           0 :                 if ( mpAnimation )
     858             :                 {
     859           0 :                     mpAnimation->Draw( pOutDev, rDestPt );
     860             :                 }
     861             :                 else
     862             :                 {
     863           0 :                     maEx.Draw( pOutDev, rDestPt );
     864             :                 }
     865             :             }
     866           0 :             break;
     867             : 
     868             :             default:
     869           0 :                 ImplDraw( pOutDev, rDestPt, maMetaFile.GetPrefSize() );
     870           0 :             break;
     871             :         }
     872             :     }
     873           0 : }
     874             : 
     875         268 : void ImpGraphic::ImplDraw( OutputDevice* pOutDev,
     876             :                            const Point& rDestPt, const Size& rDestSize ) const
     877             : {
     878         268 :     if( ImplIsSupportedGraphic() && !ImplIsSwapOut() )
     879             :     {
     880         268 :         switch( meType )
     881             :         {
     882             :             case( GRAPHIC_DEFAULT ):
     883           0 :             break;
     884             : 
     885             :             case( GRAPHIC_BITMAP ):
     886             :             {
     887           0 :                 if(maSvgData.get() && maEx.IsEmpty())
     888             :                 {
     889             :                     // use maEx as local buffer for rendered svg
     890           0 :                     const_cast< ImpGraphic* >(this)->maEx = maSvgData->getReplacement();
     891             :                 }
     892             : 
     893           0 :                 if( mpAnimation )
     894             :                 {
     895           0 :                     mpAnimation->Draw( pOutDev, rDestPt, rDestSize );
     896             :                 }
     897             :                 else
     898             :                 {
     899           0 :                     maEx.Draw( pOutDev, rDestPt, rDestSize );
     900             :                 }
     901             :             }
     902           0 :             break;
     903             : 
     904             :             default:
     905             :             {
     906         268 :                 ( (ImpGraphic*) this )->maMetaFile.WindStart();
     907         268 :                 ( (ImpGraphic*) this )->maMetaFile.Play( pOutDev, rDestPt, rDestSize );
     908         268 :                 ( (ImpGraphic*) this )->maMetaFile.WindStart();
     909             :             }
     910         268 :             break;
     911             :         }
     912             :     }
     913         268 : }
     914             : 
     915           0 : void ImpGraphic::ImplStartAnimation( OutputDevice* pOutDev, const Point& rDestPt,
     916             :                                      const Size& rDestSize, long nExtraData,
     917             :                                      OutputDevice* pFirstFrameOutDev )
     918             : {
     919           0 :     if( ImplIsSupportedGraphic() && !ImplIsSwapOut() && mpAnimation )
     920           0 :         mpAnimation->Start( pOutDev, rDestPt, rDestSize, nExtraData, pFirstFrameOutDev );
     921           0 : }
     922             : 
     923           0 : void ImpGraphic::ImplStopAnimation( OutputDevice* pOutDev, long nExtraData )
     924             : {
     925           0 :     if( ImplIsSupportedGraphic() && !ImplIsSwapOut() && mpAnimation )
     926           0 :         mpAnimation->Stop( pOutDev, nExtraData );
     927           0 : }
     928             : 
     929        8180 : void ImpGraphic::ImplSetAnimationNotifyHdl( const Link& rLink )
     930             : {
     931        8180 :     if( mpAnimation )
     932           0 :         mpAnimation->SetNotifyHdl( rLink );
     933        8180 : }
     934             : 
     935       10892 : Link ImpGraphic::ImplGetAnimationNotifyHdl() const
     936             : {
     937       10892 :     Link aLink;
     938             : 
     939       10892 :     if( mpAnimation )
     940           0 :         aLink = mpAnimation->GetNotifyHdl();
     941             : 
     942       10892 :     return aLink;
     943             : }
     944             : 
     945           0 : sal_uLong ImpGraphic::ImplGetAnimationLoopCount() const
     946             : {
     947           0 :     return( mpAnimation ? mpAnimation->GetLoopCount() : 0UL );
     948             : }
     949             : 
     950             : 
     951         671 : void ImpGraphic::ImplSetContext( GraphicReader* pReader )
     952             : {
     953         671 :     mpContext = pReader;
     954         671 : }
     955             : 
     956        8180 : void ImpGraphic::ImplSetDocFileName( const OUString& rName, sal_uLong nFilePos )
     957             : {
     958        8180 :     const INetURLObject aURL( rName );
     959             : 
     960             :     DBG_ASSERT( rName.isEmpty() || ( aURL.GetProtocol() != INET_PROT_NOT_VALID ), "Graphic::SetDocFileName(...): invalid URL" );
     961             : 
     962        8180 :     maDocFileURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE );
     963        8180 :     mnDocFilePos = nFilePos;
     964        8180 : }
     965             : 
     966       10892 : const OUString& ImpGraphic::ImplGetDocFileName() const
     967             : {
     968       10892 :     return maDocFileURLStr;
     969             : }
     970             : 
     971             : 
     972          30 : bool ImpGraphic::ImplReadEmbedded( SvStream& rIStm, bool bSwap )
     973             : {
     974          30 :     MapMode         aMapMode;
     975          30 :     Size            aSize;
     976          30 :     const sal_uLong     nStartPos = rIStm.Tell();
     977             :     sal_uInt32      nId;
     978             :     sal_uLong           nHeaderLen;
     979             :     sal_Int32       nType;
     980             :     sal_Int32       nLen;
     981          30 :     const sal_uInt16    nOldFormat = rIStm.GetNumberFormatInt();
     982          30 :     bool            bRet = false;
     983             : 
     984          30 :     if( !mbSwapUnderway )
     985             :     {
     986           0 :         const OUString aTempURLStr( maDocFileURLStr );
     987           0 :         const sal_uLong nTempPos = mnDocFilePos;
     988             : 
     989           0 :         ImplClear();
     990             : 
     991           0 :         maDocFileURLStr = aTempURLStr;
     992           0 :         mnDocFilePos = nTempPos;
     993             :     }
     994             : 
     995          30 :     rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
     996          30 :     rIStm.ReadUInt32( nId );
     997             : 
     998             :     // check version
     999          30 :     if( GRAPHIC_FORMAT_50 == nId )
    1000             :     {
    1001             :         // read new style header
    1002          30 :         VersionCompat* pCompat = new VersionCompat( rIStm, STREAM_READ );
    1003             : 
    1004          30 :         rIStm.ReadInt32( nType );
    1005          30 :         rIStm.ReadInt32( nLen );
    1006          30 :         ReadPair( rIStm, aSize );
    1007          30 :         ReadMapMode( rIStm, aMapMode );
    1008             : 
    1009          30 :         delete pCompat;
    1010             :     }
    1011             :     else
    1012             :     {
    1013             :         // read old style header
    1014             :         sal_Int32 nWidth, nHeight;
    1015             :         sal_Int32 nMapMode, nScaleNumX, nScaleDenomX;
    1016             :         sal_Int32 nScaleNumY, nScaleDenomY, nOffsX, nOffsY;
    1017             : 
    1018           0 :         rIStm.SeekRel( -4L );
    1019             : 
    1020           0 :         rIStm.ReadInt32( nType ).ReadInt32( nLen ).ReadInt32( nWidth ).ReadInt32( nHeight );
    1021           0 :         rIStm.ReadInt32( nMapMode ).ReadInt32( nScaleNumX ).ReadInt32( nScaleDenomX ).ReadInt32( nScaleNumY );
    1022           0 :         rIStm.ReadInt32( nScaleDenomY ).ReadInt32( nOffsX ).ReadInt32( nOffsY );
    1023             : 
    1024             :         // swapped
    1025           0 :         if( nType > 100L )
    1026             :         {
    1027           0 :             nType = OSL_SWAPDWORD( nType );
    1028           0 :             nLen = OSL_SWAPDWORD( nLen );
    1029           0 :             nWidth = OSL_SWAPDWORD( nWidth );
    1030           0 :             nHeight = OSL_SWAPDWORD( nHeight );
    1031           0 :             nMapMode = OSL_SWAPDWORD( nMapMode );
    1032           0 :             nScaleNumX = OSL_SWAPDWORD( nScaleNumX );
    1033           0 :             nScaleDenomX = OSL_SWAPDWORD( nScaleDenomX );
    1034           0 :             nScaleNumY = OSL_SWAPDWORD( nScaleNumY );
    1035           0 :             nScaleDenomY = OSL_SWAPDWORD( nScaleDenomY );
    1036           0 :             nOffsX = OSL_SWAPDWORD( nOffsX );
    1037           0 :             nOffsY = OSL_SWAPDWORD( nOffsY );
    1038             :         }
    1039             : 
    1040           0 :         aSize = Size( nWidth, nHeight );
    1041           0 :         aMapMode = MapMode( (MapUnit) nMapMode, Point( nOffsX, nOffsY ),
    1042             :                             Fraction( nScaleNumX, nScaleDenomX ),
    1043           0 :                             Fraction( nScaleNumY, nScaleDenomY ) );
    1044             :     }
    1045             : 
    1046          30 :     nHeaderLen = rIStm.Tell() - nStartPos;
    1047          30 :     meType = (GraphicType) nType;
    1048             : 
    1049          30 :     if( meType )
    1050             :     {
    1051          30 :         if( meType == GRAPHIC_BITMAP )
    1052             :         {
    1053          30 :             if(maSvgData.get() && maEx.IsEmpty())
    1054             :             {
    1055             :                 // use maEx as local buffer for rendered svg
    1056           0 :                 maEx = maSvgData->getReplacement();
    1057             :             }
    1058             : 
    1059          30 :             maEx.aBitmapSize = aSize;
    1060             : 
    1061          30 :             if( aMapMode != MapMode() )
    1062             :             {
    1063          24 :                 maEx.SetPrefMapMode( aMapMode );
    1064          24 :                 maEx.SetPrefSize( aSize );
    1065             :             }
    1066             :         }
    1067             :         else
    1068             :         {
    1069           0 :             maMetaFile.SetPrefMapMode( aMapMode );
    1070           0 :             maMetaFile.SetPrefSize( aSize );
    1071             :         }
    1072             : 
    1073          30 :         if( bSwap )
    1074             :         {
    1075           0 :             if (!maDocFileURLStr.isEmpty())
    1076             :             {
    1077           0 :                 rIStm.Seek( nStartPos + nHeaderLen + nLen );
    1078           0 :                 bRet = mbSwapOut = true;
    1079             :             }
    1080             :             else
    1081             :             {
    1082           0 :                 ::utl::TempFile     aTempFile;
    1083           0 :                 const INetURLObject aTmpURL( aTempFile.GetURL() );
    1084             : 
    1085           0 :                 if( !aTmpURL.GetMainURL( INetURLObject::NO_DECODE ).isEmpty() )
    1086             :                 {
    1087           0 :                     boost::scoped_ptr<SvStream> pOStm;
    1088             :                     try
    1089             :                     {
    1090           0 :                         pOStm.reset(::utl::UcbStreamHelper::CreateStream( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READWRITE | STREAM_SHARE_DENYWRITE ));
    1091             :                     }
    1092           0 :                     catch( const ::com::sun::star::uno::Exception& )
    1093             :                     {
    1094             :                     }
    1095             : 
    1096           0 :                     if( pOStm )
    1097             :                     {
    1098           0 :                         sal_uLong   nFullLen = nHeaderLen + nLen;
    1099           0 :                         sal_uLong   nPartLen = std::min( nFullLen, (sal_uLong) GRAPHIC_MAXPARTLEN );
    1100           0 :                         sal_uInt8*  pBuffer = (sal_uInt8*) rtl_allocateMemory( nPartLen );
    1101             : 
    1102           0 :                           pOStm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
    1103             : 
    1104           0 :                         if( pBuffer )
    1105             :                         {
    1106           0 :                             rIStm.Seek( nStartPos );
    1107             : 
    1108           0 :                             while( nFullLen )
    1109             :                             {
    1110           0 :                                 rIStm.Read( (char*) pBuffer, nPartLen );
    1111           0 :                                 pOStm->Write( (char*) pBuffer, nPartLen );
    1112             : 
    1113           0 :                                 nFullLen -= nPartLen;
    1114             : 
    1115           0 :                                 if( nFullLen < GRAPHIC_MAXPARTLEN )
    1116           0 :                                     nPartLen = nFullLen;
    1117             :                             }
    1118             : 
    1119           0 :                             rtl_freeMemory( pBuffer );
    1120           0 :                             sal_uLong nReadErr = rIStm.GetError(), nWriteErr = pOStm->GetError();
    1121           0 :                             pOStm.reset();
    1122             : 
    1123           0 :                             if( !nReadErr && !nWriteErr )
    1124             :                             {
    1125           0 :                                 bRet = mbSwapOut = true;
    1126           0 :                                 mpSwapFile = new ImpSwapFile;
    1127           0 :                                 mpSwapFile->nRefCount = 1;
    1128           0 :                                 mpSwapFile->aSwapURL = aTmpURL;
    1129             :                             }
    1130             :                             else
    1131             :                             {
    1132             :                                 try
    1133             :                                 {
    1134             :                                     ::ucbhelper::Content aCnt( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ),
    1135             :                                                          ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(),
    1136           0 :                                                          comphelper::getProcessComponentContext() );
    1137             : 
    1138             :                                     aCnt.executeCommand( OUString("delete"),
    1139           0 :                                                          ::com::sun::star::uno::makeAny( true ) );
    1140             :                                 }
    1141           0 :                                 catch( const ::com::sun::star::ucb::ContentCreationException& )
    1142             :                                 {
    1143             :                                 }
    1144           0 :                                 catch( const ::com::sun::star::uno::RuntimeException& )
    1145             :                                 {
    1146             :                                 }
    1147           0 :                                 catch( const ::com::sun::star::ucb::CommandAbortedException& )
    1148             :                                 {
    1149             :                                 }
    1150           0 :                                 catch( const ::com::sun::star::uno::Exception& )
    1151             :                                 {
    1152             :                                 }
    1153             :                             }
    1154             :                         }
    1155           0 :                     }
    1156           0 :                 }
    1157             :             }
    1158             :         }
    1159          30 :         else if( meType == GRAPHIC_BITMAP || meType == GRAPHIC_GDIMETAFILE )
    1160             :         {
    1161          30 :             ReadImpGraphic( rIStm, *this );
    1162          30 :             bRet = ( rIStm.GetError() == 0UL );
    1163             :         }
    1164           0 :         else if( sal::static_int_cast<sal_uLong>(meType) >= SYS_WINMETAFILE
    1165           0 :                  && sal::static_int_cast<sal_uLong>(meType) <= SYS_MACMETAFILE )
    1166             :         {
    1167           0 :             Graphic aSysGraphic;
    1168             :             sal_uLong   nCvtType;
    1169             : 
    1170           0 :             switch( sal::static_int_cast<sal_uLong>(meType) )
    1171             :             {
    1172             :                 case( SYS_WINMETAFILE ):
    1173           0 :                 case( SYS_WNTMETAFILE ): nCvtType = CVT_WMF; break;
    1174           0 :                 case( SYS_OS2METAFILE ): nCvtType = CVT_MET; break;
    1175           0 :                 case( SYS_MACMETAFILE ): nCvtType = CVT_PCT; break;
    1176             : 
    1177             :                 default:
    1178           0 :                     nCvtType = CVT_UNKNOWN;
    1179           0 :                 break;
    1180             :             }
    1181             : 
    1182           0 :             if( nType && GraphicConverter::Import( rIStm, aSysGraphic, nCvtType ) == ERRCODE_NONE )
    1183             :             {
    1184           0 :                 *this = ImpGraphic( aSysGraphic.GetGDIMetaFile() );
    1185           0 :                 bRet = ( rIStm.GetError() == 0UL );
    1186             :             }
    1187             :             else
    1188           0 :                 meType = GRAPHIC_DEFAULT;
    1189             :         }
    1190             : 
    1191          30 :         if( bRet )
    1192             :         {
    1193          30 :             ImplSetPrefMapMode( aMapMode );
    1194          30 :             ImplSetPrefSize( aSize );
    1195             :         }
    1196             :     }
    1197             :     else
    1198           0 :         bRet = true;
    1199             : 
    1200          30 :     rIStm.SetNumberFormatInt( nOldFormat );
    1201             : 
    1202          30 :     return bRet;
    1203             : }
    1204             : 
    1205          68 : bool ImpGraphic::ImplWriteEmbedded( SvStream& rOStm )
    1206             : {
    1207          68 :     bool bRet = false;
    1208             : 
    1209          68 :     if( ( meType != GRAPHIC_NONE ) && ( meType != GRAPHIC_DEFAULT ) && !ImplIsSwapOut() )
    1210             :     {
    1211          68 :         const MapMode   aMapMode( ImplGetPrefMapMode() );
    1212          68 :         const Size      aSize( ImplGetPrefSize() );
    1213          68 :         const sal_uInt16    nOldFormat = rOStm.GetNumberFormatInt();
    1214             :         sal_uLong           nDataFieldPos;
    1215             : 
    1216          68 :         rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
    1217             : 
    1218             :         // write correct version ( old style/new style header )
    1219          68 :         if( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 )
    1220             :         {
    1221             :             // write ID for new format (5.0)
    1222          68 :             rOStm.WriteUInt32( GRAPHIC_FORMAT_50 );
    1223             : 
    1224             :             // write new style header
    1225          68 :             VersionCompat* pCompat = new VersionCompat( rOStm, STREAM_WRITE, 1 );
    1226             : 
    1227          68 :             rOStm.WriteInt32( meType );
    1228             : 
    1229             :             // data size is updated later
    1230          68 :             nDataFieldPos = rOStm.Tell();
    1231          68 :             rOStm.WriteInt32( 0 );
    1232             : 
    1233          68 :             WritePair( rOStm, aSize );
    1234          68 :             WriteMapMode( rOStm, aMapMode );
    1235             : 
    1236          68 :             delete pCompat;
    1237             :         }
    1238             :         else
    1239             :         {
    1240             :             // write old style (<=4.0) header
    1241           0 :             rOStm.WriteInt32( meType );
    1242             : 
    1243             :             // data size is updated later
    1244           0 :             nDataFieldPos = rOStm.Tell();
    1245           0 :             rOStm.WriteInt32( 0 );
    1246           0 :             rOStm.WriteInt32( aSize.Width() );
    1247           0 :             rOStm.WriteInt32( aSize.Height() );
    1248           0 :             rOStm.WriteInt32( aMapMode.GetMapUnit() );
    1249           0 :             rOStm.WriteInt32( aMapMode.GetScaleX().GetNumerator() );
    1250           0 :             rOStm.WriteInt32( aMapMode.GetScaleX().GetDenominator() );
    1251           0 :             rOStm.WriteInt32( aMapMode.GetScaleY().GetNumerator() );
    1252           0 :             rOStm.WriteInt32( aMapMode.GetScaleY().GetDenominator() );
    1253           0 :             rOStm.WriteInt32( aMapMode.GetOrigin().X() );
    1254           0 :             rOStm.WriteInt32( aMapMode.GetOrigin().Y() );
    1255             :         }
    1256             : 
    1257             :         // write data block
    1258          68 :         if( !rOStm.GetError() )
    1259             :         {
    1260          68 :             const sal_uLong nDataStart = rOStm.Tell();
    1261             : 
    1262          68 :             if( ImplIsSupportedGraphic() )
    1263          68 :                 WriteImpGraphic( rOStm, *this );
    1264             : 
    1265          68 :             if( !rOStm.GetError() )
    1266             :             {
    1267          68 :                 const sal_uLong nStmPos2 = rOStm.Tell();
    1268          68 :                 rOStm.Seek( nDataFieldPos );
    1269          68 :                 rOStm.WriteInt32( nStmPos2 - nDataStart );
    1270          68 :                 rOStm.Seek( nStmPos2 );
    1271          68 :                 bRet = true;
    1272             :             }
    1273             :         }
    1274             : 
    1275          68 :         rOStm.SetNumberFormatInt( nOldFormat );
    1276             :     }
    1277             : 
    1278          68 :     return bRet;
    1279             : }
    1280             : 
    1281          68 : bool ImpGraphic::ImplSwapOut()
    1282             : {
    1283          68 :     bool bRet = false;
    1284             : 
    1285          68 :     if( !ImplIsSwapOut() )
    1286             :     {
    1287          68 :         if (maDocFileURLStr.isEmpty())
    1288             :         {
    1289          68 :             ::utl::TempFile     aTempFile;
    1290         136 :             const INetURLObject aTmpURL( aTempFile.GetURL() );
    1291             : 
    1292          68 :             if( !aTmpURL.GetMainURL( INetURLObject::NO_DECODE ).isEmpty() )
    1293             :             {
    1294          68 :                 boost::scoped_ptr<SvStream> pOStm;
    1295             :                 try
    1296             :                 {
    1297          68 :                     pOStm.reset(::utl::UcbStreamHelper::CreateStream( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READWRITE | STREAM_SHARE_DENYWRITE ));
    1298             :                 }
    1299           0 :                 catch( const ::com::sun::star::uno::Exception& )
    1300             :                 {
    1301             :                 }
    1302          68 :                 if( pOStm )
    1303             :                 {
    1304          68 :                     pOStm->SetVersion( SOFFICE_FILEFORMAT_50 );
    1305          68 :                     pOStm->SetCompressMode( COMPRESSMODE_NATIVE );
    1306             : 
    1307          68 :                     if( ( bRet = ImplSwapOut( pOStm.get() ) ) )
    1308             :                     {
    1309          68 :                         mpSwapFile = new ImpSwapFile;
    1310          68 :                         mpSwapFile->nRefCount = 1;
    1311          68 :                         mpSwapFile->aSwapURL = aTmpURL;
    1312             :                     }
    1313             :                     else
    1314             :                     {
    1315           0 :                         pOStm.reset();
    1316             : 
    1317             :                         try
    1318             :                         {
    1319             :                             ::ucbhelper::Content aCnt( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ),
    1320             :                                                  ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(),
    1321           0 :                                                  comphelper::getProcessComponentContext() );
    1322             : 
    1323             :                             aCnt.executeCommand( OUString("delete"),
    1324           0 :                                                  ::com::sun::star::uno::makeAny( true ) );
    1325             :                         }
    1326           0 :                         catch( const ::com::sun::star::ucb::ContentCreationException& )
    1327             :                         {
    1328             :                         }
    1329           0 :                         catch( const ::com::sun::star::uno::RuntimeException& )
    1330             :                         {
    1331             :                         }
    1332           0 :                         catch( const ::com::sun::star::ucb::CommandAbortedException& )
    1333             :                         {
    1334             :                         }
    1335           0 :                         catch( const ::com::sun::star::uno::Exception& )
    1336             :                         {
    1337             :                         }
    1338             :                     }
    1339          68 :                 }
    1340          68 :             }
    1341             :         }
    1342             :         else
    1343             :         {
    1344           0 :             ImplClearGraphics( true );
    1345           0 :             bRet = mbSwapOut = true;
    1346             :         }
    1347             :     }
    1348             : 
    1349          68 :     return bRet;
    1350             : }
    1351             : 
    1352          72 : bool ImpGraphic::ImplSwapOut( SvStream* pOStm )
    1353             : {
    1354          72 :     bool bRet = false;
    1355             : 
    1356          72 :     if( pOStm )
    1357             :     {
    1358          68 :         pOStm->SetBufferSize( GRAPHIC_STREAMBUFSIZE );
    1359             : 
    1360          68 :         if( !pOStm->GetError() && ImplWriteEmbedded( *pOStm ) )
    1361             :         {
    1362          68 :             pOStm->Flush();
    1363             : 
    1364          68 :             if( !pOStm->GetError() )
    1365             :             {
    1366          68 :                 ImplClearGraphics( true );
    1367          68 :                 bRet = mbSwapOut = true;
    1368             :             }
    1369             :         }
    1370             :     }
    1371             :     else
    1372             :     {
    1373           4 :         ImplClearGraphics( true );
    1374           4 :         bRet = mbSwapOut = true;
    1375             :     }
    1376             : 
    1377          72 :     return bRet;
    1378             : }
    1379             : 
    1380          90 : bool ImpGraphic::ImplSwapIn()
    1381             : {
    1382          90 :     bool bRet = false;
    1383             : 
    1384          90 :     if( ImplIsSwapOut() )
    1385             :     {
    1386          30 :         OUString aSwapURL;
    1387             : 
    1388          30 :         if( mpSwapFile )
    1389          30 :             aSwapURL = mpSwapFile->aSwapURL.GetMainURL( INetURLObject::NO_DECODE );
    1390             :         else
    1391           0 :             aSwapURL = maDocFileURLStr;
    1392             : 
    1393          30 :         if( !aSwapURL.isEmpty() )
    1394             :         {
    1395          30 :             boost::scoped_ptr<SvStream> pIStm;
    1396             :             try
    1397             :             {
    1398          30 :                 pIStm.reset(::utl::UcbStreamHelper::CreateStream( aSwapURL, STREAM_READWRITE | STREAM_SHARE_DENYWRITE ));
    1399             :             }
    1400           0 :             catch( const ::com::sun::star::uno::Exception& )
    1401             :             {
    1402             :             }
    1403             : 
    1404          30 :             if( pIStm )
    1405             :             {
    1406          30 :                 pIStm->SetVersion( SOFFICE_FILEFORMAT_50 );
    1407          30 :                 pIStm->SetCompressMode( COMPRESSMODE_NATIVE );
    1408             : 
    1409          30 :                 if( !mpSwapFile )
    1410           0 :                     pIStm->Seek( mnDocFilePos );
    1411             : 
    1412          30 :                 bRet = ImplSwapIn( pIStm.get() );
    1413          30 :                 pIStm.reset();
    1414             : 
    1415          30 :                 if( mpSwapFile )
    1416             :                 {
    1417          30 :                     if( mpSwapFile->nRefCount > 1 )
    1418           0 :                         mpSwapFile->nRefCount--;
    1419             :                     else
    1420             :                     {
    1421             :                         try
    1422             :                         {
    1423             :                             ::ucbhelper::Content aCnt( aSwapURL,
    1424             :                                                  ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >(),
    1425          30 :                                                  comphelper::getProcessComponentContext() );
    1426             : 
    1427             :                             aCnt.executeCommand( OUString("delete"),
    1428          30 :                                                  ::com::sun::star::uno::makeAny( true ) );
    1429             :                         }
    1430           0 :                         catch( const ::com::sun::star::ucb::ContentCreationException& )
    1431             :                         {
    1432             :                         }
    1433           0 :                         catch( const ::com::sun::star::uno::RuntimeException& )
    1434             :                         {
    1435             :                         }
    1436           0 :                         catch( const ::com::sun::star::ucb::CommandAbortedException& )
    1437             :                         {
    1438             :                         }
    1439           0 :                         catch( const ::com::sun::star::uno::Exception& )
    1440             :                         {
    1441             :                         }
    1442             : 
    1443          30 :                         delete mpSwapFile;
    1444             :                     }
    1445             : 
    1446          30 :                     mpSwapFile = NULL;
    1447             :                 }
    1448          30 :             }
    1449          30 :         }
    1450             :     }
    1451             : 
    1452          90 :     return bRet;
    1453             : }
    1454             : 
    1455          30 : bool ImpGraphic::ImplSwapIn( SvStream* pIStm )
    1456             : {
    1457          30 :     bool bRet = false;
    1458             : 
    1459          30 :     if( pIStm )
    1460             :     {
    1461          30 :         pIStm->SetBufferSize( GRAPHIC_STREAMBUFSIZE );
    1462             : 
    1463          30 :         if( !pIStm->GetError() )
    1464             :         {
    1465          30 :             mbSwapUnderway = true;
    1466          30 :             bRet = ImplReadEmbedded( *pIStm );
    1467          30 :             mbSwapUnderway = false;
    1468             : 
    1469          30 :             if( !bRet )
    1470           0 :                 ImplClear();
    1471             :             else
    1472          30 :                 mbSwapOut = false;
    1473             :         }
    1474             :     }
    1475             : 
    1476          30 :     return bRet;
    1477             : }
    1478             : 
    1479             : 
    1480       10997 : void ImpGraphic::ImplSetLink( const GfxLink& rGfxLink )
    1481             : {
    1482       10997 :     delete mpGfxLink;
    1483       10997 :     mpGfxLink = new GfxLink( rGfxLink );
    1484             : 
    1485       10997 :     if( mpGfxLink->IsNative() )
    1486       10957 :         mpGfxLink->SwapOut();
    1487       10997 : }
    1488             : 
    1489        2100 : GfxLink ImpGraphic::ImplGetLink()
    1490             : {
    1491        2100 :     return( mpGfxLink ? *mpGfxLink : GfxLink() );
    1492             : }
    1493             : 
    1494       48036 : bool ImpGraphic::ImplIsLink() const
    1495             : {
    1496       48036 :     return ( mpGfxLink != NULL );
    1497             : }
    1498             : 
    1499        5957 : sal_uLong ImpGraphic::ImplGetChecksum() const
    1500             : {
    1501        5957 :     sal_uLong nRet = 0;
    1502             : 
    1503        5957 :     if( ImplIsSupportedGraphic() && !ImplIsSwapOut() )
    1504             :     {
    1505        5957 :         switch( meType )
    1506             :         {
    1507             :             case( GRAPHIC_DEFAULT ):
    1508           0 :             break;
    1509             : 
    1510             :             case( GRAPHIC_BITMAP ):
    1511             :             {
    1512        4301 :                 if(maSvgData.get() && maEx.IsEmpty())
    1513             :                 {
    1514             :                     // use maEx as local buffer for rendered svg
    1515           0 :                     const_cast< ImpGraphic* >(this)->maEx = maSvgData->getReplacement();
    1516             :                 }
    1517             : 
    1518        4301 :                 if( mpAnimation )
    1519             :                 {
    1520           0 :                     nRet = mpAnimation->GetChecksum();
    1521             :                 }
    1522             :                 else
    1523             :                 {
    1524        4301 :                     nRet = maEx.GetChecksum();
    1525             :                 }
    1526             :             }
    1527        4301 :             break;
    1528             : 
    1529             :             default:
    1530        1656 :                 nRet = maMetaFile.GetChecksum();
    1531        1656 :             break;
    1532             :         }
    1533             :     }
    1534             : 
    1535        5957 :     return nRet;
    1536             : }
    1537             : 
    1538         696 : bool ImpGraphic::ImplExportNative( SvStream& rOStm ) const
    1539             : {
    1540         696 :     bool bResult = false;
    1541             : 
    1542         696 :     if( !rOStm.GetError() )
    1543             :     {
    1544         696 :         if( !ImplIsSwapOut() )
    1545             :         {
    1546         696 :             if( mpGfxLink && mpGfxLink->IsNative() )
    1547          42 :                 bResult = mpGfxLink->ExportNative( rOStm );
    1548             :             else
    1549             :             {
    1550         654 :                 WriteImpGraphic( rOStm, *this );
    1551         654 :                 bResult = ( rOStm.GetError() == ERRCODE_NONE );
    1552             :             }
    1553             :         }
    1554             :         else
    1555           0 :              rOStm.SetError( SVSTREAM_GENERALERROR );
    1556             :     }
    1557             : 
    1558         696 :     return bResult;
    1559             : }
    1560             : 
    1561             : 
    1562       10002 : SvStream& ReadImpGraphic( SvStream& rIStm, ImpGraphic& rImpGraphic )
    1563             : {
    1564       10002 :     if( !rIStm.GetError() )
    1565             :     {
    1566       10002 :         const sal_uLong nStmPos1 = rIStm.Tell();
    1567             :         sal_uInt32 nTmp;
    1568             : 
    1569       10002 :         if ( !rImpGraphic.mbSwapUnderway )
    1570        9972 :             rImpGraphic.ImplClear();
    1571             : 
    1572             :         // read Id
    1573       10002 :         rIStm.ReadUInt32( nTmp );
    1574             : 
    1575             :         // if there is no more data, avoid further expensive
    1576             :         // reading which will create VDevs and other stuff, just to
    1577             :         // read nothing. CAUTION: Eof is only true AFTER reading another
    1578             :         // byte, a speciality of SvMemoryStream (!)
    1579       10002 :         if(!rIStm.GetError() && !rIStm.IsEof())
    1580             :         {
    1581        9960 :             if( NATIVE_FORMAT_50 == nTmp )
    1582             :             {
    1583          24 :                 Graphic         aGraphic;
    1584          48 :                 GfxLink         aLink;
    1585             :                 VersionCompat*  pCompat;
    1586             : 
    1587             :                 // read compat info
    1588          24 :                 pCompat = new VersionCompat( rIStm, STREAM_READ );
    1589          24 :                 delete pCompat;
    1590             : 
    1591          24 :                 ReadGfxLink( rIStm, aLink );
    1592             : 
    1593             :                 // set dummy link to avoid creation of additional link after filtering;
    1594             :                 // we set a default link to avoid unnecessary swapping of native data
    1595          24 :                 aGraphic.SetLink( GfxLink() );
    1596             : 
    1597          24 :                 if( !rIStm.GetError() && aLink.LoadNative( aGraphic ) )
    1598             :                 {
    1599             :                     // set link only, if no other link was set
    1600          24 :                     const bool bSetLink = ( rImpGraphic.mpGfxLink == NULL );
    1601             : 
    1602             :                     // assign graphic
    1603          24 :                     rImpGraphic = *aGraphic.ImplGetImpGraphic();
    1604             : 
    1605          24 :                     if( aLink.IsPrefMapModeValid() )
    1606          24 :                         rImpGraphic.ImplSetPrefMapMode( aLink.GetPrefMapMode() );
    1607             : 
    1608          24 :                     if( aLink.IsPrefSizeValid() )
    1609          24 :                         rImpGraphic.ImplSetPrefSize( aLink.GetPrefSize() );
    1610             : 
    1611          24 :                     if( bSetLink )
    1612          24 :                         rImpGraphic.ImplSetLink( aLink );
    1613             :                 }
    1614             :                 else
    1615             :                 {
    1616           0 :                     rIStm.Seek( nStmPos1 );
    1617           0 :                     rIStm.SetError( ERRCODE_IO_WRONGFORMAT );
    1618          24 :                 }
    1619             :             }
    1620             :             else
    1621             :             {
    1622        9936 :                 BitmapEx        aBmpEx;
    1623        9936 :                 const sal_uInt16    nOldFormat = rIStm.GetNumberFormatInt();
    1624             : 
    1625        9936 :                 rIStm.SeekRel( -4 );
    1626        9936 :                 rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
    1627        9936 :                 ReadDIBBitmapEx(aBmpEx, rIStm);
    1628             : 
    1629        9936 :                 if( !rIStm.GetError() )
    1630             :                 {
    1631          84 :                     sal_uInt32  nMagic1(0), nMagic2(0);
    1632          84 :                     sal_uLong   nActPos = rIStm.Tell();
    1633             : 
    1634          84 :                     rIStm.ReadUInt32( nMagic1 ).ReadUInt32( nMagic2 );
    1635          84 :                     rIStm.Seek( nActPos );
    1636             : 
    1637          84 :                     rImpGraphic = ImpGraphic( aBmpEx );
    1638             : 
    1639          84 :                     if( !rIStm.GetError() && ( 0x5344414e == nMagic1 ) && ( 0x494d4931 == nMagic2 ) )
    1640             :                     {
    1641           0 :                         delete rImpGraphic.mpAnimation;
    1642           0 :                         rImpGraphic.mpAnimation = new Animation;
    1643           0 :                         ReadAnimation( rIStm, *rImpGraphic.mpAnimation );
    1644             : 
    1645             :                         // #108077# manually set loaded BmpEx to Animation
    1646             :                         // (which skips loading its BmpEx if already done)
    1647           0 :                         rImpGraphic.mpAnimation->SetBitmapEx(aBmpEx);
    1648             :                     }
    1649             :                     else
    1650          84 :                         rIStm.ResetError();
    1651             :                 }
    1652             :                 else
    1653             :                 {
    1654        9852 :                     GDIMetaFile aMtf;
    1655             : 
    1656        9852 :                     rIStm.Seek( nStmPos1 );
    1657        9852 :                     rIStm.ResetError();
    1658        9852 :                     ReadGDIMetaFile( rIStm, aMtf );
    1659             : 
    1660        9852 :                     if( !rIStm.GetError() )
    1661             :                     {
    1662        9834 :                         rImpGraphic = aMtf;
    1663             :                     }
    1664             :                     else
    1665             :                     {
    1666             :                         // try to stream in Svg defining data (length, byte array and evtl. path)
    1667             :                         // See below (operator<<) for more information
    1668          18 :                         const sal_uInt32 nSvgMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16) | (sal_uInt32('g') << 8) | sal_uInt32('0'));
    1669             :                         sal_uInt32 nMagic;
    1670          18 :                         rIStm.Seek(nStmPos1);
    1671          18 :                         rIStm.ResetError();
    1672          18 :                         rIStm.ReadUInt32( nMagic );
    1673             : 
    1674          18 :                         if(nSvgMagic == nMagic)
    1675             :                         {
    1676           0 :                             sal_uInt32 mnSvgDataArrayLength(0);
    1677           0 :                             rIStm.ReadUInt32( mnSvgDataArrayLength );
    1678             : 
    1679           0 :                             if(mnSvgDataArrayLength)
    1680             :                             {
    1681           0 :                                 SvgDataArray aNewData(new sal_uInt8[mnSvgDataArrayLength]);
    1682           0 :                                 OUString aPath;
    1683             : 
    1684           0 :                                 rIStm.Read(aNewData.get(), mnSvgDataArrayLength);
    1685           0 :                                 aPath = rIStm.ReadUniOrByteString(rIStm.GetStreamCharSet());
    1686             : 
    1687           0 :                                 if(!rIStm.GetError())
    1688             :                                 {
    1689             :                                     SvgDataPtr aSvgDataPtr(
    1690             :                                         new SvgData(
    1691             :                                             aNewData,
    1692             :                                             mnSvgDataArrayLength,
    1693           0 :                                             OUString(aPath)));
    1694             : 
    1695           0 :                                     rImpGraphic = aSvgDataPtr;
    1696           0 :                                 }
    1697             :                             }
    1698             :                         }
    1699             : 
    1700          18 :                         rIStm.Seek(nStmPos1);
    1701        9852 :                     }
    1702             :                 }
    1703             : 
    1704        9936 :                 rIStm.SetNumberFormatInt( nOldFormat );
    1705             :             }
    1706             :         }
    1707             :     }
    1708             : 
    1709       10002 :     return rIStm;
    1710             : }
    1711             : 
    1712         920 : SvStream& WriteImpGraphic( SvStream& rOStm, const ImpGraphic& rImpGraphic )
    1713             : {
    1714         920 :     if( !rOStm.GetError() )
    1715             :     {
    1716         920 :         if( !rImpGraphic.ImplIsSwapOut() )
    1717             :         {
    1718        2574 :             if( ( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 ) &&
    1719         802 :                 ( rOStm.GetCompressMode() & COMPRESSMODE_NATIVE ) &&
    1720         960 :                 rImpGraphic.mpGfxLink && rImpGraphic.mpGfxLink->IsNative() )
    1721             :             {
    1722             :                 VersionCompat* pCompat;
    1723             : 
    1724             :                 // native format
    1725          40 :                 rOStm.WriteUInt32( NATIVE_FORMAT_50 );
    1726             : 
    1727             :                 // write compat info
    1728          40 :                 pCompat = new VersionCompat( rOStm, STREAM_WRITE, 1 );
    1729          40 :                 delete pCompat;
    1730             : 
    1731          40 :                 rImpGraphic.mpGfxLink->SetPrefMapMode( rImpGraphic.ImplGetPrefMapMode() );
    1732          40 :                 rImpGraphic.mpGfxLink->SetPrefSize( rImpGraphic.ImplGetPrefSize() );
    1733          40 :                 WriteGfxLink( rOStm, *rImpGraphic.mpGfxLink );
    1734             :             }
    1735             :             else
    1736             :             {
    1737             :                 // own format
    1738         880 :                 const sal_uInt16 nOldFormat = rOStm.GetNumberFormatInt();
    1739         880 :                 rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
    1740             : 
    1741         880 :                 switch( rImpGraphic.ImplGetType() )
    1742             :                 {
    1743             :                     case( GRAPHIC_NONE ):
    1744             :                     case( GRAPHIC_DEFAULT ):
    1745          40 :                     break;
    1746             : 
    1747             :                     case GRAPHIC_BITMAP:
    1748             :                     {
    1749         162 :                         if(rImpGraphic.getSvgData().get())
    1750             :                         {
    1751             :                             // stream out Svg defining data (length, byte array and evtl. path)
    1752             :                             // this is used e.g. in swapping out graphic data and in transporting it over UNO API
    1753             :                             // as sequence of bytes, but AFAIK not written anywhere to any kind of file, so it should be
    1754             :                             // no problem to extend it; only used at runtime
    1755           0 :                             const sal_uInt32 nSvgMagic((sal_uInt32('s') << 24) | (sal_uInt32('v') << 16) | (sal_uInt32('g') << 8) | sal_uInt32('0'));
    1756             : 
    1757           0 :                             rOStm.WriteUInt32( nSvgMagic );
    1758           0 :                             rOStm.WriteUInt32( rImpGraphic.getSvgData()->getSvgDataArrayLength() );
    1759           0 :                             rOStm.Write(rImpGraphic.getSvgData()->getSvgDataArray().get(), rImpGraphic.getSvgData()->getSvgDataArrayLength());
    1760           0 :                             rOStm.WriteUniOrByteString(rImpGraphic.getSvgData()->getPath(),
    1761           0 :                                                        rOStm.GetStreamCharSet());
    1762             :                         }
    1763         162 :                         else if( rImpGraphic.ImplIsAnimated())
    1764             :                         {
    1765           0 :                             WriteAnimation( rOStm, *rImpGraphic.mpAnimation );
    1766             :                         }
    1767             :                         else
    1768             :                         {
    1769         162 :                             WriteDIBBitmapEx(rImpGraphic.maEx, rOStm);
    1770             :                         }
    1771             :                     }
    1772         162 :                     break;
    1773             : 
    1774             :                     default:
    1775             :                     {
    1776         678 :                         if( rImpGraphic.ImplIsSupportedGraphic() )
    1777         678 :                             WriteGDIMetaFile( rOStm, rImpGraphic.maMetaFile );
    1778             :                     }
    1779         678 :                     break;
    1780             :                 }
    1781             : 
    1782         880 :                 rOStm.SetNumberFormatInt( nOldFormat );
    1783             :             }
    1784             :         }
    1785             :         else
    1786           0 :              rOStm.SetError( SVSTREAM_GENERALERROR );
    1787             :     }
    1788             : 
    1789         920 :     return rOStm;
    1790        1233 : }
    1791             : 
    1792             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10