LCOV - code coverage report
Current view: top level - svtools/source/graphic - grfmgr.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 280 594 47.1 %
Date: 2015-06-13 12:38:46 Functions: 36 59 61.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11