/**
Retrieves the VGImage from the cache that was created from the supplied CFbsBitmap.
The cache is first searched to find the item containing the VGImage that was created from the CFbsBitmap.
If no matching item is found, no VGImage is returned.
If the matching item is found, the touch count is checked to determine whether the
CFbsBitmap has been updated since the stored VGImage was created from it.  If it has, the matching item 
and VGImage is deleted from the cache and no VGImage is returned.
If the matching item is found and the CFbsitmap has not been updated sionce the VGImage was created,
the associated VGImage is returned.

@param aBitmap	The bitmap used to reference the item containing the VGImage.
@param aOrigin  The origin of the VGImage, relative to the top left corner of the source image.

@return	VG_INVALID_HANDLE if no VGImage exists for the supplied CFbsBitmap or if the stored VGImage is out of date.
		Otherwise the VGImage associated with the CFbsBitmap is returned.
 */
VGImage CVgImageCache::GetVgImageFromBitmap(const CFbsBitmap& aBitmap, const TPoint& aOrigin)
	{
	// search through cache to find the item with a matching bitmap ID
	CVgImageCacheItem** itemPtr = iCacheItemMap.Find(aBitmap.SerialNumber());
	++iNumMatchTries;
	if(itemPtr == NULL)
		{
		// searched all the way through cache and there is no matching image
		++iNumMatchMisses;
		return VG_INVALID_HANDLE;
		}
	CVgImageCacheItem* item = *itemPtr;
	// Check whether the VGImage held by the item is up-to-date
	// - check touch counts are equal.
	// - check origins used for creating VGImage are equal.
	if (aBitmap.TouchCount() != item->iTouchCount || aOrigin != item->iOrigin)
		{
		// VGImage in item needs updating, so remove and delete the entry
		// and return NULL to indicate that a new entry needs to be created.
		DeleteItem(item);
		return VG_INVALID_HANDLE;
		}
	// VGImage is up-to date.
	// If item is not already at front of list, move it there
	if(!iVgImageCache.IsFirst(item))
		{
		item->iLink.Deque();
		iVgImageCache.AddFirst(*item);
		}
	return item->iImage;
	}
/**
Adds a VGImage to the cache using the associated CFbsBitmap as a reference.

A new image cache item is created which stores the VGImage, the size of the image in pixels,
the serial number of the CFbsBitmap (which acts as a unique identifier) and the touch count
of the CFbsBitmap.  The touch count determines the number of times the underlying data of
the CFbsBitmap has changed.

The least-recently used items will be removed from the cache to create space for the new item, if needed.

@param aBitmap	The bitmap from which the VGImage was created.
@param aImage	The VGImage to store in the cache.
@param aOrigin	The origin used to create a tiled VGImage.

@return ETrue if the VGImage was successfully added to the cache, EFalse if not.
 */
TBool CVgImageCache::AddImage(const CFbsBitmap& aBitmap, VGImage& aImage, const TPoint& aOrigin)
	{
	// Calculate approximate size in bytes of image
	TDisplayMode vgCompatibleDisplayMode = ClosestVgCompatibleDisplayMode(aBitmap.DisplayMode());
	TSize imageSize = aBitmap.SizeInPixels();
	TInt dataStride = CFbsBitmap::ScanLineLength(imageSize.iWidth, vgCompatibleDisplayMode);
	TInt imageSizeInBytes = imageSize.iHeight * dataStride;
	// if size of image is too large to fit in cache 
	if(imageSizeInBytes > iMaxCacheSizeInBytes)
		{
		return EFalse;
		}
	
	CVgImageCacheItem* newItem = new CVgImageCacheItem;
	if (newItem == NULL)
		{
		return EFalse;
		}

	// check there is enough room in the cache
	// i.e. less than user-specified max memory allowed for cache
	// if not enough space, remove items from end of cache until enough space is available.
	while(iMaxCacheSizeInBytes < iCacheSizeInBytes + imageSizeInBytes)
		{
		DeleteItem(iVgImageCache.Last());
		}
	newItem->iSerialNumber = aBitmap.SerialNumber();
	newItem->iImage = aImage;
	newItem->iTouchCount = aBitmap.TouchCount();
	newItem->iOrigin = aOrigin;
	newItem->iImageSizeInBytes = imageSizeInBytes;
	TInt err = iCacheItemMap.Insert(newItem->iSerialNumber, newItem);
	if (err != KErrNone)
		{
		delete newItem;
		return EFalse;
		}
	iVgImageCache.AddFirst(*newItem);
	iCacheSizeInBytes += newItem->iImageSizeInBytes;
	return ETrue;
	}