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

Generated by: LCOV version 1.10