os/graphics/graphicsdeviceinterface/directgdiadaptation/hwsrc/glyphimagecache.cpp
Update contrib.
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "glyphimagecache.h"
17 #include "glyphlutab.h"
21 //the image of the following size will be pre-allocated for low memory conditions.
22 const TSize KMaxSizeImageOOM(72, 64);
23 #ifdef DRAWGLYPH_MULTIPLY_MODE
24 // Matrix used for converting glyphs with a background colour of black and a character colour
25 // of white to have a background colour that is fully transparent black and a character colour
27 const VGfloat KColorMatrix[20] = { 0, 0, 0, 1, // sets alpha of destination to R value of source
31 1, 1, 1, 0}; // sets RGB of destination to 1
32 #endif // DRAWGLYPH_MULTIPLY_MODE
34 //--------------class CFontGlyphTree --------------------
36 Creates a new instance of the class. Will not be shared across different threads
38 @param aFontId The unique font identifier.
39 @param aGlyphType The type for the format of a glyph bitmap.
40 @return The pointer to the CFontGlyphTree class instance.
42 CFontGlyphTree* CFontGlyphTree::NewL(TUint32 aFontId, TGlyphBitmapType aGlyphType)
44 CFontGlyphTree* self = new (ELeave) CFontGlyphTree(aFontId, aGlyphType);
45 CleanupStack::PushL(self);
47 CleanupStack::Pop(self);
52 Constructor for the image font glyph tree
54 @param aFontId The unique font identifier.
55 @param aGlyphType The type for the format of a glyph bitmap.
57 CFontGlyphTree::CFontGlyphTree(TUint32 aFontId, TGlyphBitmapType aGlyphType) :
58 iKey(_FOFF(TGlyphEntry,iGlyphCode),ECmpTUint32),
60 iGlyphType(aGlyphType)
65 Destructor for the image font glyph tree.
67 Destroys the VGImages, page pool and binary tree.
69 CFontGlyphTree::~CFontGlyphTree()
71 TRAP_IGNORE(DestroyAllVGImagesL());
77 Constructs memory page pool and binary tree. Glyph code will be used as a key.
79 void CFontGlyphTree::ConstructL()
81 iPagePool = CMemPagePool::NewL();
85 case EFourColourBlendGlyphBitmap:
86 iGlyphTree = new (ELeave) TBtreeFix<TGlyphEntryCompound, TChar> (EBtreeFast);
87 ((TBtreeFix<TGlyphEntryCompound, TChar> *)iGlyphTree) -> Connect(iPagePool, &iKey);
89 case EMonochromeGlyphBitmap:
90 case EAntiAliasedGlyphBitmap:
91 iGlyphTree = new (ELeave) TBtreeFix<TGlyphEntry, TChar> (EBtreeFast);
92 ((TBtreeFix<TGlyphEntry, TChar> *)iGlyphTree) -> Connect(iPagePool, &iKey);
95 User::Leave(KErrNotSupported);
101 Searches for the image entry in the binary tree. If fails, it will create a new entry.
103 @param aGlyphCode General Unicode character value.
104 @param aGlyphImage Glyph image bitmap data. The data structure depends on glyph type.
105 @param aGlyphImageSize Size of the glyph image.
106 @param aEntry Binary tree entry, which comprises OpenVG image(s).
107 @param aDataForeground Pre-allocated buffer, which will be used for setting text VG image.
109 @see TGlyphEntryCompound
112 @pre Rendering engine has been constructed.
113 @post Requested OpenVG images are ready for rendering.
114 @return KErrNone if successful;
115 KErrNotSupported if font type is not supported,
116 otherwise one of the other system-wide error codes.
119 void CFontGlyphTree::GlyphImageEntryL(TChar aGlyphCode, const TUint8* aGlyphImage, const TSize& aGlyphImageSize, K& aEntry, TUint8* aDataForeground)
122 TBool found = EFalse;
123 found = ((TBtreeFix<K, TChar> *)iGlyphTree) -> FindL(pos, aGlyphCode);
127 ((TBtreeFix<K, TChar> *)iGlyphTree) -> ExtractAtL(pos, aEntry);
131 aEntry.iGlyphCode = aGlyphCode;
132 aEntry.iForeground = VG_INVALID_HANDLE;
133 TInt glyphSizeInByte = 0;
137 case EFourColourBlendGlyphBitmap:
139 ((TGlyphEntryCompound&) aEntry).iOutline = VG_INVALID_HANDLE;
140 ((TGlyphEntryCompound&) aEntry).iShadow = VG_INVALID_HANDLE;
141 CreateVGImageL(aGlyphImage, aGlyphImageSize, aEntry.iForeground, ((TGlyphEntryCompound&) aEntry).iOutline, ((TGlyphEntryCompound&) aEntry).iShadow, NULL, NULL, NULL);
142 glyphSizeInByte = aGlyphImageSize.iWidth * aGlyphImageSize.iHeight;
143 glyphSizeInByte *= 3; //foreground, shadow, outline
146 case EMonochromeGlyphBitmap:
147 CreateVGImageL(aGlyphImage, aGlyphImageSize, EGray2, aEntry.iForeground, aDataForeground);
148 glyphSizeInByte = (((aGlyphImageSize.iWidth + 31) / 32) << 2) * aGlyphImageSize.iHeight;
150 case EAntiAliasedGlyphBitmap:
151 CreateVGImageL(aGlyphImage, aGlyphImageSize, EGray256, aEntry.iForeground, NULL);
152 glyphSizeInByte = aGlyphImageSize.iWidth * aGlyphImageSize.iHeight;
155 User::Leave(KErrNotSupported);
158 ((TBtreeFix<K, TChar> *)iGlyphTree) -> InsertL(pos, aEntry);
159 iCacheSize += glyphSizeInByte;
164 Overridden function, which creates Open VG images for foreground, background, shadow and outline components of the font.
166 @param aGlyphImage Source bitmap data in 256 grey format. Each pixel value is an index to a constant lookup table.
167 Four entries of this table represent % of Outline, Shadow, Fill and Background colour to be used to get the final colour to be displayed on screen.
168 @param aGlyphImageSize Size of the glyph bitmap image.
169 @param aForeground Foreground component of the glyph.
170 @param aOutline Outline component of the glyph.
171 @param aShadow Shadow component of the glyph.
172 @param aPreAllocForeground Pre-allocated buffer which will be used for setting text foreground VG image
173 @param aPreAllocOutline Pre-allocated buffer which will be used for setting text outline VG image
174 @param aPreAllocShadow Pre-allocated buffer which will be used for setting text shadow VG image
176 @post Requested OpenVG images are ready for rendering.
178 void CFontGlyphTree::CreateVGImageL(const TUint8* aGlyphImage, const TSize& aGlyphImageSize, VGImage& aForeground, VGImage& aOutline, VGImage& aShadow, TUint8* aPreAllocForeground, TUint8* aPreAllocOutline, TUint8* aPreAllocShadow)
180 TInt dataStride = aGlyphImageSize.iWidth;
181 TInt targetByteCount = dataStride * aGlyphImageSize.iHeight;
182 // Allocate memory and transform source into target format.
184 TAny* foregroundBuffer = NULL;
185 TAny* outlineBuffer = NULL;
186 TAny* shadowBuffer = NULL;
187 TBool destroyTempBuffer = EFalse;
189 if(aPreAllocForeground && aPreAllocOutline && aPreAllocShadow &&
190 (aGlyphImageSize.iWidth <= KMaxSizeImageOOM.iWidth) &&
191 (aGlyphImageSize.iHeight <= KMaxSizeImageOOM.iHeight))
193 foregroundBuffer = aPreAllocForeground;
194 outlineBuffer = aPreAllocOutline;
195 shadowBuffer = aPreAllocShadow;
199 foregroundBuffer = User::AllocL(targetByteCount);
200 CleanupStack::PushL(foregroundBuffer);
201 outlineBuffer = User::AllocL(targetByteCount);
202 CleanupStack::PushL(outlineBuffer);
203 shadowBuffer = User::AllocL(targetByteCount);
204 CleanupStack::PushL(shadowBuffer);
205 destroyTempBuffer = ETrue;
208 TUint8* foregroundByte = static_cast <TUint8*> (foregroundBuffer);
209 TUint8* outlineByte = static_cast <TUint8*> (outlineBuffer);
210 TUint8* shadowByte = static_cast <TUint8*> (shadowBuffer);
212 const TUint8* endByte = (TUint8*)aGlyphImage + targetByteCount;
213 TUint8* curSrcGlyphImage = const_cast <TUint8*> (aGlyphImage);
215 while (curSrcGlyphImage < endByte)
217 *outlineByte++ = FourColorBlendLookup[*curSrcGlyphImage] [KOutlineColorIndex];
218 *shadowByte++ = FourColorBlendLookup[*curSrcGlyphImage] [KShadowColorIndex];
219 *foregroundByte++ = FourColorBlendLookup[*curSrcGlyphImage] [KFillColorIndex];
223 const VGImageFormat imageFormat = VG_sL_8;
224 if(aForeground == VG_INVALID_HANDLE)
226 aForeground = vgCreateImage(imageFormat,
227 aGlyphImageSize.iWidth,
228 aGlyphImageSize.iHeight,
229 VG_IMAGE_QUALITY_NONANTIALIASED);
230 if(aForeground == VG_INVALID_HANDLE)
232 User::Leave(KErrNoMemory);
234 aOutline = vgCreateImage(imageFormat,
235 aGlyphImageSize.iWidth,
236 aGlyphImageSize.iHeight,
237 VG_IMAGE_QUALITY_NONANTIALIASED);
238 if(aOutline == VG_INVALID_HANDLE)
240 DestroyVGImage(&aForeground);
241 User::Leave(KErrNoMemory);
244 aShadow = vgCreateImage(imageFormat,
245 aGlyphImageSize.iWidth,
246 aGlyphImageSize.iHeight,
247 VG_IMAGE_QUALITY_NONANTIALIASED);
248 if(aShadow == VG_INVALID_HANDLE)
250 DestroyVGImage(&aForeground, &aOutline);
251 User::Leave(KErrNoMemory);
256 aForeground, foregroundBuffer,
257 dataStride, imageFormat,
258 0, 0,aGlyphImageSize.iWidth, aGlyphImageSize.iHeight);
260 #ifdef DRAWGLYPH_MULTIPLY_MODE
261 VGImage image = vgCreateImage(VG_sARGB_8888_PRE, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED);
262 vgColorMatrix(image, aForeground, KColorMatrix);
263 vgDestroyImage(aForeground);
265 #endif // DRAWGLYPH_MULTIPLY_MODE
268 aOutline, outlineBuffer,
269 dataStride, imageFormat,
270 0, 0, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight);
272 #ifdef DRAWGLYPH_MULTIPLY_MODE
273 image = vgCreateImage(VG_sARGB_8888_PRE, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED);
274 vgColorMatrix(image, aOutline, KColorMatrix);
275 vgDestroyImage(aOutline);
277 #endif // DRAWGLYPH_MULTIPLY_MODE
280 aShadow, shadowBuffer,
281 dataStride, imageFormat,
282 0, 0, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight);
284 #ifdef DRAWGLYPH_MULTIPLY_MODE
285 image = vgCreateImage(VG_sARGB_8888_PRE, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED);
286 vgColorMatrix(image, aShadow, KColorMatrix);
287 vgDestroyImage(aShadow);
289 #endif // DRAWGLYPH_MULTIPLY_MODE
291 if(destroyTempBuffer)
293 CleanupStack::PopAndDestroy(3, foregroundBuffer);
298 Overridden function, which creates OpenVG images for monochrome and anti-aliased fonts.
300 @param aGlyphImage Data source bitmap in 256 or 2 Grey format.
301 @param aGlyphImageSize Glyph image data size.
302 @param aDisplayMode Image display mode.
303 @param aForeground Foreground component of the glyph.
304 @param aPreAllocForeground Pre-allocated buffer which will be used for setting foreground VG image
306 @post Requested OpenVG image is ready for rendering.
308 @panic Panic if bitmap display mode is not 256 grey or 2 grey.
310 void CFontGlyphTree::CreateVGImageL(const TUint8* aGlyphImage, const TSize& aGlyphImageSize, TDisplayMode aDisplayMode, VGImage& aForeground, TUint8* aPreAllocForeground)
312 GRAPHICS_ASSERT_DEBUG((aDisplayMode == EGray256) || (aDisplayMode == EGray2), EDirectGdiPanicInvalidDisplayMode);
313 GRAPHICS_ASSERT_DEBUG(aGlyphImage, EDirectGdiPanicInvalidParameter);
315 VGImageFormat imageFormat = VG_IMAGE_FORMAT_INVALID;
316 TInt vgCompatibleSourceStride = 0x00;
317 TUint32 binaryDataArray[32];
318 TUint8* binaryData = NULL;
319 TUint8* tempBuffer = NULL;
321 if(aDisplayMode == EGray256)
323 imageFormat = VG_sL_8;
324 vgCompatibleSourceStride = aGlyphImageSize.iWidth;
325 binaryData = const_cast <TUint8*> (aGlyphImage);
329 imageFormat = VG_BW_1;
330 vgCompatibleSourceStride = ((aGlyphImageSize.iWidth + 31) / 32) << 2;
331 if (aGlyphImageSize.iWidth > 30 || aGlyphImageSize.iHeight > 32)
333 binaryData = aPreAllocForeground;
336 tempBuffer = (TUint8*) User::AllocL(vgCompatibleSourceStride * aGlyphImageSize.iHeight);
337 CleanupStack::PushL(tempBuffer);
338 binaryData = tempBuffer;
340 DecodeBinaryDataExLarge(aGlyphImageSize, aGlyphImage, vgCompatibleSourceStride, reinterpret_cast <TUint32*> (binaryData));
344 DecodeBinaryData(aGlyphImageSize, aGlyphImage, binaryDataArray);
345 binaryData = reinterpret_cast <TUint8*> (binaryDataArray);
349 if(aForeground == VG_INVALID_HANDLE)
351 aForeground = vgCreateImage(imageFormat,
352 aGlyphImageSize.iWidth,
353 aGlyphImageSize.iHeight,
354 VG_IMAGE_QUALITY_NONANTIALIASED);
357 if (aForeground != VG_INVALID_HANDLE)
359 // Copy from the source image to our new VGImage
360 vgImageSubData(aForeground, binaryData, vgCompatibleSourceStride, imageFormat,
361 0, 0, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight);
363 #ifdef DRAWGLYPH_MULTIPLY_MODE
364 VGImage image = vgCreateImage(VG_sARGB_8888_PRE, aGlyphImageSize.iWidth, aGlyphImageSize.iHeight, VG_IMAGE_QUALITY_NONANTIALIASED);
365 vgColorMatrix(image, aForeground, KColorMatrix);
366 vgDestroyImage(aForeground);
374 CleanupStack::PopAndDestroy(tempBuffer);
376 User::Leave(KErrNoMemory);
381 CleanupStack::PopAndDestroy(tempBuffer);
386 Decodes binary data for monochrome bitmap.
388 @param aDataSize Image size.
389 @param aData Pointer to a source buffer.
390 @param aBinaryData Pointer to a destination buffer.
392 void CFontGlyphTree::DecodeBinaryData(const TSize& aDataSize,
394 TUint32* aBinaryData)
396 //Divert if the character is larger than expected; the criterion
397 //for choosing this function is only a heuristic, because it's perfectly legal for
398 //a character's bitmap to be wider than its escapement.
400 //Use a dummy value (0) for semi-ascent because this character is not italic and so semi-ascent
401 //is irrelevant; it's used for pseudo-italic slanting.
403 TInt dataheight = aDataSize.iHeight;
404 TInt datalength = aDataSize.iWidth;
407 TInt16 repeatcount=0;
408 TUint32* binarydataptr=aBinaryData;
409 TUint32* binarydataptrlimit;
410 for(TInt charline=0;charline<dataheight;charline+=repeatcount) // for lines in the character...
412 repeatcount=Load16(aData+(bitindex>>3));
413 repeatcount>>=bitindex&7;
414 TInt multilineflag=repeatcount&1;
418 binarydataptrlimit=aBinaryData+charline+repeatcount;
421 while(binarydataptr<binarydataptrlimit)
423 TInt chardataoffsetptr=TInt(aData)+(bitindex>>3);
424 TUint32* chardataword=(TUint32*)(chardataoffsetptr&~3);
425 TInt bitshift=bitindex&7;
426 bitshift+=(chardataoffsetptr&3)<<3;
427 *binarydataptr=(*chardataword++)>>bitshift;
428 if(bitshift) *binarydataptr|=(*chardataword<<(32-bitshift));
429 bitindex+=datalength;
435 TInt chardataoffsetptr=TInt(aData)+(bitindex>>3);
436 TUint32* chardataword=(TUint32*)(chardataoffsetptr&~3);
437 TInt bitshift=bitindex&7;
438 bitshift+=(chardataoffsetptr&3)<<3;
439 TUint32 data=(*chardataword++)>>bitshift;
440 if(bitshift) data|=(*chardataword<<(32-bitshift));
441 while(binarydataptr<binarydataptrlimit)
442 *binarydataptr++=data;
443 bitindex+=datalength;
449 Decodes binary data for extra large monochrome bitmap.
451 @param aDataSize Image size.
452 @param aData Pointer to a source buffer.
453 @param aStride Image data stride.
454 @param aBinaryData Pointer to a destination buffer.
456 void CFontGlyphTree::DecodeBinaryDataExLarge(const TSize& aDataSize, const TUint8* aData, TInt aStride,
457 TUint32* aBinaryData)
459 const TInt datalength = aDataSize.iWidth;
460 const TInt dataheight = aDataSize.iHeight;
462 TInt16 repeatcount=0;
463 TUint32* slbuffer=aBinaryData;
464 const TInt slwords=aStride;
466 for(TInt charline=0;charline<dataheight;charline+=repeatcount) // for lines in the character...
468 repeatcount=Load16(aData+(bitindex>>3));
469 repeatcount>>=bitindex&7;
470 const TInt multilineflag=repeatcount&1;
476 for(TInt currentline=0;currentline<repeatcount;currentline++)
478 CopyCharLine(slbuffer,slwords,aData+(bitindex>>3),bitindex&7,datalength, 1);
479 bitindex+=datalength;
484 CopyCharLine(slbuffer,slwords,aData+(bitindex>>3),bitindex&7,datalength, repeatcount);
485 bitindex+=datalength;
491 Copies image data line(s) to a destination.
493 @param aBinaryDataPtr pointer to a destination buffer.
494 @param aBufferWords Stride of the image.
495 @param aData Pointer to a source buffer.
496 @param aBitShift Number of bits, binary data will be shifted.
497 @param aCharWidth Width of the image.
498 @param aRepeatCount Number of lines to copy.
500 @panic DGDIAdapter 1018, if a null binary data pointer is passed in.
502 void CFontGlyphTree::CopyCharLine(TUint32*& aBinaryDataPtr,TInt aBufferWords,const TUint8* aData,TInt aBitShift,TInt aCharWidth, TInt16 aRepeatCount)
504 GRAPHICS_ASSERT_DEBUG(aBinaryDataPtr, EDirectGdiPanicInvalidPointer);//this shouldn't happen, as we always allocate memory prior to call this function
506 TInt wordstocopy=(aCharWidth+31)>>5;
507 if(wordstocopy>aBufferWords) wordstocopy=aBufferWords;
508 TUint32* ptrlimit=aBinaryDataPtr+wordstocopy;
509 TUint32* dataword=(TUint32*)(TInt(aData)&~3);
510 aBitShift+=(TInt(aData)-TInt(dataword))<<3;
512 TUint32* startBinaryDataPtr = aBinaryDataPtr;
513 while(aBinaryDataPtr<ptrlimit)
515 *aBinaryDataPtr=*dataword++;
516 *aBinaryDataPtr>>=aBitShift;
517 if(aBitShift) *aBinaryDataPtr|=(*dataword<<(32-aBitShift));
521 TUint32* curStartBinaryDataPtr = aBinaryDataPtr;
522 TInt byteToCopy = wordstocopy << 2;
523 while(aRepeatCount > 1)
525 Mem::Copy(curStartBinaryDataPtr, startBinaryDataPtr, byteToCopy);
526 curStartBinaryDataPtr += wordstocopy;
530 aBinaryDataPtr = curStartBinaryDataPtr;
534 Destroys OpenVG images and set variables to NULL
536 @param aForeground Pointer to the foreground VGImage.
537 @param aOutline Pointer to the outline VGImage.
538 @param aShadow Pointer to the shadow VGImage.
540 void CFontGlyphTree::DestroyVGImage(VGImage* aForeground, VGImage* aOutline, VGImage* aShadow)
542 if(aForeground && *aForeground)
544 vgDestroyImage(*aForeground);
545 *aForeground = VG_INVALID_HANDLE;
547 if(aOutline && *aOutline)
549 vgDestroyImage(*aOutline);
550 *aOutline = VG_INVALID_HANDLE;
552 if(aShadow && *aShadow)
554 vgDestroyImage(*aShadow);
555 *aShadow = VG_INVALID_HANDLE;
560 Goes through all entries and deletes VG images.
562 void CFontGlyphTree::DestroyAllVGImagesL()
566 TBool isEntry = EFalse;
568 isEntry = iGlyphTree -> FirstL(pos);
569 //go through all entries and delete VG images
573 TGlyphEntryCompound entryC;
574 (iGlyphType == EFourColourBlendGlyphBitmap) ?
575 ((TBtreeFix<TGlyphEntryCompound, TChar> *) iGlyphTree) -> ExtractAtL(pos, entryC) :
576 ((TBtreeFix<TGlyphEntry, TChar> *) iGlyphTree) -> ExtractAtL(pos, entry);
578 if(iGlyphType == EFourColourBlendGlyphBitmap)
580 DestroyVGImage(&entryC.iForeground, &entryC.iOutline, &entryC.iShadow);
584 DestroyVGImage(&entry.iForeground);
586 isEntry = iGlyphTree -> NextL(pos);
589 iGlyphTree -> ClearL();
594 Allows OpenVG images to be created in OOM conditions. Images will not be added to the binary tree.
597 void CFontGlyphTree::GlyphImageEntryOOML(TGlyphBitmapType aGlyphType, const TUint8* aGlyphImage, const TSize& aGlyphImageSize, K& aEntry, TUint8* aData, TUint8* aDataOutline, TUint8* aDataShadow)
601 case EFourColourBlendGlyphBitmap:
603 CreateVGImageL(aGlyphImage, aGlyphImageSize, aEntry.iForeground, ((TGlyphEntryCompound&) aEntry).iOutline, ((TGlyphEntryCompound&) aEntry).iShadow, aData, aDataOutline, aDataShadow);
606 case EMonochromeGlyphBitmap:
607 CreateVGImageL(aGlyphImage, aGlyphImageSize, EGray2, aEntry.iForeground, aData);
609 case EAntiAliasedGlyphBitmap:
610 CreateVGImageL(aGlyphImage, aGlyphImageSize, EGray256, aEntry.iForeground, aData);
613 User::Leave(KErrNotSupported);
617 //--------------class CFontGlyphImageStorage --------------------
619 Constructor for the font glyph image storage.
621 @param aMaxCacheSize The maximum cache size in bytes. If storage exceeds this value, the least usable binary tree will be destroyed.
623 CFontGlyphImageStorage::CFontGlyphImageStorage(TInt aMaxCacheSize) :
625 iMaxCacheSize(aMaxCacheSize)
630 Destructor for the font glyph image storage.
632 Removes and destroys all binary tree's entries in the list.
634 CFontGlyphImageStorage::~CFontGlyphImageStorage()
636 CleanGlyphImageCache();
637 DeletePreAllocatedImages();
641 The function will free memory by deleting the least usable font tree, if the size of the cache exceeds
642 some pre-defined value.
644 @see MFontGlyphImageStorage
645 @panic DGDIAdapter 46, if there is an inconsistency in the internal glyph cache structure.
647 void CFontGlyphImageStorage::CleanCacheIfRequired()
649 if(iCacheSize > iMaxCacheSize)
651 if(iFontTreeList.Count() == 1)//if it is only one tree, just delete all images
653 TInt aOldTreeSize = iFontTreeList[0]->CacheSize();
654 TRAP_IGNORE(iFontTreeList[0]->DestroyAllVGImagesL());
655 GRAPHICS_ASSERT_DEBUG(0 == (iCacheSize - (aOldTreeSize - iFontTreeList[0]->CacheSize())), EDirectGdiPanicGlyphCacheDataInconsistent);
660 CFontGlyphTree* fontTree = iFontTreeList[iFontTreeList.Count() - 1];
661 iFontTreeList.Remove(iFontTreeList.Count() - 1);
662 GRAPHICS_ASSERT_DEBUG(iCacheSize >= fontTree->CacheSize(), EDirectGdiPanicGlyphCacheDataInconsistent);
663 iCacheSize -= fontTree->CacheSize(); //since we removed the tree, we must update overall cache size to reflect this fact
670 Removes all glyph trees from the storage.
672 @see MFontGlyphImageStorage
674 void CFontGlyphImageStorage::CleanGlyphImageCache()
676 iFontTreeList.ResetAndDestroy();
683 @return Current glyph cache size in bytes.
684 @see MFontGlyphImageStorage
686 TInt CFontGlyphImageStorage::GlyphCacheSize() const
692 Sets the maximum size in bytes of the glyph cache. Checks the current size of
693 the cache and sets the maximum cache size if the current cache size is smaller
694 or equal to aCacheSize.
695 @param aMaxCacheSize The maximum size in bytes to allow for the glyph cache.
696 @return KErrNone if the maximum cache size has been changed successfully,
697 KErrArgument if aMaxCacheSize is smaller than the current cache size.
699 TInt CFontGlyphImageStorage::SetMaxGlyphCacheSize(TInt aMaxCacheSize)
701 if (iCacheSize <= aMaxCacheSize)
703 iMaxCacheSize = aMaxCacheSize;
711 @return Max glyph cache size in bytes.
712 @see MFontGlyphImageStorage
714 TInt CFontGlyphImageStorage::MaxGlyphCacheSize() const
716 return iMaxCacheSize;
720 Fills aFontListId parameter with font Id in order from most to least usable.
723 @see MFontGlyphImageStorage
725 @return KErrNone, if the insertion is successful, otherwise one of the system wide error codes.
727 TInt CFontGlyphImageStorage::FontIdInOrder(RArray<TUint32> & aFontListId) const
732 for(TInt index = 0; (index < iFontTreeList.Count()) && (err == KErrNone); index++)
734 CFontGlyphTree* glyphTree = iFontTreeList[index];
735 err = aFontListId.Append(glyphTree->FontId());
742 Enforce the system to emulate OOM failure. As sequence pre-allocated images will be used.
745 @see MFontGlyphImageStorage
748 void CFontGlyphImageStorage::EnforceOOMFailure(TBool aEnforce)
750 iEnforceOOM = aEnforce;
753 void CFontGlyphImageStorage::EnforceOOMFailure(TBool /*aEnforce*/)
759 Retrieves OpenVG images from the font image cache. If the image doesn't exist, the function will create a new one from the bitmap glyph image and
760 add it into the font image cache.
761 Each font corresponds to a particular tree of glyph images.
762 The function's search is performed in two steps:
763 1. It tries to identify the glyph tree associated with the font. Otherwise a new tree will be created
764 2. Within the tree the function will search for the particular glyph entry. Otherwise a new glyph entry will be created
765 If the size of the cache exceeds some pre-defined value, the least usable tree with all its entries will be deleted.
766 If the function fails to place the element into the tree due to shortage of memory, it will
767 still try to create VGImages without adding them to the binary tree.
768 @see CVgEngine::DrawGlyph
769 @see MFontGlyphImageStorage
771 @param aFontId Unique Font Id.
772 @param aGlypCode General Unicode character value.
773 @param aGlyphBitmapType A type for the format of a glyph bitmap.
774 @param aGlyphImage Glyph bitmap image data.
775 @param aGlyphImageSize The size of the glyph bitmap image data.
776 @param aImageForeground Pointer to VGImage text foreground handle.
777 @param aImageShadow Pointer to VGImage text shadow handle.
778 @param aImageOutline Pointer to VGImage text outline handle.
780 @pre Rendering engine has been constructed.
781 @post Requested OpenVG images are ready for rendering.
783 @panic DGDIAdapter 1018, if a null glyph image pointer is passed in.
784 @return On success KErrNone,
785 KErrArgument if passed parameters are not correct,
786 KErrNotSupported if functionality is not supported, otherwise one of the other system-wide error codes.
788 TInt CFontGlyphImageStorage::GlyphImage(TUint32 aFontId, TChar aGlypCode, TGlyphBitmapType aGlyphBitmapType, const TUint8* aGlyphImage, const TSize& aGlyphImageSize,
789 TAny* aImageForeground, TAny* aImageShadow, TAny* aImageOutline)
791 if((aGlyphImageSize.iHeight <= 0) || (aGlyphImageSize.iWidth <= 0))
795 GRAPHICS_ASSERT_ALWAYS(aGlyphImage, EDirectGdiPanicInvalidPointer); // maybe needs to change assertion type
796 GRAPHICS_ASSERT_ALWAYS(aImageForeground, EDirectGdiPanicInvalidPointer); // maybe needs to change assertion type
797 GRAPHICS_ASSERT_ALWAYS((aImageShadow && aImageOutline) || (aGlyphBitmapType != EFourColourBlendGlyphBitmap), EDirectGdiPanicInvalidPointer); // maybe needs to change assertion type
800 CFontGlyphTree* fontTree = NULL;
803 for(; index < iFontTreeList.Count(); index++)
805 CFontGlyphTree* fontTreeTemp = iFontTreeList[index];
806 if(fontTreeTemp->FontId() == aFontId)
808 fontTree = fontTreeTemp;
819 //there is no tree for that font, thus create one
820 TRAP(res, fontTree = CFontGlyphTree::NewL(aFontId, aGlyphBitmapType));
823 res = iFontTreeList.Insert(fontTree, 0);
836 iFontTreeList.Remove(index);
837 res = iFontTreeList.Insert(fontTree, 0);
839 { //we have to delete fontTree as it is not stored anywhere.
846 if(iEnforceOOM && (res == KErrNone))
853 CleanCacheIfRequired();
854 TInt treeCacheSize = fontTree->CacheSize();
855 if(aGlyphBitmapType == EFourColourBlendGlyphBitmap)
857 TRAP(res, fontTree->GlyphImageEntryL(aGlypCode, aGlyphImage, aGlyphImageSize, iEntryCompound, NULL));
861 TRAP(res, fontTree->GlyphImageEntryL(aGlypCode, aGlyphImage, aGlyphImageSize, iEntry, aGlyphBitmapType == EMonochromeGlyphBitmap ? iForegroundData : NULL));
865 iCacheSize += (fontTree->CacheSize() - treeCacheSize);
866 if(aGlyphBitmapType == EFourColourBlendGlyphBitmap)
868 *(static_cast <VGImage*> (aImageForeground)) = iEntryCompound.iForeground;
869 *(static_cast <VGImage*> (aImageShadow)) = iEntryCompound.iShadow;
870 *(static_cast <VGImage*> (aImageOutline)) = iEntryCompound.iOutline;
876 *(static_cast <VGImage*> (aImageShadow)) = VG_INVALID_HANDLE;
880 *(static_cast <VGImage*> (aImageOutline)) = VG_INVALID_HANDLE;
883 *(static_cast <VGImage*> (aImageForeground)) = iEntry.iForeground;
888 //create glyph images for OOM conditions, without putting the entry into the tree
889 if((res == KErrNoMemory) && iImagesPreAllocated && (iImageSize.iWidth >= aGlyphImageSize.iWidth ) && (iImageSize.iHeight >= aGlyphImageSize.iHeight))
891 const TInt bufferSize = iImageSize.iWidth * iImageSize.iHeight;
892 Mem::FillZ(iForegroundData, bufferSize);
893 VGImageFormat imageFormat = VG_sL_8;
894 TInt vgCompatibleSourceStride = iImageSize.iWidth;
896 if(aGlyphBitmapType == EFourColourBlendGlyphBitmap)
898 Mem::FillZ(iShadowData, bufferSize);
899 Mem::FillZ(iOutlineData, bufferSize);
900 iEntryCompound.iForeground = iImageForeground;
901 iEntryCompound.iOutline = iImageOutline;
902 iEntryCompound.iShadow = iImageShadow;
904 vgImageSubData(iEntryCompound.iForeground, iForegroundData, vgCompatibleSourceStride, imageFormat,
905 0, 0, iImageSize.iWidth, iImageSize.iHeight);
907 vgImageSubData(iEntryCompound.iOutline, iOutlineData, vgCompatibleSourceStride, imageFormat,
908 0, 0, iImageSize.iWidth, iImageSize.iHeight);
910 vgImageSubData(iEntryCompound.iShadow, iShadowData, vgCompatibleSourceStride, imageFormat,
911 0, 0, iImageSize.iWidth, iImageSize.iHeight);
913 TRAP_IGNORE(CFontGlyphTree::GlyphImageEntryOOML(aGlyphBitmapType, aGlyphImage, aGlyphImageSize, iEntryCompound, iForegroundData, iShadowData, iOutlineData));
914 *(static_cast <VGImage*> (aImageForeground)) = iImageForeground;
915 *(static_cast <VGImage*> (aImageShadow)) = iImageShadow;
916 *(static_cast <VGImage*> (aImageOutline)) = iImageOutline;
920 iEntry.iForeground = iImageForeground;
921 vgImageSubData(iEntry.iForeground, iForegroundData, vgCompatibleSourceStride, imageFormat,
922 0, 0, iImageSize.iWidth, iImageSize.iHeight);
924 TRAP_IGNORE(CFontGlyphTree::GlyphImageEntryOOML(aGlyphBitmapType, aGlyphImage, aGlyphImageSize, iEntry, iForegroundData, NULL, NULL));
925 *(static_cast <VGImage*> (aImageForeground)) = iImageForeground;
933 Creates VGImages for use in low memory conditions
935 TInt CFontGlyphImageStorage::PreAllocateImages()
937 iImageSize = KMaxSizeImageOOM;
939 #ifdef DRAWGLYPH_MULTIPLY_MODE
940 // For image_multiply mode need 32bits for each glyph instrad of 8 for non-multiply mode.
941 const TInt bufferSize = iImageSize.iWidth * iImageSize.iHeight * 4;
943 const TInt bufferSize = iImageSize.iWidth * iImageSize.iHeight;
947 iForegroundData = (TUint8*) User::Alloc(bufferSize);
956 iShadowData = (TUint8*) User::Alloc(bufferSize);
965 iOutlineData = (TUint8*) User::Alloc(bufferSize);
972 const VGImageFormat imageFormat = VG_sL_8;
973 if(iImageForeground == VG_INVALID_HANDLE)
976 iImageForeground = vgCreateImage(imageFormat,
979 VG_IMAGE_QUALITY_NONANTIALIASED);
980 if(iImageForeground == VG_INVALID_HANDLE)
986 if(iImageShadow == VG_INVALID_HANDLE)
988 iImageShadow = vgCreateImage(imageFormat,
991 VG_IMAGE_QUALITY_NONANTIALIASED);
992 if(iImageShadow == VG_INVALID_HANDLE)
998 if(iImageOutline == VG_INVALID_HANDLE)
1000 iImageOutline = vgCreateImage(imageFormat,
1003 VG_IMAGE_QUALITY_NONANTIALIASED);
1004 if(iImageOutline == VG_INVALID_HANDLE)
1006 return KErrNoMemory;
1010 iImagesPreAllocated = ETrue;
1015 Deletes all pre-allocated images and frees buffers.
1017 void CFontGlyphImageStorage::DeletePreAllocatedImages()
1021 User::Free(iForegroundData);
1022 iForegroundData = NULL;
1027 User::Free(iShadowData);
1033 User::Free(iOutlineData);
1034 iOutlineData = NULL;
1037 if(iImageForeground != VG_INVALID_HANDLE)
1039 vgDestroyImage(iImageForeground);
1040 iImageForeground = VG_INVALID_HANDLE;
1043 if(iImageShadow != VG_INVALID_HANDLE)
1045 vgDestroyImage(iImageShadow);
1046 iImageShadow = VG_INVALID_HANDLE;
1049 if(iImageOutline != VG_INVALID_HANDLE)
1051 vgDestroyImage(iImageOutline);
1052 iImageOutline = VG_INVALID_HANDLE;
1054 iImagesPreAllocated = EFalse;