LCOV - code coverage report
Current view: top level - svtools/source/graphic - grfcache.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 341 519 65.7 %
Date: 2012-08-25 Functions: 42 50 84.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 327 749 43.7 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <salhelper/timer.hxx>
      31                 :            : #include <svtools/grfmgr.hxx>
      32                 :            : #include <tools/debug.hxx>
      33                 :            : #include <vcl/metaact.hxx>
      34                 :            : #include <vcl/outdev.hxx>
      35                 :            : #include <tools/poly.hxx>
      36                 :            : #include <rtl/strbuf.hxx>
      37                 :            : #include "grfcache.hxx"
      38                 :            : 
      39                 :            : #include <memory>
      40                 :            : 
      41                 :            : // -----------
      42                 :            : // - Defines -
      43                 :            : // -----------
      44                 :            : 
      45                 :            : #define RELEASE_TIMEOUT 10000
      46                 :            : #define MAX_BMP_EXTENT  4096
      47                 :            : 
      48                 :            : // -----------
      49                 :            : // - statics -
      50                 :            : // -----------
      51                 :            : 
      52                 :            : static const char aHexData[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
      53                 :            : 
      54                 :            : // -------------
      55                 :            : // - GraphicID -
      56                 :            : // -------------
      57                 :            : 
      58                 :            : class GraphicID
      59                 :            : {
      60                 :            : private:
      61                 :            : 
      62                 :            :     sal_uInt32  mnID1;
      63                 :            :     sal_uInt32  mnID2;
      64                 :            :     sal_uInt32  mnID3;
      65                 :            :     sal_uInt32  mnID4;
      66                 :            : 
      67                 :            :                 GraphicID();
      68                 :            : 
      69                 :            : public:
      70                 :            : 
      71                 :            : 
      72                 :            :                 GraphicID( const GraphicObject& rObj );
      73                 :      49278 :                 ~GraphicID() {}
      74                 :            : 
      75                 :      81699 :     sal_Bool        operator==( const GraphicID& rID ) const
      76                 :            :                 {
      77                 :            :                     return( rID.mnID1 == mnID1 && rID.mnID2 == mnID2 &&
      78 [ +  + ][ +  + ]:      81699 :                             rID.mnID3 == mnID3 && rID.mnID4 == mnID4 );
         [ +  - ][ +  + ]
      79                 :            :                 }
      80                 :            : 
      81                 :            :     rtl::OString GetIDString() const;
      82                 :       5527 :     sal_Bool        IsEmpty() const { return( 0 == mnID4 ); }
      83                 :            : };
      84                 :            : 
      85                 :            : // -----------------------------------------------------------------------------
      86                 :            : 
      87                 :      49523 : GraphicID::GraphicID( const GraphicObject& rObj )
      88                 :            : {
      89                 :      49523 :     const Graphic& rGraphic = rObj.GetGraphic();
      90                 :            : 
      91                 :      49523 :     mnID1 = ( (sal_uLong) rGraphic.GetType() ) << 28;
      92                 :            : 
      93      [ +  +  + ]:      49523 :     switch( rGraphic.GetType() )
      94                 :            :     {
      95                 :            :         case( GRAPHIC_BITMAP ):
      96                 :            :         {
      97         [ -  + ]:      36084 :             if( rGraphic.IsAnimated() )
      98                 :            :             {
      99         [ #  # ]:          0 :                 const Animation aAnimation( rGraphic.GetAnimation() );
     100                 :            : 
     101                 :          0 :                 mnID1 |= ( aAnimation.Count() & 0x0fffffff );
     102                 :          0 :                 mnID2 = aAnimation.GetDisplaySizePixel().Width();
     103                 :          0 :                 mnID3 = aAnimation.GetDisplaySizePixel().Height();
     104 [ #  # ][ #  # ]:          0 :                 mnID4 = rGraphic.GetChecksum();
     105                 :            :             }
     106                 :            :             else
     107                 :            :             {
     108         [ +  - ]:      36084 :                 const BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
     109                 :            : 
     110 [ +  - ][ +  + ]:      36084 :                 mnID1 |= ( ( ( (sal_uLong) aBmpEx.GetTransparentType() << 8 ) | ( aBmpEx.IsAlpha() ? 1 : 0 ) ) & 0x0fffffff );
     111                 :      36084 :                 mnID2 = aBmpEx.GetSizePixel().Width();
     112                 :      36084 :                 mnID3 = aBmpEx.GetSizePixel().Height();
     113 [ +  - ][ +  - ]:      36084 :                 mnID4 = rGraphic.GetChecksum();
     114                 :            :             }
     115                 :            :         }
     116                 :      36084 :         break;
     117                 :            : 
     118                 :            :         case( GRAPHIC_GDIMETAFILE ):
     119                 :            :         {
     120                 :        212 :             const GDIMetaFile& rMtf = rGraphic.GetGDIMetaFile();
     121                 :            : 
     122                 :        212 :             mnID1 |= ( rMtf.GetActionSize() & 0x0fffffff );
     123                 :        212 :             mnID2 = rMtf.GetPrefSize().Width();
     124                 :        212 :             mnID3 = rMtf.GetPrefSize().Height();
     125                 :        212 :             mnID4 = rGraphic.GetChecksum();
     126                 :            :         }
     127                 :        212 :         break;
     128                 :            : 
     129                 :            :         default:
     130                 :      13227 :             mnID2 = mnID3 = mnID4 = 0;
     131                 :      13227 :         break;
     132                 :            :     }
     133                 :      49523 : }
     134                 :            : 
     135                 :            : // -----------------------------------------------------------------------------
     136                 :            : 
     137                 :      13321 : rtl::OString GraphicID::GetIDString() const
     138                 :            : {
     139                 :      13321 :     rtl::OStringBuffer aHexStr;
     140                 :      13321 :     sal_Int32 nShift, nIndex = 0;
     141         [ +  - ]:      13321 :     aHexStr.setLength(32);
     142                 :            : 
     143         [ +  + ]:     119889 :     for( nShift = 28; nShift >= 0; nShift -= 4 )
     144                 :     106568 :         aHexStr[nIndex++] = aHexData[ ( mnID1 >> (sal_uInt32) nShift ) & 0xf ];
     145                 :            : 
     146         [ +  + ]:     119889 :     for( nShift = 28; nShift >= 0; nShift -= 4 )
     147                 :     106568 :         aHexStr[nIndex++] = aHexData[ ( mnID2 >> (sal_uInt32) nShift ) & 0xf ];
     148                 :            : 
     149         [ +  + ]:     119889 :     for( nShift = 28; nShift >= 0; nShift -= 4 )
     150                 :     106568 :         aHexStr[nIndex++] = aHexData[ ( mnID3 >> (sal_uInt32) nShift ) & 0xf ];
     151                 :            : 
     152         [ +  + ]:     119889 :     for( nShift = 28; nShift >= 0; nShift -= 4 )
     153                 :     106568 :         aHexStr[nIndex++] = aHexData[ ( mnID4 >> (sal_uInt32) nShift ) & 0xf ];
     154                 :            : 
     155                 :      13321 :     return aHexStr.makeStringAndClear();
     156                 :            : }
     157                 :            : 
     158                 :            : // ---------------------
     159                 :            : // - GraphicCacheEntry -
     160                 :            : // ---------------------
     161                 :            : 
     162                 :            : class GraphicCacheEntry
     163                 :            : {
     164                 :            : private:
     165                 :            : 
     166                 :            :     GraphicObjectList_impl  maGraphicObjectList;
     167                 :            : 
     168                 :            :     GraphicID           maID;
     169                 :            :     GfxLink             maGfxLink;
     170                 :            :     BitmapEx*           mpBmpEx;
     171                 :            :     GDIMetaFile*        mpMtf;
     172                 :            :     Animation*          mpAnimation;
     173                 :            :     bool                mbSwappedAll;
     174                 :            : 
     175                 :            :     bool                ImplInit( const GraphicObject& rObj );
     176                 :            :     void                ImplFillSubstitute( Graphic& rSubstitute );
     177                 :            : 
     178                 :            : public:
     179                 :            : 
     180                 :            :                         GraphicCacheEntry( const GraphicObject& rObj );
     181                 :            :                         ~GraphicCacheEntry();
     182                 :            : 
     183                 :     100547 :     const GraphicID&    GetID() const { return maID; }
     184                 :            : 
     185                 :            :     void                AddGraphicObjectReference( const GraphicObject& rObj, Graphic& rSubstitute );
     186                 :            :     bool                ReleaseGraphicObjectReference( const GraphicObject& rObj );
     187                 :      34530 :     size_t              GetGraphicObjectReferenceCount() { return maGraphicObjectList.size(); }
     188                 :            :     bool                HasGraphicObjectReference( const GraphicObject& rObj );
     189                 :            : 
     190                 :            :     void                TryToSwapIn();
     191                 :            :     void                GraphicObjectWasSwappedOut( const GraphicObject& rObj );
     192                 :            :     bool                FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute );
     193                 :            :     void                GraphicObjectWasSwappedIn( const GraphicObject& rObj );
     194                 :            : };
     195                 :            : 
     196                 :            : // -----------------------------------------------------------------------------
     197                 :            : 
     198                 :      31160 : GraphicCacheEntry::GraphicCacheEntry( const GraphicObject& rObj ) :
     199                 :            :     maID            ( rObj ),
     200                 :            :     mpBmpEx         ( NULL ),
     201                 :            :     mpMtf           ( NULL ),
     202                 :            :     mpAnimation     ( NULL ),
     203 [ +  - ][ +  - ]:      31160 :     mbSwappedAll    ( !ImplInit( rObj ) )
                 [ +  - ]
     204                 :            : {
     205         [ +  - ]:      31160 :     maGraphicObjectList.push_back( (GraphicObject*)&rObj );
     206                 :      31160 : }
     207                 :            : 
     208                 :            : // -----------------------------------------------------------------------------
     209                 :            : 
     210         [ +  - ]:      30915 : GraphicCacheEntry::~GraphicCacheEntry()
     211                 :            : {
     212                 :            :     DBG_ASSERT(
     213                 :            :         maGraphicObjectList.empty(),
     214                 :            :         "GraphicCacheEntry::~GraphicCacheEntry(): Not all GraphicObjects are removed from this entry"
     215                 :            :     );
     216                 :            : 
     217 [ +  + ][ +  - ]:      30915 :     delete mpBmpEx;
     218 [ +  + ][ +  - ]:      30915 :     delete mpMtf;
     219 [ -  + ][ #  # ]:      30915 :     delete mpAnimation;
     220                 :      30915 : }
     221                 :            : 
     222                 :            : // -----------------------------------------------------------------------------
     223                 :            : 
     224                 :      31169 : bool GraphicCacheEntry::ImplInit( const GraphicObject& rObj )
     225                 :            : {
     226                 :      31169 :     bool bRet = false;
     227                 :            : 
     228         [ +  - ]:      31169 :     if( !rObj.IsSwappedOut() )
     229                 :            :     {
     230                 :      31169 :         const Graphic& rGraphic = rObj.GetGraphic();
     231                 :            : 
     232         [ -  + ]:      31169 :         if( mpBmpEx )
     233         [ #  # ]:          0 :             delete mpBmpEx, mpBmpEx = NULL;
     234                 :            : 
     235         [ -  + ]:      31169 :         if( mpMtf )
     236         [ #  # ]:          0 :             delete mpMtf, mpMtf = NULL;
     237                 :            : 
     238         [ -  + ]:      31169 :         if( mpAnimation )
     239         [ #  # ]:          0 :             delete mpAnimation, mpAnimation = NULL;
     240                 :            : 
     241      [ +  +  + ]:      31169 :         switch( rGraphic.GetType() )
     242                 :            :         {
     243                 :            :             case( GRAPHIC_BITMAP ):
     244                 :            :             {
     245         [ -  + ]:      17931 :                 if( rGraphic.IsAnimated() )
     246         [ #  # ]:          0 :                     mpAnimation = new Animation( rGraphic.GetAnimation() );
     247                 :            :                 else
     248 [ +  - ][ +  - ]:      17931 :                     mpBmpEx = new BitmapEx( rGraphic.GetBitmapEx() );
     249                 :            :             }
     250                 :      17931 :             break;
     251                 :            : 
     252                 :            :             case( GRAPHIC_GDIMETAFILE ):
     253                 :            :             {
     254         [ +  - ]:        104 :                 mpMtf = new GDIMetaFile( rGraphic.GetGDIMetaFile() );
     255                 :            :             }
     256                 :        104 :             break;
     257                 :            : 
     258                 :            :             default:
     259                 :            :                 DBG_ASSERT( GetID().IsEmpty(), "GraphicCacheEntry::ImplInit: Could not initialize graphic! (=>KA)" );
     260                 :      13134 :             break;
     261                 :            :         }
     262                 :            : 
     263         [ +  + ]:      31169 :         if( rGraphic.IsLink() )
     264         [ +  - ]:        271 :             maGfxLink = ( (Graphic&) rGraphic ).GetLink();
     265                 :            :         else
     266         [ +  - ]:      30898 :             maGfxLink = GfxLink();
     267                 :            : 
     268                 :      31169 :         bRet = true;
     269                 :            :     }
     270                 :            : 
     271                 :      31169 :     return bRet;
     272                 :            : }
     273                 :            : 
     274                 :            : // -----------------------------------------------------------------------------
     275                 :            : 
     276                 :       3621 : void GraphicCacheEntry::ImplFillSubstitute( Graphic& rSubstitute )
     277                 :            : {
     278                 :            :     // create substitute for graphic;
     279         [ +  - ]:       3621 :     const Size          aPrefSize( rSubstitute.GetPrefSize() );
     280         [ +  - ]:       3621 :     const MapMode       aPrefMapMode( rSubstitute.GetPrefMapMode() );
     281         [ +  - ]:       3621 :     const Link          aAnimationNotifyHdl( rSubstitute.GetAnimationNotifyHdl() );
     282 [ +  - ][ +  - ]:       3621 :     const String        aDocFileName( rSubstitute.GetDocFileName() );
     283         [ +  - ]:       3621 :     const sal_uLong     nDocFilePos = rSubstitute.GetDocFilePos();
     284         [ +  - ]:       3621 :     const GraphicType   eOldType = rSubstitute.GetType();
     285         [ +  - ]:       3621 :     const bool          bDefaultType = ( rSubstitute.GetType() == GRAPHIC_DEFAULT );
     286                 :            : 
     287 [ +  - ][ +  + ]:       3621 :     if( rSubstitute.IsLink() && ( GFX_LINK_TYPE_NONE == maGfxLink.GetType() ) )
         [ +  - ][ -  + ]
                 [ -  + ]
     288 [ #  # ][ #  # ]:          0 :         maGfxLink = rSubstitute.GetLink();
                 [ #  # ]
     289                 :            : 
     290         [ +  + ]:       3621 :     if( mpBmpEx )
     291 [ +  - ][ +  - ]:       3468 :         rSubstitute = *mpBmpEx;
                 [ +  - ]
     292         [ -  + ]:        153 :     else if( mpAnimation )
     293 [ #  # ][ #  # ]:          0 :         rSubstitute = *mpAnimation;
                 [ #  # ]
     294         [ +  + ]:        153 :     else if( mpMtf )
     295 [ +  - ][ +  - ]:         87 :         rSubstitute = *mpMtf;
                 [ +  - ]
     296                 :            :     else
     297         [ +  - ]:         66 :         rSubstitute.Clear();
     298                 :            : 
     299         [ +  + ]:       3621 :     if( eOldType != GRAPHIC_NONE )
     300                 :            :     {
     301         [ +  - ]:       3198 :         rSubstitute.SetPrefSize( aPrefSize );
     302         [ +  - ]:       3198 :         rSubstitute.SetPrefMapMode( aPrefMapMode );
     303         [ +  - ]:       3198 :         rSubstitute.SetAnimationNotifyHdl( aAnimationNotifyHdl );
     304         [ +  - ]:       3198 :         rSubstitute.SetDocFileName( aDocFileName, nDocFilePos );
     305                 :            :     }
     306                 :            : 
     307 [ +  - ][ +  + ]:       3621 :     if( GFX_LINK_TYPE_NONE != maGfxLink.GetType() )
     308         [ +  - ]:       1330 :         rSubstitute.SetLink( maGfxLink );
     309                 :            : 
     310         [ +  + ]:       3621 :     if( bDefaultType )
     311 [ +  - ][ +  - ]:       3621 :         rSubstitute.SetDefaultType();
                 [ +  - ]
     312                 :       3621 : }
     313                 :            : 
     314                 :            : // -----------------------------------------------------------------------------
     315                 :            : 
     316                 :       3621 : void GraphicCacheEntry::AddGraphicObjectReference( const GraphicObject& rObj, Graphic& rSubstitute )
     317                 :            : {
     318         [ +  + ]:       3621 :     if( mbSwappedAll )
     319                 :          3 :         mbSwappedAll = !ImplInit( rObj );
     320                 :            : 
     321                 :       3621 :     ImplFillSubstitute( rSubstitute );
     322         [ +  - ]:       3621 :     maGraphicObjectList.push_back( (GraphicObject*) &rObj );
     323                 :       3621 : }
     324                 :            : 
     325                 :            : // -----------------------------------------------------------------------------
     326                 :            : 
     327                 :     189778 : bool GraphicCacheEntry::ReleaseGraphicObjectReference( const GraphicObject& rObj )
     328                 :            : {
     329   [ +  -  +  - ]:     774468 :     for(
                 [ +  + ]
     330                 :     189778 :         GraphicObjectList_impl::iterator it = maGraphicObjectList.begin();
     331                 :     387234 :         it != maGraphicObjectList.end();
     332                 :            :         ++it
     333                 :            :     ) {
     334 [ +  - ][ +  + ]:     231986 :         if( &rObj == *it )
     335                 :            :         {
     336         [ +  - ]:      34530 :             maGraphicObjectList.erase( it );
     337                 :      34530 :             return true;
     338                 :            :         }
     339                 :            :     }
     340                 :            : 
     341                 :     189778 :     return false;
     342                 :            : }
     343                 :            : 
     344                 :            : // -----------------------------------------------------------------------------
     345                 :            : 
     346                 :     260840 : bool GraphicCacheEntry::HasGraphicObjectReference( const GraphicObject& rObj )
     347                 :            : {
     348                 :     260840 :     bool bRet = false;
     349                 :            : 
     350 [ +  + ][ +  + ]:     604079 :     for( size_t i = 0, n = maGraphicObjectList.size(); ( i < n ) && !bRet; ++i )
                 [ +  + ]
     351         [ +  + ]:     343239 :         if( &rObj == maGraphicObjectList[ i ] )
     352                 :      49070 :             bRet = true;
     353                 :            : 
     354                 :     260840 :     return bRet;
     355                 :            : }
     356                 :            : 
     357                 :            : // -----------------------------------------------------------------------------
     358                 :            : 
     359                 :        423 : void GraphicCacheEntry::TryToSwapIn()
     360                 :            : {
     361 [ -  + ][ #  # ]:        423 :     if( mbSwappedAll && !maGraphicObjectList.empty() )
                 [ -  + ]
     362                 :          0 :         maGraphicObjectList.front()->FireSwapInRequest();
     363                 :        423 : }
     364                 :            : 
     365                 :            : // -----------------------------------------------------------------------------
     366                 :            : 
     367                 :         27 : void GraphicCacheEntry::GraphicObjectWasSwappedOut( const GraphicObject& /*rObj*/ )
     368                 :            : {
     369                 :         27 :     mbSwappedAll = true;
     370                 :            : 
     371 [ +  + ][ +  + ]:         63 :     for( size_t i = 0, n = maGraphicObjectList.size(); ( i < n ) && mbSwappedAll; ++i )
                 [ +  + ]
     372         [ +  + ]:         36 :         if( !maGraphicObjectList[ i ]->IsSwappedOut() )
     373                 :          6 :             mbSwappedAll = false;
     374                 :            : 
     375         [ +  + ]:         27 :     if( mbSwappedAll )
     376                 :            :     {
     377         [ +  + ]:         21 :         delete mpBmpEx, mpBmpEx = NULL;
     378                 :         21 :         mpMtf = NULL; // No need to delete it as it has already been dereferenced
     379         [ -  + ]:         21 :         delete mpAnimation, mpAnimation = NULL;
     380                 :            :     }
     381                 :         27 : }
     382                 :            : 
     383                 :            : // -----------------------------------------------------------------------------
     384                 :            : 
     385                 :          8 : bool GraphicCacheEntry::FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute )
     386                 :            : {
     387                 :          8 :     bool bRet = false;
     388                 :            : 
     389 [ -  + ][ #  # ]:          8 :     if( !mbSwappedAll && rObj.IsSwappedOut() )
                 [ -  + ]
     390                 :            :     {
     391                 :          0 :         ImplFillSubstitute( rSubstitute );
     392                 :          0 :         bRet = true;
     393                 :            :     }
     394                 :            : 
     395                 :          8 :     return bRet;
     396                 :            : }
     397                 :            : 
     398                 :            : // -----------------------------------------------------------------------------
     399                 :            : 
     400                 :          6 : void GraphicCacheEntry::GraphicObjectWasSwappedIn( const GraphicObject& rObj )
     401                 :            : {
     402         [ +  - ]:          6 :     if( mbSwappedAll )
     403                 :          6 :         mbSwappedAll = !ImplInit( rObj );
     404                 :          6 : }
     405                 :            : 
     406                 :            : // ----------------------------
     407                 :            : // - GraphicDisplayCacheEntry -
     408                 :            : // ----------------------------
     409                 :            : 
     410                 :            : class GraphicDisplayCacheEntry
     411                 :            : {
     412                 :            : private:
     413                 :            : 
     414                 :            :     ::salhelper::TTimeValue     maReleaseTime;
     415                 :            :     const GraphicCacheEntry*    mpRefCacheEntry;
     416                 :            :     GDIMetaFile*                mpMtf;
     417                 :            :     BitmapEx*                   mpBmpEx;
     418                 :            :     GraphicAttr                 maAttr;
     419                 :            :     Size                        maOutSizePix;
     420                 :            :     sal_uLong                       mnCacheSize;
     421                 :            :     sal_uLong                       mnOutDevDrawMode;
     422                 :            :     sal_uInt16                      mnOutDevBitCount;
     423                 :            : 
     424                 :            :     static bool IsCacheableAsBitmap( const GDIMetaFile& rMtf, OutputDevice* pOut, const Size& rSz );
     425                 :            : 
     426                 :            : public:
     427                 :            : 
     428                 :            :     static sal_uLong                GetNeededSize( OutputDevice* pOut, const Point& rPt, const Size& rSz,
     429                 :            :                                                const GraphicObject& rObj, const GraphicAttr& rAttr );
     430                 :            : 
     431                 :            : public:
     432                 :            : 
     433                 :      17534 :                                 GraphicDisplayCacheEntry( const GraphicCacheEntry* pRefCacheEntry,
     434                 :            :                                                           OutputDevice* pOut, const Point& rPt, const Size& rSz,
     435                 :            :                                                           const GraphicObject& rObj, const GraphicAttr& rAttr,
     436                 :            :                                                           const BitmapEx& rBmpEx ) :
     437                 :            :                                     mpRefCacheEntry( pRefCacheEntry ),
     438         [ +  - ]:      17534 :                                     mpMtf( NULL ), mpBmpEx( new BitmapEx( rBmpEx ) ),
     439                 :            :                                     maAttr( rAttr ), maOutSizePix( pOut->LogicToPixel( rSz ) ),
     440         [ +  - ]:      17534 :                                     mnCacheSize( GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) ),
     441                 :      17534 :                                     mnOutDevDrawMode( pOut->GetDrawMode() ),
     442   [ +  -  +  - ]:      52602 :                                     mnOutDevBitCount( pOut->GetBitCount() )
     443                 :            :                                     {
     444                 :      17534 :                                     }
     445                 :            : 
     446                 :          0 :                                 GraphicDisplayCacheEntry( const GraphicCacheEntry* pRefCacheEntry,
     447                 :            :                                                           OutputDevice* pOut, const Point& rPt, const Size& rSz,
     448                 :            :                                                           const GraphicObject& rObj, const GraphicAttr& rAttr,
     449                 :            :                                                           const GDIMetaFile& rMtf ) :
     450                 :            :                                     mpRefCacheEntry( pRefCacheEntry ),
     451         [ #  # ]:          0 :                                     mpMtf( new GDIMetaFile( rMtf ) ), mpBmpEx( NULL ),
     452                 :            :                                     maAttr( rAttr ), maOutSizePix( pOut->LogicToPixel( rSz ) ),
     453         [ #  # ]:          0 :                                     mnCacheSize( GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) ),
     454                 :          0 :                                     mnOutDevDrawMode( pOut->GetDrawMode() ),
     455   [ #  #  #  # ]:          0 :                                     mnOutDevBitCount( pOut->GetBitCount() )
     456                 :            :                                     {
     457                 :          0 :                                     }
     458                 :            : 
     459                 :            : 
     460                 :            :                                 ~GraphicDisplayCacheEntry();
     461                 :            : 
     462                 :            :     const GraphicAttr&          GetAttr() const { return maAttr; }
     463                 :            :     const Size&                 GetOutputSizePixel() const { return maOutSizePix; }
     464                 :      35065 :     sal_uLong                   GetCacheSize() const { return mnCacheSize; }
     465                 :      17619 :     const GraphicCacheEntry*    GetReferencedCacheEntry() const { return mpRefCacheEntry; }
     466                 :            :     sal_uLong                   GetOutDevDrawMode() const { return mnOutDevDrawMode; }
     467                 :            :     sal_uInt16              GetOutDevBitCount() const { return mnOutDevBitCount; }
     468                 :            : 
     469                 :      17535 :     void                        SetReleaseTime( const ::salhelper::TTimeValue& rReleaseTime ) { maReleaseTime = rReleaseTime; }
     470                 :          0 :     const ::salhelper::TTimeValue&    GetReleaseTime() const { return maReleaseTime; }
     471                 :            : 
     472                 :         10 :     sal_Bool                        Matches( OutputDevice* pOut, const Point& /*rPtPixel*/, const Size& rSzPixel,
     473                 :            :                                          const GraphicCacheEntry* pCacheEntry, const GraphicAttr& rAttr ) const
     474                 :            :                                 {
     475                 :            :                                     // #i46805# Additional match
     476                 :            :                                     // criteria: outdev draw mode and
     477                 :            :                                     // bit count. One cannot reuse
     478                 :            :                                     // this cache object, if it's
     479                 :            :                                     // e.g. generated for
     480                 :            :                                     // DRAWMODE_GRAYBITMAP.
     481                 :            :                                     return( ( pCacheEntry == mpRefCacheEntry ) &&
     482                 :          2 :                                             ( maAttr == rAttr ) &&
     483                 :          3 :                                             ( ( maOutSizePix == rSzPixel ) || ( !maOutSizePix.Width() && !maOutSizePix.Height() ) ) &&
     484                 :          1 :                                             ( pOut->GetBitCount() == mnOutDevBitCount ) &&
     485   [ +  +  +  -  :         16 :                                             ( pOut->GetDrawMode() == mnOutDevDrawMode ) );
          +  +  -  +  #  
                #  +  - ]
                 [ +  - ]
     486                 :            :                                 }
     487                 :            : 
     488                 :            :     void                        Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz ) const;
     489                 :            : };
     490                 :            : 
     491                 :            : // -----------------------------------------------------------------------------
     492                 :            : 
     493                 :            : // This whole function is based on checkMetadataBitmap() from grfmgr2.cxx, see that one for details.
     494                 :            : // If you do changes here, change the original function too.
     495                 :          0 : static void checkMetadataBitmap( const BitmapEx& rBmpEx,
     496                 :            :                                  Point    /*rSrcPoint*/,
     497                 :            :                                  Size     rSrcSize,
     498                 :            :                                  const Point&    rDestPoint,
     499                 :            :                                  const Size&     rDestSize,
     500                 :            :                                  const Size&     rRefSize,
     501                 :            :                                  bool&           o_rbNonBitmapActionEncountered )
     502                 :            : {
     503         [ #  # ]:          0 :     if( rSrcSize == Size())
     504                 :          0 :         rSrcSize = rBmpEx.GetSizePixel();
     505                 :            : 
     506         [ #  # ]:          0 :     if( rDestPoint != Point( 0, 0 ))
     507                 :            :     {
     508                 :          0 :         o_rbNonBitmapActionEncountered = true;
     509                 :          0 :         return;
     510                 :            :     }
     511         [ #  # ]:          0 :     if( rDestSize != rRefSize )
     512 [ #  # ][ #  #  :          0 :     {    if( rBmpEx.GetSizePixel().Width() > 100 && rBmpEx.GetSizePixel().Height() > 100
             #  #  #  # ]
                 [ #  # ]
     513                 :          0 :             && abs( rDestSize.Width() - rRefSize.Width()) < 5
     514                 :          0 :             && abs( rDestSize.Height() - rRefSize.Height()) < 5 )
     515                 :            :             ; // ok, assume it's close enough
     516                 :            :         else
     517                 :            :         {  // fall back to mtf rendering
     518                 :          0 :             o_rbNonBitmapActionEncountered = true;
     519                 :          0 :             return;
     520                 :            :         }
     521                 :            :     }
     522                 :            : }
     523                 :            : 
     524                 :            : // This function is based on GraphicManager::ImplCreateOutput(), in fact it mostly copies
     525                 :            : // it, the difference is that this one does not create anything, it only checks if
     526                 :            : // ImplCreateOutput() would use the optimization of using the single bitmap.
     527                 :            : // If you do changes here, change the original function too.
     528                 :          0 : bool GraphicDisplayCacheEntry::IsCacheableAsBitmap( const GDIMetaFile& rMtf,
     529                 :            :     OutputDevice* pOut, const Size& rSz )
     530                 :            : {
     531                 :          0 :     const Size aNewSize( rMtf.GetPrefSize() );
     532         [ #  # ]:          0 :     GDIMetaFile rOutMtf = rMtf;
     533                 :            : 
     534                 :            :     // Count bitmap actions, and flag actions that paint, but
     535                 :            :     // are no bitmaps.
     536                 :          0 :     sal_Int32   nNumBitmaps(0);
     537                 :          0 :     bool        bNonBitmapActionEncountered(false);
     538 [ #  # ][ #  # ]:          0 :     if( aNewSize.Width() && aNewSize.Height() && rSz.Width() && rSz.Height() )
         [ #  # ][ #  # ]
                 [ #  # ]
     539                 :            :     {
     540         [ #  # ]:          0 :         const MapMode rPrefMapMode( rMtf.GetPrefMapMode() );
     541         [ #  # ]:          0 :         const Size rSizePix( pOut->LogicToPixel( aNewSize, rPrefMapMode ) );
     542                 :            : 
     543                 :            :         sal_uInt32  nCurPos;
     544                 :            :         MetaAction* pAct;
     545 [ #  # ][ #  # ]:          0 :         for( nCurPos = 0, pAct = (MetaAction*)rOutMtf.FirstAction(); pAct;
                 [ #  # ]
     546                 :            :              pAct = (MetaAction*)rOutMtf.NextAction(), nCurPos++ )
     547                 :            :         {
     548   [ #  #  #  #  :          0 :             switch( pAct->GetType() )
             #  #  #  #  
                      # ]
     549                 :            :             {
     550                 :            :                 case META_FONT_ACTION:
     551                 :            :                     // FALLTHROUGH intended
     552                 :            :                 case META_NULL_ACTION:
     553                 :            :                     // FALLTHROUGH intended
     554                 :            : 
     555                 :            :                     // OutDev state changes (which don't affect bitmap
     556                 :            :                     // output)
     557                 :            :                 case META_LINECOLOR_ACTION:
     558                 :            :                     // FALLTHROUGH intended
     559                 :            :                 case META_FILLCOLOR_ACTION:
     560                 :            :                     // FALLTHROUGH intended
     561                 :            :                 case META_TEXTCOLOR_ACTION:
     562                 :            :                     // FALLTHROUGH intended
     563                 :            :                 case META_TEXTFILLCOLOR_ACTION:
     564                 :            :                     // FALLTHROUGH intended
     565                 :            :                 case META_TEXTALIGN_ACTION:
     566                 :            :                     // FALLTHROUGH intended
     567                 :            :                 case META_TEXTLINECOLOR_ACTION:
     568                 :            :                     // FALLTHROUGH intended
     569                 :            :                 case META_TEXTLINE_ACTION:
     570                 :            :                     // FALLTHROUGH intended
     571                 :            :                 case META_PUSH_ACTION:
     572                 :            :                     // FALLTHROUGH intended
     573                 :            :                 case META_POP_ACTION:
     574                 :            :                     // FALLTHROUGH intended
     575                 :            :                 case META_LAYOUTMODE_ACTION:
     576                 :            :                     // FALLTHROUGH intended
     577                 :            :                 case META_TEXTLANGUAGE_ACTION:
     578                 :            :                     // FALLTHROUGH intended
     579                 :            :                 case META_COMMENT_ACTION:
     580                 :          0 :                     break;
     581                 :            : 
     582                 :            :                     // bitmap output methods
     583                 :            :                 case META_BMP_ACTION:
     584 [ #  # ][ #  # ]:          0 :                     if( !nNumBitmaps && !bNonBitmapActionEncountered )
     585                 :            :                     {
     586                 :          0 :                         MetaBmpAction* pAction = (MetaBmpAction*)pAct;
     587                 :            : 
     588                 :            :                         checkMetadataBitmap(
     589                 :          0 :                             BitmapEx( pAction->GetBitmap()),
     590                 :            :                             Point(), Size(),
     591                 :          0 :                             pOut->LogicToPixel( pAction->GetPoint(),
     592                 :            :                                                 rPrefMapMode ),
     593                 :          0 :                             pAction->GetBitmap().GetSizePixel(),
     594                 :            :                             rSizePix,
     595 [ #  # ][ #  # ]:          0 :                             bNonBitmapActionEncountered );
           [ #  #  #  # ]
     596                 :            :                     }
     597                 :          0 :                     ++nNumBitmaps;
     598                 :          0 :                     break;
     599                 :            : 
     600                 :            :                 case META_BMPSCALE_ACTION:
     601 [ #  # ][ #  # ]:          0 :                     if( !nNumBitmaps && !bNonBitmapActionEncountered )
     602                 :            :                     {
     603                 :          0 :                         MetaBmpScaleAction* pAction = (MetaBmpScaleAction*)pAct;
     604                 :            : 
     605                 :            :                         checkMetadataBitmap(
     606                 :          0 :                             BitmapEx( pAction->GetBitmap()),
     607                 :            :                             Point(), Size(),
     608                 :          0 :                             pOut->LogicToPixel( pAction->GetPoint(),
     609                 :            :                                                 rPrefMapMode ),
     610                 :          0 :                             pOut->LogicToPixel( pAction->GetSize(),
     611                 :            :                                                 rPrefMapMode ),
     612                 :            :                             rSizePix,
     613 [ #  # ][ #  # ]:          0 :                             bNonBitmapActionEncountered );
           [ #  #  #  # ]
     614                 :            :                     }
     615                 :          0 :                     ++nNumBitmaps;
     616                 :          0 :                     break;
     617                 :            : 
     618                 :            :                 case META_BMPSCALEPART_ACTION:
     619 [ #  # ][ #  # ]:          0 :                     if( !nNumBitmaps && !bNonBitmapActionEncountered )
     620                 :            :                     {
     621                 :          0 :                         MetaBmpScalePartAction* pAction = (MetaBmpScalePartAction*)pAct;
     622                 :            : 
     623                 :          0 :                         checkMetadataBitmap(        BitmapEx( pAction->GetBitmap() ),
     624                 :          0 :                                                     pAction->GetSrcPoint(),
     625                 :          0 :                                                     pAction->GetSrcSize(),
     626                 :          0 :                                                     pOut->LogicToPixel( pAction->GetDestPoint(),
     627                 :            :                                                                         rPrefMapMode ),
     628                 :          0 :                                                     pOut->LogicToPixel( pAction->GetDestSize(),
     629                 :            :                                                                         rPrefMapMode ),
     630                 :            :                                                     rSizePix,
     631 [ #  # ][ #  #  :          0 :                                                     bNonBitmapActionEncountered );
             #  #  #  # ]
     632                 :            :                     }
     633                 :          0 :                     ++nNumBitmaps;
     634                 :          0 :                     break;
     635                 :            : 
     636                 :            :                 case META_BMPEX_ACTION:
     637 [ #  # ][ #  # ]:          0 :                     if( !nNumBitmaps && !bNonBitmapActionEncountered )
     638                 :            :                     {
     639                 :          0 :                         MetaBmpExAction* pAction = (MetaBmpExAction*)pAct;
     640                 :            : 
     641                 :            :                         checkMetadataBitmap(
     642                 :          0 :                             pAction->GetBitmapEx(),
     643                 :            :                             Point(), Size(),
     644                 :          0 :                             pOut->LogicToPixel( pAction->GetPoint(),
     645                 :            :                                                 rPrefMapMode ),
     646                 :          0 :                             pAction->GetBitmapEx().GetSizePixel(),
     647                 :            :                             rSizePix,
     648         [ #  # ]:          0 :                             bNonBitmapActionEncountered );
     649                 :            :                     }
     650                 :          0 :                     ++nNumBitmaps;
     651                 :          0 :                     break;
     652                 :            : 
     653                 :            :                 case META_BMPEXSCALE_ACTION:
     654 [ #  # ][ #  # ]:          0 :                     if( !nNumBitmaps && !bNonBitmapActionEncountered )
     655                 :            :                     {
     656                 :          0 :                         MetaBmpExScaleAction* pAction = (MetaBmpExScaleAction*)pAct;
     657                 :            : 
     658                 :            :                         checkMetadataBitmap(
     659                 :          0 :                             pAction->GetBitmapEx(),
     660                 :            :                             Point(), Size(),
     661                 :          0 :                             pOut->LogicToPixel( pAction->GetPoint(),
     662                 :            :                                                 rPrefMapMode ),
     663                 :          0 :                             pOut->LogicToPixel( pAction->GetSize(),
     664                 :            :                                                 rPrefMapMode ),
     665                 :            :                             rSizePix,
     666   [ #  #  #  # ]:          0 :                             bNonBitmapActionEncountered );
     667                 :            :                     }
     668                 :          0 :                     ++nNumBitmaps;
     669                 :          0 :                     break;
     670                 :            : 
     671                 :            :                 case META_BMPEXSCALEPART_ACTION:
     672 [ #  # ][ #  # ]:          0 :                     if( !nNumBitmaps && !bNonBitmapActionEncountered )
     673                 :            :                     {
     674                 :          0 :                         MetaBmpExScalePartAction* pAction = (MetaBmpExScalePartAction*)pAct;
     675                 :            : 
     676                 :          0 :                         checkMetadataBitmap( pAction->GetBitmapEx(),
     677                 :          0 :                                                     pAction->GetSrcPoint(),
     678                 :          0 :                                                     pAction->GetSrcSize(),
     679                 :          0 :                                                     pOut->LogicToPixel( pAction->GetDestPoint(),
     680                 :            :                                                                         rPrefMapMode ),
     681                 :          0 :                                                     pOut->LogicToPixel( pAction->GetDestSize(),
     682                 :            :                                                                         rPrefMapMode ),
     683                 :            :                                                     rSizePix,
     684   [ #  #  #  # ]:          0 :                                                     bNonBitmapActionEncountered );
     685                 :            :                     }
     686                 :          0 :                     ++nNumBitmaps;
     687                 :          0 :                     break;
     688                 :            : 
     689                 :            :                     // these actions actually output something (that's
     690                 :            :                     // different from a bitmap)
     691                 :            :                 case META_RASTEROP_ACTION:
     692         [ #  # ]:          0 :                     if( ((MetaRasterOpAction*)pAct)->GetRasterOp() == ROP_OVERPAINT )
     693                 :          0 :                         break;
     694                 :            :                     // FALLTHROUGH intended
     695                 :            :                 case META_PIXEL_ACTION:
     696                 :            :                     // FALLTHROUGH intended
     697                 :            :                 case META_POINT_ACTION:
     698                 :            :                     // FALLTHROUGH intended
     699                 :            :                 case META_LINE_ACTION:
     700                 :            :                     // FALLTHROUGH intended
     701                 :            :                 case META_RECT_ACTION:
     702                 :            :                     // FALLTHROUGH intended
     703                 :            :                 case META_ROUNDRECT_ACTION:
     704                 :            :                     // FALLTHROUGH intended
     705                 :            :                 case META_ELLIPSE_ACTION:
     706                 :            :                     // FALLTHROUGH intended
     707                 :            :                 case META_ARC_ACTION:
     708                 :            :                     // FALLTHROUGH intended
     709                 :            :                 case META_PIE_ACTION:
     710                 :            :                     // FALLTHROUGH intended
     711                 :            :                 case META_CHORD_ACTION:
     712                 :            :                     // FALLTHROUGH intended
     713                 :            :                 case META_POLYLINE_ACTION:
     714                 :            :                     // FALLTHROUGH intended
     715                 :            :                 case META_POLYGON_ACTION:
     716                 :            :                     // FALLTHROUGH intended
     717                 :            :                 case META_POLYPOLYGON_ACTION:
     718                 :            :                     // FALLTHROUGH intended
     719                 :            : 
     720                 :            :                 case META_TEXT_ACTION:
     721                 :            :                     // FALLTHROUGH intended
     722                 :            :                 case META_TEXTARRAY_ACTION:
     723                 :            :                     // FALLTHROUGH intended
     724                 :            :                 case META_STRETCHTEXT_ACTION:
     725                 :            :                     // FALLTHROUGH intended
     726                 :            :                 case META_TEXTRECT_ACTION:
     727                 :            :                     // FALLTHROUGH intended
     728                 :            : 
     729                 :            :                 case META_MASK_ACTION:
     730                 :            :                     // FALLTHROUGH intended
     731                 :            :                 case META_MASKSCALE_ACTION:
     732                 :            :                     // FALLTHROUGH intended
     733                 :            :                 case META_MASKSCALEPART_ACTION:
     734                 :            :                     // FALLTHROUGH intended
     735                 :            : 
     736                 :            :                 case META_GRADIENT_ACTION:
     737                 :            :                     // FALLTHROUGH intended
     738                 :            :                 case META_HATCH_ACTION:
     739                 :            :                     // FALLTHROUGH intended
     740                 :            :                 case META_WALLPAPER_ACTION:
     741                 :            :                     // FALLTHROUGH intended
     742                 :            : 
     743                 :            :                 case META_TRANSPARENT_ACTION:
     744                 :            :                     // FALLTHROUGH intended
     745                 :            :                 case META_EPS_ACTION:
     746                 :            :                     // FALLTHROUGH intended
     747                 :            :                 case META_FLOATTRANSPARENT_ACTION:
     748                 :            :                     // FALLTHROUGH intended
     749                 :            :                 case META_GRADIENTEX_ACTION:
     750                 :            :                     // FALLTHROUGH intended
     751                 :            :                 case META_RENDERGRAPHIC_ACTION:
     752                 :            :                     // FALLTHROUGH intended
     753                 :            : 
     754                 :            :                     // OutDev state changes that _do_ affect bitmap
     755                 :            :                     // output
     756                 :            :                 case META_CLIPREGION_ACTION:
     757                 :            :                     // FALLTHROUGH intended
     758                 :            :                 case META_ISECTRECTCLIPREGION_ACTION:
     759                 :            :                     // FALLTHROUGH intended
     760                 :            :                 case META_ISECTREGIONCLIPREGION_ACTION:
     761                 :            :                     // FALLTHROUGH intended
     762                 :            :                 case META_MOVECLIPREGION_ACTION:
     763                 :            :                     // FALLTHROUGH intended
     764                 :            : 
     765                 :            :                 case META_MAPMODE_ACTION:
     766                 :            :                     // FALLTHROUGH intended
     767                 :            :                 case META_REFPOINT_ACTION:
     768                 :            :                     // FALLTHROUGH intended
     769                 :            :                 default:
     770                 :          0 :                     bNonBitmapActionEncountered = true;
     771                 :          0 :                     break;
     772                 :            :             }
     773         [ #  # ]:          0 :         }
     774                 :            :     }
     775 [ #  # ][ #  # ]:          0 :     return nNumBitmaps == 1 && !bNonBitmapActionEncountered;
                 [ #  # ]
     776                 :            : }
     777                 :            : 
     778                 :      52602 : sal_uLong GraphicDisplayCacheEntry::GetNeededSize( OutputDevice* pOut, const Point& /*rPt*/, const Size& rSz,
     779                 :            :                                                const GraphicObject& rObj, const GraphicAttr& rAttr )
     780                 :            : {
     781                 :      52602 :     const Graphic&      rGraphic = rObj.GetGraphic();
     782                 :      52602 :     const GraphicType   eType = rGraphic.GetType();
     783                 :            : 
     784                 :      52602 :     bool canCacheAsBitmap = false;
     785         [ +  - ]:      52602 :     if( GRAPHIC_BITMAP == eType )
     786                 :      52602 :         canCacheAsBitmap = true;
     787         [ #  # ]:          0 :     else if( GRAPHIC_GDIMETAFILE == eType )
     788                 :          0 :         canCacheAsBitmap = IsCacheableAsBitmap( rGraphic.GetGDIMetaFile(), pOut, rSz );
     789                 :            :     else
     790                 :          0 :         return 0;
     791         [ +  - ]:      52602 :     if( canCacheAsBitmap )
     792                 :            :     {
     793         [ +  - ]:      52602 :         const Size aOutSizePix( pOut->LogicToPixel( rSz ) );
     794         [ +  - ]:      52602 :         const long nBitCount = pOut->GetBitCount();
     795                 :            : 
     796   [ +  -  -  + ]:     105204 :         if( ( aOutSizePix.Width() > MAX_BMP_EXTENT ) ||
                 [ -  + ]
     797                 :      52602 :             ( aOutSizePix.Height() > MAX_BMP_EXTENT ) )
     798                 :            :         {
     799                 :          0 :             return ULONG_MAX;
     800                 :            :         }
     801         [ +  - ]:      52602 :         else if( nBitCount )
     802                 :            :         {
     803                 :      52602 :             sal_uLong nNeededSize = aOutSizePix.Width() * aOutSizePix.Height() * nBitCount / 8;
     804 [ -  + ][ +  + ]:      52602 :             if( rObj.IsTransparent() || ( rAttr.GetRotation() % 3600 ) )
                 [ +  + ]
     805                 :      52593 :                 nNeededSize += nNeededSize / nBitCount;
     806                 :      52602 :             return nNeededSize;
     807                 :            :         }
     808                 :            :         else
     809                 :            :         {
     810                 :            :             OSL_FAIL( "GraphicDisplayCacheEntry::GetNeededSize(): pOut->GetBitCount() == 0" );
     811                 :      52602 :             return 256000;
     812                 :            :         }
     813                 :            :     }
     814                 :            :     else
     815                 :      52602 :         return rGraphic.GetSizeBytes();
     816                 :            : }
     817                 :            : 
     818                 :            : // -----------------------------------------------------------------------------
     819                 :            : 
     820                 :      17531 : GraphicDisplayCacheEntry::~GraphicDisplayCacheEntry()
     821                 :            : {
     822         [ -  + ]:      17531 :     if( mpMtf )
     823 [ #  # ][ #  # ]:          0 :         delete mpMtf;
     824                 :            : 
     825         [ +  - ]:      17531 :     if( mpBmpEx )
     826 [ +  - ][ +  - ]:      17531 :         delete mpBmpEx;
     827                 :      17531 : }
     828                 :            : 
     829                 :            : // -----------------------------------------------------------------------------
     830                 :            : 
     831                 :          1 : void GraphicDisplayCacheEntry::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz ) const
     832                 :            : {
     833         [ -  + ]:          1 :     if( mpMtf )
     834                 :          0 :         GraphicManager::ImplDraw( pOut, rPt, rSz, *mpMtf, maAttr );
     835         [ +  - ]:          1 :     else if( mpBmpEx )
     836                 :            :     {
     837         [ -  + ]:          1 :         if( maAttr.IsRotated() )
     838                 :            :         {
     839 [ #  # ][ #  # ]:          0 :             Polygon aPoly( Rectangle( rPt, rSz ) );
     840                 :            : 
     841         [ #  # ]:          0 :             aPoly.Rotate( rPt, maAttr.GetRotation() % 3600 );
     842         [ #  # ]:          0 :             const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
     843 [ #  # ][ #  # ]:          0 :             pOut->DrawBitmapEx( aRotBoundRect.TopLeft(), aRotBoundRect.GetSize(), *mpBmpEx );
                 [ #  # ]
     844                 :            :         }
     845                 :            :         else
     846                 :          1 :             pOut->DrawBitmapEx( rPt, rSz, *mpBmpEx );
     847                 :            :     }
     848                 :          1 : }
     849                 :            : 
     850                 :            : // -----------------------
     851                 :            : // - GraphicCache -
     852                 :            : // -----------------------
     853                 :            : 
     854                 :        138 : GraphicCache::GraphicCache( sal_uLong nDisplayCacheSize, sal_uLong nMaxObjDisplayCacheSize ) :
     855                 :            :     mnReleaseTimeoutSeconds ( 0UL ),
     856                 :            :     mnMaxDisplaySize        ( nDisplayCacheSize ),
     857                 :            :     mnMaxObjDisplaySize     ( nMaxObjDisplayCacheSize ),
     858 [ +  - ][ +  - ]:        138 :     mnUsedDisplaySize       ( 0UL )
     859                 :            : {
     860         [ +  - ]:        138 :     maReleaseTimer.SetTimeoutHdl( LINK( this, GraphicCache, ReleaseTimeoutHdl ) );
     861         [ +  - ]:        138 :     maReleaseTimer.SetTimeout( RELEASE_TIMEOUT );
     862         [ +  - ]:        138 :     maReleaseTimer.Start();
     863                 :        138 : }
     864                 :            : 
     865                 :            : // -----------------------------------------------------------------------------
     866                 :            : 
     867                 :         51 : GraphicCache::~GraphicCache()
     868                 :            : {
     869                 :            :     DBG_ASSERT( !maGraphicCache.size(), "GraphicCache::~GraphicCache(): there are some GraphicObjects in cache" );
     870                 :            :     DBG_ASSERT( maDisplayCache.empty(), "GraphicCache::~GraphicCache(): there are some GraphicObjects in display cache" );
     871                 :         51 : }
     872                 :            : 
     873                 :            : // -----------------------------------------------------------------------------
     874                 :            : 
     875                 :      34781 : void GraphicCache::AddGraphicObject(
     876                 :            :     const GraphicObject& rObj,
     877                 :            :     Graphic& rSubstitute,
     878                 :            :     const rtl::OString* pID,
     879                 :            :     const GraphicObject* pCopyObj
     880                 :            : )
     881                 :            : {
     882                 :      34781 :     sal_Bool bInserted = sal_False;
     883                 :            : 
     884 [ +  - ][ +  + ]:      72895 :     if(  !rObj.IsSwappedOut()
           [ +  +  +  +  
           +  + ][ +  + ]
     885                 :            :       && (  pID
     886                 :            :          || (    pCopyObj
     887                 :       6644 :             && ( pCopyObj->GetType() != GRAPHIC_NONE )
     888                 :            :             )
     889                 :      31470 :          || ( rObj.GetType() != GRAPHIC_NONE )
     890                 :            :          )
     891                 :            :       )
     892                 :            :     {
     893   [ +  +  +  - ]:      24562 :         if( pCopyObj
                 [ +  + ]
     894                 :       2888 :           && !maGraphicCache.empty()
     895                 :            :         )
     896                 :            :         {
     897                 :       2888 :             GraphicCacheEntryList::iterator it = maGraphicCache.begin();
     898   [ +  +  +  - ]:      64735 :             while(  !bInserted
                 [ +  + ]
     899         [ +  + ]:      42194 :                  && ( it != maGraphicCache.end() )
     900                 :            :                  )
     901                 :            :             {
     902 [ +  - ][ +  + ]:      19653 :                 if( (*it)->HasGraphicObjectReference( *pCopyObj ) )
     903                 :            :                 {
     904         [ +  - ]:       2888 :                     (*it)->AddGraphicObjectReference( rObj, rSubstitute );
     905                 :       2888 :                     bInserted = sal_True;
     906                 :            :                 }
     907                 :            :                 else
     908                 :            :                 {
     909                 :      16765 :                     ++it;
     910                 :            :                 }
     911                 :            :             }
     912                 :            :         }
     913                 :            : 
     914         [ +  + ]:      21674 :         if( !bInserted )
     915                 :            :         {
     916                 :      18786 :             GraphicCacheEntryList::iterator it = maGraphicCache.begin();
     917                 :      18786 :             ::std::auto_ptr< GraphicID > apID;
     918                 :            : 
     919         [ +  + ]:      18786 :             if( !pID )
     920                 :            :             {
     921 [ +  - ][ +  - ]:      18363 :                 apID.reset( new GraphicID( rObj ) );
     922                 :            :             }
     923                 :            : 
     924   [ +  +  +  + ]:     312422 :             while(  !bInserted
                 [ +  + ]
     925         [ +  + ]:     208037 :                  && ( it != maGraphicCache.end() )
     926                 :            :                  )
     927                 :            :             {
     928                 :      85599 :                 const GraphicID& rEntryID = (*it)->GetID();
     929                 :            : 
     930         [ +  + ]:      85599 :                 if( pID )
     931                 :            :                 {
     932 [ +  - ][ +  + ]:       3900 :                     if( rEntryID.GetIDString() == *pID )
     933                 :            :                     {
     934         [ +  - ]:        423 :                         (*it)->TryToSwapIn();
     935                 :            : 
     936                 :            :                         // since pEntry->TryToSwapIn can modify our current list, we have to
     937                 :            :                         // iterate from beginning to add a reference to the appropriate
     938                 :            :                         // CacheEntry object; after this, quickly jump out of the outer iteration
     939   [ +  +  +  - ]:      12546 :                         for( GraphicCacheEntryList::iterator jt = maGraphicCache.begin();
                 [ +  + ]
     940         [ +  + ]:       8223 :                              !bInserted && jt != maGraphicCache.end();
     941                 :            :                              ++jt
     942                 :            :                         )
     943                 :            :                         {
     944                 :       3900 :                             const GraphicID& rID = (*jt)->GetID();
     945                 :            : 
     946 [ +  + ][ +  - ]:       3900 :                             if( rID.GetIDString() == *pID )
     947                 :            :                             {
     948         [ +  - ]:        423 :                                 (*jt)->AddGraphicObjectReference( rObj, rSubstitute );
     949                 :        423 :                                 bInserted = sal_True;
     950                 :            :                             }
     951                 :            :                         }
     952                 :            : 
     953         [ -  + ]:        423 :                         if( !bInserted )
     954                 :            :                         {
     955 [ #  # ][ #  # ]:          0 :                             maGraphicCache.push_back( new GraphicCacheEntry( rObj ) );
                 [ #  # ]
     956                 :          0 :                             bInserted = sal_True;
     957                 :            :                         }
     958                 :            :                     }
     959                 :            :                 }
     960                 :            :                 else
     961                 :            :                 {
     962         [ +  + ]:      81699 :                     if( rEntryID == *apID )
     963                 :            :                     {
     964         [ +  - ]:        310 :                         (*it)->AddGraphicObjectReference( rObj, rSubstitute );
     965                 :        310 :                         bInserted = sal_True;
     966                 :            :                     }
     967                 :            :                 }
     968                 :            : 
     969         [ +  + ]:      85599 :                 if( !bInserted )
     970                 :      84866 :                     ++it;
     971                 :      18786 :             }
     972                 :            :         }
     973                 :            :     }
     974                 :            : 
     975         [ +  + ]:      34781 :     if( !bInserted )
     976 [ +  - ][ +  - ]:      31160 :         maGraphicCache.push_back( new GraphicCacheEntry( rObj ) );
     977                 :      34781 : }
     978                 :            : 
     979                 :            : // -----------------------------------------------------------------------------
     980                 :            : 
     981                 :      34530 : void GraphicCache::ReleaseGraphicObject( const GraphicObject& rObj )
     982                 :            : {
     983                 :            :     // Release cached object
     984                 :      34530 :     bool    bRemoved = false;
     985                 :      34530 :     GraphicCacheEntryList::iterator it = maGraphicCache.begin();
     986 [ +  + ][ +  - ]:     224308 :     while (!bRemoved && it != maGraphicCache.end())
         [ +  + ][ +  + ]
     987                 :            :     {
     988         [ +  - ]:     189778 :         bRemoved = (*it)->ReleaseGraphicObjectReference( rObj );
     989                 :            : 
     990         [ +  + ]:     189778 :         if( bRemoved )
     991                 :            :         {
     992         [ +  + ]:      34530 :             if( 0 == (*it)->GetGraphicObjectReferenceCount() )
     993                 :            :             {
     994                 :            :                 // if graphic cache entry has no more references,
     995                 :            :                 // the corresponding display cache object can be removed
     996                 :      30915 :                 GraphicDisplayCacheEntryList::iterator it2 = maDisplayCache.begin();
     997         [ +  + ]:      48534 :                 while( it2 != maDisplayCache.end() )
     998                 :            :                 {
     999                 :      17619 :                     GraphicDisplayCacheEntry* pDisplayEntry = *it2;
    1000         [ +  + ]:      17619 :                     if( pDisplayEntry->GetReferencedCacheEntry() == *it )
    1001                 :            :                     {
    1002                 :      17531 :                         mnUsedDisplaySize -= pDisplayEntry->GetCacheSize();
    1003         [ +  - ]:      17531 :                         it2 = maDisplayCache.erase( it2 );
    1004 [ +  - ][ +  - ]:      17531 :                         delete pDisplayEntry;
    1005                 :            :                     }
    1006                 :            :                     else
    1007                 :         88 :                         ++it2;
    1008                 :            :                 }
    1009                 :            : 
    1010                 :            :                 // delete graphic cache entry
    1011 [ +  - ][ +  - ]:      30915 :                 delete *it;
    1012         [ +  - ]:      30915 :                 it = maGraphicCache.erase( it );
    1013                 :            :             }
    1014                 :            :         }
    1015                 :            :         else
    1016                 :     155248 :             ++it;
    1017                 :            :     }
    1018                 :            : 
    1019                 :            :     DBG_ASSERT( bRemoved, "GraphicCache::ReleaseGraphicObject(...): GraphicObject not found in cache" );
    1020                 :      34530 : }
    1021                 :            : 
    1022                 :            : // -----------------------------------------------------------------------------
    1023                 :            : 
    1024                 :         27 : void GraphicCache::GraphicObjectWasSwappedOut( const GraphicObject& rObj )
    1025                 :            : {
    1026                 :            :     // notify cache that rObj is swapped out (and can thus be pruned
    1027                 :            :     // from the cache)
    1028                 :         27 :     GraphicCacheEntry* pEntry = ImplGetCacheEntry( rObj );
    1029                 :            : 
    1030         [ +  - ]:         27 :     if( pEntry )
    1031                 :         27 :         pEntry->GraphicObjectWasSwappedOut( rObj );
    1032                 :         27 : }
    1033                 :            : 
    1034                 :            : // -----------------------------------------------------------------------------
    1035                 :            : 
    1036                 :          8 : sal_Bool GraphicCache::FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute )
    1037                 :            : {
    1038                 :          8 :     GraphicCacheEntry* pEntry = ImplGetCacheEntry( rObj );
    1039                 :            : 
    1040         [ -  + ]:          8 :     if( !pEntry )
    1041                 :          0 :         return sal_False;
    1042                 :            : 
    1043                 :          8 :     return pEntry->FillSwappedGraphicObject( rObj, rSubstitute );
    1044                 :            : }
    1045                 :            : 
    1046                 :            : // -----------------------------------------------------------------------------
    1047                 :            : 
    1048                 :          6 : void GraphicCache::GraphicObjectWasSwappedIn( const GraphicObject& rObj )
    1049                 :            : {
    1050                 :          6 :     GraphicCacheEntry* pEntry = ImplGetCacheEntry( rObj );
    1051                 :            : 
    1052         [ +  - ]:          6 :     if( pEntry )
    1053                 :            :     {
    1054         [ -  + ]:          6 :         if( pEntry->GetID().IsEmpty() )
    1055                 :            :         {
    1056                 :          0 :             ReleaseGraphicObject( rObj );
    1057                 :          0 :             AddGraphicObject( rObj, (Graphic&) rObj.GetGraphic(), NULL, NULL );
    1058                 :            :         }
    1059                 :            :         else
    1060                 :          6 :             pEntry->GraphicObjectWasSwappedIn( rObj );
    1061                 :            :     }
    1062                 :          6 : }
    1063                 :            : 
    1064                 :            : // -----------------------------------------------------------------------------
    1065                 :            : 
    1066                 :          0 : void GraphicCache::SetMaxDisplayCacheSize( sal_uLong nNewCacheSize )
    1067                 :            : {
    1068                 :          0 :     mnMaxDisplaySize = nNewCacheSize;
    1069                 :            : 
    1070         [ #  # ]:          0 :     if( GetMaxDisplayCacheSize() < GetUsedDisplayCacheSize() )
    1071                 :          0 :         ImplFreeDisplayCacheSpace( GetUsedDisplayCacheSize() - GetMaxDisplayCacheSize() );
    1072                 :          0 : }
    1073                 :            : 
    1074                 :            : // -----------------------------------------------------------------------------
    1075                 :            : 
    1076                 :          0 : void GraphicCache::SetMaxObjDisplayCacheSize( sal_uLong nNewMaxObjSize, sal_Bool bDestroyGreaterCached )
    1077                 :            : {
    1078 [ #  # ][ #  # ]:          0 :     const sal_Bool bDestroy = ( bDestroyGreaterCached && ( nNewMaxObjSize < mnMaxObjDisplaySize ) );
    1079                 :            : 
    1080                 :          0 :     mnMaxObjDisplaySize = Min( nNewMaxObjSize, mnMaxDisplaySize );
    1081                 :            : 
    1082         [ #  # ]:          0 :     if( bDestroy )
    1083                 :            :     {
    1084                 :          0 :         GraphicDisplayCacheEntryList::iterator it = maDisplayCache.begin();
    1085         [ #  # ]:          0 :         while( it != maDisplayCache.end() )
    1086                 :            :         {
    1087                 :          0 :             GraphicDisplayCacheEntry* pCacheObj = *it;
    1088         [ #  # ]:          0 :             if( pCacheObj->GetCacheSize() > mnMaxObjDisplaySize )
    1089                 :            :             {
    1090                 :          0 :                 mnUsedDisplaySize -= pCacheObj->GetCacheSize();
    1091         [ #  # ]:          0 :                 it = maDisplayCache.erase( it );
    1092 [ #  # ][ #  # ]:          0 :                 delete pCacheObj;
    1093                 :            :             }
    1094                 :            :             else
    1095                 :          0 :                 ++it;
    1096                 :            :         }
    1097                 :            :     }
    1098                 :          0 : }
    1099                 :            : 
    1100                 :            : // -----------------------------------------------------------------------------
    1101                 :            : 
    1102                 :        138 : void GraphicCache::SetCacheTimeout( sal_uLong nTimeoutSeconds )
    1103                 :            : {
    1104         [ +  - ]:        138 :     if( mnReleaseTimeoutSeconds != nTimeoutSeconds )
    1105                 :            :     {
    1106                 :        138 :         ::salhelper::TTimeValue           aReleaseTime;
    1107                 :            : 
    1108         [ +  - ]:        138 :         if( ( mnReleaseTimeoutSeconds = nTimeoutSeconds ) != 0 )
    1109                 :            :         {
    1110         [ +  - ]:        138 :             osl_getSystemTime( &aReleaseTime );
    1111         [ +  - ]:        138 :             aReleaseTime.addTime( ::salhelper::TTimeValue( nTimeoutSeconds, 0 ) );
    1112                 :            :         }
    1113                 :            : 
    1114         [ -  + ]:        276 :         for( GraphicDisplayCacheEntryList::const_iterator it = maDisplayCache.begin();
    1115                 :        138 :              it != maDisplayCache.end(); ++it )
    1116                 :            :         {
    1117                 :          0 :             (*it)->SetReleaseTime( aReleaseTime );
    1118                 :            :         }
    1119                 :            :     }
    1120                 :        138 : }
    1121                 :            : 
    1122                 :            : // -----------------------------------------------------------------------------
    1123                 :            : 
    1124                 :      17534 : sal_Bool GraphicCache::IsDisplayCacheable( OutputDevice* pOut, const Point& rPt, const Size& rSz,
    1125                 :            :                                        const GraphicObject& rObj, const GraphicAttr& rAttr ) const
    1126                 :            : {
    1127                 :      17534 :     return( GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) <=
    1128                 :      17534 :             GetMaxObjDisplayCacheSize() );
    1129                 :            : }
    1130                 :            : 
    1131                 :            : // -----------------------------------------------------------------------------
    1132                 :            : 
    1133                 :         30 : sal_Bool GraphicCache::IsInDisplayCache( OutputDevice* pOut, const Point& rPt, const Size& rSz,
    1134                 :            :                                      const GraphicObject& rObj, const GraphicAttr& rAttr ) const
    1135                 :            : {
    1136         [ +  - ]:         30 :     const Point                 aPtPixel( pOut->LogicToPixel( rPt ) );
    1137         [ +  - ]:         30 :     const Size                  aSzPixel( pOut->LogicToPixel( rSz ) );
    1138         [ +  - ]:         30 :     const GraphicCacheEntry*    pCacheEntry = ( (GraphicCache*) this )->ImplGetCacheEntry( rObj );
    1139                 :         30 :     sal_Bool                        bFound = sal_False;
    1140                 :            : 
    1141         [ +  - ]:         30 :     if( pCacheEntry )
    1142                 :            :     {
    1143   [ +  -  -  + ]:         90 :         for( GraphicDisplayCacheEntryList::const_iterator it = maDisplayCache.begin();
                 [ -  + ]
    1144         [ +  - ]:         60 :              !bFound && ( it != maDisplayCache.end() ); ++it )
    1145                 :            :         {
    1146 [ #  # ][ #  # ]:          0 :             if( (*it)->Matches( pOut, aPtPixel, aSzPixel, pCacheEntry, rAttr ) )
    1147                 :          0 :                 bFound = sal_True;
    1148                 :            :         }
    1149                 :            :     }
    1150                 :            : 
    1151                 :         30 :     return bFound;
    1152                 :            : }
    1153                 :            : 
    1154                 :            : // -----------------------------------------------------------------------------
    1155                 :            : 
    1156                 :       5521 : rtl::OString GraphicCache::GetUniqueID( const GraphicObject& rObj ) const
    1157                 :            : {
    1158                 :       5521 :     rtl::OString aRet;
    1159         [ +  - ]:       5521 :     GraphicCacheEntry*  pEntry = ( (GraphicCache*) this )->ImplGetCacheEntry( rObj );
    1160                 :            : 
    1161                 :            :     // ensure that the entry is correctly initialized (it has to be read at least once)
    1162 [ +  - ][ -  + ]:       5521 :     if( pEntry && pEntry->GetID().IsEmpty() )
                 [ -  + ]
    1163         [ #  # ]:          0 :         pEntry->TryToSwapIn();
    1164                 :            : 
    1165                 :            :     // do another call to ImplGetCacheEntry in case of modified entry list
    1166         [ +  - ]:       5521 :     pEntry = ( (GraphicCache*) this )->ImplGetCacheEntry( rObj );
    1167                 :            : 
    1168         [ +  - ]:       5521 :     if( pEntry )
    1169         [ +  - ]:       5521 :         aRet = pEntry->GetID().GetIDString();
    1170                 :            : 
    1171                 :       5521 :     return aRet;
    1172                 :            : }
    1173                 :            : 
    1174                 :            : // -----------------------------------------------------------------------------
    1175                 :            : 
    1176                 :      17534 : sal_Bool GraphicCache::CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
    1177                 :            :                                           const GraphicObject& rObj, const GraphicAttr& rAttr,
    1178                 :            :                                           const BitmapEx& rBmpEx )
    1179                 :            : {
    1180                 :      17534 :     const sal_uLong nNeededSize = GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr );
    1181                 :      17534 :     sal_Bool        bRet = sal_False;
    1182                 :            : 
    1183         [ +  - ]:      17534 :     if( nNeededSize <= GetMaxObjDisplayCacheSize() )
    1184                 :            :     {
    1185         [ -  + ]:      17534 :         if( nNeededSize > GetFreeDisplayCacheSize() )
    1186         [ #  # ]:          0 :             ImplFreeDisplayCacheSpace( nNeededSize - GetFreeDisplayCacheSize() );
    1187                 :            : 
    1188                 :            :         GraphicDisplayCacheEntry* pNewEntry = new GraphicDisplayCacheEntry( ImplGetCacheEntry( rObj ),
    1189 [ +  - ][ +  - ]:      17534 :                                                                             pOut, rPt, rSz, rObj, rAttr, rBmpEx );
                 [ +  - ]
    1190                 :            : 
    1191         [ +  - ]:      17534 :         if( GetCacheTimeout() )
    1192                 :            :         {
    1193                 :      17534 :             ::salhelper::TTimeValue aReleaseTime;
    1194                 :            : 
    1195         [ +  - ]:      17534 :             osl_getSystemTime( &aReleaseTime );
    1196         [ +  - ]:      17534 :             aReleaseTime.addTime( ::salhelper::TTimeValue( GetCacheTimeout(), 0 ) );
    1197                 :      17534 :             pNewEntry->SetReleaseTime( aReleaseTime );
    1198                 :            :         }
    1199                 :            : 
    1200         [ +  - ]:      17534 :         maDisplayCache.push_back( pNewEntry );
    1201                 :      17534 :         mnUsedDisplaySize += pNewEntry->GetCacheSize();
    1202                 :      17534 :         bRet = sal_True;
    1203                 :            :     }
    1204                 :            : 
    1205                 :      17534 :     return bRet;
    1206                 :            : }
    1207                 :            : 
    1208                 :            : // -----------------------------------------------------------------------------
    1209                 :            : 
    1210                 :          0 : sal_Bool GraphicCache::CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
    1211                 :            :                                           const GraphicObject& rObj, const GraphicAttr& rAttr,
    1212                 :            :                                           const GDIMetaFile& rMtf )
    1213                 :            : {
    1214                 :          0 :     const sal_uLong nNeededSize = GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr );
    1215                 :          0 :     sal_Bool        bRet = sal_False;
    1216                 :            : 
    1217         [ #  # ]:          0 :     if( nNeededSize <= GetMaxObjDisplayCacheSize() )
    1218                 :            :     {
    1219         [ #  # ]:          0 :         if( nNeededSize > GetFreeDisplayCacheSize() )
    1220         [ #  # ]:          0 :             ImplFreeDisplayCacheSpace( nNeededSize - GetFreeDisplayCacheSize() );
    1221                 :            : 
    1222                 :            :         GraphicDisplayCacheEntry* pNewEntry = new GraphicDisplayCacheEntry( ImplGetCacheEntry( rObj ),
    1223 [ #  # ][ #  # ]:          0 :                                                                             pOut, rPt, rSz, rObj, rAttr, rMtf );
                 [ #  # ]
    1224                 :            : 
    1225         [ #  # ]:          0 :         if( GetCacheTimeout() )
    1226                 :            :         {
    1227                 :          0 :             ::salhelper::TTimeValue aReleaseTime;
    1228                 :            : 
    1229         [ #  # ]:          0 :             osl_getSystemTime( &aReleaseTime );
    1230         [ #  # ]:          0 :             aReleaseTime.addTime( ::salhelper::TTimeValue( GetCacheTimeout(), 0 ) );
    1231                 :          0 :             pNewEntry->SetReleaseTime( aReleaseTime );
    1232                 :            :         }
    1233                 :            : 
    1234         [ #  # ]:          0 :         maDisplayCache.push_back( pNewEntry );
    1235                 :          0 :         mnUsedDisplaySize += pNewEntry->GetCacheSize();
    1236                 :          0 :         bRet = sal_True;
    1237                 :            :     }
    1238                 :            : 
    1239                 :          0 :     return bRet;
    1240                 :            : }
    1241                 :            : 
    1242                 :            : // -----------------------------------------------------------------------------
    1243                 :            : 
    1244                 :      17535 : sal_Bool GraphicCache::DrawDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz,
    1245                 :            :                                         const GraphicObject& rObj, const GraphicAttr& rAttr )
    1246                 :            : {
    1247         [ +  - ]:      17535 :     const Point                 aPtPixel( pOut->LogicToPixel( rPt ) );
    1248         [ +  - ]:      17535 :     const Size                  aSzPixel( pOut->LogicToPixel( rSz ) );
    1249         [ +  - ]:      17535 :     const GraphicCacheEntry*    pCacheEntry = ImplGetCacheEntry( rObj );
    1250                 :      17535 :     GraphicDisplayCacheEntry*   pDisplayCacheEntry = NULL;
    1251                 :      17535 :     GraphicDisplayCacheEntryList::iterator it = maDisplayCache.begin();
    1252                 :      17535 :     sal_Bool                    bRet = sal_False;
    1253                 :            : 
    1254 [ +  + ][ +  + ]:      17545 :     while( !bRet && it != maDisplayCache.end() )
         [ +  + ][ +  + ]
    1255                 :            :     {
    1256                 :         10 :         pDisplayCacheEntry = *it;
    1257 [ +  + ][ +  - ]:         10 :         if( pDisplayCacheEntry->Matches( pOut, aPtPixel, aSzPixel, pCacheEntry, rAttr ) )
    1258                 :            :         {
    1259                 :          1 :             ::salhelper::TTimeValue aReleaseTime;
    1260                 :            : 
    1261                 :            :             // put found object at last used position
    1262         [ +  - ]:          1 :             it = maDisplayCache.erase( it );
    1263         [ +  - ]:          1 :             maDisplayCache.push_back( pDisplayCacheEntry );
    1264                 :            : 
    1265         [ +  - ]:          1 :             if( GetCacheTimeout() )
    1266                 :            :             {
    1267         [ +  - ]:          1 :                 osl_getSystemTime( &aReleaseTime );
    1268         [ +  - ]:          1 :                 aReleaseTime.addTime( ::salhelper::TTimeValue( GetCacheTimeout(), 0 ) );
    1269                 :            :             }
    1270                 :            : 
    1271                 :          1 :             pDisplayCacheEntry->SetReleaseTime( aReleaseTime );
    1272                 :          1 :             bRet = sal_True;
    1273                 :            :         }
    1274                 :            :         else
    1275                 :          9 :             ++it;
    1276                 :            :     }
    1277                 :            : 
    1278         [ +  + ]:      17535 :     if( bRet )
    1279         [ +  - ]:          1 :         pDisplayCacheEntry->Draw( pOut, rPt, rSz );
    1280                 :            : 
    1281                 :      17535 :     return bRet;
    1282                 :            : }
    1283                 :            : 
    1284                 :            : // -----------------------------------------------------------------------------
    1285                 :            : 
    1286                 :          0 : sal_Bool GraphicCache::ImplFreeDisplayCacheSpace( sal_uLong nSizeToFree )
    1287                 :            : {
    1288                 :          0 :     sal_uLong nFreedSize = 0UL;
    1289                 :            : 
    1290         [ #  # ]:          0 :     if( nSizeToFree )
    1291                 :            :     {
    1292                 :          0 :         GraphicDisplayCacheEntryList::iterator it = maDisplayCache.begin();
    1293                 :            : 
    1294         [ #  # ]:          0 :         if( nSizeToFree > mnUsedDisplaySize )
    1295                 :          0 :             nSizeToFree = mnUsedDisplaySize;
    1296                 :            : 
    1297         [ #  # ]:          0 :         while( it != maDisplayCache.end() )
    1298                 :            :         {
    1299                 :          0 :             GraphicDisplayCacheEntry* pCacheObj = *it;
    1300                 :            : 
    1301                 :          0 :             nFreedSize += pCacheObj->GetCacheSize();
    1302                 :          0 :             mnUsedDisplaySize -= pCacheObj->GetCacheSize();
    1303         [ #  # ]:          0 :             it = maDisplayCache.erase( it );
    1304 [ #  # ][ #  # ]:          0 :             delete pCacheObj;
    1305                 :            : 
    1306         [ #  # ]:          0 :             if( nFreedSize >= nSizeToFree )
    1307                 :          0 :                 break;
    1308                 :            :         }
    1309                 :            :     }
    1310                 :            : 
    1311                 :          0 :     return( nFreedSize >= nSizeToFree );
    1312                 :            : }
    1313                 :            : 
    1314                 :            : // -----------------------------------------------------------------------------
    1315                 :            : 
    1316                 :      46182 : GraphicCacheEntry* GraphicCache::ImplGetCacheEntry( const GraphicObject& rObj )
    1317                 :            : {
    1318                 :      46182 :     GraphicCacheEntry* pRet = NULL;
    1319                 :            : 
    1320   [ +  +  +  - ]:     815925 :     for(
                 [ +  + ]
    1321                 :      46182 :         GraphicCacheEntryList::iterator it = maGraphicCache.begin();
    1322         [ +  + ]:     528556 :         !pRet && it != maGraphicCache.end();
    1323                 :            :         ++it
    1324                 :            :     ) {
    1325 [ +  - ][ +  + ]:     241187 :         if( (*it)->HasGraphicObjectReference( rObj ) ) {
    1326                 :      46182 :             pRet = *it;
    1327                 :            :         }
    1328                 :            :     }
    1329                 :            : 
    1330                 :      46182 :     return pRet;
    1331                 :            : }
    1332                 :            : 
    1333                 :            : // -----------------------------------------------------------------------------
    1334                 :            : 
    1335                 :        777 : IMPL_LINK( GraphicCache, ReleaseTimeoutHdl, Timer*, pTimer )
    1336                 :            : {
    1337         [ +  - ]:        777 :     pTimer->Stop();
    1338                 :            : 
    1339                 :        777 :     ::salhelper::TTimeValue           aCurTime;
    1340                 :        777 :     GraphicDisplayCacheEntryList::iterator it = maDisplayCache.begin();
    1341                 :            : 
    1342         [ +  - ]:        777 :     osl_getSystemTime( &aCurTime );
    1343                 :            : 
    1344         [ -  + ]:        777 :     while( it != maDisplayCache.end() )
    1345                 :            :     {
    1346                 :          0 :         GraphicDisplayCacheEntry*   pDisplayEntry = *it;
    1347                 :          0 :         const ::salhelper::TTimeValue& rReleaseTime = pDisplayEntry->GetReleaseTime();
    1348                 :            : 
    1349 [ #  # ][ #  # ]:          0 :         if( !rReleaseTime.isEmpty() && ( rReleaseTime < aCurTime ) )
                 [ #  # ]
    1350                 :            :         {
    1351                 :          0 :             mnUsedDisplaySize -= pDisplayEntry->GetCacheSize();
    1352         [ #  # ]:          0 :             it = maDisplayCache.erase( it );
    1353 [ #  # ][ #  # ]:          0 :             delete pDisplayEntry;
    1354                 :            :         }
    1355                 :            :         else
    1356                 :          0 :             ++it;
    1357                 :            :     }
    1358                 :            : 
    1359         [ +  - ]:        777 :     pTimer->Start();
    1360                 :            : 
    1361                 :        777 :     return 0;
    1362                 :            : }
    1363                 :            : 
    1364                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10