1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_svtools.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <vos/timer.hxx> 32*cdf0e10cSrcweir #include <tools/debug.hxx> 33*cdf0e10cSrcweir #include <vcl/outdev.hxx> 34*cdf0e10cSrcweir #include <tools/poly.hxx> 35*cdf0e10cSrcweir #include "grfcache.hxx" 36*cdf0e10cSrcweir 37*cdf0e10cSrcweir #include <memory> 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir // ----------- 40*cdf0e10cSrcweir // - Defines - 41*cdf0e10cSrcweir // ----------- 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir #define RELEASE_TIMEOUT 10000 44*cdf0e10cSrcweir #define MAX_BMP_EXTENT 4096 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir // ----------- 47*cdf0e10cSrcweir // - statics - 48*cdf0e10cSrcweir // ----------- 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir static const char aHexData[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir // ------------- 53*cdf0e10cSrcweir // - GraphicID - 54*cdf0e10cSrcweir // ------------- 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir class GraphicID 57*cdf0e10cSrcweir { 58*cdf0e10cSrcweir private: 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir sal_uInt32 mnID1; 61*cdf0e10cSrcweir sal_uInt32 mnID2; 62*cdf0e10cSrcweir sal_uInt32 mnID3; 63*cdf0e10cSrcweir sal_uInt32 mnID4; 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir GraphicID(); 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir public: 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir 70*cdf0e10cSrcweir GraphicID( const GraphicObject& rObj ); 71*cdf0e10cSrcweir ~GraphicID() {} 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir sal_Bool operator==( const GraphicID& rID ) const 74*cdf0e10cSrcweir { 75*cdf0e10cSrcweir return( rID.mnID1 == mnID1 && rID.mnID2 == mnID2 && 76*cdf0e10cSrcweir rID.mnID3 == mnID3 && rID.mnID4 == mnID4 ); 77*cdf0e10cSrcweir } 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir ByteString GetIDString() const; 80*cdf0e10cSrcweir sal_Bool IsEmpty() const { return( 0 == mnID4 ); } 81*cdf0e10cSrcweir }; 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir GraphicID::GraphicID( const GraphicObject& rObj ) 86*cdf0e10cSrcweir { 87*cdf0e10cSrcweir const Graphic& rGraphic = rObj.GetGraphic(); 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir mnID1 = ( (sal_uLong) rGraphic.GetType() ) << 28; 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir switch( rGraphic.GetType() ) 92*cdf0e10cSrcweir { 93*cdf0e10cSrcweir case( GRAPHIC_BITMAP ): 94*cdf0e10cSrcweir { 95*cdf0e10cSrcweir if( rGraphic.IsAnimated() ) 96*cdf0e10cSrcweir { 97*cdf0e10cSrcweir const Animation aAnimation( rGraphic.GetAnimation() ); 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir mnID1 |= ( aAnimation.Count() & 0x0fffffff ); 100*cdf0e10cSrcweir mnID2 = aAnimation.GetDisplaySizePixel().Width(); 101*cdf0e10cSrcweir mnID3 = aAnimation.GetDisplaySizePixel().Height(); 102*cdf0e10cSrcweir mnID4 = rGraphic.GetChecksum(); 103*cdf0e10cSrcweir } 104*cdf0e10cSrcweir else 105*cdf0e10cSrcweir { 106*cdf0e10cSrcweir const BitmapEx aBmpEx( rGraphic.GetBitmapEx() ); 107*cdf0e10cSrcweir 108*cdf0e10cSrcweir mnID1 |= ( ( ( (sal_uLong) aBmpEx.GetTransparentType() << 8 ) | ( aBmpEx.IsAlpha() ? 1 : 0 ) ) & 0x0fffffff ); 109*cdf0e10cSrcweir mnID2 = aBmpEx.GetSizePixel().Width(); 110*cdf0e10cSrcweir mnID3 = aBmpEx.GetSizePixel().Height(); 111*cdf0e10cSrcweir mnID4 = rGraphic.GetChecksum(); 112*cdf0e10cSrcweir } 113*cdf0e10cSrcweir } 114*cdf0e10cSrcweir break; 115*cdf0e10cSrcweir 116*cdf0e10cSrcweir case( GRAPHIC_GDIMETAFILE ): 117*cdf0e10cSrcweir { 118*cdf0e10cSrcweir const GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() ); 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir mnID1 |= ( aMtf.GetActionCount() & 0x0fffffff ); 121*cdf0e10cSrcweir mnID2 = aMtf.GetPrefSize().Width(); 122*cdf0e10cSrcweir mnID3 = aMtf.GetPrefSize().Height(); 123*cdf0e10cSrcweir mnID4 = rGraphic.GetChecksum(); 124*cdf0e10cSrcweir } 125*cdf0e10cSrcweir break; 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir default: 128*cdf0e10cSrcweir mnID2 = mnID3 = mnID4 = 0; 129*cdf0e10cSrcweir break; 130*cdf0e10cSrcweir } 131*cdf0e10cSrcweir } 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir ByteString GraphicID::GetIDString() const 136*cdf0e10cSrcweir { 137*cdf0e10cSrcweir ByteString aHexStr; 138*cdf0e10cSrcweir sal_Char* pStr = aHexStr.AllocBuffer( 32 ); 139*cdf0e10cSrcweir sal_Int32 nShift; 140*cdf0e10cSrcweir 141*cdf0e10cSrcweir for( nShift = 28; nShift >= 0; nShift -= 4 ) 142*cdf0e10cSrcweir *pStr++ = aHexData[ ( mnID1 >> (sal_uInt32) nShift ) & 0xf ]; 143*cdf0e10cSrcweir 144*cdf0e10cSrcweir for( nShift = 28; nShift >= 0; nShift -= 4 ) 145*cdf0e10cSrcweir *pStr++ = aHexData[ ( mnID2 >> (sal_uInt32) nShift ) & 0xf ]; 146*cdf0e10cSrcweir 147*cdf0e10cSrcweir for( nShift = 28; nShift >= 0; nShift -= 4 ) 148*cdf0e10cSrcweir *pStr++ = aHexData[ ( mnID3 >> (sal_uInt32) nShift ) & 0xf ]; 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir for( nShift = 28; nShift >= 0; nShift -= 4 ) 151*cdf0e10cSrcweir *pStr++ = aHexData[ ( mnID4 >> (sal_uInt32) nShift ) & 0xf ]; 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir return aHexStr; 154*cdf0e10cSrcweir } 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir // --------------------- 157*cdf0e10cSrcweir // - GraphicCacheEntry - 158*cdf0e10cSrcweir // --------------------- 159*cdf0e10cSrcweir 160*cdf0e10cSrcweir class GraphicCacheEntry 161*cdf0e10cSrcweir { 162*cdf0e10cSrcweir private: 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir List maGraphicObjectList; 165*cdf0e10cSrcweir GraphicID maID; 166*cdf0e10cSrcweir GfxLink maGfxLink; 167*cdf0e10cSrcweir BitmapEx* mpBmpEx; 168*cdf0e10cSrcweir GDIMetaFile* mpMtf; 169*cdf0e10cSrcweir Animation* mpAnimation; 170*cdf0e10cSrcweir sal_Bool mbSwappedAll; 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir sal_Bool ImplInit( const GraphicObject& rObj ); 173*cdf0e10cSrcweir sal_Bool ImplMatches( const GraphicObject& rObj ) const { return( GraphicID( rObj ) == maID ); } 174*cdf0e10cSrcweir void ImplFillSubstitute( Graphic& rSubstitute ); 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir public: 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir GraphicCacheEntry( const GraphicObject& rObj ); 179*cdf0e10cSrcweir ~GraphicCacheEntry(); 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir const GraphicID& GetID() const { return maID; } 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir void AddGraphicObjectReference( const GraphicObject& rObj, Graphic& rSubstitute ); 184*cdf0e10cSrcweir sal_Bool ReleaseGraphicObjectReference( const GraphicObject& rObj ); 185*cdf0e10cSrcweir sal_uLong GetGraphicObjectReferenceCount() { return maGraphicObjectList.Count(); } 186*cdf0e10cSrcweir sal_Bool HasGraphicObjectReference( const GraphicObject& rObj ); 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir void TryToSwapIn(); 189*cdf0e10cSrcweir void GraphicObjectWasSwappedOut( const GraphicObject& rObj ); 190*cdf0e10cSrcweir sal_Bool FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute ); 191*cdf0e10cSrcweir void GraphicObjectWasSwappedIn( const GraphicObject& rObj ); 192*cdf0e10cSrcweir }; 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir GraphicCacheEntry::GraphicCacheEntry( const GraphicObject& rObj ) : 197*cdf0e10cSrcweir maID ( rObj ), 198*cdf0e10cSrcweir mpBmpEx ( NULL ), 199*cdf0e10cSrcweir mpMtf ( NULL ), 200*cdf0e10cSrcweir mpAnimation ( NULL ), 201*cdf0e10cSrcweir mbSwappedAll ( !ImplInit( rObj ) ) 202*cdf0e10cSrcweir { 203*cdf0e10cSrcweir maGraphicObjectList.Insert( (void*) &rObj, LIST_APPEND ); 204*cdf0e10cSrcweir } 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir GraphicCacheEntry::~GraphicCacheEntry() 209*cdf0e10cSrcweir { 210*cdf0e10cSrcweir DBG_ASSERT( !maGraphicObjectList.Count(), "GraphicCacheEntry::~GraphicCacheEntry(): Not all GraphicObjects are removed from this entry" ); 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir delete mpBmpEx; 213*cdf0e10cSrcweir delete mpMtf; 214*cdf0e10cSrcweir delete mpAnimation; 215*cdf0e10cSrcweir } 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir sal_Bool GraphicCacheEntry::ImplInit( const GraphicObject& rObj ) 220*cdf0e10cSrcweir { 221*cdf0e10cSrcweir sal_Bool bRet; 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir if( !rObj.IsSwappedOut() ) 224*cdf0e10cSrcweir { 225*cdf0e10cSrcweir const Graphic& rGraphic = rObj.GetGraphic(); 226*cdf0e10cSrcweir 227*cdf0e10cSrcweir if( mpBmpEx ) 228*cdf0e10cSrcweir delete mpBmpEx, mpBmpEx = NULL; 229*cdf0e10cSrcweir 230*cdf0e10cSrcweir if( mpMtf ) 231*cdf0e10cSrcweir delete mpMtf, mpMtf = NULL; 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir if( mpAnimation ) 234*cdf0e10cSrcweir delete mpAnimation, mpAnimation = NULL; 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir switch( rGraphic.GetType() ) 237*cdf0e10cSrcweir { 238*cdf0e10cSrcweir case( GRAPHIC_BITMAP ): 239*cdf0e10cSrcweir { 240*cdf0e10cSrcweir if( rGraphic.IsAnimated() ) 241*cdf0e10cSrcweir mpAnimation = new Animation( rGraphic.GetAnimation() ); 242*cdf0e10cSrcweir else 243*cdf0e10cSrcweir mpBmpEx = new BitmapEx( rGraphic.GetBitmapEx() ); 244*cdf0e10cSrcweir } 245*cdf0e10cSrcweir break; 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir case( GRAPHIC_GDIMETAFILE ): 248*cdf0e10cSrcweir { 249*cdf0e10cSrcweir mpMtf = new GDIMetaFile( rGraphic.GetGDIMetaFile() ); 250*cdf0e10cSrcweir } 251*cdf0e10cSrcweir break; 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir default: 254*cdf0e10cSrcweir DBG_ASSERT( GetID().IsEmpty(), "GraphicCacheEntry::ImplInit: Could not initialize graphic! (=>KA)" ); 255*cdf0e10cSrcweir break; 256*cdf0e10cSrcweir } 257*cdf0e10cSrcweir 258*cdf0e10cSrcweir if( rGraphic.IsLink() ) 259*cdf0e10cSrcweir maGfxLink = ( (Graphic&) rGraphic ).GetLink(); 260*cdf0e10cSrcweir else 261*cdf0e10cSrcweir maGfxLink = GfxLink(); 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir bRet = sal_True; 264*cdf0e10cSrcweir } 265*cdf0e10cSrcweir else 266*cdf0e10cSrcweir bRet = sal_False; 267*cdf0e10cSrcweir 268*cdf0e10cSrcweir return bRet; 269*cdf0e10cSrcweir } 270*cdf0e10cSrcweir 271*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 272*cdf0e10cSrcweir 273*cdf0e10cSrcweir void GraphicCacheEntry::ImplFillSubstitute( Graphic& rSubstitute ) 274*cdf0e10cSrcweir { 275*cdf0e10cSrcweir // create substitute for graphic; 276*cdf0e10cSrcweir const Size aPrefSize( rSubstitute.GetPrefSize() ); 277*cdf0e10cSrcweir const MapMode aPrefMapMode( rSubstitute.GetPrefMapMode() ); 278*cdf0e10cSrcweir const Link aAnimationNotifyHdl( rSubstitute.GetAnimationNotifyHdl() ); 279*cdf0e10cSrcweir const String aDocFileName( rSubstitute.GetDocFileName() ); 280*cdf0e10cSrcweir const sal_uLong nDocFilePos = rSubstitute.GetDocFilePos(); 281*cdf0e10cSrcweir const GraphicType eOldType = rSubstitute.GetType(); 282*cdf0e10cSrcweir const sal_Bool bDefaultType = ( rSubstitute.GetType() == GRAPHIC_DEFAULT ); 283*cdf0e10cSrcweir 284*cdf0e10cSrcweir if( rSubstitute.IsLink() && ( GFX_LINK_TYPE_NONE == maGfxLink.GetType() ) ) 285*cdf0e10cSrcweir maGfxLink = rSubstitute.GetLink(); 286*cdf0e10cSrcweir 287*cdf0e10cSrcweir if( mpBmpEx ) 288*cdf0e10cSrcweir rSubstitute = *mpBmpEx; 289*cdf0e10cSrcweir else if( mpAnimation ) 290*cdf0e10cSrcweir rSubstitute = *mpAnimation; 291*cdf0e10cSrcweir else if( mpMtf ) 292*cdf0e10cSrcweir rSubstitute = *mpMtf; 293*cdf0e10cSrcweir else 294*cdf0e10cSrcweir rSubstitute.Clear(); 295*cdf0e10cSrcweir 296*cdf0e10cSrcweir if( eOldType != GRAPHIC_NONE ) 297*cdf0e10cSrcweir { 298*cdf0e10cSrcweir rSubstitute.SetPrefSize( aPrefSize ); 299*cdf0e10cSrcweir rSubstitute.SetPrefMapMode( aPrefMapMode ); 300*cdf0e10cSrcweir rSubstitute.SetAnimationNotifyHdl( aAnimationNotifyHdl ); 301*cdf0e10cSrcweir rSubstitute.SetDocFileName( aDocFileName, nDocFilePos ); 302*cdf0e10cSrcweir } 303*cdf0e10cSrcweir 304*cdf0e10cSrcweir if( GFX_LINK_TYPE_NONE != maGfxLink.GetType() ) 305*cdf0e10cSrcweir rSubstitute.SetLink( maGfxLink ); 306*cdf0e10cSrcweir 307*cdf0e10cSrcweir if( bDefaultType ) 308*cdf0e10cSrcweir rSubstitute.SetDefaultType(); 309*cdf0e10cSrcweir } 310*cdf0e10cSrcweir 311*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 312*cdf0e10cSrcweir 313*cdf0e10cSrcweir void GraphicCacheEntry::AddGraphicObjectReference( const GraphicObject& rObj, Graphic& rSubstitute ) 314*cdf0e10cSrcweir { 315*cdf0e10cSrcweir if( mbSwappedAll ) 316*cdf0e10cSrcweir mbSwappedAll = !ImplInit( rObj ); 317*cdf0e10cSrcweir 318*cdf0e10cSrcweir ImplFillSubstitute( rSubstitute ); 319*cdf0e10cSrcweir maGraphicObjectList.Insert( (void*) &rObj, LIST_APPEND ); 320*cdf0e10cSrcweir } 321*cdf0e10cSrcweir 322*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 323*cdf0e10cSrcweir 324*cdf0e10cSrcweir sal_Bool GraphicCacheEntry::ReleaseGraphicObjectReference( const GraphicObject& rObj ) 325*cdf0e10cSrcweir { 326*cdf0e10cSrcweir sal_Bool bRet = sal_False; 327*cdf0e10cSrcweir 328*cdf0e10cSrcweir for( void* pObj = maGraphicObjectList.First(); !bRet && pObj; pObj = maGraphicObjectList.Next() ) 329*cdf0e10cSrcweir { 330*cdf0e10cSrcweir if( &rObj == (GraphicObject*) pObj ) 331*cdf0e10cSrcweir { 332*cdf0e10cSrcweir maGraphicObjectList.Remove( pObj ); 333*cdf0e10cSrcweir bRet = sal_True; 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir } 336*cdf0e10cSrcweir 337*cdf0e10cSrcweir return bRet; 338*cdf0e10cSrcweir } 339*cdf0e10cSrcweir 340*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 341*cdf0e10cSrcweir 342*cdf0e10cSrcweir sal_Bool GraphicCacheEntry::HasGraphicObjectReference( const GraphicObject& rObj ) 343*cdf0e10cSrcweir { 344*cdf0e10cSrcweir sal_Bool bRet = sal_False; 345*cdf0e10cSrcweir 346*cdf0e10cSrcweir for( void* pObj = maGraphicObjectList.First(); !bRet && pObj; pObj = maGraphicObjectList.Next() ) 347*cdf0e10cSrcweir if( &rObj == (GraphicObject*) pObj ) 348*cdf0e10cSrcweir bRet = sal_True; 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir return bRet; 351*cdf0e10cSrcweir } 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir void GraphicCacheEntry::TryToSwapIn() 356*cdf0e10cSrcweir { 357*cdf0e10cSrcweir if( mbSwappedAll && maGraphicObjectList.Count() ) 358*cdf0e10cSrcweir ( (GraphicObject*) maGraphicObjectList.First() )->FireSwapInRequest(); 359*cdf0e10cSrcweir } 360*cdf0e10cSrcweir 361*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 362*cdf0e10cSrcweir 363*cdf0e10cSrcweir void GraphicCacheEntry::GraphicObjectWasSwappedOut( const GraphicObject& /*rObj*/ ) 364*cdf0e10cSrcweir { 365*cdf0e10cSrcweir mbSwappedAll = sal_True; 366*cdf0e10cSrcweir 367*cdf0e10cSrcweir for( void* pObj = maGraphicObjectList.First(); mbSwappedAll && pObj; pObj = maGraphicObjectList.Next() ) 368*cdf0e10cSrcweir if( !( (GraphicObject*) pObj )->IsSwappedOut() ) 369*cdf0e10cSrcweir mbSwappedAll = sal_False; 370*cdf0e10cSrcweir 371*cdf0e10cSrcweir if( mbSwappedAll ) 372*cdf0e10cSrcweir { 373*cdf0e10cSrcweir delete mpBmpEx, mpBmpEx = NULL; 374*cdf0e10cSrcweir delete mpMtf, mpMtf = NULL; 375*cdf0e10cSrcweir delete mpAnimation, mpAnimation = NULL; 376*cdf0e10cSrcweir } 377*cdf0e10cSrcweir } 378*cdf0e10cSrcweir 379*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 380*cdf0e10cSrcweir 381*cdf0e10cSrcweir sal_Bool GraphicCacheEntry::FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute ) 382*cdf0e10cSrcweir { 383*cdf0e10cSrcweir sal_Bool bRet; 384*cdf0e10cSrcweir 385*cdf0e10cSrcweir if( !mbSwappedAll && rObj.IsSwappedOut() ) 386*cdf0e10cSrcweir { 387*cdf0e10cSrcweir ImplFillSubstitute( rSubstitute ); 388*cdf0e10cSrcweir bRet = sal_True; 389*cdf0e10cSrcweir } 390*cdf0e10cSrcweir else 391*cdf0e10cSrcweir bRet = sal_False; 392*cdf0e10cSrcweir 393*cdf0e10cSrcweir return bRet; 394*cdf0e10cSrcweir } 395*cdf0e10cSrcweir 396*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 397*cdf0e10cSrcweir 398*cdf0e10cSrcweir void GraphicCacheEntry::GraphicObjectWasSwappedIn( const GraphicObject& rObj ) 399*cdf0e10cSrcweir { 400*cdf0e10cSrcweir if( mbSwappedAll ) 401*cdf0e10cSrcweir mbSwappedAll = !ImplInit( rObj ); 402*cdf0e10cSrcweir } 403*cdf0e10cSrcweir 404*cdf0e10cSrcweir // ---------------------------- 405*cdf0e10cSrcweir // - GraphicDisplayCacheEntry - 406*cdf0e10cSrcweir // ---------------------------- 407*cdf0e10cSrcweir 408*cdf0e10cSrcweir class GraphicDisplayCacheEntry 409*cdf0e10cSrcweir { 410*cdf0e10cSrcweir private: 411*cdf0e10cSrcweir 412*cdf0e10cSrcweir ::vos::TTimeValue maReleaseTime; 413*cdf0e10cSrcweir const GraphicCacheEntry* mpRefCacheEntry; 414*cdf0e10cSrcweir GDIMetaFile* mpMtf; 415*cdf0e10cSrcweir BitmapEx* mpBmpEx; 416*cdf0e10cSrcweir GraphicAttr maAttr; 417*cdf0e10cSrcweir Size maOutSizePix; 418*cdf0e10cSrcweir sal_uLong mnCacheSize; 419*cdf0e10cSrcweir sal_uLong mnOutDevDrawMode; 420*cdf0e10cSrcweir sal_uInt16 mnOutDevBitCount; 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir public: 423*cdf0e10cSrcweir 424*cdf0e10cSrcweir static sal_uLong GetNeededSize( OutputDevice* pOut, const Point& rPt, const Size& rSz, 425*cdf0e10cSrcweir const GraphicObject& rObj, const GraphicAttr& rAttr ); 426*cdf0e10cSrcweir 427*cdf0e10cSrcweir public: 428*cdf0e10cSrcweir 429*cdf0e10cSrcweir GraphicDisplayCacheEntry( const GraphicCacheEntry* pRefCacheEntry, 430*cdf0e10cSrcweir OutputDevice* pOut, const Point& rPt, const Size& rSz, 431*cdf0e10cSrcweir const GraphicObject& rObj, const GraphicAttr& rAttr, 432*cdf0e10cSrcweir const BitmapEx& rBmpEx ) : 433*cdf0e10cSrcweir mpRefCacheEntry( pRefCacheEntry ), 434*cdf0e10cSrcweir mpMtf( NULL ), mpBmpEx( new BitmapEx( rBmpEx ) ), 435*cdf0e10cSrcweir maAttr( rAttr ), maOutSizePix( pOut->LogicToPixel( rSz ) ), 436*cdf0e10cSrcweir mnCacheSize( GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) ), 437*cdf0e10cSrcweir mnOutDevDrawMode( pOut->GetDrawMode() ), 438*cdf0e10cSrcweir mnOutDevBitCount( pOut->GetBitCount() ) 439*cdf0e10cSrcweir { 440*cdf0e10cSrcweir } 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir GraphicDisplayCacheEntry( const GraphicCacheEntry* pRefCacheEntry, 443*cdf0e10cSrcweir OutputDevice* pOut, const Point& rPt, const Size& rSz, 444*cdf0e10cSrcweir const GraphicObject& rObj, const GraphicAttr& rAttr, 445*cdf0e10cSrcweir const GDIMetaFile& rMtf ) : 446*cdf0e10cSrcweir mpRefCacheEntry( pRefCacheEntry ), 447*cdf0e10cSrcweir mpMtf( new GDIMetaFile( rMtf ) ), mpBmpEx( NULL ), 448*cdf0e10cSrcweir maAttr( rAttr ), maOutSizePix( pOut->LogicToPixel( rSz ) ), 449*cdf0e10cSrcweir mnCacheSize( GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) ), 450*cdf0e10cSrcweir mnOutDevDrawMode( pOut->GetDrawMode() ), 451*cdf0e10cSrcweir mnOutDevBitCount( pOut->GetBitCount() ) 452*cdf0e10cSrcweir { 453*cdf0e10cSrcweir } 454*cdf0e10cSrcweir 455*cdf0e10cSrcweir 456*cdf0e10cSrcweir ~GraphicDisplayCacheEntry(); 457*cdf0e10cSrcweir 458*cdf0e10cSrcweir const GraphicAttr& GetAttr() const { return maAttr; } 459*cdf0e10cSrcweir const Size& GetOutputSizePixel() const { return maOutSizePix; } 460*cdf0e10cSrcweir sal_uLong GetCacheSize() const { return mnCacheSize; } 461*cdf0e10cSrcweir const GraphicCacheEntry* GetReferencedCacheEntry() const { return mpRefCacheEntry; } 462*cdf0e10cSrcweir sal_uLong GetOutDevDrawMode() const { return mnOutDevDrawMode; } 463*cdf0e10cSrcweir sal_uInt16 GetOutDevBitCount() const { return mnOutDevBitCount; } 464*cdf0e10cSrcweir 465*cdf0e10cSrcweir void SetReleaseTime( const ::vos::TTimeValue& rReleaseTime ) { maReleaseTime = rReleaseTime; } 466*cdf0e10cSrcweir const ::vos::TTimeValue& GetReleaseTime() const { return maReleaseTime; } 467*cdf0e10cSrcweir 468*cdf0e10cSrcweir sal_Bool Matches( OutputDevice* pOut, const Point& /*rPtPixel*/, const Size& rSzPixel, 469*cdf0e10cSrcweir const GraphicCacheEntry* pCacheEntry, const GraphicAttr& rAttr ) const 470*cdf0e10cSrcweir { 471*cdf0e10cSrcweir // #i46805# Additional match 472*cdf0e10cSrcweir // criteria: outdev draw mode and 473*cdf0e10cSrcweir // bit count. One cannot reuse 474*cdf0e10cSrcweir // this cache object, if it's 475*cdf0e10cSrcweir // e.g. generated for 476*cdf0e10cSrcweir // DRAWMODE_GRAYBITMAP. 477*cdf0e10cSrcweir return( ( pCacheEntry == mpRefCacheEntry ) && 478*cdf0e10cSrcweir ( maAttr == rAttr ) && 479*cdf0e10cSrcweir ( ( maOutSizePix == rSzPixel ) || ( !maOutSizePix.Width() && !maOutSizePix.Height() ) ) && 480*cdf0e10cSrcweir ( pOut->GetBitCount() == mnOutDevBitCount ) && 481*cdf0e10cSrcweir ( pOut->GetDrawMode() == mnOutDevDrawMode ) ); 482*cdf0e10cSrcweir } 483*cdf0e10cSrcweir 484*cdf0e10cSrcweir void Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz ) const; 485*cdf0e10cSrcweir }; 486*cdf0e10cSrcweir 487*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 488*cdf0e10cSrcweir 489*cdf0e10cSrcweir sal_uLong GraphicDisplayCacheEntry::GetNeededSize( OutputDevice* pOut, const Point& /*rPt*/, const Size& rSz, 490*cdf0e10cSrcweir const GraphicObject& rObj, const GraphicAttr& rAttr ) 491*cdf0e10cSrcweir { 492*cdf0e10cSrcweir const Graphic& rGraphic = rObj.GetGraphic(); 493*cdf0e10cSrcweir const GraphicType eType = rGraphic.GetType(); 494*cdf0e10cSrcweir sal_uLong nNeededSize; 495*cdf0e10cSrcweir 496*cdf0e10cSrcweir if( GRAPHIC_BITMAP == eType ) 497*cdf0e10cSrcweir { 498*cdf0e10cSrcweir const Size aOutSizePix( pOut->LogicToPixel( rSz ) ); 499*cdf0e10cSrcweir const long nBitCount = pOut->GetBitCount(); 500*cdf0e10cSrcweir 501*cdf0e10cSrcweir if( ( aOutSizePix.Width() > MAX_BMP_EXTENT ) || 502*cdf0e10cSrcweir ( aOutSizePix.Height() > MAX_BMP_EXTENT ) ) 503*cdf0e10cSrcweir { 504*cdf0e10cSrcweir nNeededSize = ULONG_MAX; 505*cdf0e10cSrcweir } 506*cdf0e10cSrcweir else if( nBitCount ) 507*cdf0e10cSrcweir { 508*cdf0e10cSrcweir nNeededSize = aOutSizePix.Width() * aOutSizePix.Height() * nBitCount / 8; 509*cdf0e10cSrcweir 510*cdf0e10cSrcweir if( rObj.IsTransparent() || ( rAttr.GetRotation() % 3600 ) ) 511*cdf0e10cSrcweir nNeededSize += nNeededSize / nBitCount; 512*cdf0e10cSrcweir } 513*cdf0e10cSrcweir else 514*cdf0e10cSrcweir { 515*cdf0e10cSrcweir DBG_ERROR( "GraphicDisplayCacheEntry::GetNeededSize(): pOut->GetBitCount() == 0" ); 516*cdf0e10cSrcweir nNeededSize = 256000; 517*cdf0e10cSrcweir } 518*cdf0e10cSrcweir } 519*cdf0e10cSrcweir else if( GRAPHIC_GDIMETAFILE == eType ) 520*cdf0e10cSrcweir nNeededSize = rGraphic.GetSizeBytes(); 521*cdf0e10cSrcweir else 522*cdf0e10cSrcweir nNeededSize = 0; 523*cdf0e10cSrcweir 524*cdf0e10cSrcweir return nNeededSize; 525*cdf0e10cSrcweir } 526*cdf0e10cSrcweir 527*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 528*cdf0e10cSrcweir 529*cdf0e10cSrcweir GraphicDisplayCacheEntry::~GraphicDisplayCacheEntry() 530*cdf0e10cSrcweir { 531*cdf0e10cSrcweir if( mpMtf ) 532*cdf0e10cSrcweir delete mpMtf; 533*cdf0e10cSrcweir 534*cdf0e10cSrcweir if( mpBmpEx ) 535*cdf0e10cSrcweir delete mpBmpEx; 536*cdf0e10cSrcweir } 537*cdf0e10cSrcweir 538*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 539*cdf0e10cSrcweir 540*cdf0e10cSrcweir void GraphicDisplayCacheEntry::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz ) const 541*cdf0e10cSrcweir { 542*cdf0e10cSrcweir if( mpMtf ) 543*cdf0e10cSrcweir GraphicManager::ImplDraw( pOut, rPt, rSz, *mpMtf, maAttr ); 544*cdf0e10cSrcweir else if( mpBmpEx ) 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir if( maAttr.IsRotated() ) 547*cdf0e10cSrcweir { 548*cdf0e10cSrcweir Polygon aPoly( Rectangle( rPt, rSz ) ); 549*cdf0e10cSrcweir 550*cdf0e10cSrcweir aPoly.Rotate( rPt, maAttr.GetRotation() % 3600 ); 551*cdf0e10cSrcweir const Rectangle aRotBoundRect( aPoly.GetBoundRect() ); 552*cdf0e10cSrcweir pOut->DrawBitmapEx( aRotBoundRect.TopLeft(), aRotBoundRect.GetSize(), *mpBmpEx ); 553*cdf0e10cSrcweir } 554*cdf0e10cSrcweir else 555*cdf0e10cSrcweir pOut->DrawBitmapEx( rPt, rSz, *mpBmpEx ); 556*cdf0e10cSrcweir } 557*cdf0e10cSrcweir } 558*cdf0e10cSrcweir 559*cdf0e10cSrcweir // ----------------------- 560*cdf0e10cSrcweir // - GraphicCache - 561*cdf0e10cSrcweir // ----------------------- 562*cdf0e10cSrcweir 563*cdf0e10cSrcweir GraphicCache::GraphicCache( GraphicManager& rMgr, sal_uLong nDisplayCacheSize, sal_uLong nMaxObjDisplayCacheSize ) : 564*cdf0e10cSrcweir mrMgr ( rMgr ), 565*cdf0e10cSrcweir mnReleaseTimeoutSeconds ( 0UL ), 566*cdf0e10cSrcweir mnMaxDisplaySize ( nDisplayCacheSize ), 567*cdf0e10cSrcweir mnMaxObjDisplaySize ( nMaxObjDisplayCacheSize ), 568*cdf0e10cSrcweir mnUsedDisplaySize ( 0UL ) 569*cdf0e10cSrcweir { 570*cdf0e10cSrcweir maReleaseTimer.SetTimeoutHdl( LINK( this, GraphicCache, ReleaseTimeoutHdl ) ); 571*cdf0e10cSrcweir maReleaseTimer.SetTimeout( RELEASE_TIMEOUT ); 572*cdf0e10cSrcweir maReleaseTimer.Start(); 573*cdf0e10cSrcweir } 574*cdf0e10cSrcweir 575*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 576*cdf0e10cSrcweir 577*cdf0e10cSrcweir GraphicCache::~GraphicCache() 578*cdf0e10cSrcweir { 579*cdf0e10cSrcweir DBG_ASSERT( !maGraphicCache.Count(), "GraphicCache::~GraphicCache(): there are some GraphicObjects in cache" ); 580*cdf0e10cSrcweir DBG_ASSERT( !maDisplayCache.Count(), "GraphicCache::~GraphicCache(): there are some GraphicObjects in display cache" ); 581*cdf0e10cSrcweir } 582*cdf0e10cSrcweir 583*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 584*cdf0e10cSrcweir 585*cdf0e10cSrcweir void GraphicCache::AddGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute, 586*cdf0e10cSrcweir const ByteString* pID, const GraphicObject* pCopyObj ) 587*cdf0e10cSrcweir { 588*cdf0e10cSrcweir sal_Bool bInserted = sal_False; 589*cdf0e10cSrcweir 590*cdf0e10cSrcweir if( !rObj.IsSwappedOut() && 591*cdf0e10cSrcweir ( pID || ( pCopyObj && ( pCopyObj->GetType() != GRAPHIC_NONE ) ) || ( rObj.GetType() != GRAPHIC_NONE ) ) ) 592*cdf0e10cSrcweir { 593*cdf0e10cSrcweir if( pCopyObj ) 594*cdf0e10cSrcweir { 595*cdf0e10cSrcweir GraphicCacheEntry* pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.First() ); 596*cdf0e10cSrcweir 597*cdf0e10cSrcweir while( !bInserted && pEntry ) 598*cdf0e10cSrcweir { 599*cdf0e10cSrcweir if( pEntry->HasGraphicObjectReference( *pCopyObj ) ) 600*cdf0e10cSrcweir { 601*cdf0e10cSrcweir pEntry->AddGraphicObjectReference( rObj, rSubstitute ); 602*cdf0e10cSrcweir bInserted = sal_True; 603*cdf0e10cSrcweir } 604*cdf0e10cSrcweir else 605*cdf0e10cSrcweir { 606*cdf0e10cSrcweir pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.Next() ); 607*cdf0e10cSrcweir } 608*cdf0e10cSrcweir } 609*cdf0e10cSrcweir } 610*cdf0e10cSrcweir 611*cdf0e10cSrcweir if( !bInserted ) 612*cdf0e10cSrcweir { 613*cdf0e10cSrcweir GraphicCacheEntry* pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.First() ); 614*cdf0e10cSrcweir ::std::auto_ptr< GraphicID > apID; 615*cdf0e10cSrcweir 616*cdf0e10cSrcweir if( !pID ) 617*cdf0e10cSrcweir { 618*cdf0e10cSrcweir apID.reset( new GraphicID( rObj ) ); 619*cdf0e10cSrcweir } 620*cdf0e10cSrcweir 621*cdf0e10cSrcweir while( !bInserted && pEntry ) 622*cdf0e10cSrcweir { 623*cdf0e10cSrcweir const GraphicID& rEntryID = pEntry->GetID(); 624*cdf0e10cSrcweir 625*cdf0e10cSrcweir if( pID ) 626*cdf0e10cSrcweir { 627*cdf0e10cSrcweir if( rEntryID.GetIDString() == *pID ) 628*cdf0e10cSrcweir { 629*cdf0e10cSrcweir pEntry->TryToSwapIn(); 630*cdf0e10cSrcweir 631*cdf0e10cSrcweir // since pEntry->TryToSwapIn can modify our current list, we have to 632*cdf0e10cSrcweir // iterate from beginning to add a reference to the appropriate 633*cdf0e10cSrcweir // CacheEntry object; after this, quickly jump out of the outer iteration 634*cdf0e10cSrcweir for( pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.First() ); 635*cdf0e10cSrcweir !bInserted && pEntry; 636*cdf0e10cSrcweir pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.Next() ) ) 637*cdf0e10cSrcweir { 638*cdf0e10cSrcweir const GraphicID& rID = pEntry->GetID(); 639*cdf0e10cSrcweir 640*cdf0e10cSrcweir if( rID.GetIDString() == *pID ) 641*cdf0e10cSrcweir { 642*cdf0e10cSrcweir pEntry->AddGraphicObjectReference( rObj, rSubstitute ); 643*cdf0e10cSrcweir bInserted = sal_True; 644*cdf0e10cSrcweir } 645*cdf0e10cSrcweir } 646*cdf0e10cSrcweir 647*cdf0e10cSrcweir if( !bInserted ) 648*cdf0e10cSrcweir { 649*cdf0e10cSrcweir maGraphicCache.Insert( new GraphicCacheEntry( rObj ), LIST_APPEND ); 650*cdf0e10cSrcweir bInserted = sal_True; 651*cdf0e10cSrcweir } 652*cdf0e10cSrcweir } 653*cdf0e10cSrcweir } 654*cdf0e10cSrcweir else 655*cdf0e10cSrcweir { 656*cdf0e10cSrcweir if( rEntryID == *apID ) 657*cdf0e10cSrcweir { 658*cdf0e10cSrcweir pEntry->AddGraphicObjectReference( rObj, rSubstitute ); 659*cdf0e10cSrcweir bInserted = sal_True; 660*cdf0e10cSrcweir } 661*cdf0e10cSrcweir } 662*cdf0e10cSrcweir 663*cdf0e10cSrcweir if( !bInserted ) 664*cdf0e10cSrcweir pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.Next() ); 665*cdf0e10cSrcweir } 666*cdf0e10cSrcweir } 667*cdf0e10cSrcweir } 668*cdf0e10cSrcweir 669*cdf0e10cSrcweir if( !bInserted ) 670*cdf0e10cSrcweir maGraphicCache.Insert( new GraphicCacheEntry( rObj ), LIST_APPEND ); 671*cdf0e10cSrcweir } 672*cdf0e10cSrcweir 673*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 674*cdf0e10cSrcweir 675*cdf0e10cSrcweir void GraphicCache::ReleaseGraphicObject( const GraphicObject& rObj ) 676*cdf0e10cSrcweir { 677*cdf0e10cSrcweir // Release cached object 678*cdf0e10cSrcweir GraphicCacheEntry* pEntry = (GraphicCacheEntry*) maGraphicCache.First(); 679*cdf0e10cSrcweir sal_Bool bRemoved = sal_False; 680*cdf0e10cSrcweir 681*cdf0e10cSrcweir while( !bRemoved && pEntry ) 682*cdf0e10cSrcweir { 683*cdf0e10cSrcweir bRemoved = pEntry->ReleaseGraphicObjectReference( rObj ); 684*cdf0e10cSrcweir 685*cdf0e10cSrcweir if( bRemoved ) 686*cdf0e10cSrcweir { 687*cdf0e10cSrcweir if( 0 == pEntry->GetGraphicObjectReferenceCount() ) 688*cdf0e10cSrcweir { 689*cdf0e10cSrcweir // if graphic cache entry has no more references, 690*cdf0e10cSrcweir // the corresponding display cache object can be removed 691*cdf0e10cSrcweir GraphicDisplayCacheEntry* pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.First(); 692*cdf0e10cSrcweir 693*cdf0e10cSrcweir while( pDisplayEntry ) 694*cdf0e10cSrcweir { 695*cdf0e10cSrcweir if( pDisplayEntry->GetReferencedCacheEntry() == pEntry ) 696*cdf0e10cSrcweir { 697*cdf0e10cSrcweir mnUsedDisplaySize -= pDisplayEntry->GetCacheSize(); 698*cdf0e10cSrcweir maDisplayCache.Remove( pDisplayEntry ); 699*cdf0e10cSrcweir delete pDisplayEntry; 700*cdf0e10cSrcweir pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.GetCurObject(); 701*cdf0e10cSrcweir } 702*cdf0e10cSrcweir else 703*cdf0e10cSrcweir pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.Next(); 704*cdf0e10cSrcweir } 705*cdf0e10cSrcweir 706*cdf0e10cSrcweir // delete graphic cache entry 707*cdf0e10cSrcweir maGraphicCache.Remove( (void*) pEntry ); 708*cdf0e10cSrcweir delete pEntry; 709*cdf0e10cSrcweir } 710*cdf0e10cSrcweir } 711*cdf0e10cSrcweir else 712*cdf0e10cSrcweir pEntry = (GraphicCacheEntry*) maGraphicCache.Next(); 713*cdf0e10cSrcweir } 714*cdf0e10cSrcweir 715*cdf0e10cSrcweir DBG_ASSERT( bRemoved, "GraphicCache::ReleaseGraphicObject(...): GraphicObject not found in cache" ); 716*cdf0e10cSrcweir } 717*cdf0e10cSrcweir 718*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 719*cdf0e10cSrcweir 720*cdf0e10cSrcweir void GraphicCache::GraphicObjectWasSwappedOut( const GraphicObject& rObj ) 721*cdf0e10cSrcweir { 722*cdf0e10cSrcweir // notify cache that rObj is swapped out (and can thus be pruned 723*cdf0e10cSrcweir // from the cache) 724*cdf0e10cSrcweir GraphicCacheEntry* pEntry = ImplGetCacheEntry( rObj ); 725*cdf0e10cSrcweir 726*cdf0e10cSrcweir if( pEntry ) 727*cdf0e10cSrcweir pEntry->GraphicObjectWasSwappedOut( rObj ); 728*cdf0e10cSrcweir } 729*cdf0e10cSrcweir 730*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 731*cdf0e10cSrcweir 732*cdf0e10cSrcweir sal_Bool GraphicCache::FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute ) 733*cdf0e10cSrcweir { 734*cdf0e10cSrcweir GraphicCacheEntry* pEntry = ImplGetCacheEntry( rObj ); 735*cdf0e10cSrcweir 736*cdf0e10cSrcweir if( !pEntry ) 737*cdf0e10cSrcweir return sal_False; 738*cdf0e10cSrcweir 739*cdf0e10cSrcweir return pEntry->FillSwappedGraphicObject( rObj, rSubstitute ); 740*cdf0e10cSrcweir } 741*cdf0e10cSrcweir 742*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 743*cdf0e10cSrcweir 744*cdf0e10cSrcweir void GraphicCache::GraphicObjectWasSwappedIn( const GraphicObject& rObj ) 745*cdf0e10cSrcweir { 746*cdf0e10cSrcweir GraphicCacheEntry* pEntry = ImplGetCacheEntry( rObj ); 747*cdf0e10cSrcweir 748*cdf0e10cSrcweir if( pEntry ) 749*cdf0e10cSrcweir { 750*cdf0e10cSrcweir if( pEntry->GetID().IsEmpty() ) 751*cdf0e10cSrcweir { 752*cdf0e10cSrcweir ReleaseGraphicObject( rObj ); 753*cdf0e10cSrcweir AddGraphicObject( rObj, (Graphic&) rObj.GetGraphic(), NULL, NULL ); 754*cdf0e10cSrcweir } 755*cdf0e10cSrcweir else 756*cdf0e10cSrcweir pEntry->GraphicObjectWasSwappedIn( rObj ); 757*cdf0e10cSrcweir } 758*cdf0e10cSrcweir } 759*cdf0e10cSrcweir 760*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 761*cdf0e10cSrcweir 762*cdf0e10cSrcweir void GraphicCache::SetMaxDisplayCacheSize( sal_uLong nNewCacheSize ) 763*cdf0e10cSrcweir { 764*cdf0e10cSrcweir mnMaxDisplaySize = nNewCacheSize; 765*cdf0e10cSrcweir 766*cdf0e10cSrcweir if( GetMaxDisplayCacheSize() < GetUsedDisplayCacheSize() ) 767*cdf0e10cSrcweir ImplFreeDisplayCacheSpace( GetUsedDisplayCacheSize() - GetMaxDisplayCacheSize() ); 768*cdf0e10cSrcweir } 769*cdf0e10cSrcweir 770*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 771*cdf0e10cSrcweir 772*cdf0e10cSrcweir void GraphicCache::SetMaxObjDisplayCacheSize( sal_uLong nNewMaxObjSize, sal_Bool bDestroyGreaterCached ) 773*cdf0e10cSrcweir { 774*cdf0e10cSrcweir const sal_Bool bDestroy = ( bDestroyGreaterCached && ( nNewMaxObjSize < mnMaxObjDisplaySize ) ); 775*cdf0e10cSrcweir 776*cdf0e10cSrcweir mnMaxObjDisplaySize = Min( nNewMaxObjSize, mnMaxDisplaySize ); 777*cdf0e10cSrcweir 778*cdf0e10cSrcweir if( bDestroy ) 779*cdf0e10cSrcweir { 780*cdf0e10cSrcweir GraphicDisplayCacheEntry* pCacheObj = (GraphicDisplayCacheEntry*) maDisplayCache.First(); 781*cdf0e10cSrcweir 782*cdf0e10cSrcweir while( pCacheObj ) 783*cdf0e10cSrcweir { 784*cdf0e10cSrcweir if( pCacheObj->GetCacheSize() > mnMaxObjDisplaySize ) 785*cdf0e10cSrcweir { 786*cdf0e10cSrcweir mnUsedDisplaySize -= pCacheObj->GetCacheSize(); 787*cdf0e10cSrcweir maDisplayCache.Remove( pCacheObj ); 788*cdf0e10cSrcweir delete pCacheObj; 789*cdf0e10cSrcweir pCacheObj = (GraphicDisplayCacheEntry*) maDisplayCache.GetCurObject(); 790*cdf0e10cSrcweir } 791*cdf0e10cSrcweir else 792*cdf0e10cSrcweir pCacheObj = (GraphicDisplayCacheEntry*) maDisplayCache.Next(); 793*cdf0e10cSrcweir } 794*cdf0e10cSrcweir } 795*cdf0e10cSrcweir } 796*cdf0e10cSrcweir 797*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 798*cdf0e10cSrcweir 799*cdf0e10cSrcweir void GraphicCache::SetCacheTimeout( sal_uLong nTimeoutSeconds ) 800*cdf0e10cSrcweir { 801*cdf0e10cSrcweir if( mnReleaseTimeoutSeconds != nTimeoutSeconds ) 802*cdf0e10cSrcweir { 803*cdf0e10cSrcweir GraphicDisplayCacheEntry* pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.First(); 804*cdf0e10cSrcweir ::vos::TTimeValue aReleaseTime; 805*cdf0e10cSrcweir 806*cdf0e10cSrcweir if( ( mnReleaseTimeoutSeconds = nTimeoutSeconds ) != 0 ) 807*cdf0e10cSrcweir { 808*cdf0e10cSrcweir osl_getSystemTime( &aReleaseTime ); 809*cdf0e10cSrcweir aReleaseTime.addTime( ::vos::TTimeValue( nTimeoutSeconds, 0 ) ); 810*cdf0e10cSrcweir } 811*cdf0e10cSrcweir 812*cdf0e10cSrcweir while( pDisplayEntry ) 813*cdf0e10cSrcweir { 814*cdf0e10cSrcweir pDisplayEntry->SetReleaseTime( aReleaseTime ); 815*cdf0e10cSrcweir pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.Next(); 816*cdf0e10cSrcweir } 817*cdf0e10cSrcweir } 818*cdf0e10cSrcweir } 819*cdf0e10cSrcweir 820*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 821*cdf0e10cSrcweir 822*cdf0e10cSrcweir void GraphicCache::ClearDisplayCache() 823*cdf0e10cSrcweir { 824*cdf0e10cSrcweir for( void* pObj = maDisplayCache.First(); pObj; pObj = maDisplayCache.Next() ) 825*cdf0e10cSrcweir delete (GraphicDisplayCacheEntry*) pObj; 826*cdf0e10cSrcweir 827*cdf0e10cSrcweir maDisplayCache.Clear(); 828*cdf0e10cSrcweir mnUsedDisplaySize = 0UL; 829*cdf0e10cSrcweir } 830*cdf0e10cSrcweir 831*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 832*cdf0e10cSrcweir 833*cdf0e10cSrcweir sal_Bool GraphicCache::IsDisplayCacheable( OutputDevice* pOut, const Point& rPt, const Size& rSz, 834*cdf0e10cSrcweir const GraphicObject& rObj, const GraphicAttr& rAttr ) const 835*cdf0e10cSrcweir { 836*cdf0e10cSrcweir return( GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) <= 837*cdf0e10cSrcweir GetMaxObjDisplayCacheSize() ); 838*cdf0e10cSrcweir } 839*cdf0e10cSrcweir 840*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 841*cdf0e10cSrcweir 842*cdf0e10cSrcweir sal_Bool GraphicCache::IsInDisplayCache( OutputDevice* pOut, const Point& rPt, const Size& rSz, 843*cdf0e10cSrcweir const GraphicObject& rObj, const GraphicAttr& rAttr ) const 844*cdf0e10cSrcweir { 845*cdf0e10cSrcweir const Point aPtPixel( pOut->LogicToPixel( rPt ) ); 846*cdf0e10cSrcweir const Size aSzPixel( pOut->LogicToPixel( rSz ) ); 847*cdf0e10cSrcweir const GraphicCacheEntry* pCacheEntry = ( (GraphicCache*) this )->ImplGetCacheEntry( rObj ); 848*cdf0e10cSrcweir //GraphicDisplayCacheEntry* pDisplayEntry = (GraphicDisplayCacheEntry*) ( (GraphicCache*) this )->maDisplayCache.First(); // -Wall removed .... 849*cdf0e10cSrcweir sal_Bool bFound = sal_False; 850*cdf0e10cSrcweir 851*cdf0e10cSrcweir if( pCacheEntry ) 852*cdf0e10cSrcweir { 853*cdf0e10cSrcweir for( long i = 0, nCount = maDisplayCache.Count(); !bFound && ( i < nCount ); i++ ) 854*cdf0e10cSrcweir if( ( (GraphicDisplayCacheEntry*) maDisplayCache.GetObject( i ) )->Matches( pOut, aPtPixel, aSzPixel, pCacheEntry, rAttr ) ) 855*cdf0e10cSrcweir bFound = sal_True; 856*cdf0e10cSrcweir } 857*cdf0e10cSrcweir 858*cdf0e10cSrcweir return bFound; 859*cdf0e10cSrcweir } 860*cdf0e10cSrcweir 861*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 862*cdf0e10cSrcweir 863*cdf0e10cSrcweir ByteString GraphicCache::GetUniqueID( const GraphicObject& rObj ) const 864*cdf0e10cSrcweir { 865*cdf0e10cSrcweir ByteString aRet; 866*cdf0e10cSrcweir GraphicCacheEntry* pEntry = ( (GraphicCache*) this )->ImplGetCacheEntry( rObj ); 867*cdf0e10cSrcweir 868*cdf0e10cSrcweir // ensure that the entry is correctly initialized (it has to be read at least once) 869*cdf0e10cSrcweir if( pEntry && pEntry->GetID().IsEmpty() ) 870*cdf0e10cSrcweir pEntry->TryToSwapIn(); 871*cdf0e10cSrcweir 872*cdf0e10cSrcweir // do another call to ImplGetCacheEntry in case of modified entry list 873*cdf0e10cSrcweir pEntry = ( (GraphicCache*) this )->ImplGetCacheEntry( rObj ); 874*cdf0e10cSrcweir 875*cdf0e10cSrcweir if( pEntry ) 876*cdf0e10cSrcweir aRet = pEntry->GetID().GetIDString(); 877*cdf0e10cSrcweir 878*cdf0e10cSrcweir return aRet; 879*cdf0e10cSrcweir } 880*cdf0e10cSrcweir 881*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 882*cdf0e10cSrcweir 883*cdf0e10cSrcweir sal_Bool GraphicCache::CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz, 884*cdf0e10cSrcweir const GraphicObject& rObj, const GraphicAttr& rAttr, 885*cdf0e10cSrcweir const BitmapEx& rBmpEx ) 886*cdf0e10cSrcweir { 887*cdf0e10cSrcweir const sal_uLong nNeededSize = GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr ); 888*cdf0e10cSrcweir sal_Bool bRet = sal_False; 889*cdf0e10cSrcweir 890*cdf0e10cSrcweir if( nNeededSize <= GetMaxObjDisplayCacheSize() ) 891*cdf0e10cSrcweir { 892*cdf0e10cSrcweir if( nNeededSize > GetFreeDisplayCacheSize() ) 893*cdf0e10cSrcweir ImplFreeDisplayCacheSpace( nNeededSize - GetFreeDisplayCacheSize() ); 894*cdf0e10cSrcweir 895*cdf0e10cSrcweir GraphicDisplayCacheEntry* pNewEntry = new GraphicDisplayCacheEntry( ImplGetCacheEntry( rObj ), 896*cdf0e10cSrcweir pOut, rPt, rSz, rObj, rAttr, rBmpEx ); 897*cdf0e10cSrcweir 898*cdf0e10cSrcweir if( GetCacheTimeout() ) 899*cdf0e10cSrcweir { 900*cdf0e10cSrcweir ::vos::TTimeValue aReleaseTime; 901*cdf0e10cSrcweir 902*cdf0e10cSrcweir osl_getSystemTime( &aReleaseTime ); 903*cdf0e10cSrcweir aReleaseTime.addTime( ::vos::TTimeValue( GetCacheTimeout(), 0 ) ); 904*cdf0e10cSrcweir pNewEntry->SetReleaseTime( aReleaseTime ); 905*cdf0e10cSrcweir } 906*cdf0e10cSrcweir 907*cdf0e10cSrcweir maDisplayCache.Insert( pNewEntry, LIST_APPEND ); 908*cdf0e10cSrcweir mnUsedDisplaySize += pNewEntry->GetCacheSize(); 909*cdf0e10cSrcweir bRet = sal_True; 910*cdf0e10cSrcweir } 911*cdf0e10cSrcweir 912*cdf0e10cSrcweir return bRet; 913*cdf0e10cSrcweir } 914*cdf0e10cSrcweir 915*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 916*cdf0e10cSrcweir 917*cdf0e10cSrcweir sal_Bool GraphicCache::CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz, 918*cdf0e10cSrcweir const GraphicObject& rObj, const GraphicAttr& rAttr, 919*cdf0e10cSrcweir const GDIMetaFile& rMtf ) 920*cdf0e10cSrcweir { 921*cdf0e10cSrcweir const sal_uLong nNeededSize = GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr ); 922*cdf0e10cSrcweir sal_Bool bRet = sal_False; 923*cdf0e10cSrcweir 924*cdf0e10cSrcweir if( nNeededSize <= GetMaxObjDisplayCacheSize() ) 925*cdf0e10cSrcweir { 926*cdf0e10cSrcweir if( nNeededSize > GetFreeDisplayCacheSize() ) 927*cdf0e10cSrcweir ImplFreeDisplayCacheSpace( nNeededSize - GetFreeDisplayCacheSize() ); 928*cdf0e10cSrcweir 929*cdf0e10cSrcweir GraphicDisplayCacheEntry* pNewEntry = new GraphicDisplayCacheEntry( ImplGetCacheEntry( rObj ), 930*cdf0e10cSrcweir pOut, rPt, rSz, rObj, rAttr, rMtf ); 931*cdf0e10cSrcweir 932*cdf0e10cSrcweir if( GetCacheTimeout() ) 933*cdf0e10cSrcweir { 934*cdf0e10cSrcweir ::vos::TTimeValue aReleaseTime; 935*cdf0e10cSrcweir 936*cdf0e10cSrcweir osl_getSystemTime( &aReleaseTime ); 937*cdf0e10cSrcweir aReleaseTime.addTime( ::vos::TTimeValue( GetCacheTimeout(), 0 ) ); 938*cdf0e10cSrcweir pNewEntry->SetReleaseTime( aReleaseTime ); 939*cdf0e10cSrcweir } 940*cdf0e10cSrcweir 941*cdf0e10cSrcweir maDisplayCache.Insert( pNewEntry, LIST_APPEND ); 942*cdf0e10cSrcweir mnUsedDisplaySize += pNewEntry->GetCacheSize(); 943*cdf0e10cSrcweir bRet = sal_True; 944*cdf0e10cSrcweir } 945*cdf0e10cSrcweir 946*cdf0e10cSrcweir return bRet; 947*cdf0e10cSrcweir } 948*cdf0e10cSrcweir 949*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 950*cdf0e10cSrcweir 951*cdf0e10cSrcweir sal_Bool GraphicCache::DrawDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz, 952*cdf0e10cSrcweir const GraphicObject& rObj, const GraphicAttr& rAttr ) 953*cdf0e10cSrcweir { 954*cdf0e10cSrcweir const Point aPtPixel( pOut->LogicToPixel( rPt ) ); 955*cdf0e10cSrcweir const Size aSzPixel( pOut->LogicToPixel( rSz ) ); 956*cdf0e10cSrcweir const GraphicCacheEntry* pCacheEntry = ImplGetCacheEntry( rObj ); 957*cdf0e10cSrcweir GraphicDisplayCacheEntry* pDisplayCacheEntry = (GraphicDisplayCacheEntry*) maDisplayCache.First(); 958*cdf0e10cSrcweir sal_Bool bRet = sal_False; 959*cdf0e10cSrcweir 960*cdf0e10cSrcweir while( !bRet && pDisplayCacheEntry ) 961*cdf0e10cSrcweir { 962*cdf0e10cSrcweir if( pDisplayCacheEntry->Matches( pOut, aPtPixel, aSzPixel, pCacheEntry, rAttr ) ) 963*cdf0e10cSrcweir { 964*cdf0e10cSrcweir ::vos::TTimeValue aReleaseTime; 965*cdf0e10cSrcweir 966*cdf0e10cSrcweir // put found object at last used position 967*cdf0e10cSrcweir maDisplayCache.Insert( maDisplayCache.Remove( pDisplayCacheEntry ), LIST_APPEND ); 968*cdf0e10cSrcweir 969*cdf0e10cSrcweir if( GetCacheTimeout() ) 970*cdf0e10cSrcweir { 971*cdf0e10cSrcweir osl_getSystemTime( &aReleaseTime ); 972*cdf0e10cSrcweir aReleaseTime.addTime( ::vos::TTimeValue( GetCacheTimeout(), 0 ) ); 973*cdf0e10cSrcweir } 974*cdf0e10cSrcweir 975*cdf0e10cSrcweir pDisplayCacheEntry->SetReleaseTime( aReleaseTime ); 976*cdf0e10cSrcweir bRet = sal_True; 977*cdf0e10cSrcweir } 978*cdf0e10cSrcweir else 979*cdf0e10cSrcweir pDisplayCacheEntry = (GraphicDisplayCacheEntry*) maDisplayCache.Next(); 980*cdf0e10cSrcweir } 981*cdf0e10cSrcweir 982*cdf0e10cSrcweir if( bRet ) 983*cdf0e10cSrcweir pDisplayCacheEntry->Draw( pOut, rPt, rSz ); 984*cdf0e10cSrcweir 985*cdf0e10cSrcweir return bRet; 986*cdf0e10cSrcweir } 987*cdf0e10cSrcweir 988*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 989*cdf0e10cSrcweir 990*cdf0e10cSrcweir sal_Bool GraphicCache::ImplFreeDisplayCacheSpace( sal_uLong nSizeToFree ) 991*cdf0e10cSrcweir { 992*cdf0e10cSrcweir sal_uLong nFreedSize = 0UL; 993*cdf0e10cSrcweir 994*cdf0e10cSrcweir if( nSizeToFree ) 995*cdf0e10cSrcweir { 996*cdf0e10cSrcweir void* pObj = maDisplayCache.First(); 997*cdf0e10cSrcweir 998*cdf0e10cSrcweir if( nSizeToFree > mnUsedDisplaySize ) 999*cdf0e10cSrcweir nSizeToFree = mnUsedDisplaySize; 1000*cdf0e10cSrcweir 1001*cdf0e10cSrcweir while( pObj ) 1002*cdf0e10cSrcweir { 1003*cdf0e10cSrcweir GraphicDisplayCacheEntry* pCacheObj = (GraphicDisplayCacheEntry*) pObj; 1004*cdf0e10cSrcweir 1005*cdf0e10cSrcweir nFreedSize += pCacheObj->GetCacheSize(); 1006*cdf0e10cSrcweir mnUsedDisplaySize -= pCacheObj->GetCacheSize(); 1007*cdf0e10cSrcweir maDisplayCache.Remove( pObj ); 1008*cdf0e10cSrcweir delete pCacheObj; 1009*cdf0e10cSrcweir 1010*cdf0e10cSrcweir if( nFreedSize >= nSizeToFree ) 1011*cdf0e10cSrcweir break; 1012*cdf0e10cSrcweir else 1013*cdf0e10cSrcweir pObj = maDisplayCache.GetCurObject(); 1014*cdf0e10cSrcweir } 1015*cdf0e10cSrcweir } 1016*cdf0e10cSrcweir 1017*cdf0e10cSrcweir return( nFreedSize >= nSizeToFree ); 1018*cdf0e10cSrcweir } 1019*cdf0e10cSrcweir 1020*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1021*cdf0e10cSrcweir 1022*cdf0e10cSrcweir GraphicCacheEntry* GraphicCache::ImplGetCacheEntry( const GraphicObject& rObj ) 1023*cdf0e10cSrcweir { 1024*cdf0e10cSrcweir GraphicCacheEntry* pRet = NULL; 1025*cdf0e10cSrcweir 1026*cdf0e10cSrcweir for( void* pObj = maGraphicCache.First(); !pRet && pObj; pObj = maGraphicCache.Next() ) 1027*cdf0e10cSrcweir if( ( (GraphicCacheEntry*) pObj )->HasGraphicObjectReference( rObj ) ) 1028*cdf0e10cSrcweir pRet = (GraphicCacheEntry*) pObj; 1029*cdf0e10cSrcweir 1030*cdf0e10cSrcweir return pRet; 1031*cdf0e10cSrcweir } 1032*cdf0e10cSrcweir 1033*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1034*cdf0e10cSrcweir 1035*cdf0e10cSrcweir IMPL_LINK( GraphicCache, ReleaseTimeoutHdl, Timer*, pTimer ) 1036*cdf0e10cSrcweir { 1037*cdf0e10cSrcweir pTimer->Stop(); 1038*cdf0e10cSrcweir 1039*cdf0e10cSrcweir ::vos::TTimeValue aCurTime; 1040*cdf0e10cSrcweir GraphicDisplayCacheEntry* pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.First(); 1041*cdf0e10cSrcweir 1042*cdf0e10cSrcweir osl_getSystemTime( &aCurTime ); 1043*cdf0e10cSrcweir 1044*cdf0e10cSrcweir while( pDisplayEntry ) 1045*cdf0e10cSrcweir { 1046*cdf0e10cSrcweir const ::vos::TTimeValue& rReleaseTime = pDisplayEntry->GetReleaseTime(); 1047*cdf0e10cSrcweir 1048*cdf0e10cSrcweir if( !rReleaseTime.isEmpty() && ( rReleaseTime < aCurTime ) ) 1049*cdf0e10cSrcweir { 1050*cdf0e10cSrcweir mnUsedDisplaySize -= pDisplayEntry->GetCacheSize(); 1051*cdf0e10cSrcweir maDisplayCache.Remove( pDisplayEntry ); 1052*cdf0e10cSrcweir delete pDisplayEntry; 1053*cdf0e10cSrcweir pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.GetCurObject(); 1054*cdf0e10cSrcweir } 1055*cdf0e10cSrcweir else 1056*cdf0e10cSrcweir pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.Next(); 1057*cdf0e10cSrcweir } 1058*cdf0e10cSrcweir 1059*cdf0e10cSrcweir pTimer->Start(); 1060*cdf0e10cSrcweir 1061*cdf0e10cSrcweir return 0; 1062*cdf0e10cSrcweir } 1063