// $Id: bitmapcache.cpp 1282 2006-06-09 09:46:49Z alex $ // BitmapCache.cpp: implementation of the CBitmapCache class. // ////////////////////////////////////////////////////////////////////// /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ #include "camtypes.h" //#include "bitmapcache.h" - in camtypes.h [AUTOMATICALLY REMOVED] /********************************************************************************************* Preference: Percentage of RAM devoted to cache Section: Cacheing Range: 0 - 100 (although greater values are acceptable) Purpose: How much RAM to devote to cacheing bitmaps SeeAlso: - **********************************************************************************************/ INT32 CBitmapCache::CacheRAMPercent = 25; // 25% of free RAM or 25% of half total RAM UINT32 AFXAPI HashKey(const CBitmapCacheKey& key) { return key.Hash(); } ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CBitmapCache::CBitmapCache() { m_lMaxDataSize = 0; m_lCurrentDataSize = 0; m_lMaxHashTableLoad = 0; } /******************************************************************************************** > UINT32 CBitmapCache::Initialise() Author: Phil_Martin (Xara Group Ltd) Created: 11/06/2004 Inputs: - Outputs: - Returns: - Purpose: - Errors: - SeeAlso: - ********************************************************************************************/ void CBitmapCache::Initialise() { // Declare the section that the magnetic options will live in BOOL Worked = Camelot.DeclareSection(TEXT("Cache"), 2); // declare the 2 prefs that there are if (Worked) Camelot.DeclarePref(TEXT("Cache"), TEXT("CacheRAMPercent"), &CacheRAMPercent, 0, 200); // Set up the default maximum cache size m_lMaxDataSize = CalcRecommendedMaximumDataSize(); TRACEUSER( "Phil", _T("Recommended Cache Size = %I64d\n"), m_lMaxDataSize); // Make the hash table big enough for however many average 80*80*32BPP pixel bitmaps // will fit into the configured maximum cache size. Make the hash table twice that size // to keep it sparse and thus running more efficiently and ensure that it's prime. m_lMaxHashTableLoad = (UINT32) m_lMaxDataSize/(80*80*4); // InitHashTable(PrimeAbove(m_lMaxHashTableLoad*2), TRUE); } /******************************************************************************************** > void CBitmapCache::DeInitialise() Author: Phil_Martin (Xara Group Ltd) Created: 18/06/2004 Inputs: - Outputs: - Returns: - Purpose: - Errors: - SeeAlso: - ********************************************************************************************/ void CBitmapCache::DeInitialise() { // Get rid of all cached bitmaps... /* POSITION pos = GetStartPosition(); while (pos) { CBitmapCacheKey key; CCachedBitmap bitmap; GetNextAssoc(pos, key, bitmap); RemoveKey(key); m_lCurrentDataSize -= bitmap.GetBitmapSize(); FreeDIB(bitmap.pbmpInfo, bitmap.pbmpBits); } */ CCacheKeyMap::iterator pos; for ( pos=m_map.begin() ; pos!=m_map.end() ; pos++ ) { CBitmapCacheKey key = pos->first; CCachedBitmap bitmap = pos->second; // m_map.erase(key); m_lCurrentDataSize -= bitmap.GetBitmapSize(); FreeDIB(bitmap.pbmpInfo, bitmap.pbmpBits); } m_map.clear(); } /******************************************************************************************** > void CBitmapCache::RemoveLowPriorityBitmaps(const INT32 maxpriority = CACHEPRIORITY_TEMPBITMAP_HIGH) Author: Phil_Martin (Xara Group Ltd) Created: 15/09/2004 Inputs: - Outputs: - Returns: - Purpose: - Errors: - SeeAlso: - ********************************************************************************************/ void CBitmapCache::RemoveLowPriorityBitmaps(const INT32 maxpriority) { // Get rid of all cached bitmaps... /* POSITION pos = GetStartPosition(); while (pos) { CBitmapCacheKey key; CCachedBitmap bitmap; GetNextAssoc(pos, key, bitmap); if (bitmap.nPriority <= maxpriority) { RemoveKey(key); m_lCurrentDataSize -= bitmap.GetBitmapSize(); FreeDIB(bitmap.pbmpInfo, bitmap.pbmpBits); } } */ CCacheKeyMap::iterator pos; for ( pos=m_map.begin() ; pos!=m_map.end() ; ) { CBitmapCacheKey key = pos->first; CCachedBitmap bitmap = pos->second; pos++; if (bitmap.nPriority <= maxpriority) { m_map.erase(key); m_lCurrentDataSize -= bitmap.GetBitmapSize(); FreeDIB(bitmap.pbmpInfo, bitmap.pbmpBits); } } } /******************************************************************************************** > UINT32 CBitmapCache::StoreBitmap() Author: Phil_Martin (Xara Group Ltd) Created: 11/06/2004 Inputs: key Bitmap Outputs: - Returns: - Purpose: Places a bitmap in the cache (making room if necessary by removing others) Errors: - SeeAlso: - ********************************************************************************************/ void CBitmapCache::StoreBitmap(const CBitmapCacheKey& key, const CCachedBitmap& bitmap) { /* #if _DEBUG if ((UINT32)m_nCount >= m_lMaxHashTableLoad) { TRACE( _T("BitmapCache hash table moving into inefficient zone!\n")); // ERROR3("BitmapCache hash table moving into inefficient zone\n"); } #endif */ // ENSURE(bitmap.rectCachedRect.IsValid(), "Invalid rect in CBitmapCache::StoreBitmap"); ENSURE(bitmap.pbmpInfo->bmiHeader.biCompression==BI_RGB || bitmap.pbmpInfo->bmiHeader.biCompression==0x80000001, "Invalid compression type in StoreBitmap"); // Remove the previous entry for this key, if there was one... CCachedBitmap cbmp = RemoveBitmap(key); // Watch out - doesn't release bitmap memory! if (bitmap.pbmpBits!=cbmp.pbmpBits && bitmap.pbmpInfo!=cbmp.pbmpInfo) // Only release the bitmap if we're not still using it cbmp.Release(); // But this does! UINT32 newitemsize = bitmap.GetBitmapSize(); UINT32 priority = bitmap.nPriority; while ((UINT64)(m_lCurrentDataSize+newitemsize) > m_lMaxDataSize) { CCachedBitmap cbmp = RemoveRandomBitmap(priority); // Remove random bitmap from cache if (cbmp.IsValid()) { ERROR3IF(bitmap.pbmpInfo==cbmp.pbmpInfo || bitmap.pbmpBits==cbmp.pbmpBits, "RemoveRandomBitmap found the same bitmap we're trying to Store! Something's gone horribly wrong!\n"); TRACE( _T("Removing bitmap to make room in cache!\n") ); cbmp.Release(); } else { // We have run out of room in the cache for this priority level TRACEUSER( "Phil", _T("Changing priority to make room in cache\n")); if (priority < CACHEPRIORITY_TEMPBITMAP_HIGH) { // We can try to remove higher-priority temp bitmaps... // (But not the very highest, permanent bitmaps...) priority = CACHEPRIORITY_TEMPBITMAP_HIGH; } else { // We have no more room to remove any temporary bitmaps // ARGH!!!! Now what? ERROR3("Bitmap Cache is full!"); break; // Just gobble up the user's memory! } } } m_lCurrentDataSize += newitemsize; // SetAt(key, (CCachedBitmap)bitmap); m_map.insert(pair(key,(CCachedBitmap)bitmap)); } /******************************************************************************************** > CCachedBitmap CBitmapCache::RemoveBitmap(const CBitmapCacheKey& key) Author: Phil_Martin (Xara Group Ltd) Created: 11/06/2004 Inputs: key Outputs: - Returns: Pointer to bitmap or NULL if not found Purpose: Removes either the specified bitmap from the cache or a selected bitmap according to the removal policy NOTE! It's up to the caller to delete the bitmap returned!!! Errors: - SeeAlso: - ********************************************************************************************/ CCachedBitmap CBitmapCache::RemoveBitmap(const CBitmapCacheKey& key) { CCachedBitmap bitmap; if (m_map.size()==0) return bitmap; if (key.IsValid()) { // Then we must remove the specified bitmap from the cache if (Lookup(key, bitmap)) { m_lCurrentDataSize -= bitmap.GetBitmapSize(); m_map.erase(key); // RemoveKey(key); } } return bitmap; } /******************************************************************************************** > CCachedBitmap CBitmapCache::RemoveRandomBitmap(const INT32 maxpriority = CACHEPRIORITY_TEMPBITMAP_HIGH) Author: Phil_Martin (Xara Group Ltd) Created: 11/06/2004 Inputs: key Outputs: - Returns: Pointer to bitmap or NULL if not found Purpose: Removes either the specified bitmap from the cache or a selected bitmap according to the removal policy NOTE! It's up to the caller to delete the bitmap returned!!! NOTE! This routine only uses the primary association array of the hash table The chains of values stored in the same slot are ignored at first (but obviously will be considered later on if their head item has been removed) Errors: - SeeAlso: - ********************************************************************************************/ CCachedBitmap CBitmapCache::RemoveRandomBitmap(const INT32 maxpriority) { // ENSURE(m_nHashTableSize!=0, "Zero-sized hash table found in RemoveRandomBitmap\n"); /* // Implement cache removal policy - remove a random bitmap // // Select a bitmap of our choosing for removal // The removal policy is random (ish) // Must be Order(0) complexity // CCachedBitmap bitmap; UINT32 startitem = rand() % m_nHashTableSize; UINT32 item = startitem; CAssoc* pAssoc = NULL; do { pAssoc = m_pHashTable[item]; item++; if (item==m_nHashTableSize) item = 0; // If we have found a value, check whether it's of equal or lesser "value" // than the one we're trying to store before throwing it out... if (pAssoc) { // bitmap = (CCachedBitmap)pAssoc->value; // Get value in a form we can use if (((CCachedBitmap)pAssoc->value).nPriority <= maxpriority) // Check whether value's priority is <= priority limit break; // If so, we'll get rid of this one else pAssoc = NULL; } } while (item != startitem); if (pAssoc) { // Remove the bitmap that we found from the cache... bitmap = (CCachedBitmap)pAssoc->value; m_lCurrentDataSize -= bitmap.GetBitmapSize(); RemoveKey(pAssoc->key); } return bitmap; */ // Implement cache removal policy - remove a random bitmap // // Select a bitmap of our choosing for removal // The removal policy is random (ish) // Must be Order(0) complexity // // Pick a random start point iterate // through the map from there... // srand((unsigned)time(NULL)); UINT32 item = rand()%(UINT32)m_map.size(); CCacheKeyMap::iterator pos; for ( pos=m_map.begin() ; item-- ; pos++ ) ; CCacheKeyMap::iterator spos = pos; do { if ( pos==m_map.end() ) pos = m_map.begin() ; CBitmapCacheKey key = pos->first; CCachedBitmap bitmap = pos->second; if ( bitmap.nPriority<=maxpriority ) // Check whether value's priority is <= priority limit { m_lCurrentDataSize -= bitmap.GetBitmapSize(); m_map.erase(key); return bitmap; } pos++; } while ( pos!=spos ); return m_map.begin()->second; } /******************************************************************************************** > BOOL CBitmapCache::RemoveAllOwnedBitmaps(const CBitmapCacheKey& key, const BOOL bOpaqueOnly, const INT32 maxpriority = CACHEPRIORITY_TEMPBITMAP_HIGH) Author: Phil_Martin (Xara Group Ltd) Created: 11/06/2004 Inputs: key Outputs: - Returns: TRUE if removed one or more bitmap associated with the owner of this key FALSE otherwise Purpose: Removes all bitmaps from the cache that have the owner specified in the key... Errors: - SeeAlso: - ********************************************************************************************/ BOOL CBitmapCache::RemoveAllOwnedBitmaps(const CBitmapCacheKey& key, const BOOL bOpaqueOnly, const INT32 maxpriority) { BOOL bRemovedSome = FALSE; CCachedBitmap abitmap; if (!key.IsValid()) return FALSE; if (m_map.size()==0) return FALSE; // Use the owner information stored in the keys to find all bitmap entries // in the hash table with the same owner... /* POSITION pos = GetStartPosition(); while (pos) { CBitmapCacheKey akey; GetNextAssoc(pos, akey, abitmap); if (akey.pOwner == key.pOwner && abitmap.nPriority <= maxpriority) { if (bOpaqueOnly==FALSE || !abitmap.IsTransparent()) { RemoveKey(akey); m_lCurrentDataSize -= abitmap.GetBitmapSize(); FreeDIB(abitmap.pbmpInfo, abitmap.pbmpBits); bRemovedSome = TRUE; } } } */ CCacheKeyMap::iterator pos; for ( pos=m_map.begin() ; pos!=m_map.end() ; ) { CBitmapCacheKey akey = pos->first; CCachedBitmap abitmap = pos->second; pos++; if (akey.pOwner == key.pOwner && abitmap.nPriority <= maxpriority) { if (bOpaqueOnly==FALSE || !abitmap.IsTransparent()) { m_map.erase(akey); m_lCurrentDataSize -= abitmap.GetBitmapSize(); FreeDIB(abitmap.pbmpInfo, abitmap.pbmpBits); bRemovedSome = TRUE; } } } return bRemovedSome; } /******************************************************************************************** > CCachedBitmap CBitmapCache::FindNextOwnedBitmap(POSITION& pos, CBitmapCacheKey& key, const BOOL bOpaqueOnly, const INT32 maxpriority = CACHEPRIORITY_TEMPBITMAP_HIGH) Author: Phil_Martin (Xara Group Ltd) Created: 11/06/2004 Inputs: key Outputs: - Returns: TRUE is removed one or more bitmap associated with the owner of this key FALSE otherwise Purpose: Removes all bitmaps from the cache that have the owner specified in the key... Errors: - SeeAlso: - ********************************************************************************************/ CCachedBitmap CBitmapCache::FindNextOwnedBitmap(CCacheKeyMap::iterator &pos, CBitmapCacheKey& key, const BOOL bOpaqueOnly, const INT32 maxpriority) { // BOOL bRemovedSome = FALSE; CCachedBitmap abitmap; if (!key.IsValid()) return abitmap; if (m_map.size()==0) return abitmap; // Use the owner information stored in the keys to find all bitmap entries // in the hash table with the same owner... /* while (pos) { CBitmapCacheKey akey; GetNextAssoc(pos, akey, abitmap); if (akey.pOwner == key.pOwner && abitmap.nPriority <= maxpriority) { if (bOpaqueOnly==FALSE || !abitmap.IsTransparent()) { key = akey; // Return the key we found return abitmap; // along with the bitmap we found } } } */ while (pos!=m_map.end()) { CBitmapCacheKey akey = pos->first; CCachedBitmap abitmap = pos->second; pos++; if (akey.pOwner == key.pOwner && abitmap.nPriority <= maxpriority) { if (bOpaqueOnly==FALSE || !abitmap.IsTransparent()) { key = akey; // Return the key we found return abitmap; // along with the bitmap we found } } } return CCachedBitmap(); } /******************************************************************************************** > void CBitmapCache::SetMaximumDataSize(UINT64 maxsize) Author: Phil_Martin (Xara Group Ltd) Created: 11/06/2004 Inputs: - Outputs: - Returns: - Purpose: - Errors: - SeeAlso: - ********************************************************************************************/ void CBitmapCache::SetMaximumDataSize(UINT64 maxsize) { m_lMaxDataSize = maxsize; } /******************************************************************************************** > UINT64 CBitmapCache::GetMaximumDataSize() Author: Phil_Martin (Xara Group Ltd) Created: 11/06/2004 Inputs: - Outputs: - Returns: - Purpose: - Errors: - SeeAlso: - ********************************************************************************************/ UINT64 CBitmapCache::GetMaximumDataSize() { return m_lMaxDataSize; } /******************************************************************************************** > UINT32 CBitmapCache::GetCurrentDataSize() Author: Phil_Martin (Xara Group Ltd) Created: 11/06/2004 Inputs: - Outputs: - Returns: - Purpose: - Errors: - SeeAlso: - ********************************************************************************************/ UINT32 CBitmapCache::GetCurrentDataSize() { return m_lCurrentDataSize; } /******************************************************************************************** > UINT64 CBitmapCache::CalcRecommendedMaximumDataSize() Author: Phil_Martin (Xara Group Ltd) Created: 11/06/2004 Inputs: - Outputs: - Returns: Recommended max cache size in current memory environment Purpose: Work out how much RAM this machine can afford to devote to the bitmap cache. Never use more than 50% of physical RAM Never use more RAM than is free Use CachRAMPercent preference to decide percentage of free ram to grab Errors: - SeeAlso: - ********************************************************************************************/ UINT64 CBitmapCache::CalcRecommendedMaximumDataSize() { UINT64 ullPhysRAM = 0; UINT32 LoadPercentage = 0; GetMemoryStatus(&ullPhysRAM, &LoadPercentage); // Don't use more than 50% of physical ram in the Bitmap Cache if (LoadPercentage<50) LoadPercentage = 50; // If <50% in use pretend that 50% is used (never use more than 50%) return ullPhysRAM * (100-LoadPercentage) * CacheRAMPercent / 10000; } /******************************************************************************************** > UINT32 CBitmapCache::PrimeAbove(UINT32 number) Author: Phil_Martin (Xara Group Ltd) (from the Internet) Created: 11/06/2004 Inputs: number to start from Outputs: - Returns: prime number above the starting value Purpose: Computes the first prime number equal to or greater than a specified number. Errors: - SeeAlso: - ********************************************************************************************/ /* UINT32 CBitmapCache::PrimeAbove(UINT32 number) { if (number < 4) return (number) ; // 0, 1, 2, and 3 are prime. if ((number % 2) == 0) number++ ; // Prime must be odd. for ( ; ; ) { // Check for possible divisors. The "divisor > dividend" test is similar // to checking 2 .. sqrt(N) as possible divisors, but avoids the need for // linking to the math library. for ( UINT32 divisor = 3 ; ; divisor+=2 ) { if ((number % divisor) == 0) break ; // Not prime - divisor found. if (divisor > (number / divisor)) return number ; // Prime - no divisors found. } number += 2 ; // Check next odd number. } } */ #ifdef _DEBUG /******************************************************************************************** > void CBitmapCache::DebugDump() Author: Phil_Martin (Xara Group Ltd) Created: 02/11/2004 Inputs: - Outputs: - Returns: - Purpose: - Errors: - SeeAlso: - ********************************************************************************************/ void CBitmapCache::DebugDump() { TRACE( _T("Contents of Bitmap Cache:\n")); /* POSITION pos = GetStartPosition(); while (pos) { CBitmapCacheKey key; CCachedBitmap bitmap; GetNextAssoc(pos, key, bitmap); TRACE( _T("Bitmap: %x (%d*%d, %d) Priority: %d Owner: %x %d %s\n"), bitmap.pbmpInfo, bitmap.pbmpInfo->bmiHeader.biWidth, bitmap.pbmpInfo->bmiHeader.biHeight, bitmap.GetBitmapSize(), bitmap.nPriority, key.pOwner, key.nOption, ((CCObject*)key.pOwner)->GetRuntimeClass()->m_lpszClassName ); } */ CCacheKeyMap::iterator pos; for ( pos=m_map.begin() ; pos!=m_map.end() ; pos++ ) { CBitmapCacheKey key = pos->first; CCachedBitmap bitmap = pos->second; TRACE( _T("Bitmap: %x (%d*%d, %d) Priority: %d Owner: %x %d %s\n"), bitmap.pbmpInfo, bitmap.pbmpInfo->bmiHeader.biWidth, bitmap.pbmpInfo->bmiHeader.biHeight, bitmap.GetBitmapSize(), bitmap.nPriority, key.pOwner, key.nOption, ((CCObject*)key.pOwner)->GetRuntimeClass()->m_lpszClassName ); } } #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CCachedBitmap::CCachedBitmap() { pbmpInfo = NULL; pbmpBits = NULL; // rectCachedRect = DocRect(0,0,0,0); coord0 = DocCoord(0,0); coord1 = DocCoord(0,0); coord2 = DocCoord(0,0); nPriority = 0; } CCachedBitmap::CCachedBitmap(LPBITMAPINFO pNewInfo, LPBYTE pNewBits, INT32 nNewPriority) { pbmpInfo = pNewInfo; pbmpBits = pNewBits; // rectCachedRect = DocRect(0,0,0,0); coord0 = DocCoord(0,0); coord1 = DocCoord(0,0); coord2 = DocCoord(0,0); nPriority = nNewPriority; } CCachedBitmap::CCachedBitmap(const CCachedBitmap& cbmp) { pbmpInfo = cbmp.pbmpInfo; pbmpBits = cbmp.pbmpBits; // rectCachedRect = cbmp.rectCachedRect; coord0 = cbmp.coord0; coord1 = cbmp.coord1; coord2 = cbmp.coord2; nPriority = cbmp.nPriority; } CCachedBitmap::CCachedBitmap(UINT32 Width, UINT32 Height, UINT32 Depth, DocRect rect, INT32 nNewPriority) { ENSURE(rect.IsValid(), "Attempt to create a cached bitmap with an invalid rectangle!"); pbmpInfo = AllocDIB(Width, Height, Depth, &pbmpBits); // rectCachedRect = rect; coord0 = DocCoord(rect.lo.x, rect.lo.y); coord1 = DocCoord(rect.hi.x, rect.lo.y); coord2 = DocCoord(rect.lo.x, rect.hi.y); nPriority = nNewPriority; } CCachedBitmap::~CCachedBitmap() { // if (pbmpInfo && pbmpBits) DON'T DO THIS!!! // DIBUtil::FreeDIB(pbmpInfo, pbmpBits); pbmpInfo = NULL; pbmpBits = NULL; } /******************************************************************************************** > void CCachedBitmap::Release() Author: Phil_Martin (Xara Group Ltd) Created: 21/06/2004 Inputs: - Outputs: - Returns: TRUE if this key is valid FALSE otherwise Purpose: Test whether this object has been constructed correctly Errors: - SeeAlso: - ********************************************************************************************/ void CCachedBitmap::Release() { FreeDIB(pbmpInfo, pbmpBits); } /******************************************************************************************** > CCachedBitmap CCachedBitmap::Copy() Author: Phil_Martin (Xara Group Ltd) Created: 21/10/2004 Inputs: - Outputs: - Returns: - Purpose: Copy this cached bitmap (actually copy the bitmap, not just the bitmap pointers) Errors: - SeeAlso: - ********************************************************************************************/ CCachedBitmap CCachedBitmap::Copy() { CCachedBitmap copybmp(*this); INT32 lHRes = pbmpInfo->bmiHeader.biXPelsPerMeter; INT32 lVRes = pbmpInfo->bmiHeader.biYPelsPerMeter; DIBUtil::CopyBitmap(pbmpInfo, pbmpBits, ©bmp.pbmpInfo, ©bmp.pbmpBits); if (copybmp.pbmpInfo) { copybmp.pbmpInfo->bmiHeader.biXPelsPerMeter = lHRes; copybmp.pbmpInfo->bmiHeader.biYPelsPerMeter = lVRes; } return copybmp; } /******************************************************************************************** > CCachedBitmap::operator==() Author: Phil_Martin (Xara Group Ltd) Created: 10/06/2004 Inputs: - Outputs: - Returns: TRUE if this key is exactly the same the the specified key Purpose: Test whether this object has been constructed correctly Required by CTypedPtrMap Errors: - SeeAlso: - ********************************************************************************************/ bool CCachedBitmap::operator==(const CCachedBitmap& cbmp) const { return (pbmpInfo == cbmp.pbmpInfo && pbmpBits == cbmp.pbmpBits && // rectCachedRect == cbmp.rectCachedRect && coord0 == cbmp.coord0 && coord1 == cbmp.coord1 && coord2 == cbmp.coord2 && nPriority == cbmp.nPriority ); } /******************************************************************************************** > CCachedBitmap::operator=() Author: Phil_Martin (Xara Group Ltd) Created: 10/06/2004 Inputs: - Outputs: - Returns: TRUE if this key is exactly the same the the specified key Purpose: Test whether this object has been constructed correctly Required by CTypedPtrMap Errors: - SeeAlso: - ********************************************************************************************/ const CCachedBitmap& CCachedBitmap::operator=(const CCachedBitmap& cbmp) { pbmpInfo = cbmp.pbmpInfo; pbmpBits = cbmp.pbmpBits; // rectCachedRect = cbmp.rectCachedRect; coord0 = cbmp.coord0; coord1 = cbmp.coord1; coord2 = cbmp.coord2; nPriority = cbmp.nPriority; return cbmp; } /******************************************************************************************** > BOOL CCachedBitmap::IsValid() const Author: Phil_Martin (Xara Group Ltd) Created: 10/06/2004 Inputs: - Outputs: - Returns: TRUE if this key is valid FALSE otherwise Purpose: Test whether this object has been constructed correctly Errors: - SeeAlso: - ********************************************************************************************/ BOOL CCachedBitmap::IsValid() const { return (pbmpInfo!=NULL && pbmpBits!=NULL); } /******************************************************************************************** > UINT32 CCachedBitmap::GetBitmapSize() const Author: Phil_Martin (Xara Group Ltd) Created: 18/06/2004 Inputs: - Outputs: - Returns: Size of bitmap in bytes Purpose: Find the size of this bitmap Errors: - SeeAlso: - ********************************************************************************************/ UINT32 CCachedBitmap::GetBitmapSize() const { return (pbmpInfo->bmiHeader.biSizeImage); } /******************************************************************************************** > BOOL CCachedBitmap::IsTransparent() const Author: Phil_Martin (Xara Group Ltd) Created: 29/06/2004 Inputs: - Outputs: - Returns: TRUE if cached bitmap is 32BPP (transparent) Purpose: Find out whether this bitmap has a transparency channel or not Errors: - SeeAlso: - ********************************************************************************************/ BOOL CCachedBitmap::IsTransparent() const { return (pbmpInfo->bmiHeader.biCompression!=BI_RGB); } /******************************************************************************************** > UINT32 CCachedBitmap::GetBPP() const Author: Phil_Martin (Xara Group Ltd) Created: 30/06/2004 Inputs: - Outputs: - Returns: Bits Per Pixel Purpose: Get bit depth of cached bitmap Errors: - SeeAlso: - ********************************************************************************************/ UINT32 CCachedBitmap::GetBPP() const { return (pbmpInfo->bmiHeader.biBitCount); } /******************************************************************************************** > void CCachedBitmap::Transform(TransformBase& Trans) Author: Phil_Martin (Xara Group Ltd) Created: 21/20/2004 Inputs: Transform to apply to the stored coords of this bitmap Outputs: - Returns: - Purpose: Transform the cached bitmap so that it can be distorted/repositioned Errors: - SeeAlso: - ********************************************************************************************/ void CCachedBitmap::Transform(TransformBase& Trans) { // Trans.Transform((DocCoord*)&rectCachedRect, 2); Trans.Transform(&coord0, 3); } /******************************************************************************************** > DocRect CCachedBitmap::GetCachedRect() Author: Phil_Martin (Xara Group Ltd) Created: 21/20/2004 Inputs: - Outputs: - Returns: DocRect - upright rectangle containing all points in stored parallelogram Purpose: Transform the cached bitmap so that it can be distorted/repositioned Errors: - SeeAlso: - ********************************************************************************************/ DocRect CCachedBitmap::GetCachedRect() { DocRect r(coord0, coord0); r.IncludePoint(coord1); r.IncludePoint(coord2); r.IncludePoint(DocCoord(coord2.x+coord1.x-coord0.x, coord2.y+coord1.y-coord0.y)); return r; } /******************************************************************************************** > void CCachedBitmap::SetCachedRect(DocRect r) Author: Phil_Martin (Xara Group Ltd) Created: 21/20/2004 Inputs: - Outputs: - Returns: DocRect - upright rectangle containing all points in stored parallelogram Purpose: Transform the cached bitmap so that it can be distorted/repositioned Errors: - SeeAlso: - ********************************************************************************************/ void CCachedBitmap::SetCachedRect(DocRect r) { coord0 = r.lo; coord1 = DocCoord(r.hi.x, r.lo.y); coord2 = DocCoord(r.lo.x, r.hi.y); } /******************************************************************************************** > void CCachedBitmap::SetCachedParallelogram(DocCoord* pCoords, UINT32 numCoords) Author: Phil_Martin (Xara Group Ltd) Created: 28/07/2005 Inputs: - Outputs: - Returns: - Purpose: Store parallelogram details Errors: - SeeAlso: - ********************************************************************************************/ void CCachedBitmap::SetCachedParallelogram(DocCoord* pCoords, UINT32 numCoords) { coord0 = pCoords[0]; coord1 = pCoords[1]; coord2 = pCoords[2]; }