LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/svtools/source/graphic - grfmgr.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 271 610 44.4 %
Date: 2013-07-09 Functions: 39 62 62.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 <algorithm>
      23             : 
      24             : #include <officecfg/Office/Common.hxx>
      25             : #include <tools/vcompat.hxx>
      26             : #include <tools/helpers.hxx>
      27             : #include <unotools/ucbstreamhelper.hxx>
      28             : #include <unotools/localfilehelper.hxx>
      29             : #include <unotools/tempfile.hxx>
      30             : #include <vcl/svapp.hxx>
      31             : #include <vcl/cvtgrf.hxx>
      32             : #include <vcl/metaact.hxx>
      33             : #include <vcl/virdev.hxx>
      34             : #include <svtools/grfmgr.hxx>
      35             : 
      36             : #include <vcl/pdfextoutdevdata.hxx>
      37             : 
      38             : #include <com/sun/star/container/XNameContainer.hpp>
      39             : #include <com/sun/star/beans/XPropertySet.hpp>
      40             : 
      41             : using com::sun::star::uno::Reference;
      42             : using com::sun::star::uno::XInterface;
      43             : using com::sun::star::uno::UNO_QUERY;
      44             : using com::sun::star::uno::Sequence;
      45             : using com::sun::star::container::XNameContainer;
      46             : using com::sun::star::beans::XPropertySet;
      47             : 
      48             : GraphicManager* GraphicObject::mpGlobalMgr = NULL;
      49             : 
      50           0 : struct GrfSimpleCacheObj
      51             : {
      52             :     Graphic     maGraphic;
      53             :     GraphicAttr maAttr;
      54             : 
      55           0 :                 GrfSimpleCacheObj( const Graphic& rGraphic, const GraphicAttr& rAttr ) :
      56           0 :                     maGraphic( rGraphic ), maAttr( rAttr ) {}
      57             : };
      58             : 
      59           0 : TYPEINIT1_AUTOFACTORY( GraphicObject, SvDataCopyStream );
      60             : 
      61         347 : GraphicObject::GraphicObject( const GraphicManager* pMgr ) :
      62             :     mpLink      ( NULL ),
      63         347 :     mpUserData  ( NULL )
      64             : {
      65         347 :     ImplConstruct();
      66         347 :     ImplAssignGraphicData();
      67         347 :     ImplSetGraphicManager( pMgr );
      68         347 : }
      69             : 
      70        1646 : GraphicObject::GraphicObject( const Graphic& rGraphic, const GraphicManager* pMgr ) :
      71             :     maGraphic   ( rGraphic ),
      72             :     mpLink      ( NULL ),
      73        1646 :     mpUserData  ( NULL )
      74             : {
      75        1646 :     ImplConstruct();
      76        1646 :     ImplAssignGraphicData();
      77        1646 :     ImplSetGraphicManager( pMgr );
      78        1646 : }
      79             : 
      80        2367 : GraphicObject::GraphicObject( const GraphicObject& rGraphicObj, const GraphicManager* pMgr ) :
      81             :     SvDataCopyStream(),
      82        2367 :     maGraphic   ( rGraphicObj.GetGraphic() ),
      83             :     maAttr      ( rGraphicObj.maAttr ),
      84           0 :     mpLink      ( rGraphicObj.mpLink ? ( new String( *rGraphicObj.mpLink ) ) : NULL ),
      85        4734 :     mpUserData  ( rGraphicObj.mpUserData ? ( new String( *rGraphicObj.mpUserData ) ) : NULL )
      86             : {
      87        2367 :     ImplConstruct();
      88        2367 :     ImplAssignGraphicData();
      89        2367 :     ImplSetGraphicManager( pMgr, NULL, &rGraphicObj );
      90        2367 : }
      91             : 
      92         263 : GraphicObject::GraphicObject( const OString& rUniqueID, const GraphicManager* pMgr ) :
      93             :     mpLink      ( NULL ),
      94         263 :     mpUserData  ( NULL )
      95             : {
      96         263 :     ImplConstruct();
      97             : 
      98             :     // assign default properties
      99         263 :     ImplAssignGraphicData();
     100             : 
     101         263 :     ImplSetGraphicManager( pMgr, &rUniqueID );
     102             : 
     103             :     // update properties
     104         263 :     ImplAssignGraphicData();
     105         263 : }
     106             : 
     107        9394 : GraphicObject::~GraphicObject()
     108             : {
     109        4545 :     if( mpMgr )
     110             :     {
     111        4545 :         mpMgr->ImplUnregisterObj( *this );
     112             : 
     113        4545 :         if( ( mpMgr == mpGlobalMgr ) && !mpGlobalMgr->ImplHasObjects() )
     114         263 :             delete mpGlobalMgr, mpGlobalMgr = NULL;
     115             :     }
     116             : 
     117        4545 :     delete mpSwapOutTimer;
     118        4545 :     delete mpSwapStreamHdl;
     119        4545 :     delete mpLink;
     120        4545 :     delete mpUserData;
     121        4545 :     delete mpSimpleCache;
     122        4849 : }
     123             : 
     124        4623 : void GraphicObject::ImplConstruct()
     125             : {
     126        4623 :     mpMgr = NULL;
     127        4623 :     mpSwapStreamHdl = NULL;
     128        4623 :     mpSwapOutTimer = NULL;
     129        4623 :     mpSimpleCache = NULL;
     130        4623 :     mnAnimationLoopCount = 0;
     131        4623 :     mbAutoSwapped = sal_False;
     132        4623 :     mbIsInSwapIn = sal_False;
     133        4623 :     mbIsInSwapOut = sal_False;
     134        4623 : }
     135             : 
     136        5220 : void GraphicObject::ImplAssignGraphicData()
     137             : {
     138        5220 :     maPrefSize = maGraphic.GetPrefSize();
     139        5220 :     maPrefMapMode = maGraphic.GetPrefMapMode();
     140        5220 :     mnSizeBytes = maGraphic.GetSizeBytes();
     141        5220 :     meType = maGraphic.GetType();
     142        5220 :     mbTransparent = maGraphic.IsTransparent();
     143        5220 :     mbAlpha = maGraphic.IsAlpha();
     144        5220 :     mbAnimated = maGraphic.IsAnimated();
     145        5220 :     mbEPS = maGraphic.IsEPS();
     146        5220 :     mnAnimationLoopCount = ( mbAnimated ? maGraphic.GetAnimationLoopCount() : 0 );
     147        5220 : }
     148             : 
     149        4623 : void GraphicObject::ImplSetGraphicManager( const GraphicManager* pMgr, const OString* pID, const GraphicObject* pCopyObj )
     150             : {
     151        4623 :     if( !mpMgr || ( pMgr != mpMgr ) )
     152             :     {
     153        4623 :         if( !pMgr && mpMgr && ( mpMgr == mpGlobalMgr ) )
     154        4623 :             return;
     155             :         else
     156             :         {
     157        4623 :             if( mpMgr )
     158             :             {
     159           0 :                 mpMgr->ImplUnregisterObj( *this );
     160             : 
     161           0 :                 if( ( mpMgr == mpGlobalMgr ) && !mpGlobalMgr->ImplHasObjects() )
     162           0 :                     delete mpGlobalMgr, mpGlobalMgr = NULL;
     163             :             }
     164             : 
     165        4623 :             if( !pMgr )
     166             :             {
     167        4623 :                 if( !mpGlobalMgr )
     168             :                 {
     169             :                     mpGlobalMgr = new GraphicManager(
     170             :                         (officecfg::Office::Common::Cache::GraphicManager::
     171         622 :                          TotalCacheSize::get()),
     172             :                         (officecfg::Office::Common::Cache::GraphicManager::
     173         311 :                          ObjectCacheSize::get()));
     174             :                     mpGlobalMgr->SetCacheTimeout(
     175             :                         officecfg::Office::Common::Cache::GraphicManager::
     176         311 :                         ObjectReleaseTime::get());
     177             :                 }
     178             : 
     179        4623 :                 mpMgr = mpGlobalMgr;
     180             :             }
     181             :             else
     182           0 :                 mpMgr = (GraphicManager*) pMgr;
     183             : 
     184        4623 :             mpMgr->ImplRegisterObj( *this, maGraphic, pID, pCopyObj );
     185             :         }
     186             :     }
     187             : }
     188             : 
     189          57 : void GraphicObject::ImplAutoSwapIn()
     190             : {
     191          57 :     if( IsSwappedOut() )
     192             :     {
     193           8 :         if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) )
     194           0 :             mbAutoSwapped = sal_False;
     195             :         else
     196             :         {
     197           8 :             mbIsInSwapIn = sal_True;
     198             : 
     199           8 :             if( maGraphic.SwapIn() )
     200           6 :                 mbAutoSwapped = sal_False;
     201             :             else
     202             :             {
     203           2 :                 SvStream* pStream = GetSwapStream();
     204             : 
     205           2 :                 if( GRFMGR_AUTOSWAPSTREAM_NONE != pStream )
     206             :                 {
     207           1 :                     if( GRFMGR_AUTOSWAPSTREAM_LINK == pStream )
     208             :                     {
     209           0 :                         if( HasLink() )
     210             :                         {
     211           0 :                             OUString aURLStr;
     212             : 
     213           0 :                             if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( GetLink(), aURLStr ) )
     214             :                             {
     215           0 :                                 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURLStr, STREAM_READ );
     216             : 
     217           0 :                                 if( pIStm )
     218             :                                 {
     219           0 :                                     (*pIStm) >> maGraphic;
     220           0 :                                     mbAutoSwapped = ( maGraphic.GetType() != GRAPHIC_NONE );
     221           0 :                                     delete pIStm;
     222             :                                 }
     223           0 :                             }
     224             :                         }
     225             :                     }
     226           1 :                     else if( GRFMGR_AUTOSWAPSTREAM_TEMP == pStream )
     227           0 :                         mbAutoSwapped = !maGraphic.SwapIn();
     228           1 :                     else if( GRFMGR_AUTOSWAPSTREAM_LOADED == pStream )
     229           1 :                         mbAutoSwapped = maGraphic.IsSwapOut();
     230             :                     else
     231             :                     {
     232           0 :                         mbAutoSwapped = !maGraphic.SwapIn( pStream );
     233           0 :                         delete pStream;
     234             :                     }
     235             :                 }
     236             :                 else
     237             :                 {
     238             :                     DBG_ASSERT( ( GRAPHIC_NONE == meType ) || ( GRAPHIC_DEFAULT == meType ),
     239             :                                 "GraphicObject::ImplAutoSwapIn: could not get stream to swap in graphic! (=>KA)" );
     240             :                 }
     241             :             }
     242             : 
     243           8 :             mbIsInSwapIn = sal_False;
     244             : 
     245           8 :             if( !mbAutoSwapped && mpMgr )
     246           7 :                 mpMgr->ImplGraphicObjectWasSwappedIn( *this );
     247             :         }
     248             :     }
     249          57 : }
     250             : 
     251           2 : sal_Bool GraphicObject::ImplGetCropParams( OutputDevice* pOut, Point& rPt, Size& rSz, const GraphicAttr* pAttr,
     252             :                                        PolyPolygon& rClipPolyPoly, sal_Bool& bRectClipRegion ) const
     253             : {
     254           2 :     sal_Bool bRet = sal_False;
     255             : 
     256           2 :     if( GetType() != GRAPHIC_NONE )
     257             :     {
     258           2 :         Polygon         aClipPoly( Rectangle( rPt, rSz ) );
     259           2 :         const sal_uInt16    nRot10 = pAttr->GetRotation() % 3600;
     260           2 :         const Point     aOldOrigin( rPt );
     261           4 :         const MapMode   aMap100( MAP_100TH_MM );
     262           2 :         Size            aSize100;
     263             :         long            nTotalWidth, nTotalHeight;
     264             : 
     265           2 :         if( nRot10 )
     266             :         {
     267           0 :             aClipPoly.Rotate( rPt, nRot10 );
     268           0 :             bRectClipRegion = sal_False;
     269             :         }
     270             :         else
     271           2 :             bRectClipRegion = sal_True;
     272             : 
     273           2 :         rClipPolyPoly = aClipPoly;
     274             : 
     275           2 :         if( maGraphic.GetPrefMapMode() == MAP_PIXEL )
     276           2 :             aSize100 = Application::GetDefaultDevice()->PixelToLogic( maGraphic.GetPrefSize(), aMap100 );
     277             :         else
     278             :         {
     279           0 :             MapMode m(maGraphic.GetPrefMapMode());
     280           0 :             aSize100 = pOut->LogicToLogic( maGraphic.GetPrefSize(), &m, &aMap100 );
     281             :         }
     282             : 
     283           2 :         nTotalWidth = aSize100.Width() - pAttr->GetLeftCrop() - pAttr->GetRightCrop();
     284           2 :         nTotalHeight = aSize100.Height() - pAttr->GetTopCrop() - pAttr->GetBottomCrop();
     285             : 
     286           2 :         if( aSize100.Width() > 0 && aSize100.Height() > 0 && nTotalWidth > 0 && nTotalHeight > 0 )
     287             :         {
     288           0 :             double fScale = (double) aSize100.Width() / nTotalWidth;
     289           0 :             const long nNewLeft = -FRound( ( ( pAttr->GetMirrorFlags() & BMP_MIRROR_HORZ ) ? pAttr->GetRightCrop() : pAttr->GetLeftCrop() ) * fScale );
     290           0 :             const long nNewRight = nNewLeft + FRound( aSize100.Width() * fScale ) - 1;
     291             : 
     292           0 :             fScale = (double) rSz.Width() / aSize100.Width();
     293           0 :             rPt.X() += FRound( nNewLeft * fScale );
     294           0 :             rSz.Width() = FRound( ( nNewRight - nNewLeft + 1 ) * fScale );
     295             : 
     296           0 :             fScale = (double) aSize100.Height() / nTotalHeight;
     297           0 :             const long nNewTop = -FRound( ( ( pAttr->GetMirrorFlags() & BMP_MIRROR_VERT ) ? pAttr->GetBottomCrop() : pAttr->GetTopCrop() ) * fScale );
     298           0 :             const long nNewBottom = nNewTop + FRound( aSize100.Height() * fScale ) - 1;
     299             : 
     300           0 :             fScale = (double) rSz.Height() / aSize100.Height();
     301           0 :             rPt.Y() += FRound( nNewTop * fScale );
     302           0 :             rSz.Height() = FRound( ( nNewBottom - nNewTop + 1 ) * fScale );
     303             : 
     304           0 :             if( nRot10 )
     305             :             {
     306           0 :                 Polygon aOriginPoly( 1 );
     307             : 
     308           0 :                 aOriginPoly[ 0 ] = rPt;
     309           0 :                 aOriginPoly.Rotate( aOldOrigin, nRot10 );
     310           0 :                 rPt = aOriginPoly[ 0 ];
     311             :             }
     312             : 
     313           0 :             bRet = sal_True;
     314           2 :         }
     315             :     }
     316             : 
     317           2 :     return bRet;
     318             : }
     319             : 
     320         133 : GraphicObject& GraphicObject::operator=( const GraphicObject& rGraphicObj )
     321             : {
     322         133 :     if( &rGraphicObj != this )
     323             :     {
     324         133 :         mpMgr->ImplUnregisterObj( *this );
     325             : 
     326         133 :         delete mpSwapStreamHdl, mpSwapStreamHdl = NULL;
     327         133 :         delete mpSimpleCache, mpSimpleCache = NULL;
     328         133 :         delete mpLink;
     329         133 :         delete mpUserData;
     330             : 
     331         133 :         maGraphic = rGraphicObj.GetGraphic();
     332         133 :         maAttr = rGraphicObj.maAttr;
     333         133 :         mpLink = rGraphicObj.mpLink ? new String( *rGraphicObj.mpLink ) : NULL;
     334         133 :         mpUserData = rGraphicObj.mpUserData ? new String( *rGraphicObj.mpUserData ) : NULL;
     335         133 :         ImplAssignGraphicData();
     336         133 :         mbAutoSwapped = sal_False;
     337         133 :         mpMgr = rGraphicObj.mpMgr;
     338             : 
     339         133 :         mpMgr->ImplRegisterObj( *this, maGraphic, NULL, &rGraphicObj );
     340             :     }
     341             : 
     342         133 :     return *this;
     343             : }
     344             : 
     345        1334 : sal_Bool GraphicObject::operator==( const GraphicObject& rGraphicObj ) const
     346             : {
     347        2648 :     return( ( rGraphicObj.maGraphic == maGraphic ) &&
     348        6610 :             ( rGraphicObj.maAttr == maAttr ) &&
     349        5276 :             ( rGraphicObj.GetLink() == GetLink() ) );
     350             : }
     351             : 
     352           0 : void GraphicObject::Load( SvStream& rIStm )
     353             : {
     354           0 :     rIStm >> *this;
     355           0 : }
     356             : 
     357           0 : void GraphicObject::Save( SvStream& rOStm )
     358             : {
     359           0 :     rOStm << *this;
     360           0 : }
     361             : 
     362           0 : void GraphicObject::Assign( const SvDataCopyStream& rCopyStream )
     363             : {
     364           0 :     *this = (const GraphicObject& ) rCopyStream;
     365           0 : }
     366             : 
     367         444 : OString GraphicObject::GetUniqueID() const
     368             : {
     369         444 :     if ( !IsInSwapIn() && IsEPS() )
     370           0 :         const_cast<GraphicObject*>(this)->FireSwapInRequest();
     371             : 
     372         444 :     OString aRet;
     373             : 
     374         444 :     if( mpMgr )
     375         444 :         aRet = mpMgr->ImplGetUniqueID( *this );
     376             : 
     377         444 :     return aRet;
     378             : }
     379             : 
     380          62 : SvStream* GraphicObject::GetSwapStream() const
     381             : {
     382          62 :     return( HasSwapStreamHdl() ? (SvStream*) mpSwapStreamHdl->Call( (void*) this ) : GRFMGR_AUTOSWAPSTREAM_NONE );
     383             : }
     384             : 
     385          11 : void GraphicObject::SetAttr( const GraphicAttr& rAttr )
     386             : {
     387          11 :     maAttr = rAttr;
     388             : 
     389          11 :     if( mpSimpleCache && ( mpSimpleCache->maAttr != rAttr ) )
     390           0 :         delete mpSimpleCache, mpSimpleCache = NULL;
     391          11 : }
     392             : 
     393           0 : void GraphicObject::SetLink()
     394             : {
     395           0 :     if( mpLink )
     396           0 :         delete mpLink, mpLink = NULL;
     397           0 : }
     398             : 
     399           5 : void GraphicObject::SetLink( const String& rLink )
     400             : {
     401           5 :     delete mpLink, mpLink = new String( rLink );
     402           5 : }
     403             : 
     404        2642 : String GraphicObject::GetLink() const
     405             : {
     406        2642 :     if( mpLink )
     407          14 :         return *mpLink;
     408             :     else
     409        2628 :         return String();
     410             : }
     411             : 
     412         125 : void GraphicObject::SetUserData()
     413             : {
     414         125 :     if( mpUserData )
     415           0 :         delete mpUserData, mpUserData = NULL;
     416         125 : }
     417             : 
     418          12 : void GraphicObject::SetUserData( const String& rUserData )
     419             : {
     420          12 :     delete mpUserData, mpUserData = new String( rUserData );
     421          12 : }
     422             : 
     423           4 : String GraphicObject::GetUserData() const
     424             : {
     425           4 :     if( mpUserData )
     426           4 :         return *mpUserData;
     427             :     else
     428           0 :         return String();
     429             : }
     430             : 
     431           0 : void GraphicObject::SetSwapStreamHdl()
     432             : {
     433           0 :     if( mpSwapStreamHdl )
     434             :     {
     435           0 :         delete mpSwapOutTimer, mpSwapOutTimer = NULL;
     436           0 :         delete mpSwapStreamHdl, mpSwapStreamHdl = NULL;
     437             :     }
     438           0 : }
     439             : 
     440         219 : void GraphicObject::SetSwapStreamHdl( const Link& rHdl, const sal_uLong nSwapOutTimeout )
     441             : {
     442         219 :     delete mpSwapStreamHdl, mpSwapStreamHdl = new Link( rHdl );
     443             : 
     444         219 :     if( nSwapOutTimeout )
     445             :     {
     446         162 :         if( !mpSwapOutTimer )
     447             :         {
     448         117 :             mpSwapOutTimer = new Timer;
     449         117 :             mpSwapOutTimer->SetTimeoutHdl( LINK( this, GraphicObject, ImplAutoSwapOutHdl ) );
     450             :         }
     451             : 
     452         162 :         mpSwapOutTimer->SetTimeout( nSwapOutTimeout );
     453         162 :         mpSwapOutTimer->Start();
     454             :     }
     455             :     else
     456          57 :         delete mpSwapOutTimer, mpSwapOutTimer = NULL;
     457         219 : }
     458             : 
     459          55 : void GraphicObject::FireSwapInRequest()
     460             : {
     461          55 :     ImplAutoSwapIn();
     462          55 : }
     463             : 
     464          70 : void GraphicObject::FireSwapOutRequest()
     465             : {
     466          70 :     ImplAutoSwapOutHdl( NULL );
     467          70 : }
     468             : 
     469           0 : void GraphicObject::GraphicManagerDestroyed()
     470             : {
     471             :     // we're alive, but our manager doesn't live anymore ==> connect to default manager
     472           0 :     mpMgr = NULL;
     473           0 :     ImplSetGraphicManager( NULL );
     474           0 : }
     475             : 
     476          14 : sal_Bool GraphicObject::IsCached( OutputDevice* pOut, const Point& rPt, const Size& rSz,
     477             :                               const GraphicAttr* pAttr, sal_uLong nFlags ) const
     478             : {
     479             :     sal_Bool bRet;
     480             : 
     481          14 :     if( nFlags & GRFMGR_DRAW_CACHED )
     482             :     {
     483          14 :         Point aPt( rPt );
     484          14 :         Size aSz( rSz );
     485          14 :         if ( pAttr->IsCropped() )
     486             :         {
     487           2 :             PolyPolygon aClipPolyPoly;
     488             :             sal_Bool        bRectClip;
     489           2 :             ImplGetCropParams( pOut, aPt, aSz, pAttr, aClipPolyPoly, bRectClip );
     490             :         }
     491          14 :         bRet = mpMgr->IsInCache( pOut, aPt, aSz, *this, ( pAttr ? *pAttr : GetAttr() ) );
     492             :     }
     493             :     else
     494           0 :         bRet = sal_False;
     495             : 
     496          14 :     return bRet;
     497             : }
     498             : 
     499          24 : void GraphicObject::ReleaseFromCache()
     500             : {
     501             : 
     502          24 :     mpMgr->ReleaseFromCache( *this );
     503          24 : }
     504             : 
     505           1 : bool GraphicObject::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz,
     506             :                           const GraphicAttr* pAttr, sal_uLong nFlags )
     507             : {
     508           1 :     GraphicAttr         aAttr( pAttr ? *pAttr : GetAttr() );
     509           1 :     Point               aPt( rPt );
     510           1 :     Size                aSz( rSz );
     511           1 :     const sal_uInt32    nOldDrawMode = pOut->GetDrawMode();
     512           1 :     sal_Bool                bCropped = aAttr.IsCropped();
     513           1 :     sal_Bool                bCached = sal_False;
     514             :     bool bRet;
     515             : 
     516             :     // #i29534# Provide output rects for PDF writer
     517           1 :     Rectangle           aCropRect;
     518             : 
     519           1 :     if( !( GRFMGR_DRAW_USE_DRAWMODE_SETTINGS & nFlags ) )
     520           1 :         pOut->SetDrawMode( nOldDrawMode & ( ~( DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT ) ) );
     521             : 
     522             :     // mirrored horizontically
     523           1 :     if( aSz.Width() < 0L )
     524             :     {
     525           0 :         aPt.X() += aSz.Width() + 1;
     526           0 :         aSz.Width() = -aSz.Width();
     527           0 :         aAttr.SetMirrorFlags( aAttr.GetMirrorFlags() ^ BMP_MIRROR_HORZ );
     528             :     }
     529             : 
     530             :     // mirrored vertically
     531           1 :     if( aSz.Height() < 0L )
     532             :     {
     533           0 :         aPt.Y() += aSz.Height() + 1;
     534           0 :         aSz.Height() = -aSz.Height();
     535           0 :         aAttr.SetMirrorFlags( aAttr.GetMirrorFlags() ^ BMP_MIRROR_VERT );
     536             :     }
     537             : 
     538           1 :     if( bCropped )
     539             :     {
     540           0 :         PolyPolygon aClipPolyPoly;
     541             :         sal_Bool        bRectClip;
     542           0 :         const sal_Bool  bCrop = ImplGetCropParams( pOut, aPt, aSz, &aAttr, aClipPolyPoly, bRectClip );
     543             : 
     544           0 :         pOut->Push( PUSH_CLIPREGION );
     545             : 
     546           0 :         if( bCrop )
     547             :         {
     548           0 :             if( bRectClip )
     549             :             {
     550             :                 // #i29534# Store crop rect for later forwarding to
     551             :                 // PDF writer
     552           0 :                 aCropRect = aClipPolyPoly.GetBoundRect();
     553           0 :                 pOut->IntersectClipRegion( aCropRect );
     554             :             }
     555             :             else
     556             :             {
     557           0 :                 pOut->IntersectClipRegion(Region(aClipPolyPoly));
     558             :             }
     559           0 :         }
     560             :     }
     561             : 
     562           1 :     bRet = mpMgr->DrawObj( pOut, aPt, aSz, *this, aAttr, nFlags, bCached );
     563             : 
     564           1 :     if( bCropped )
     565           0 :         pOut->Pop();
     566             : 
     567           1 :     pOut->SetDrawMode( nOldDrawMode );
     568             : 
     569             :     // #i29534# Moved below OutDev restoration, to avoid multiple swap-ins
     570             :     // (code above needs to call GetGraphic twice)
     571           1 :     if( bCached )
     572             :     {
     573           1 :         if( mpSwapOutTimer )
     574           0 :             mpSwapOutTimer->Start();
     575             :         else
     576           1 :             FireSwapOutRequest();
     577             :     }
     578             : 
     579           1 :     return bRet;
     580             : }
     581             : 
     582             : // #i105243#
     583           1 : sal_Bool GraphicObject::DrawWithPDFHandling( OutputDevice& rOutDev,
     584             :                                          const Point& rPt, const Size& rSz,
     585             :                                          const GraphicAttr* pGrfAttr,
     586             :                                          const sal_uLong nFlags )
     587             : {
     588           1 :     const GraphicAttr aGrfAttr( pGrfAttr ? *pGrfAttr : GetAttr() );
     589             : 
     590             :     // Notify PDF writer about linked graphic (if any)
     591           1 :     sal_Bool bWritingPdfLinkedGraphic( sal_False );
     592           1 :     Point aPt( rPt );
     593           1 :     Size aSz( rSz );
     594           1 :     Rectangle aCropRect;
     595             :     vcl::PDFExtOutDevData* pPDFExtOutDevData =
     596           1 :             dynamic_cast<vcl::PDFExtOutDevData*>(rOutDev.GetExtOutDevData());
     597           1 :     if( pPDFExtOutDevData )
     598             :     {
     599             :         // only delegate image handling to PDF, if no special treatment is necessary
     600           0 :         if( GetGraphic().IsLink() &&
     601           0 :             rSz.Width() > 0L &&
     602           0 :             rSz.Height() > 0L &&
     603           0 :             !aGrfAttr.IsSpecialDrawMode() &&
     604           0 :             !aGrfAttr.IsMirrored() &&
     605           0 :             !aGrfAttr.IsRotated() &&
     606           0 :             !aGrfAttr.IsAdjusted() )
     607             :         {
     608           0 :             bWritingPdfLinkedGraphic = true;
     609             : 
     610           0 :             if( aGrfAttr.IsCropped() )
     611             :             {
     612           0 :                 PolyPolygon aClipPolyPoly;
     613             :                 sal_Bool bRectClip;
     614             :                 const sal_Bool bCrop = ImplGetCropParams( &rOutDev,
     615             :                                                       aPt, aSz,
     616             :                                                       &aGrfAttr,
     617             :                                                       aClipPolyPoly,
     618           0 :                                                       bRectClip );
     619           0 :                 if ( bCrop && bRectClip )
     620             :                 {
     621           0 :                     aCropRect = aClipPolyPoly.GetBoundRect();
     622           0 :                 }
     623             :             }
     624             : 
     625           0 :             pPDFExtOutDevData->BeginGroup();
     626             :         }
     627             :     }
     628             : 
     629           1 :     sal_Bool bRet = Draw( &rOutDev, rPt, rSz, &aGrfAttr, nFlags );
     630             : 
     631             :     // Notify PDF writer about linked graphic (if any)
     632           1 :     if( bWritingPdfLinkedGraphic )
     633             :     {
     634           0 :         pPDFExtOutDevData->EndGroup( const_cast< Graphic& >(GetGraphic()),
     635           0 :                                      aGrfAttr.GetTransparency(),
     636             :                                      Rectangle( aPt, aSz ),
     637           0 :                                      aCropRect );
     638             :     }
     639             : 
     640           1 :     return bRet;
     641             : }
     642             : 
     643           0 : sal_Bool GraphicObject::DrawTiled( OutputDevice* pOut, const Rectangle& rArea, const Size& rSize,
     644             :                                const Size& rOffset, const GraphicAttr* pAttr, sal_uLong nFlags, int nTileCacheSize1D )
     645             : {
     646           0 :     if( pOut == NULL || rSize.Width() == 0 || rSize.Height() == 0 )
     647           0 :         return sal_False;
     648             : 
     649           0 :     const MapMode   aOutMapMode( pOut->GetMapMode() );
     650           0 :     const MapMode   aMapMode( aOutMapMode.GetMapUnit(), Point(), aOutMapMode.GetScaleX(), aOutMapMode.GetScaleY() );
     651             :     // #106258# Clamp size to 1 for zero values. This is okay, since
     652             :     // logical size of zero is handled above already
     653           0 :     const Size      aOutTileSize( ::std::max( 1L, pOut->LogicToPixel( rSize, aOutMapMode ).Width() ),
     654           0 :                                   ::std::max( 1L, pOut->LogicToPixel( rSize, aOutMapMode ).Height() ) );
     655             : 
     656             :     //#i69780 clip final tile size to a sane max size
     657           0 :     while (((sal_Int64)rSize.Width() * nTileCacheSize1D) > SAL_MAX_UINT16)
     658           0 :         nTileCacheSize1D /= 2;
     659           0 :     while (((sal_Int64)rSize.Height() * nTileCacheSize1D) > SAL_MAX_UINT16)
     660           0 :         nTileCacheSize1D /= 2;
     661             : 
     662           0 :     return ImplDrawTiled( pOut, rArea, aOutTileSize, rOffset, pAttr, nFlags, nTileCacheSize1D );
     663             : }
     664             : 
     665           0 : sal_Bool GraphicObject::StartAnimation( OutputDevice* pOut, const Point& rPt, const Size& rSz,
     666             :                                     long nExtraData, const GraphicAttr* pAttr, sal_uLong /*nFlags*/,
     667             :                                     OutputDevice* pFirstFrameOutDev )
     668             : {
     669           0 :     sal_Bool bRet = sal_False;
     670             : 
     671           0 :     GetGraphic();
     672             : 
     673           0 :     if( !IsSwappedOut() )
     674             :     {
     675           0 :         const GraphicAttr aAttr( pAttr ? *pAttr : GetAttr() );
     676             : 
     677           0 :         if( mbAnimated )
     678             :         {
     679           0 :             Point   aPt( rPt );
     680           0 :             Size    aSz( rSz );
     681           0 :             sal_Bool    bCropped = aAttr.IsCropped();
     682             : 
     683           0 :             if( bCropped )
     684             :             {
     685           0 :                 PolyPolygon aClipPolyPoly;
     686             :                 sal_Bool        bRectClip;
     687           0 :                 const sal_Bool  bCrop = ImplGetCropParams( pOut, aPt, aSz, &aAttr, aClipPolyPoly, bRectClip );
     688             : 
     689           0 :                 pOut->Push( PUSH_CLIPREGION );
     690             : 
     691           0 :                 if( bCrop )
     692             :                 {
     693           0 :                     if( bRectClip )
     694           0 :                         pOut->IntersectClipRegion( aClipPolyPoly.GetBoundRect() );
     695             :                     else
     696           0 :                         pOut->IntersectClipRegion(Region(aClipPolyPoly));
     697           0 :                 }
     698             :             }
     699             : 
     700           0 :             if( !mpSimpleCache || ( mpSimpleCache->maAttr != aAttr ) || pFirstFrameOutDev )
     701             :             {
     702           0 :                 if( mpSimpleCache )
     703           0 :                     delete mpSimpleCache;
     704             : 
     705           0 :                 mpSimpleCache = new GrfSimpleCacheObj( GetTransformedGraphic( &aAttr ), aAttr );
     706           0 :                 mpSimpleCache->maGraphic.SetAnimationNotifyHdl( GetAnimationNotifyHdl() );
     707             :             }
     708             : 
     709           0 :             mpSimpleCache->maGraphic.StartAnimation( pOut, aPt, aSz, nExtraData, pFirstFrameOutDev );
     710             : 
     711           0 :             if( bCropped )
     712           0 :                 pOut->Pop();
     713             : 
     714           0 :             bRet = sal_True;
     715             :         }
     716             :         else
     717           0 :             bRet = Draw( pOut, rPt, rSz, &aAttr, GRFMGR_DRAW_STANDARD );
     718             :     }
     719             : 
     720           0 :     return bRet;
     721             : }
     722             : 
     723           0 : void GraphicObject::StopAnimation( OutputDevice* pOut, long nExtraData )
     724             : {
     725           0 :     if( mpSimpleCache )
     726           0 :         mpSimpleCache->maGraphic.StopAnimation( pOut, nExtraData );
     727           0 : }
     728             : 
     729       11183 : const Graphic& GraphicObject::GetGraphic() const
     730             : {
     731       11183 :     if( mbAutoSwapped )
     732           2 :         ( (GraphicObject*) this )->ImplAutoSwapIn();
     733             : 
     734       11183 :     return maGraphic;
     735             : }
     736             : 
     737         201 : void GraphicObject::SetGraphic( const Graphic& rGraphic, const GraphicObject* pCopyObj )
     738             : {
     739         201 :     mpMgr->ImplUnregisterObj( *this );
     740             : 
     741         201 :     if( mpSwapOutTimer )
     742          73 :         mpSwapOutTimer->Stop();
     743             : 
     744         201 :     maGraphic = rGraphic;
     745         201 :     mbAutoSwapped = sal_False;
     746         201 :     ImplAssignGraphicData();
     747         201 :     delete mpLink, mpLink = NULL;
     748         201 :     delete mpSimpleCache, mpSimpleCache = NULL;
     749             : 
     750         201 :     mpMgr->ImplRegisterObj( *this, maGraphic, 0, pCopyObj);
     751             : 
     752         201 :     if( mpSwapOutTimer )
     753          73 :         mpSwapOutTimer->Start();
     754         201 : }
     755             : 
     756          21 : void GraphicObject::SetGraphic( const Graphic& rGraphic, const String& rLink )
     757             : {
     758          21 :     SetGraphic( rGraphic );
     759          21 :     mpLink = new String( rLink );
     760          21 : }
     761             : 
     762           0 : Graphic GraphicObject::GetTransformedGraphic( const Size& rDestSize, const MapMode& rDestMap, const GraphicAttr& rAttr ) const
     763             : {
     764             :     // #104550# Extracted from svx/source/svdraw/svdograf.cxx
     765           0 :     Graphic             aTransGraphic( maGraphic );
     766           0 :     const GraphicType   eType = GetType();
     767           0 :     const Size          aSrcSize( aTransGraphic.GetPrefSize() );
     768             : 
     769             :     // #104115# Convert the crop margins to graphic object mapmode
     770           0 :     const MapMode aMapGraph( aTransGraphic.GetPrefMapMode() );
     771           0 :     const MapMode aMap100( MAP_100TH_MM );
     772             : 
     773           0 :     Size aCropLeftTop;
     774           0 :     Size aCropRightBottom;
     775             : 
     776           0 :     if( GRAPHIC_GDIMETAFILE == eType )
     777             :     {
     778           0 :         GDIMetaFile aMtf( aTransGraphic.GetGDIMetaFile() );
     779             : 
     780           0 :         if( aMapGraph == MAP_PIXEL )
     781             :         {
     782             :             aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetLeftCrop(),
     783             :                                                                                 rAttr.GetTopCrop() ),
     784           0 :                                                                           aMap100 );
     785             :             aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel( Size( rAttr.GetRightCrop(),
     786             :                                                                                     rAttr.GetBottomCrop() ),
     787           0 :                                                                               aMap100 );
     788             :         }
     789             :         else
     790             :         {
     791             :             aCropLeftTop = OutputDevice::LogicToLogic( Size( rAttr.GetLeftCrop(),
     792             :                                                              rAttr.GetTopCrop() ),
     793             :                                                        aMap100,
     794           0 :                                                        aMapGraph );
     795             :             aCropRightBottom = OutputDevice::LogicToLogic( Size( rAttr.GetRightCrop(),
     796             :                                                                  rAttr.GetBottomCrop() ),
     797             :                                                            aMap100,
     798           0 :                                                            aMapGraph );
     799             :         }
     800             : 
     801             :         // #104115# If the metafile is cropped, give it a special
     802             :         // treatment: clip against the remaining area, scale up such
     803             :         // that this area later fills the desired size, and move the
     804             :         // origin to the upper left edge of that area.
     805           0 :         if( rAttr.IsCropped() )
     806             :         {
     807           0 :             const MapMode aMtfMapMode( aMtf.GetPrefMapMode() );
     808             : 
     809           0 :             Rectangle aClipRect( aMtfMapMode.GetOrigin().X() + aCropLeftTop.Width(),
     810           0 :                                  aMtfMapMode.GetOrigin().Y() + aCropLeftTop.Height(),
     811           0 :                                  aMtfMapMode.GetOrigin().X() + aSrcSize.Width() - aCropRightBottom.Width(),
     812           0 :                                  aMtfMapMode.GetOrigin().Y() + aSrcSize.Height() - aCropRightBottom.Height() );
     813             : 
     814             :             // #104115# To correctly crop rotated metafiles, clip by view rectangle
     815           0 :             aMtf.AddAction( new MetaISectRectClipRegionAction( aClipRect ), 0 );
     816             : 
     817             :             // #104115# To crop the metafile, scale larger than the output rectangle
     818           0 :             aMtf.Scale( (double)rDestSize.Width() / (aSrcSize.Width() - aCropLeftTop.Width() - aCropRightBottom.Width()),
     819           0 :                         (double)rDestSize.Height() / (aSrcSize.Height() - aCropLeftTop.Height() - aCropRightBottom.Height()) );
     820             : 
     821             :             // #104115# Adapt the pref size by hand (scale changes it
     822             :             // proportionally, but we want it to be smaller than the
     823             :             // former size, to crop the excess out)
     824           0 :             aMtf.SetPrefSize( Size( (long)((double)rDestSize.Width() *  (1.0 + (aCropLeftTop.Width() + aCropRightBottom.Width()) / aSrcSize.Width())  + .5),
     825           0 :                                     (long)((double)rDestSize.Height() * (1.0 + (aCropLeftTop.Height() + aCropRightBottom.Height()) / aSrcSize.Height()) + .5) ) );
     826             : 
     827             :             // #104115# Adapt the origin of the new mapmode, such that it
     828             :             // is shifted to the place where the cropped output starts
     829           0 :             Point aNewOrigin( (long)((double)aMtfMapMode.GetOrigin().X() + rDestSize.Width() * aCropLeftTop.Width() / (aSrcSize.Width() - aCropLeftTop.Width() - aCropRightBottom.Width()) + .5),
     830           0 :                               (long)((double)aMtfMapMode.GetOrigin().Y() + rDestSize.Height() * aCropLeftTop.Height() / (aSrcSize.Height() - aCropLeftTop.Height() - aCropRightBottom.Height()) + .5) );
     831           0 :             MapMode aNewMap( rDestMap );
     832           0 :             aNewMap.SetOrigin( OutputDevice::LogicToLogic(aNewOrigin, aMtfMapMode, rDestMap) );
     833           0 :             aMtf.SetPrefMapMode( aNewMap );
     834             :         }
     835             :         else
     836             :         {
     837           0 :             aMtf.Scale( Fraction( rDestSize.Width(), aSrcSize.Width() ), Fraction( rDestSize.Height(), aSrcSize.Height() ) );
     838           0 :             aMtf.SetPrefMapMode( rDestMap );
     839             :         }
     840             : 
     841           0 :         aTransGraphic = aMtf;
     842             :     }
     843           0 :     else if( GRAPHIC_BITMAP == eType )
     844             :     {
     845           0 :         BitmapEx aBitmapEx( aTransGraphic.GetBitmapEx() );
     846           0 :         Rectangle aCropRect;
     847             : 
     848             :         // convert crops to pixel (crops are always in GraphicObject units)
     849           0 :         if(rAttr.IsCropped())
     850             :         {
     851             :             aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel(
     852             :                 Size(rAttr.GetLeftCrop(), rAttr.GetTopCrop()),
     853           0 :                 aMapGraph);
     854             :             aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel(
     855             :                 Size(rAttr.GetRightCrop(), rAttr.GetBottomCrop()),
     856           0 :                 aMapGraph);
     857             : 
     858             :             // convert from prefmapmode to pixel
     859             :             Size aSrcSizePixel(
     860             :                 Application::GetDefaultDevice()->LogicToPixel(
     861             :                     aSrcSize,
     862           0 :                     aMapGraph));
     863             : 
     864           0 :             if(rAttr.IsCropped()
     865           0 :                 && (aSrcSizePixel.Width() != aBitmapEx.GetSizePixel().Width() || aSrcSizePixel.Height() != aBitmapEx.GetSizePixel().Height())
     866           0 :                 && aSrcSizePixel.Width())
     867             :             {
     868             :                 // the size in pixels calculated from Graphic's internal MapMode (aTransGraphic.GetPrefMapMode())
     869             :                 // and it's internal size (aTransGraphic.GetPrefSize()) is different from it's real pixel size.
     870             :                 // This can be interpreted as this values to be set wrong, but needs to be corrected since e.g.
     871             :                 // existing cropping is calculated based on this logic values already.
     872             :                 // aBitmapEx.Scale(aSrcSizePixel);
     873             : 
     874             :                 // another possibility is to adapt the values created so far with a factor; this
     875             :                 // will keep the original Bitmap untouched and thus quality will not change
     876           0 :                 const double fFactorX(aBitmapEx.GetSizePixel().Width() / aSrcSizePixel.Width());
     877           0 :                 const double fFactorY(aBitmapEx.GetSizePixel().Height() / aSrcSizePixel.Height());
     878             : 
     879           0 :                 aCropLeftTop.Width() = basegfx::fround(aCropLeftTop.Width() * fFactorX);
     880           0 :                 aCropLeftTop.Height() = basegfx::fround(aCropLeftTop.Height() * fFactorY);
     881           0 :                 aCropRightBottom.Width() = basegfx::fround(aCropRightBottom.Width() * fFactorX);
     882           0 :                 aCropRightBottom.Height() = basegfx::fround(aCropRightBottom.Height() * fFactorY);
     883             : 
     884           0 :                 aSrcSizePixel = aBitmapEx.GetSizePixel();
     885             :             }
     886             : 
     887             :             // setup crop rectangle in pixel
     888           0 :             aCropRect = Rectangle( aCropLeftTop.Width(), aCropLeftTop.Height(),
     889           0 :                                  aSrcSizePixel.Width() - aCropRightBottom.Width(),
     890           0 :                                  aSrcSizePixel.Height() - aCropRightBottom.Height() );
     891             :         }
     892             : 
     893             :         // #105641# Also crop animations
     894           0 :         if( aTransGraphic.IsAnimated() )
     895             :         {
     896             :             sal_uInt16 nFrame;
     897           0 :             Animation aAnim( aTransGraphic.GetAnimation() );
     898             : 
     899           0 :             for( nFrame=0; nFrame<aAnim.Count(); ++nFrame )
     900             :             {
     901           0 :                 AnimationBitmap aAnimBmp( aAnim.Get( nFrame ) );
     902             : 
     903           0 :                 if( !aCropRect.IsInside( Rectangle(aAnimBmp.aPosPix, aAnimBmp.aSizePix) ) )
     904             :                 {
     905             :                     // setup actual cropping (relative to frame position)
     906           0 :                     Rectangle aCropRectRel( aCropRect );
     907           0 :                     aCropRectRel.Move( -aAnimBmp.aPosPix.X(),
     908           0 :                                        -aAnimBmp.aPosPix.Y() );
     909             : 
     910             :                     // cropping affects this frame, apply it then
     911             :                     // do _not_ apply enlargement, this is done below
     912             :                     ImplTransformBitmap( aAnimBmp.aBmpEx, rAttr, Size(), Size(),
     913           0 :                                          aCropRectRel, rDestSize, sal_False );
     914             : 
     915           0 :                     aAnim.Replace( aAnimBmp, nFrame );
     916             :                 }
     917             :                 // else: bitmap completely within crop area,
     918             :                 // i.e. nothing is cropped away
     919           0 :             }
     920             : 
     921             :             // now, apply enlargement (if any) through global animation size
     922           0 :             if( aCropLeftTop.Width() < 0 ||
     923           0 :                 aCropLeftTop.Height() < 0 ||
     924           0 :                 aCropRightBottom.Width() < 0 ||
     925           0 :                 aCropRightBottom.Height() < 0 )
     926             :             {
     927           0 :                 Size aNewSize( aAnim.GetDisplaySizePixel() );
     928           0 :                 aNewSize.Width() += aCropRightBottom.Width() < 0 ? -aCropRightBottom.Width() : 0;
     929           0 :                 aNewSize.Width() += aCropLeftTop.Width() < 0 ? -aCropLeftTop.Width() : 0;
     930           0 :                 aNewSize.Height() += aCropRightBottom.Height() < 0 ? -aCropRightBottom.Height() : 0;
     931           0 :                 aNewSize.Height() += aCropLeftTop.Height() < 0 ? -aCropLeftTop.Height() : 0;
     932           0 :                 aAnim.SetDisplaySizePixel( aNewSize );
     933             :             }
     934             : 
     935             :             // if topleft has changed, we must move all frames to the
     936             :             // right and bottom, resp.
     937           0 :             if( aCropLeftTop.Width() < 0 ||
     938           0 :                 aCropLeftTop.Height() < 0 )
     939             :             {
     940           0 :                 Point aPosOffset( aCropLeftTop.Width() < 0 ? -aCropLeftTop.Width() : 0,
     941           0 :                                   aCropLeftTop.Height() < 0 ? -aCropLeftTop.Height() : 0 );
     942             : 
     943           0 :                 for( nFrame=0; nFrame<aAnim.Count(); ++nFrame )
     944             :                 {
     945           0 :                     AnimationBitmap aAnimBmp( aAnim.Get( nFrame ) );
     946             : 
     947           0 :                     aAnimBmp.aPosPix += aPosOffset;
     948             : 
     949           0 :                     aAnim.Replace( aAnimBmp, nFrame );
     950           0 :                 }
     951             :             }
     952             : 
     953           0 :             aTransGraphic = aAnim;
     954             :         }
     955             :         else
     956             :         {
     957             :             ImplTransformBitmap( aBitmapEx, rAttr, aCropLeftTop, aCropRightBottom,
     958           0 :                                  aCropRect, rDestSize, sal_True );
     959             : 
     960           0 :             aTransGraphic = aBitmapEx;
     961             :         }
     962             : 
     963           0 :         aTransGraphic.SetPrefSize( rDestSize );
     964           0 :         aTransGraphic.SetPrefMapMode( rDestMap );
     965             :     }
     966             : 
     967           0 :     GraphicObject aGrfObj( aTransGraphic );
     968           0 :     aTransGraphic = aGrfObj.GetTransformedGraphic( &rAttr );
     969             : 
     970           0 :     return aTransGraphic;
     971             : }
     972             : 
     973          31 : Graphic GraphicObject::GetTransformedGraphic( const GraphicAttr* pAttr ) const // TODO: Change to Impl
     974             : {
     975          31 :     GetGraphic();
     976             : 
     977          31 :     Graphic     aGraphic;
     978          62 :     GraphicAttr aAttr( pAttr ? *pAttr : GetAttr() );
     979             : 
     980          31 :     if( maGraphic.IsSupportedGraphic() && !maGraphic.IsSwapOut() )
     981             :     {
     982          31 :         if( aAttr.IsSpecialDrawMode() || aAttr.IsAdjusted() || aAttr.IsMirrored() || aAttr.IsRotated() || aAttr.IsTransparent() )
     983             :         {
     984           0 :             if( GetType() == GRAPHIC_BITMAP )
     985             :             {
     986           0 :                 if( IsAnimated() )
     987             :                 {
     988           0 :                     Animation aAnimation( maGraphic.GetAnimation() );
     989           0 :                     GraphicManager::ImplAdjust( aAnimation, aAttr, ADJUSTMENT_ALL );
     990           0 :                     aAnimation.SetLoopCount( mnAnimationLoopCount );
     991           0 :                     aGraphic = aAnimation;
     992             :                 }
     993             :                 else
     994             :                 {
     995           0 :                     BitmapEx aBmpEx( maGraphic.GetBitmapEx() );
     996           0 :                     GraphicManager::ImplAdjust( aBmpEx, aAttr, ADJUSTMENT_ALL );
     997           0 :                     aGraphic = aBmpEx;
     998             :                 }
     999             :             }
    1000             :             else
    1001             :             {
    1002           0 :                 GDIMetaFile aMtf( maGraphic.GetGDIMetaFile() );
    1003           0 :                 GraphicManager::ImplAdjust( aMtf, aAttr, ADJUSTMENT_ALL );
    1004           0 :                 aGraphic = aMtf;
    1005             :             }
    1006             :         }
    1007             :         else
    1008             :         {
    1009          31 :             if( ( GetType() == GRAPHIC_BITMAP ) && IsAnimated() )
    1010             :             {
    1011           0 :                 Animation aAnimation( maGraphic.GetAnimation() );
    1012           0 :                 aAnimation.SetLoopCount( mnAnimationLoopCount );
    1013           0 :                 aGraphic = aAnimation;
    1014             :             }
    1015             :             else
    1016          31 :                 aGraphic = maGraphic;
    1017             :         }
    1018             :     }
    1019             : 
    1020          62 :     return aGraphic;
    1021             : }
    1022             : 
    1023          11 : sal_Bool GraphicObject::SwapOut()
    1024             : {
    1025          11 :     sal_Bool bRet = ( !mbAutoSwapped ? maGraphic.SwapOut() : sal_False );
    1026             : 
    1027          11 :     if( bRet && mpMgr )
    1028          11 :         mpMgr->ImplGraphicObjectWasSwappedOut( *this );
    1029             : 
    1030          11 :     return bRet;
    1031             : }
    1032             : 
    1033           0 : sal_Bool GraphicObject::SwapOut( SvStream* pOStm )
    1034             : {
    1035           0 :     sal_Bool bRet = ( !mbAutoSwapped ? maGraphic.SwapOut( pOStm ) : sal_False );
    1036             : 
    1037           0 :     if( bRet && mpMgr )
    1038           0 :         mpMgr->ImplGraphicObjectWasSwappedOut( *this );
    1039             : 
    1040           0 :     return bRet;
    1041             : }
    1042             : 
    1043           0 : sal_Bool GraphicObject::SwapIn()
    1044             : {
    1045             :     sal_Bool bRet;
    1046             : 
    1047           0 :     if( mbAutoSwapped )
    1048             :     {
    1049           0 :         ImplAutoSwapIn();
    1050           0 :         bRet = sal_True;
    1051             :     }
    1052           0 :     else if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) )
    1053           0 :         bRet = sal_True;
    1054             :     else
    1055             :     {
    1056           0 :         bRet = maGraphic.SwapIn();
    1057             : 
    1058           0 :         if( bRet && mpMgr )
    1059           0 :             mpMgr->ImplGraphicObjectWasSwappedIn( *this );
    1060             :     }
    1061             : 
    1062           0 :     if( bRet )
    1063           0 :         ImplAssignGraphicData();
    1064             : 
    1065           0 :     return bRet;
    1066             : }
    1067             : 
    1068          12 : void GraphicObject::SetSwapState()
    1069             : {
    1070          12 :     if( !IsSwappedOut() )
    1071             :     {
    1072          12 :         mbAutoSwapped = sal_True;
    1073             : 
    1074          12 :         if( mpMgr )
    1075          12 :             mpMgr->ImplGraphicObjectWasSwappedOut( *this );
    1076             :     }
    1077          12 : }
    1078             : 
    1079          74 : IMPL_LINK_NOARG(GraphicObject, ImplAutoSwapOutHdl)
    1080             : {
    1081          72 :     if( !IsSwappedOut() )
    1082             :     {
    1083          60 :         mbIsInSwapOut = sal_True;
    1084             : 
    1085          60 :         SvStream* pStream = GetSwapStream();
    1086             : 
    1087          60 :         if( GRFMGR_AUTOSWAPSTREAM_NONE != pStream )
    1088             :         {
    1089          11 :             if( GRFMGR_AUTOSWAPSTREAM_LINK == pStream )
    1090           0 :                 mbAutoSwapped = SwapOut( NULL );
    1091             :             else
    1092             :             {
    1093          11 :                 if( GRFMGR_AUTOSWAPSTREAM_TEMP == pStream )
    1094          11 :                     mbAutoSwapped = SwapOut();
    1095             :                 else
    1096             :                 {
    1097           0 :                     mbAutoSwapped = SwapOut( pStream );
    1098           0 :                     delete pStream;
    1099             :                 }
    1100             :             }
    1101             :         }
    1102             : 
    1103          60 :         mbIsInSwapOut = sal_False;
    1104             :     }
    1105             : 
    1106          72 :     if( mpSwapOutTimer )
    1107          71 :         mpSwapOutTimer->Start();
    1108             : 
    1109          72 :     return 0L;
    1110             : }
    1111             : 
    1112           0 : SvStream& operator>>( SvStream& rIStm, GraphicObject& rGraphicObj )
    1113             : {
    1114           0 :     VersionCompat   aCompat( rIStm, STREAM_READ );
    1115           0 :     Graphic         aGraphic;
    1116           0 :     GraphicAttr     aAttr;
    1117             :     sal_Bool            bLink;
    1118             : 
    1119           0 :     rIStm >> aGraphic >> aAttr >> bLink;
    1120             : 
    1121           0 :     rGraphicObj.SetGraphic( aGraphic );
    1122           0 :     rGraphicObj.SetAttr( aAttr );
    1123             : 
    1124           0 :     if( bLink )
    1125             :     {
    1126           0 :         OUString aLink = read_lenPrefixed_uInt8s_ToOUString<sal_uInt16>(rIStm, RTL_TEXTENCODING_UTF8);
    1127           0 :         rGraphicObj.SetLink(aLink);
    1128             :     }
    1129             :     else
    1130           0 :         rGraphicObj.SetLink();
    1131             : 
    1132           0 :     rGraphicObj.SetSwapStreamHdl();
    1133             : 
    1134           0 :     return rIStm;
    1135             : }
    1136             : 
    1137           0 : SvStream& operator<<( SvStream& rOStm, const GraphicObject& rGraphicObj )
    1138             : {
    1139           0 :     VersionCompat   aCompat( rOStm, STREAM_WRITE, 1 );
    1140           0 :     const sal_Bool      bLink =  rGraphicObj.HasLink();
    1141             : 
    1142           0 :     rOStm << rGraphicObj.GetGraphic() << rGraphicObj.GetAttr() << bLink;
    1143             : 
    1144           0 :     if( bLink )
    1145           0 :         write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rOStm, rGraphicObj.GetLink(), RTL_TEXTENCODING_UTF8);
    1146             : 
    1147           0 :     return rOStm;
    1148             : }
    1149             : 
    1150             : #define UNO_NAME_GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:"
    1151             : 
    1152         172 : GraphicObject GraphicObject::CreateGraphicObjectFromURL( const OUString &rURL )
    1153             : {
    1154         344 :     const String aURL( rURL ), aPrefix( RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_GRAPHOBJ_URLPREFIX) );
    1155         172 :     if( aURL.Search( aPrefix ) == 0 )
    1156             :     {
    1157             :         // graphic manager url
    1158         172 :         OString aUniqueID(OUStringToOString(rURL.copy(sizeof(UNO_NAME_GRAPHOBJ_URLPREFIX) - 1), RTL_TEXTENCODING_UTF8));
    1159         172 :         return GraphicObject( aUniqueID );
    1160             :     }
    1161             :     else
    1162             :     {
    1163           0 :         Graphic     aGraphic;
    1164           0 :         if ( aURL.Len() )
    1165             :         {
    1166           0 :             SvStream*   pStream = utl::UcbStreamHelper::CreateStream( aURL, STREAM_READ );
    1167           0 :             if( pStream )
    1168           0 :                 GraphicConverter::Import( *pStream, aGraphic );
    1169             :         }
    1170             : 
    1171           0 :         return GraphicObject( aGraphic );
    1172         172 :     }
    1173             : }
    1174             : 
    1175             : void
    1176           0 : GraphicObject::InspectForGraphicObjectImageURL( const Reference< XInterface >& xIf,  std::vector< OUString >& rvEmbedImgUrls )
    1177             : {
    1178           0 :     static OUString sImageURL( "ImageURL" );
    1179           0 :     Reference< XPropertySet > xProps( xIf, UNO_QUERY );
    1180           0 :     if ( xProps.is() )
    1181             :     {
    1182             : 
    1183           0 :         if ( xProps->getPropertySetInfo()->hasPropertyByName( sImageURL ) )
    1184             :         {
    1185           0 :             OUString sURL;
    1186           0 :             xProps->getPropertyValue( sImageURL ) >>= sURL;
    1187           0 :             if ( !sURL.isEmpty() && sURL.startsWith( UNO_NAME_GRAPHOBJ_URLPREFIX ) )
    1188           0 :                 rvEmbedImgUrls.push_back( sURL );
    1189             :         }
    1190             :     }
    1191           0 :     Reference< XNameContainer > xContainer( xIf, UNO_QUERY );
    1192           0 :     if ( xContainer.is() )
    1193             :     {
    1194           0 :         Sequence< OUString > sNames = xContainer->getElementNames();
    1195           0 :         sal_Int32 nContainees = sNames.getLength();
    1196           0 :         for ( sal_Int32 index = 0; index < nContainees; ++index )
    1197             :         {
    1198           0 :             Reference< XInterface > xCtrl;
    1199           0 :             xContainer->getByName( sNames[ index ] ) >>= xCtrl;
    1200           0 :             InspectForGraphicObjectImageURL( xCtrl, rvEmbedImgUrls );
    1201           0 :         }
    1202           0 :     }
    1203           0 : }
    1204             : 
    1205             : // calculate scalings between real image size and logic object size. This
    1206             : // is necessary since the crop values are relative to original bitmap size
    1207           0 : basegfx::B2DVector GraphicObject::calculateCropScaling(
    1208             :     double fWidth,
    1209             :     double fHeight,
    1210             :     double fLeftCrop,
    1211             :     double fTopCrop,
    1212             :     double fRightCrop,
    1213             :     double fBottomCrop) const
    1214             : {
    1215           0 :     const MapMode aMapMode100thmm(MAP_100TH_MM);
    1216           0 :     Size aBitmapSize(GetPrefSize());
    1217           0 :     double fFactorX(1.0);
    1218           0 :     double fFactorY(1.0);
    1219             : 
    1220           0 :     if(MAP_PIXEL == GetPrefMapMode().GetMapUnit())
    1221             :     {
    1222           0 :         aBitmapSize = Application::GetDefaultDevice()->PixelToLogic(aBitmapSize, aMapMode100thmm);
    1223             :     }
    1224             :     else
    1225             :     {
    1226           0 :         aBitmapSize = Application::GetDefaultDevice()->LogicToLogic(aBitmapSize, GetPrefMapMode(), aMapMode100thmm);
    1227             :     }
    1228             : 
    1229           0 :     const double fDivX(aBitmapSize.Width() - fLeftCrop - fRightCrop);
    1230           0 :     const double fDivY(aBitmapSize.Height() - fTopCrop - fBottomCrop);
    1231             : 
    1232           0 :     if(!basegfx::fTools::equalZero(fDivX))
    1233             :     {
    1234           0 :         fFactorX = fabs(fWidth) / fDivX;
    1235             :     }
    1236             : 
    1237           0 :     if(!basegfx::fTools::equalZero(fDivY))
    1238             :     {
    1239           0 :         fFactorY = fabs(fHeight) / fDivY;
    1240             :     }
    1241             : 
    1242           0 :     return basegfx::B2DVector(fFactorX,fFactorY);
    1243         465 : }
    1244             : 
    1245             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10