Update contrib.
2 * Copyright (c) 1995-2010 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
22 #include <graphics/shapeimpl.h>
26 #include <graphics/shaperparams.h>
28 #define DO_LOADFONT_OPTIMIZATION 1
29 #include <linkedfonts.h>
30 #include "linkedfontsprivate.h"
31 #include "openfontsprivate.h"
32 #include <openfontlinkedtypefaceelementspec.h>
33 #include <graphics/openfontlinkedtypefaceextension.h>
34 #include <graphics/openfontlinkedtypefacespecification.h>
35 #include <graphics/openfontrasterizer.h>
36 #include <graphics/openfontconstants.h>
38 #include "OstTraceDefinitions.h"
39 #ifdef OST_TRACE_COMPILER_IN_USE
40 #include "FNTSTORETraces.h"
44 static const TUint32 KOutlineGlyphIdHashMask = 0x0000ffff;
45 static const TUint32 KOutlineFileUidHashMask = 0x00ff0000;
46 static const TUint32 KOutlineFaceIndexHashMask = 0x0f000000;
47 static const TUint32 KOutlineFontPtrHashMask = 0x0fff0000;
49 // uncomment to enable some verbose debug prints
50 //#define VERBOSE_DEBUG 1
53 /** These constants set the default pixel width and height, in Twips x1000.
54 Hal Data information overrides this if it is available. EDisplayXPixels & EDisplayXTwips,
55 EDisplayYPixels & EDisplayYTwips values are required respectively.
57 (11860 is approx equivalent to 120 pixels per inch.)
60 const TInt KDefaultPixelWidthInTwips = 11860;
61 const TInt KDefaultPixelHeightInTwips = 11860;
63 // default granularity for arrays
64 const TInt KDefaultArrayGranularity = 8;
66 /* Maximum height of a character bitmap. When font height in pixel is 1024, each
67 character bitmap is equal to (roughly) 1024 x 1024 x 8 bits/pixel = 1 MB.
70 const TInt KMaxFontHeightInPixels = 1024;
72 /* Minimum height of font in pixels that can be displayed on the screen.
75 const TInt KMinFontHeightInPixels = 2;
77 The arbitrary list of sizes, in points, returned for scaleable fonts.
78 We can't return 2^32 - 1 sizes, or something that reflect the fact
79 that any size is okay, because a UI will probably try to create a listbox containing all the sizes.
81 Array stored in Twips as that is the only form of the value currently used.
84 #define POINTSIZE_IN_TWIPS(p) ((p) * 20)
85 const TInt gOpenFontSizeInTwipsArray[] =
87 // 4pt-18pt in steps of 1pt (15 sizes)
88 POINTSIZE_IN_TWIPS(4), POINTSIZE_IN_TWIPS(5), POINTSIZE_IN_TWIPS(6),
89 POINTSIZE_IN_TWIPS(7), POINTSIZE_IN_TWIPS(8), POINTSIZE_IN_TWIPS(9),
90 POINTSIZE_IN_TWIPS(10), POINTSIZE_IN_TWIPS(11), POINTSIZE_IN_TWIPS(12),
91 POINTSIZE_IN_TWIPS(13), POINTSIZE_IN_TWIPS(14), POINTSIZE_IN_TWIPS(15),
92 POINTSIZE_IN_TWIPS(16), POINTSIZE_IN_TWIPS(17), POINTSIZE_IN_TWIPS(18),
93 // 20pt-36pt in steps of 2pt (9 sizes)
94 POINTSIZE_IN_TWIPS(20), POINTSIZE_IN_TWIPS(22), POINTSIZE_IN_TWIPS(24),
95 POINTSIZE_IN_TWIPS(26), POINTSIZE_IN_TWIPS(28), POINTSIZE_IN_TWIPS(30),
96 POINTSIZE_IN_TWIPS(32), POINTSIZE_IN_TWIPS(34), POINTSIZE_IN_TWIPS(36),
97 // 40pt-72pt in steps of 4pt (9 sizes)
98 POINTSIZE_IN_TWIPS(40), POINTSIZE_IN_TWIPS(44), POINTSIZE_IN_TWIPS(48),
99 POINTSIZE_IN_TWIPS(52), POINTSIZE_IN_TWIPS(56), POINTSIZE_IN_TWIPS(60),
100 POINTSIZE_IN_TWIPS(64), POINTSIZE_IN_TWIPS(68), POINTSIZE_IN_TWIPS(72),
101 // 80pt-144pt in steps of 8pt (9 sizes)
102 POINTSIZE_IN_TWIPS(80), POINTSIZE_IN_TWIPS(88), POINTSIZE_IN_TWIPS(96),
103 POINTSIZE_IN_TWIPS(104), POINTSIZE_IN_TWIPS(112), POINTSIZE_IN_TWIPS(120),
104 POINTSIZE_IN_TWIPS(128), POINTSIZE_IN_TWIPS(136), POINTSIZE_IN_TWIPS(144)
107 const TInt KOpenFontSizeArrayCount = sizeof(gOpenFontSizeInTwipsArray) / sizeof(gOpenFontSizeInTwipsArray[0]);
111 The folder used to store linked fonts; the character represents the system drive
112 location and the descriptor contains the private path of fbserv.
114 _LIT(KLinkedFontFileFolder, "%c:%Slfonts\\");
118 The folder used to store updated linked fonts; the descriptor should be formatted
119 with the formatted version of KLinkedFontFileFolder. Files will be moved from this
120 folder to KLinkedFontFileFolder at boot time before the font loading procedure.
122 _LIT(KLinkedFontFileTempFolder, "update\\");
125 The font search string. The Y: directory prefix forces the search to
126 start with drive Y:. The drives will be searched in the order Y: to A: then Z:
128 _LIT(KFBSERVFontDirSecure, "y:\\resource\\fonts\\");
130 /**The maximum length of the linked font folder path*/
131 const TInt KMaxLinkedFontPathLength = 36;
133 /**The maximum length of a private path*/
134 const TInt KMaxPrivatePathLength = 19;
136 /** Container for TTypefaceSupport that describes an Open Font family.
138 There is an implicit assumption that all fonts in the family will have the same attributes
139 as the first instance found. E.g. that the range of font heights is the same.
141 An array of pointers to the COpenFontFile file objects that hold fonts in this family
142 also provides reference counting for the object.
146 NONSHARABLE_CLASS(CTypefaceSupportInfo) : public CBase
149 CTypefaceSupportInfo();
150 inline TInt AddFontFilePtr(COpenFontFile* aOpenFontFile);
151 inline TInt AddUniqueFontFilePtr(COpenFontFile* aOpenFontFile,const TOpenFontFaceAttrib& aFaceAttrib);
152 inline TInt FindFontFilePtr(COpenFontFile* aOpenFontFile);
153 inline TBool RemoveFontFilePtr(TInt aIndex);
154 void SetTypefaceInfo(const TOpenFontFaceAttrib& aFaceAttrib, TInt aMinHeightInTwips);
155 inline const TTypefaceSupport* TypefaceSupport() const;
156 inline TInt NearestPointSizeIndex() const;
157 static TInt CompareFontNames(const CTypefaceSupportInfo& aTypeface1, const CTypefaceSupportInfo& aTypeface2);
158 ~CTypefaceSupportInfo();
161 TTypefaceSupport iSupport;
162 // pointers back to the COpenFontFile object which has one or more typefaces in this family
163 RPointerArray<COpenFontFile> iOpenFontFilePtrArray;
164 // nearest standard point size index;
165 TInt iNearestPointSizeIndex;
169 /** helper class used with the cleanup stack
172 class TCleanupRemoveFontFile
175 inline TCleanupRemoveFontFile(CFontStore* aFontStore, TUid aFontUid);
177 CFontStore* iFontStore;
182 // declare static functions
183 static TInt MatchFontSpecsInPixels(const TOpenFontSpec& aCandidateFontSpec,
184 const TOpenFontSpec& aIdealFontSpec, TInt aCandidateMaxHeight = 0, TInt aIdealMaxHeight = 0);
185 static void ReadFromFileL(RFile& aFile, TDes8& aDes, TInt aLength);
186 static TUint TtfTableTagFromBufferL(TDes8& aDes);
189 static TUint32 StartTiming(void);
190 static TUint32 FinishTimingL(TUint32 startTime);
193 static TBool FileIsOnZ(TParse& aFileName);
194 static TBool FileIsInList(TParse& aFileName, RArray<TParse>& aList);
197 /** Helper function for converting a pointer to an offset from the passed
198 heap base. Use OffsetToPointer() to convert the returned offset back to a
200 @param aAny A pointer to be converted to an offset.
201 @param aHeapBase The heap base of the current process.
202 @return An offset representing the passed pointer that can be converted
203 back to a pointer using the function OffsetToPointer().
204 @see OffsetToPointer()
206 LOCAL_C TInt PointerToOffset(const TAny* aAny, TUint8* aHeapBase)
208 if (aAny && aHeapBase)
210 return reinterpret_cast<TInt>(aAny) - reinterpret_cast<TInt>(aHeapBase);
215 /** Helper function for converting an offset (that was calculated using
216 PointerToOffset()) back to a pointer relative to the passed heap base.
217 @param aOffset The offset to be converted to a pointer.
218 @param aHeapBase The heap base of the current process.
219 @return A pointer relative to the passed heap base.
220 @see PointerToOffset()
222 LOCAL_C TAny* OffsetToPointer(TInt aOffset, TUint8* aHeapBase)
224 if (aOffset && aHeapBase)
226 return reinterpret_cast<TAny*>(aOffset + reinterpret_cast<TInt>(aHeapBase));
232 // CTypefaceSupportInfo
233 CTypefaceSupportInfo::CTypefaceSupportInfo()
238 CTypefaceSupportInfo::~CTypefaceSupportInfo()
239 { // no ownership of font files, so just Close the array
240 iOpenFontFilePtrArray.Close();
244 /** Add a back pointer to an Open Font file, in sorted order.
245 @param aOpenFontFile font file that has a typeface in this family.
246 @return KErrNone if added, KErrAlreadyExists if file is already referenced, or KErrNoMemory.
249 TInt CTypefaceSupportInfo::AddFontFilePtr(COpenFontFile* aOpenFontFile)
251 return iOpenFontFilePtrArray.InsertInAddressOrder(aOpenFontFile);
254 /** Add a back pointer to an Open Font file, in sorted order, but only if the font details are unique.
255 @param aOpenFontFile font file that has a typeface in this family.
256 @return KErrNone if added, KErrInUse if another file already defines this, KErrAlreadyExists if file is already referenced, or KErrNoMemory.
259 TInt CTypefaceSupportInfo::AddUniqueFontFilePtr(COpenFontFile* aOpenFontFile,const TOpenFontFaceAttrib& aFaceAttrib)
262 _LIT(KLoadedFont, "TypefaceSupport: already loaded font: %S\n");
265 TPtrC findName=aFaceAttrib.FullName();
266 for (TInt i=0,maxi=iOpenFontFilePtrArray.Count();i<maxi;i++)
267 { //Do any of the fonts already registered with this family already provide this specific font?
268 COpenFontFile* cmpFont=iOpenFontFilePtrArray[i];
269 if (cmpFont==aOpenFontFile)
270 { //Another specific font in this font file has already been added to this family
271 //InsertInAddressOrder would detect this.
273 RDebug::Print(KLoadedFont, &findName);
275 return KErrAlreadyExists;
279 for (TInt j=0,maxj=cmpFont->FaceCount();j<maxj;j++)
280 { //The expectation is that open fonts will only have 1 face per file, so this loop is 1-pass generally.
281 const TOpenFontFaceAttrib& cmpFace=cmpFont->FaceAttrib(j);
282 TPtrC cmpName=cmpFace.FullName();
283 if (cmpName==findName)
286 RDebug::Print(KLoadedFont, &findName);
293 return iOpenFontFilePtrArray.InsertInAddressOrder(aOpenFontFile);
296 /** Check font family for back pointer to an Open Font file.
297 @param aOpenFontFile font file that may have a typeface in this family.
298 @return KErrNotFound or the index of pointer
301 TInt CTypefaceSupportInfo::FindFontFilePtr(COpenFontFile* aOpenFontFile)
303 return iOpenFontFilePtrArray.FindInAddressOrder(aOpenFontFile);
307 /** Remove a font file back pointer.
308 @param aIndex the index of pointer, from FindFontFilePtr()
309 @return ETrue if there are no more implementations of the font family
312 TBool CTypefaceSupportInfo::RemoveFontFilePtr(TInt aIndex)
314 iOpenFontFilePtrArray.Remove(aIndex);
315 return iOpenFontFilePtrArray.Count() == 0;
319 /** Set the details of the typeface family.
320 @param aFaceAttrib typeface to parameterise.
323 void CTypefaceSupportInfo::SetTypefaceInfo(const TOpenFontFaceAttrib& aFaceAttrib, TInt aMinHeightInTwips)
325 iSupport.iTypeface.iName = aFaceAttrib.ShortFamilyName();
326 iSupport.iTypeface.SetIsProportional(!aFaceAttrib.IsMonoWidth());
327 iSupport.iTypeface.SetIsSerif(aFaceAttrib.IsSerif());
328 iSupport.iTypeface.SetIsSymbol(aFaceAttrib.IsSymbol());
330 // Find minimum size in twips then find the next higher standard size.
331 iSupport.iMinHeightInTwips = aMinHeightInTwips;
332 TInt fontSizeIndex = 0;
333 for (; fontSizeIndex < KOpenFontSizeArrayCount; ++fontSizeIndex)
335 const TInt KMinHeightInTwips = gOpenFontSizeInTwipsArray[fontSizeIndex];
336 if (aMinHeightInTwips <= KMinHeightInTwips)
338 aMinHeightInTwips = KMinHeightInTwips;
342 iNearestPointSizeIndex = fontSizeIndex;
343 iSupport.iMaxHeightInTwips = Max(gOpenFontSizeInTwipsArray[KOpenFontSizeArrayCount - 1], iSupport.iMinHeightInTwips);
344 iSupport.iNumHeights = Max(1,KOpenFontSizeArrayCount - iNearestPointSizeIndex);
345 iSupport.iIsScalable = TRUE;
349 /** Get the details of the typeface family.
352 const TTypefaceSupport* CTypefaceSupportInfo::TypefaceSupport() const
357 /** Get the Nearest Standard Point Size Index.
360 TInt CTypefaceSupportInfo::NearestPointSizeIndex() const
362 return iNearestPointSizeIndex;
366 TInt CTypefaceSupportInfo::CompareFontNames(const CTypefaceSupportInfo& aTypeface1, const CTypefaceSupportInfo& aTypeface2)
368 return aTypeface1.iSupport.iTypeface.iName.CompareF(aTypeface2.iSupport.iTypeface.iName);
372 // TCleanupRemoveFontFile
373 TCleanupRemoveFontFile::TCleanupRemoveFontFile(CFontStore* aFontStore, TUid aFontUid) :
374 iFontStore(aFontStore), iFontUid(aFontUid)
379 TBitmapFontCharacterOffset::TBitmapFontCharacterOffset()
383 void TBitmapFontCharacterOffset::InternalizeL(RReadStream& aStream)
385 iBitmapOffset = aStream.ReadUint16L();
388 EXPORT_C TCharacterMetrics::TCharacterMetrics()
389 : iAscentInPixels(0),
391 iLeftAdjustInPixels(0),
393 iRightAdjustInPixels(0)
397 TBitmapFontCharacterMetrics::TBitmapFontCharacterMetrics()
398 : iAscentInPixels(0),
400 iLeftAdjustInPixels(0),
402 iRightAdjustInPixels(0)
406 void TBitmapFontCharacterMetrics::InternalizeL(RReadStream& aStream)
408 iAscentInPixels = aStream.ReadInt8L();
409 iHeightInPixels = aStream.ReadInt8L();
410 iLeftAdjustInPixels = aStream.ReadInt8L();
411 iMoveInPixels = aStream.ReadInt8L();
412 iRightAdjustInPixels = aStream.ReadInt8L();
416 EXPORT_C TAlgStyle::TAlgStyle()
417 : iBaselineOffsetInPixels(0),
424 /** Sets whether the font is bold.
426 @param aIsBold ETrue if the font is bold; otherwise EFalse. */
427 EXPORT_C void TAlgStyle::SetIsBold(TBool aIsBold)
435 /** Sets whether the font is italic.
437 @param aIsItalic ETrue if the font is italic; otherwise EFalse. */
438 EXPORT_C void TAlgStyle::SetIsItalic(TBool aIsItalic)
446 /** Sets whether the font is mono width - i.e. all characters have the same width.
448 @param aIsMono ETrue if the font is mono width; otherwise EFalse. */
449 EXPORT_C void TAlgStyle::SetIsMono(TBool aIsMono)
457 /** Sets the width factor.
459 @param aWidthFactor A width factor. */
460 EXPORT_C void TAlgStyle::SetWidthFactor(TInt aWidthFactor)
462 iWidthFactor=(TInt8) aWidthFactor;
465 /** Sets the height factor.
467 @param aHeightFactor A height factor. */
468 EXPORT_C void TAlgStyle::SetHeightFactor(TInt aHeightFactor)
470 iHeightFactor=(TInt8) aHeightFactor;
473 /** Returns whether the font is bold.
475 @return ETrue if the font is bold; otherwise EFalse. */
476 EXPORT_C TBool TAlgStyle::IsBold() const
481 /** Returns whether the font is italic.
483 @return ETrue if the font is italic; otherwise EFalse. */
484 EXPORT_C TBool TAlgStyle::IsItalic() const
486 return iFlags&EItalic;
489 /** Returns whether the font is mono - i.e. all characters have the same width.
491 @return ETrue if the font is mono; otherwise EFalse. */
492 EXPORT_C TBool TAlgStyle::IsMono() const
497 /** Returns the width factor.
499 @return A width factor. */
500 EXPORT_C TInt TAlgStyle::WidthFactor() const
505 /** Returns the height factor.
507 @return A height factor. */
508 EXPORT_C TInt TAlgStyle::HeightFactor() const
510 return iHeightFactor;
513 EXPORT_C TBool TAlgStyle::operator==(const TAlgStyle& aAlgStyle) const
515 return (iFlags==aAlgStyle.iFlags) &&
516 (iWidthFactor==aAlgStyle.iWidthFactor) &&
517 (iHeightFactor==aAlgStyle.iHeightFactor) &&
518 (iBaselineOffsetInPixels==aAlgStyle.iBaselineOffsetInPixels);
524 TBool TAlgStyle::operator!=(const TAlgStyle& aAlgStyle) const
526 return !this->operator==(aAlgStyle);
529 CBitmapFont::CBitmapFont(
531 const TFontSpec& aFontSpecInTwips,
532 const TAlgStyle& aAlgStyle,
533 CFontBitmap* aFontBitmap):
534 iFontSpecInTwips(aFontSpecInTwips),
535 iAlgStyle(aAlgStyle),
538 iFontBitmapOffset = (TInt) ((TUint)(aFontBitmap) - (TUint)(this));
541 CBitmapFont::CBitmapFont(
543 const TFontSpec& aFontSpecInTwips,
544 const TAlgStyle& aAlgStyle,
545 COpenFont* aOpenFont):
546 iFontSpecInTwips(aFontSpecInTwips),
547 iAlgStyle(aAlgStyle),
550 // Set iOpenFont to be the offset of aOpenFont from the address of CBitmapFont.
551 // In order to be able to identify iOpenFont as an offset instead of a pointer,
552 // bitwise or the offset with 1. Pointers will always be word aligned (and therefore even).
555 __ASSERT_DEBUG(!(reinterpret_cast<TInt>(aOpenFont) & 1), Panic(EFntPointerNotByteAligned));
556 iOpenFont = reinterpret_cast<COpenFont*>((reinterpret_cast<TInt>(aOpenFont) - reinterpret_cast<TInt>(this)) | 1);
564 /** This member is private and not intended for use. */
565 void CBitmapFont::ConstructL()
568 FontBitmap()->UseL();
571 /** This member is private and not intended for use. */
572 CBitmapFont::~CBitmapFont()
574 if (!IsOpenFont() && iFontBitmapOffset)
575 FontBitmap()->Release();
576 else if (IsOpenFont())
580 CBitmapFont* CBitmapFont::NewL(
582 const TFontSpec& aFontSpecInTwips,
583 const TAlgStyle& aAlgStyle,
584 CFontBitmap* aFontBitmap)
586 // font is placed in shared heap
587 CBitmapFont* f = (CBitmapFont*) aHeap->AllocL(sizeof(CBitmapFont));
588 new(f) CBitmapFont(aHeap, aFontSpecInTwips, aAlgStyle, aFontBitmap);
589 CleanupStack::PushL(f);
591 CleanupStack::Pop(f);
595 CBitmapFont* CBitmapFont::NewL(
597 const TFontSpec& aFontSpecInTwips,
598 const TAlgStyle& aAlgStyle,
599 COpenFont* aOpenFont)
601 // font is placed in shared heap
602 CBitmapFont* f = (CBitmapFont*) aHeap->AllocL(sizeof(CBitmapFont));
603 new(f) CBitmapFont(aHeap,aFontSpecInTwips,aAlgStyle,aOpenFont);
607 /** Returns the font type identifier:KCBitmapFontUidVal.
609 @return The font type identifier. */
610 EXPORT_C TUid CBitmapFont::DoTypeUid() const
612 return TUid::Uid(KCBitmapFontUidVal);
615 /** Returns a font identifier.
617 If it uses an open font the UID returned has a value of zero. Otherwise it
618 has the UID value of the CFontBitmap it uses.
620 @return A font identifier. */
621 TUid CBitmapFont::Uid() const
626 return FontBitmap()->iUid;
629 /** Returns the font height in pixels.
630 For an open font this will be the design height (notional rather than exact).
632 @return Font height in pixels.
635 EXPORT_C TInt CBitmapFont::DoHeightInPixels() const
638 return Height(OpenFont()->Metrics().Size());
640 return Height(FontBitmap()->iCellHeightInPixels);
643 /** Returns the font ascent in pixels.
645 The ascent is usually the height of a Latin capital letter above the baseline.
646 For an open font, the returned value is likely to be inaccurate.
647 Don't rely on it to get exact metrics at the pixel level.
649 @return Font ascent in pixels.
650 @see FontCapitalAscent()
653 EXPORT_C TInt CBitmapFont::DoAscentInPixels() const
656 return Height(OpenFont()->Metrics().Ascent());
658 return Height(FontBitmap()->iAscentInPixels);
661 /** Returns the width, in pixels, of the given character.
663 If all characters have the same width (i.e. the font is mono - an attribute
664 stored in iAlgStyle) then this is the maximum normal width, returned using
665 MaxNormalCharWidthInPixels().
667 Note: For OpenType fonts this function returns the horizontal advance of
668 the character, which may be different from the actual width.
670 @param aChar A character.
671 @return The character width in pixels. */
672 EXPORT_C TInt CBitmapFont::DoCharWidthInPixels(TChar aChar) const
675 if (iAlgStyle.IsMono())
676 return MaxNormalCharWidthInPixels();
678 return Width(CharacterMetrics(aChar,bytes).iMoveInPixels);
681 /** Returns the width, in pixels, of the given text.
683 @param aText Text string.
684 @return Width of the text in pixels. */
685 EXPORT_C TInt CBitmapFont::DoTextWidthInPixels(const TDesC &aText) const
687 TMeasureTextInput* dummy = NULL;
688 return DoTextWidthInPixels(aText, dummy);
691 /** Returns the width, in pixels, of the given text.
693 @param aText Text string.
694 @return Width of the text in pixels. */
695 TInt CBitmapFont::DoTextWidthInPixels(const TDesC &aText, const TMeasureTextInput* aParam) const
697 TMeasureTextOutput output;
698 TInt advance_width = MeasureText(aText,aParam,&output);
699 return Max(advance_width,output.iBounds.Width());
703 /** Returns the baseline offset in pixels, as stored in iAlgStyle.
705 @return The baseline offset in pixels. */
706 EXPORT_C TInt CBitmapFont::DoBaselineOffsetInPixels() const
708 return iAlgStyle.iBaselineOffsetInPixels;
711 /** Returns the number of whole characters of aText, starting from the beginning,
712 that fit into the given pixel width.
714 @param aText A text string.
715 @param aWidthInPixels A width in pixels.
716 @return The number of whole characters of aText that fit into aWidthInPixels.
718 EXPORT_C TInt CBitmapFont::DoTextCount(const TDesC &aText,TInt aWidthInPixels) const
721 const TInt length = aText.Length();
723 // accumulate text width character by character, until target is reached or exceeded
724 TInt widthDiff = aWidthInPixels - width;
725 while ( (widthDiff > 0) && (length > count) )
727 width += TextWidthInPixels(aText.Mid(count,1));
728 widthDiff = aWidthInPixels - width;
730 { // width <= aWidthInPixels
737 /** Returns the number of whole characters of aText, starting from the beginning,
738 that fit into the given pixel width, and gets the excess width.
740 @param aText A text descriptor.
741 @param aWidthInPixels A width in pixels.
742 @param aExcessWidthInPixels On return, the width left over of aWidthInPixels
743 after the maximum possible whole number of characters of aText have been fit
745 @return The number of whole characters of aText that fit into aWidthInPixels. */
746 EXPORT_C TInt CBitmapFont::DoTextCount(const TDesC &aText,TInt aWidthInPixels,TInt &aExcessWidthInPixels) const
748 TInt count = TextCount(aText,aWidthInPixels);
749 aExcessWidthInPixels = aWidthInPixels - TextWidthInPixels(aText.Left(count));
753 /** Returns the font's maximum character width in pixels.
755 @return The maximum character width in pixels. */
756 EXPORT_C TInt CBitmapFont::DoMaxCharWidthInPixels() const
759 return Width(OpenFont()->Metrics().MaxWidth());
761 return Width(FontBitmap()->iMaxCharWidthInPixels);
764 /** Returns the font's normal maximum character width in pixels.
766 Note that when a CFontBitmap is used this value is the same as the maximum
767 character width in pixels returned by MaxCharWidthInPixels(), but when a COpenFont
768 is used the value may be different.
770 @return The normal maximum character width in pixels. */
771 EXPORT_C TInt CBitmapFont::DoMaxNormalCharWidthInPixels() const
774 return Width(OpenFont()->Metrics().MaxWidth());
776 return Width(FontBitmap()->iMaxNormalCharWidthInPixels);
779 /** Returns the device-independent font specification for the font.
781 Note that this is set when the bitmap font object is constructed.
783 @return A font specification. */
784 EXPORT_C TFontSpec CBitmapFont::DoFontSpecInTwips() const
786 return iFontSpecInTwips;
790 /** Attempts to rasterize a character (aCode) into a data area (aGlyphData) in
793 This works only for open fonts: where the bitmap font object is using a COpenFont.
795 Bitmap fonts are deemed to be fully rasterized after they have been loaded
798 Returns ETrue if the character was successfully rasterized or was already
799 in the cache. This function can be called only by the server; rasterization
800 uses memory and other resources (e.g., file handles) owned by the server.
802 @param aSessionHandle A session handle for the open font system.
803 @param aCode A character code.
804 @param aGlyphData A data area in shared memory.
805 @return ETrue if the character was successfully rasterized or was already in
806 the cache; otherwise EFalse. */
807 EXPORT_C TBool CBitmapFont::Rasterize(TInt aSessionHandle, TInt aCode, TOpenFontGlyphData* aGlyphData) const
810 return OpenFont()->Rasterize(aSessionHandle, aCode, aGlyphData);
815 /** Gets a pointer to a bitmap and the metrics for a specified character, but only
816 if a CFontBitmap is being used by the bitmap font object.
818 This function does not work when a COpenFont is being used, but GetCharacterData()
821 If the specified character does not exist in the font then the bitmap pointer
822 and character metrics are gotten for a replacement character, KReplacementCharacter.
824 @param aCode A character code.
825 @param aBytes On return, a pointer to the bitmap for the specified character.
826 @return Metrics for the specified character. */
827 EXPORT_C TCharacterMetrics CBitmapFont::CharacterMetrics(TInt aCode,const TUint8*& aBytes) const
830 This function does not work for Open Fonts because the character data need not be
831 shared between sessions and a session handle is needed; GetCharacterData should be used instead.
836 return TCharacterMetrics();
839 TBitmapFontCharacterMetrics bitmap_font_metrics = FontBitmap()->CharacterMetrics(aCode,aBytes);
841 // Substitute the replacement character if this character doesn't exist in the font.
843 bitmap_font_metrics = FontBitmap()->CharacterMetrics(KReplacementCharacter,aBytes);
845 TCharacterMetrics metrics;
846 metrics.iAscentInPixels = bitmap_font_metrics.iAscentInPixels;
847 metrics.iHeightInPixels = bitmap_font_metrics.iHeightInPixels;
848 metrics.iLeftAdjustInPixels = bitmap_font_metrics.iLeftAdjustInPixels;
849 metrics.iMoveInPixels = bitmap_font_metrics.iMoveInPixels;
850 metrics.iRightAdjustInPixels = bitmap_font_metrics.iRightAdjustInPixels;
852 if (iAlgStyle.IsMono())
854 TInt width = metrics.iMoveInPixels - metrics.iLeftAdjustInPixels - metrics.iRightAdjustInPixels;
855 metrics.iMoveInPixels = FontBitmap()->iMaxNormalCharWidthInPixels;
856 metrics.iLeftAdjustInPixels = (TInt16)((metrics.iMoveInPixels - width) / 2);
857 metrics.iRightAdjustInPixels = (TInt16)(metrics.iMoveInPixels - width - metrics.iLeftAdjustInPixels);
860 return metrics; // N.B. Not doubled for double height and double width.
864 /** Gets a pointer to a bitmap and the metrics for a specified character.
866 Note that this function calls CharacterMetrics() if a CFontBitmap is being
867 used by the bitmap font object, and maps the TCharacterMetrics values returned
868 by that function to aMetrics.
870 If the function fails to get the bitmap and metric values (because the character
871 is in an open font and has not yet been rasterized) returns EFalse.
873 @param aSessionHandle A session handle for the open font system.
874 @param aCode A character code.
875 @param aMetrics On return, metrics for the specified character.
876 @param aBitmap On return, a pointer to the bitmap for the specified character.
877 @return ETrue if successful, otherwise EFalse. */
878 EXPORT_C TBool CBitmapFont::GetCharacterData(TInt aSessionHandle,TInt aCode,
879 TOpenFontCharMetrics& aMetrics,const TUint8*& aBitmap) const
883 const TOpenFontCharMetrics* nm;
884 if (OpenFont()->GetCharacterData(aSessionHandle,aCode,nm,aBitmap))
894 TCharacterMetrics m = CharacterMetrics(aCode,aBitmap);
895 aMetrics = TOpenFontCharMetrics(m);
900 /** Gets the open font metrics.
902 These metrics distinguish between maximum character height and depth and typographic
903 ascent and descent, so that the clipping rectangle for text can be distinguished
904 from the distance to neighbouring baselines.
906 @param aMetrics Open font metrics. */
908 EXPORT_C void CBitmapFont::GetFontMetrics(TOpenFontMetrics& aMetrics) const
911 aMetrics = OpenFont()->Metrics();
914 new(&aMetrics) TOpenFontMetrics;
915 aMetrics.SetSize(CBitmapFont::DoHeightInPixels());
916 aMetrics.SetAscent(CBitmapFont::DoAscentInPixels());
917 aMetrics.SetDescent(aMetrics.Size() - aMetrics.Ascent());
918 aMetrics.SetMaxHeight(aMetrics.Ascent());
919 aMetrics.SetMaxDepth(aMetrics.Descent());
920 aMetrics.SetMaxWidth(CBitmapFont::DoMaxCharWidthInPixels());
925 /** Gets the open font typeface attributes if possible.
927 At present no attempt is made to sythesize these attributes for bitmap fonts
930 @param aAttrib On return, the open font typeface attributes.
931 @return ETrue if successful; EFalse if not possible to get the open font typeface
933 EXPORT_C TBool CBitmapFont::GetFaceAttrib(TOpenFontFaceAttrib& aAttrib) const
937 const TOpenFontFaceAttrib* a = OpenFont()->FaceAttrib();
947 /** Gets encoding if a bitmap font (a CFontBitmap) is used.
949 @return Bitmap encoding value. */
950 EXPORT_C TInt CBitmapFont::BitmapEncoding() const
955 return FontBitmap()->iBitmapEncoding;
958 /** Gets whether the open or bitmap font has the specified character.
960 @param aCode A character code.
961 @return ETrue if the font has the specified character; otherwise EFalse. */
962 EXPORT_C TBool CBitmapFont::HasCharacterL(TInt aCode) const
965 return OpenFont()->HasCharacterL(aCode);
969 FontBitmap()->CharacterMetrics(aCode,bytes);
970 return (bytes != NULL);
974 /** Gets whether the specified character needs to be rasterised.
976 False is returned if it is a bitmap font (a CFontBitmap) being used by the
977 bitmap font object (so no rasterization is required) or if is an open font
978 (a COpenFont) and the character has been rasterized.
980 @param aSessionHandle A session handle for the open font system.
981 @param aCode A character code.
982 @return ETrue if the character needs to be rasterized; otherwise EFalse. */
983 EXPORT_C TBool CBitmapFont::CharacterNeedsToBeRasterized(TInt aSessionHandle,TInt aCode) const
986 return OpenFont()->CharacterNeedsToBeRasterized(aSessionHandle,aCode);
988 return FALSE; // characters in bitmap fonts do not need to be rasterized
991 /** Turns text into glyph codes and positions.
992 @param aText The Unicode text to shape plus context
993 @return The output shape header from the per-font cache, or 0 on failure.
996 EXPORT_C TShapeHeader* CBitmapFont::ShapeTextL(const TDesC16& aText,
997 TInt aSessionHandle, const TShapeMessageParameters& aParams)
999 TShapeHeader* shape = 0;
1003 // get the data in a CShaper::TInput for the shaper
1004 CShaper::TInput input;
1005 input.iText = &aText;
1006 input.iStart = aParams.iStart;
1007 input.iEnd = aParams.iEnd;
1008 input.iScript= aParams.iScript;
1009 input.iLanguage = aParams.iLanguage;
1010 input.iMaximumAdvance = KMaxTInt;
1012 input.iSessionHandle = aSessionHandle;
1013 input.iReserved1 = 0;
1015 TFontShapeFunctionParameters params;
1016 params.iEnd = input.iEnd;
1017 params.iLanguage = input.iLanguage;
1018 params.iScript = input.iScript;
1019 params.iStart = input.iStart;
1020 params.iText = input.iText;
1022 COpenFont* openFont = OpenFont();
1024 //if already exist just increase the reference count for that session
1025 shape = openFont->GetShapedData(aSessionHandle,¶ms);
1029 if (!openFont->HasShaper()
1030 || (openFont->HasShaper() && (
1031 (TUint32)(openFont->GetShaper()->ExtendedInterface(KUidShaperGetScript)) != input.iScript
1032 || (TUint32)(openFont->GetShaper()->ExtendedInterface(KUidShaperGetLang)) != input.iLanguage)))
1033 { // Install the shaper
1034 openFont->DeleteShaper();
1035 InstallOpenFontShaper(openFont, input);
1038 if (openFont->HasShaper())
1040 TInt error = openFont->GetShaper()->ShapeText(shape, input, iHeap);
1041 if (error != KErrNone)
1044 // Put this into the session cache
1045 TShapeHeader* cached_header = openFont->InsertShapedDataIntoCache(aSessionHandle,¶ms, shape);
1047 User::LeaveNoMemory();
1049 shape = cached_header;
1057 void CBitmapFont::InstallOpenFontShaper(COpenFont* aOpenFont, CShaper::TInput& aShaperInput)
1059 CShaper* shaper = NULL;
1060 const CArrayPtrFlat<CShaperFactory>* shaperFactoryList = aOpenFont->File()->GetFontStore()->ShaperFactoryList();
1062 TInt factoryCount = shaperFactoryList->Count();
1063 for (TInt index = 0; index < factoryCount; index++)
1065 TRAPD(err, shaper = (*shaperFactoryList)[index]->NewShaperL(this,
1066 aShaperInput.iScript, aShaperInput.iLanguage, iHeap));
1067 if (err == KErrNone)
1069 aOpenFont->SetShaper(shaper);
1070 OstTrace0( TRACE_IMPORTANT, CBITMAPFONT_INSTALLOPENFONTSHAPER, "A shaper is installed" );
1077 /** Frees the memory taken up as a result of shaping
1078 @internalTechnology */
1079 EXPORT_C void CBitmapFont::DeleteShape(TInt aSessionHandle,TShapeHeader* aHeader)
1081 //safe to assume aHeader is never NULL?
1084 //we just need to decrease the reference count, no deletion here
1085 //as the entry in cache can still be reused by other client
1086 //only in the case where the memory is full, the freeing will
1087 //delete any cache entry that is not referenced at all
1088 TInt ret=OpenFont()->DecrementCachedRefCount(aSessionHandle,aHeader);
1089 //panic in debug mode if trying to delete something that is not there.
1090 if ((ret != KErrNone) && (ret != KErrNotFound))
1092 OstTrace1( TRACE_FATAL, CBITMAPFONT_DELETESHAPE, "OpenFont()->DecrementCachedRefCount() return %d, Invariant", ret);
1093 __ASSERT_DEBUG(0, User::Invariant());
1098 EXPORT_C void CBitmapFont::operator delete(TAny *aThis)
1100 if (((CBitmapFont *)aThis)->iHeap)
1101 ((CBitmapFont *)aThis)->iHeap->Free(aThis);
1104 TInt CBitmapFont::Width(TInt aNum) const
1106 TInt widthfactor=iAlgStyle.WidthFactor();
1107 return ((widthfactor==1)? aNum: aNum*widthfactor);
1110 TInt CBitmapFont::Height(TInt aNum) const
1112 TInt heightfactor=iAlgStyle.HeightFactor();
1113 return ((heightfactor==1)? aNum: aNum*heightfactor);
1116 CFontBitmap* CBitmapFont::FontBitmap() const
1117 /** This member is private and not intended for use. */
1121 OstTrace0( TRACE_FATAL, CBITMAPFONT_FONTBITMAP, "Panic(EFntTypefaceHasNoFontBitmaps)" );
1122 __ASSERT_ALWAYS(0, Panic(EFntTypefaceHasNoFontBitmaps));
1124 if(iFontBitmapOffset)
1125 return reinterpret_cast<CFontBitmap*>(reinterpret_cast<TInt>(this)+iFontBitmapOffset);
1130 /** Gets a font table.
1131 @param aTag: Input. The name of the font table.
1132 @param aTableContent: Output. To return the address of the table content.
1133 @param aLength: Output. To return the length (in bytes) of the table.
1134 @param aSessionHandle: Input. A handle to the session requesting this table.
1135 @return KErrNone on success, specific error code on failure.
1138 EXPORT_C TInt CBitmapFont::GetFontTable(TUint32 aTag, TAny *&aTableContent,
1139 TInt &aLength, TInt aSessionHandle)
1141 COpenFont *fontPtr = NULL;
1143 fontPtr = OpenFont();
1145 return KErrNotSupported;
1147 // try to find it in cache.
1148 CFontStore *fntStore = fontPtr->File()->GetFontStore();
1149 TUid fileUid = fontPtr->File()->Uid();
1150 TInt ret = fntStore->FindFontTableInCache(fileUid, aTag, aTableContent, aLength);
1151 if (KErrNone == ret)
1153 ret = fntStore->IncFontTableRefCount(fileUid, aTag, aSessionHandle);
1157 // font table not found in cache.
1158 ret = fontPtr->GetFontTable(aTag, aTableContent, aLength);
1159 if (KErrNone == ret)
1161 ret = fntStore->CacheFontTable(fileUid, aTag, aTableContent, aLength);
1162 if (KErrNone == ret)
1164 ret = fntStore->IncFontTableRefCount(fileUid, aTag, aSessionHandle);
1168 aTableContent = NULL;
1175 /** Release a font table. Decrement its reference count. Remove from cache if
1176 * reference decreases to zero.
1177 @param aTag: Input. The name of the font table to be released.
1178 @param aSessionHandle: Input. Handle to the session releasing this table.
1179 @return KErrNone on success, specific error code on failure.
1182 EXPORT_C void CBitmapFont::ReleaseFontTable(TUint32 aTag,
1183 TInt aSessionHandle)
1185 COpenFont *fontPtr = NULL;
1187 fontPtr = OpenFont();
1191 CFontStore *fntStore = fontPtr->File()->GetFontStore();
1192 TUid fileUid = fontPtr->File()->Uid();
1193 fntStore->ReleaseFontTable(fileUid, aTag, aSessionHandle);
1197 /** Release a number of glyph outlines. Decrement their reference count.
1198 * Remove it from cache if reference count decreases to zero.
1199 @param aCount: Input. Number of outlines to be released.
1200 @param aCodes: Input. An array of codes. Its interpretation depends on the parameter
1201 'aIsGlyphId' (see below).
1202 @param aIsGlyphId: Input. When aIsGlyphId==ETrue, 'aCodes' is an array of glyph ID's.
1203 When aIsGlyphId==EFalse, 'aCodes' is an array of Unicode values.
1204 @param aHinted: Input. To indicate if the outlines are hinted or unhinted.
1205 @param aSessionHandle: Input. Handle to the session releasing the outlines.
1206 @return KErrNone on success, specific error code on failure.
1209 EXPORT_C void CBitmapFont::ReleaseGlyphOutlines(TInt aCount, const TUint *aCodes,
1210 TBool aHinted, TInt aSessionHandle)
1212 COpenFont *fontPtr = NULL;
1214 fontPtr = OpenFont();
1218 CFontStore *fontStore = fontPtr->File()->GetFontStore();
1220 for (TInt i = 0; i < aCount; ++i)
1224 THintedOutlineId outlineId(fontPtr, aCodes[i]);
1225 fontStore->ReleaseHintedOutline(outlineId, aSessionHandle);
1229 TInt faceId = fontPtr->FaceIndex();
1230 TUnhintedOutlineId outlineId(fontPtr->File()->Uid(), faceId, aCodes[i]);
1231 fontStore->ReleaseUnhintedOutline(outlineId, aSessionHandle);
1236 /** Gets a font table.
1237 @param aCode: Input. An glyph code. Its interpretation depends on the parameter
1238 'aIsGlyphId' (see below).
1239 @param aIsGlyphId: Input. When aIsGlyphId==ETrue, 'aCode' is a glyph ID.
1240 When aIsGlyphId==EFalse, 'aCode' is a Unicode values.
1241 @param aHinted: Input. To indicate if hinted or unhinted outline is needed.
1242 @param aOutline: Output. A 'void*' pointer, pointing to the outline in memory.
1243 @param aLength: Output. A TInt, recording the lenght (in bytes) of the outline.
1244 @param aSessionHandle: Input. Handle to the session requesting this outline.
1245 @return KErrNone on success, specific error code on failure.
1248 EXPORT_C TInt CBitmapFont::GetGlyphOutline(TUint aCode,
1249 TBool aHinted, TAny *&aOutline, TInt &aLength, TInt aSessionHandle)
1251 COpenFont *fontPtr = NULL;
1253 fontPtr = OpenFont();
1255 return KErrNotSupported;
1257 CFontStore *fontStore = fontPtr->File()->GetFontStore();
1258 TAny *outlineData = NULL;
1259 TInt len = KErrGeneral;
1260 TInt ret = KErrNone;
1263 TInt faceId = fontPtr->FaceIndex();
1264 TUnhintedOutlineId outlineId(fontPtr->File()->Uid(), faceId, aCode);
1265 ret = fontStore->FindUnhintedOutlineInCache(outlineId, outlineData, len);
1266 if (KErrNotFound == ret)
1268 TAny* tmpOutline = 0;
1270 ret = fontPtr->GetGlyphOutline(aCode, aHinted, tmpOutline, tmpLen);
1271 if (KErrNone == ret)
1273 fontStore->CacheUnhintedOutline(outlineId,
1274 tmpOutline, (TInt)tmpLen, outlineData, len);
1276 User::Free(tmpOutline);
1278 if (KErrNone == ret)
1280 fontStore->IncreaseUnhintedOutlineRefCount(outlineId, aSessionHandle);
1285 THintedOutlineId outlineId(fontPtr, aCode);
1286 ret = fontStore->FindHintedOutlineInCache(outlineId, outlineData, len);
1287 if (KErrNotFound == ret)
1289 TAny* tmpOutline = 0;
1291 ret = fontPtr->GetGlyphOutline(aCode, aHinted, tmpOutline, tmpLen);
1292 if (KErrNone == ret)
1294 fontStore->CacheHintedOutline(outlineId,
1295 tmpOutline, (TInt)tmpLen, outlineData, len);
1297 User::Free(tmpOutline);
1299 if (KErrNone == ret)
1301 fontStore->IncreaseHintedOutlineRefCount(outlineId, aSessionHandle);
1305 aOutline = outlineData;
1310 EXPORT_C TUint32 CBitmapFont::UniqueFontId()
1312 return iUniqueFontId;
1315 void CBitmapFont::SetUniqueFontId(TUint32 aUniqueFontId)
1317 iUniqueFontId = aUniqueFontId;
1320 /** API extension system that enables the caller to access a particular API
1321 extension function. As an overload of this function in a derived class
1322 it calls its immediate parent implementation for any extension function Uid
1323 that it does not recognize and handle.
1324 @param aInterfaceId UID of the required extension function
1325 @param aParam Pointer to an arbitrary parameter block that can be used to
1326 provide and/or return information to/from the particular extension function,
1328 @return Integer return value from extension function
1332 EXPORT_C TInt CBitmapFont::DoExtendedFunction(TUid aFunctionId, TAny* aParam) const
1334 if (KFontCapitalAscent == aFunctionId)
1336 return Height(IsOpenFont() ? OpenFont()->FontCapitalAscent() : FontBitmap()->FontCapitalAscent());
1338 else if (KFontMaxAscent == aFunctionId)
1340 return Height(IsOpenFont() ? OpenFont()->FontMaxAscent() : FontBitmap()->FontMaxAscent());
1342 else if (KFontStandardDescent == aFunctionId)
1344 return Height(IsOpenFont() ? OpenFont()->FontStandardDescent() : FontBitmap()->FontStandardDescent());
1346 else if (KFontMaxDescent == aFunctionId)
1348 return Height(IsOpenFont() ? OpenFont()->FontMaxDescent() : FontBitmap()->FontMaxDescent());
1350 else if (KFontLineGap == aFunctionId)
1352 return Height(IsOpenFont() ? OpenFont()->FontLineGap() : FontBitmap()->FontLineGap());
1355 return CFont::DoExtendedFunction(aFunctionId, aParam);
1359 CFontTableCacheItem::CFontTableCacheItem(TUid &aFileUid, const TUint32 aTag,
1360 TInt aOffset, TInt aLength): iFileUid(aFileUid), iTag(aTag),
1361 iOffset(aOffset), iLength(aLength)
1363 // a null constructor
1366 CFontTableCacheItem::~CFontTableCacheItem()
1368 iUsers.ResetAndDestroy();
1372 TBool CFontTableCacheItem::HasOutstandingRefCount()
1374 TInt count = iUsers.Count();
1375 for (TInt j = 0; j < count; ++j)
1377 if (iUsers[j]->iRefCount > 0)
1386 TInt CFontTableCacheItem::FindUser(TInt aSessionHandle, TInt *id)
1388 TInt len = iUsers.Count();
1389 for (TInt i = 0; i < len; ++i)
1391 if (aSessionHandle == iUsers[i]->iSessionHandle)
1397 return KErrNotFound;
1400 TInt CFontTableCacheItem::DecRefCount(TInt aSessionHandle)
1403 TInt ret = FindUser(aSessionHandle, &id);
1404 if (KErrNone == ret)
1406 iUsers[id]->iRefCount--;
1407 if (0 == iUsers[id]->iRefCount)
1412 return iUsers.Count();
1414 return KErrNotFound;
1417 TInt CFontTableCacheItem::IncRefCount(TInt aSessionHandle)
1420 TInt ret = FindUser(aSessionHandle, &id);
1421 if (KErrNone == ret)
1423 iUsers[id]->iRefCount++;
1427 TCacheUserInfo *newUser = new TCacheUserInfo(aSessionHandle, 1);
1428 if (NULL != newUser)
1430 TRAP(ret, iUsers.AppendL(newUser));
1436 //coverity[leaked_storage]
1437 // The 'newUser' is kept in iUsers. It will be deleted in DecRefCount().
1442 TInt CFontTableCache::Append(TUid aFileUid, TUint32 aTag,
1443 TAny *&aContent, TInt aLength)
1446 if ((TUint32)iCacheMemMon.GetMemUsage() >= KFontTable_GlyphOutline_CacheMaxMem)
1448 RDebug::Printf("Table/Glyph cache full. Unable to add new item.");
1449 return KErrNoMemory;
1451 // make a copy of the table content on the shared heap.
1452 TAny *sharedCopy = iHeap->Alloc(aLength);
1453 if (NULL == sharedCopy)
1455 return KErrNoMemory;
1458 Mem::Copy(sharedCopy, aContent, aLength);
1460 CFontTableCacheItem *newItem = NULL;
1461 TInt offset = PointerToOffset(sharedCopy, iHeap->Base());
1462 TRAP(ret, newItem = new(ELeave) CFontTableCacheItem(aFileUid, aTag, offset, aLength));
1463 if (KErrNone != ret)
1465 iHeap->Free(sharedCopy);
1469 TRAP(ret, iCacheItems.AppendL(newItem));
1470 if (KErrNone == ret)
1472 // do not free 'aContent', because the mem is managed by
1473 // rasterizer cache.
1474 aContent = sharedCopy;
1475 iCacheMemMon.Inc(aLength);
1479 iHeap->Free(sharedCopy);
1482 GetCacheState(__func__);
1487 TInt CFontTableCache::Find(TUid aFileUid, TUint32 aTag, TAny *&aContent,
1488 TInt &aLength, TInt *id)
1491 TInt len = iCacheItems.Count();
1493 TInt ret = KErrNotFound;
1494 for (TInt i = 0; i < len; ++i)
1496 CFontTableCacheItem *item = iCacheItems[i];
1497 if (item->iFileUid == aFileUid && item->iTag == aTag)
1499 aContent = OffsetToPointer(item->iOffset, iHeap->Base());
1500 aLength = item->iLength;
1508 GetCacheState(__func__);
1513 CFontTableCache::CFontTableCache(RHeap *aHeap, TFontTableGlyphOutlineCacheMemMonitor &aMon):
1514 iCacheMemMon(aMon), iHeap(aHeap)
1519 CFontTableCache::~CFontTableCache()
1521 for (TInt i = 0; i < iCacheItems.Count(); ++i)
1523 iHeap->Free(OffsetToPointer(iCacheItems[i]->iOffset, iHeap->Base()));
1525 iCacheItems.ResetAndDestroy();
1526 iCacheItems.Close();
1529 TInt CFontTableCache::IncRefCount(TUid aFileUid, TUint32 aTag, TInt aSessionHandle)
1531 TAny *outline = NULL;
1535 TInt ret = Find(aFileUid, aTag, outline, len, &id);
1536 if (KErrNone == ret)
1538 ret = iCacheItems[id]->IncRefCount(aSessionHandle);
1542 GetCacheState(__func__);
1547 TInt CFontTableCache::DecRefCount(TUid aFileUid, TUint32 aTag, TInt aSessionHandle)
1549 TAny *outline = NULL;
1553 TInt ret = Find(aFileUid, aTag, outline, len, &id);
1554 if (KErrNone == ret)
1556 TInt numUsers = iCacheItems[id]->DecRefCount(aSessionHandle);
1559 // There is no outstanding reference to the cache item.
1560 iHeap->Free(outline);
1561 iCacheMemMon.Dec(len);
1562 delete (iCacheItems[id]);
1563 iCacheItems.Remove(id);
1568 GetCacheState(__func__);
1573 TBool CFontTableCache::HasOutstandingRefCount()
1575 TInt len = iCacheItems.Count();
1577 for (TInt i = 0; i < len; ++i)
1579 if (iCacheItems[i]->HasOutstandingRefCount())
1587 TBool CFontTableCache::HasOutstandingRefCountWithUid(TUid aFileUid)
1589 TInt len = iCacheItems.Count();
1591 for (TInt i = 0; i < len; ++i)
1593 if (iCacheItems[i]->iFileUid == aFileUid)
1595 if (iCacheItems[i]->HasOutstandingRefCount())
1604 void CFontTableCache::CleanupCacheOnOpenFontFileRemoval(COpenFontFile *)
1606 // In CFontStore::RemoveFile(), a font file is not allowed to be removed if
1607 // there are outstanding ref counts on any table in it. If that check passed
1608 // and this function is called, there shall be no cache item for that file.
1610 // Currently a cache item having a refcount of 0 is removed immediately.
1611 // If this strategy is changed in the future, we may need to do some
1615 void CFontTableCache::CleanupCacheOnFbsSessionTermination(TInt aSessionHandle)
1617 TInt len = iCacheItems.Count();
1619 for (TInt i = 0; i < len; ++i)
1622 if (KErrNone == iCacheItems[i]->FindUser(aSessionHandle, &id))
1624 iCacheItems[i]->iUsers.Remove(id);
1625 if (iCacheItems[i]->iUsers.Count() == 0)
1627 iHeap->Free(OffsetToPointer(iCacheItems[i]->iOffset, iHeap->Base()));
1628 iCacheMemMon.Dec(iCacheItems[i]->iLength);
1629 delete iCacheItems[i];
1630 iCacheItems.Remove(i);
1638 TInt CFontTableCache::GetCacheState(const char *func)
1640 RDebug::Printf("%s called from %s: ", __func__, func);
1643 int len = iCacheItems.Count();
1644 int numTables = 0, numSessions = 0, totalRef = 0;
1645 buf.Append(_L("Table cache: "));
1646 for (int i = 0; i < len; ++i)
1649 TInt abc = iCacheItems[i]->iUsers.Count();
1651 for (int j = 0; j < abc; ++j)
1653 totalRef += iCacheItems[i]->iUsers[j]->iRefCount;
1656 if (0 == iCacheItems.Count())
1658 buf.Append(_L("cache empty. "));
1662 buf.AppendFormat(_L("%d tables referenced by %d sessions, total ref count %d"),
1663 numTables, numSessions, totalRef);
1665 RDebug::RawPrint(buf);
1672 TInt COutlineCacheItem::FindUser(TInt aSessionHandle, TInt *id)
1674 TInt len = iUsers.Count();
1675 for (TInt i = 0; i < len; ++i)
1677 if (aSessionHandle == iUsers[i]->iSessionHandle)
1683 return KErrNotFound;
1686 COutlineCacheItem::~COutlineCacheItem()
1688 iUsers.ResetAndDestroy();
1691 COutlineCacheItem::COutlineCacheItem(TInt aOffset, TInt aLength):
1692 iOffset(aOffset), iLength(aLength)
1694 // a null constructor.
1697 TInt COutlineCacheItem::DecRefCount(TInt aSessionHandle)
1700 TInt ret = FindUser(aSessionHandle, &id);
1701 if (KErrNone == ret)
1703 iUsers[id]->iRefCount--;
1704 if (0 == iUsers[id]->iRefCount)
1709 return iUsers.Count();
1711 return KErrNotFound;
1714 TInt COutlineCacheItem::IncRefCount(TInt aSessionHandle)
1717 TInt ret = FindUser(aSessionHandle, &id);
1718 if (KErrNone == ret)
1720 iUsers[id]->iRefCount++;
1724 TCacheUserInfo *newUser = new TCacheUserInfo(aSessionHandle, 1);
1725 if (NULL != newUser)
1727 TRAP(ret, iUsers.AppendL(newUser));
1733 //coverity[leaked_storage]
1734 // The 'newUser' is kept in iUsers. It will be deleted in DecRefCount().
1740 TInt CUnhintedOutlineCache::GetCacheState(const char *func)
1742 RDebug::Printf("%s called from %s: ", __func__, func);
1743 int numSessions = 0, totalRef = 0;
1744 THashMapIter<TUnhintedOutlineId, COutlineCacheItem*> it(iItemIdMap);
1746 while (it.CurrentValue())
1748 COutlineCacheItem **data = it.CurrentValue();
1749 int len = (*data)->iUsers.Count();
1751 for (int j = 0; j < len; ++j)
1753 totalRef += (*data)->iUsers[j]->iRefCount;
1759 buf.Append(_L("Unhinted outline cache: "));
1760 TInt numItems = iItemIdMap.Count();
1763 buf.Append(_L("empty. "));
1767 buf.AppendFormat(_L("%d glyphs, %d sessions, total refcount %d"),
1768 numItems, numSessions, totalRef);
1771 RDebug::RawPrint(buf);
1777 CUnhintedOutlineCache::CUnhintedOutlineCache(RHeap *aHeap, TFontTableGlyphOutlineCacheMemMonitor &aMon):
1778 iCacheMemMon(aMon), iHeap(aHeap),
1779 iItemIdMap(THashFunction32<TUnhintedOutlineId>(CUnhintedOutlineCache::IdHash),
1780 TIdentityRelation<TUnhintedOutlineId>(CUnhintedOutlineCache::IdIdentity))
1785 CUnhintedOutlineCache::~CUnhintedOutlineCache()
1787 THashMapIter<TUnhintedOutlineId, COutlineCacheItem*> it(iItemIdMap);
1789 while (it.CurrentValue())
1791 const TUnhintedOutlineId *outlineId = it.CurrentKey();
1792 COutlineCacheItem **data = it.CurrentValue();
1795 iHeap->Free(OffsetToPointer((*data)->iOffset, iHeap->Base()));
1797 iItemIdMap.Remove(*outlineId);
1806 TInt CUnhintedOutlineCache::CleanupCacheOnOpenFontFileRemoval(COpenFontFile *aFontFile)
1808 TUid fileUid = aFontFile->Uid();
1810 THashMapIter<TUnhintedOutlineId, COutlineCacheItem*> it(iItemIdMap);
1812 while (it.CurrentValue())
1814 const TUnhintedOutlineId *outlineId = it.CurrentKey();
1815 COutlineCacheItem **data = it.CurrentValue();
1818 if (outlineId->iFileUid == fileUid)
1820 iHeap->Free(OffsetToPointer((*data)->iOffset, iHeap->Base()));
1821 iCacheMemMon.Dec((*data)->iLength);
1823 iItemIdMap.Remove(*outlineId);
1832 TInt CUnhintedOutlineCache::CleanupCacheOnFbsSessionTermination(TInt aSessionHandle)
1834 THashMapIter<TUnhintedOutlineId, COutlineCacheItem*> it(iItemIdMap);
1836 while (it.CurrentValue())
1838 const TUnhintedOutlineId *outlineId = it.CurrentKey();
1839 COutlineCacheItem **data = it.CurrentValue();
1843 TInt ret = (*data)->FindUser(aSessionHandle, &id);
1844 if (KErrNone == ret)
1846 delete (*data)->iUsers[id];
1847 (*data)->iUsers.Remove(id);
1848 if (0 == (*data)->iUsers.Count())
1850 iHeap->Free(OffsetToPointer((*data)->iOffset, iHeap->Base()));
1851 iCacheMemMon.Dec((*data)->iLength);
1853 iItemIdMap.Remove(*outlineId);
1864 TInt CUnhintedOutlineCache::CacheUnhintedOutline(const TUnhintedOutlineId &aOutlineId,
1865 TAny* const aData, const TInt aLength, TAny *&aOutline, TInt &aLen)
1868 GetCacheState(__func__);
1870 if ((TUint32)iCacheMemMon.GetMemUsage() >= KFontTable_GlyphOutline_CacheMaxMem)
1872 RDebug::Printf("Table/Glyph cache full. Unable to add new item.");
1873 return KErrNoMemory;
1877 TInt ret1= KErrNone;
1879 // make a copy of the outline data on the shared heap.
1880 TAny *sharedCopy = iHeap->Alloc(aLength);
1881 if (NULL == sharedCopy)
1883 return KErrNoMemory;
1886 Mem::Copy(sharedCopy, aData, aLength);
1888 COutlineCacheItem *newItem = NULL;
1889 TInt offset = PointerToOffset(sharedCopy, iHeap->Base());
1890 TRAP(ret1, newItem = new(ELeave) COutlineCacheItem(offset, aLength));
1891 if (KErrNone != ret1)
1893 iHeap->Free(sharedCopy);
1898 TRAP(ret1, iItemIdMap.InsertL(aOutlineId, newItem));
1899 if (KErrNone != ret1)
1902 iHeap->Free(sharedCopy);
1907 iCacheMemMon.Inc(aLength);
1911 aOutline = sharedCopy;
1915 TInt CUnhintedOutlineCache::IncRefCount(const TUnhintedOutlineId &aOutlineId,
1916 TInt aSessionHandle)
1919 GetCacheState(__func__);
1921 COutlineCacheItem **ret = iItemIdMap.Find(aOutlineId);
1924 (*ret)->IncRefCount(aSessionHandle);
1926 return (NULL==ret?KErrNotFound:KErrNone);
1929 TInt CUnhintedOutlineCache::DecRefCount(const TUnhintedOutlineId &aOutlineId,
1930 TInt aSessionHandle)
1933 GetCacheState(__func__);
1935 COutlineCacheItem **ret = iItemIdMap.Find(aOutlineId);
1938 TInt numUsers = (*ret)->DecRefCount(aSessionHandle);
1941 // There is no outstanding reference to the cache item.
1942 iHeap->Free(OffsetToPointer((*ret)->iOffset, iHeap->Base()));
1943 iCacheMemMon.Dec((*ret)->iLength);
1945 iItemIdMap.Remove(aOutlineId);
1948 return (NULL==ret?KErrNotFound:KErrNone);
1951 TInt CUnhintedOutlineCache::Find(const TUnhintedOutlineId &aOutlineId, TAny *&aData,
1954 COutlineCacheItem **ret = iItemIdMap.Find(aOutlineId);
1955 TInt ret2 = KErrNone;
1958 aData = OffsetToPointer((*ret)->iOffset, iHeap->Base());
1959 aLength = (*ret)->iLength;
1963 ret2 = KErrNotFound;
1969 TUint32 CUnhintedOutlineCache::IdHash(const TUnhintedOutlineId &outlineId)
1972 // bits 0-15: glyph id;
1973 // bits 16-23: lower 8 bit of font file uid
1974 // bits 24-27: lower 4 bit of the face index
1975 // bit 28: 'isGlyphId'
1977 ret |= (outlineId.iId & KOutlineGlyphIdHashMask);
1978 ret |= (KOutlineFileUidHashMask & (outlineId.iFileUid.iUid << 16));
1979 ret |= (KOutlineFaceIndexHashMask & (outlineId.iFaceIndex << 24));
1984 TBool CUnhintedOutlineCache::IdIdentity(const TUnhintedOutlineId &id1, const TUnhintedOutlineId &id2)
1986 return id1.iId == id2.iId && id1.iFaceIndex == id2.iFaceIndex &&
1987 id1.iFileUid == id2.iFileUid;
1990 // hinted outline cache
1992 TInt CHintedOutlineCache::GetCacheState(const char *func)
1994 RDebug::Printf("%s called from %s: ", __func__, func);
1995 int numSessions = 0, totalRef = 0;
1996 THashMapIter<THintedOutlineId, COutlineCacheItem*> it(iItemIdMap);
1998 while (it.CurrentValue())
2000 COutlineCacheItem **data = it.CurrentValue();
2001 int len = (*data)->iUsers.Count();
2003 for (int j = 0; j < len; ++j)
2005 totalRef += (*data)->iUsers[j]->iRefCount;
2011 buf.Append(_L("Hinted outline cache: "));
2012 TInt numItems = iItemIdMap.Count();
2015 buf.Append(_L("empty. "));
2019 buf.AppendFormat(_L("%d glyphs, %d sessions, total refcount %d"),
2020 numItems, numSessions, totalRef);
2023 RDebug::RawPrint(buf);
2029 TInt CHintedOutlineCache::CleanupCacheOnOpenFontRemoval(COpenFont *aFont)
2031 THashMapIter<THintedOutlineId, COutlineCacheItem*> it(iItemIdMap);
2033 while (it.CurrentValue())
2035 const THintedOutlineId *outlineId = it.CurrentKey();
2036 COutlineCacheItem **data = it.CurrentValue();
2039 if (outlineId->iFont == aFont)
2041 iCacheMemMon.Dec((*data)->iLength);
2042 iHeap->Free(OffsetToPointer((*data)->iOffset, iHeap->Base()));
2044 iItemIdMap.Remove(*outlineId);
2053 TInt CHintedOutlineCache::CleanupCacheOnFbsSessionTermination(TInt aSessionHandle)
2055 THashMapIter<THintedOutlineId, COutlineCacheItem*> it(iItemIdMap);
2057 while (it.CurrentValue())
2059 const THintedOutlineId *outlineId = it.CurrentKey();
2060 COutlineCacheItem **data = it.CurrentValue();
2064 TInt ret = (*data)->FindUser(aSessionHandle, &id);
2065 if (KErrNone == ret)
2067 delete (*data)->iUsers[id];
2068 (*data)->iUsers.Remove(id);
2069 if (0 == (*data)->iUsers.Count())
2071 iCacheMemMon.Dec((*data)->iLength);
2072 iHeap->Free(OffsetToPointer((*data)->iOffset, iHeap->Base()));
2074 iItemIdMap.Remove(*outlineId);
2086 CHintedOutlineCache::CHintedOutlineCache(RHeap *aHeap, TFontTableGlyphOutlineCacheMemMonitor &aMon):
2087 iCacheMemMon(aMon), iHeap(aHeap),
2088 iItemIdMap(THashFunction32<THintedOutlineId>(CHintedOutlineCache::IdHash),
2089 TIdentityRelation<THintedOutlineId>(CHintedOutlineCache::IdIdentity))
2091 // a null constructor
2094 TInt CHintedOutlineCache::CacheHintedOutline(const THintedOutlineId &aOutlineId,
2095 TAny* aData, TInt aLength, TAny *&aOutline, TInt &aLen)
2098 GetCacheState(__func__);
2100 if ((TUint32)iCacheMemMon.GetMemUsage() >= KFontTable_GlyphOutline_CacheMaxMem)
2102 RDebug::Printf("Table/Glyph cache full. Unable to add new item.");
2103 return KErrNoMemory;
2107 TInt ret = KErrNone;
2108 // make a copy of the outline data on the shared heap.
2109 TAny *sharedCopy = iHeap->Alloc(aLength);
2110 if (NULL == sharedCopy)
2112 return KErrNoMemory;
2115 Mem::Copy(sharedCopy, aData, aLength);
2117 COutlineCacheItem *newItem = NULL;
2118 TInt offset = PointerToOffset(sharedCopy, iHeap->Base());
2119 TRAP(ret, newItem = new(ELeave) COutlineCacheItem(offset, aLength));
2120 if (KErrNone != ret)
2122 iHeap->Free(sharedCopy);
2127 TRAP(ret, iItemIdMap.InsertL(aOutlineId, newItem));
2128 if (KErrNone != ret)
2131 iHeap->Free(sharedCopy);
2136 iCacheMemMon.Inc(aLength);
2140 aOutline = sharedCopy;
2144 TInt CHintedOutlineCache::IncRefCount(const THintedOutlineId &aOutlineId,
2145 TInt aSessionHandle)
2148 GetCacheState(__func__);
2150 COutlineCacheItem **data = iItemIdMap.Find(aOutlineId);
2153 (*data)->IncRefCount(aSessionHandle);
2155 return (NULL==data?KErrNotFound:KErrNone);
2158 TInt CHintedOutlineCache::DecRefCount(const THintedOutlineId &aOutlineId,
2159 TInt aSessionHandle)
2162 GetCacheState(__func__);
2164 COutlineCacheItem **data = iItemIdMap.Find(aOutlineId);
2167 TInt numUsers = (*data)->DecRefCount(aSessionHandle);
2170 // There is no outstanding reference to the cache item.
2171 iCacheMemMon.Dec((*data)->iLength);
2172 iHeap->Free(OffsetToPointer((*data)->iOffset, iHeap->Base()));
2174 iItemIdMap.Remove(aOutlineId);
2177 return (NULL==data?KErrNotFound:KErrNone);
2180 TInt CHintedOutlineCache::Find(const THintedOutlineId &aOutlineId,
2181 TAny *&aData, TInt &aLength)
2183 COutlineCacheItem **ret = iItemIdMap.Find(aOutlineId);
2184 TInt ret2 = KErrNone;
2187 aData = OffsetToPointer((*ret)->iOffset, iHeap->Base());
2188 aLength = (*ret)->iLength;
2192 ret2 = KErrNotFound;
2198 TUint32 CHintedOutlineCache::IdHash(const THintedOutlineId &outlineId)
2201 // bits 0-15: the outline id
2202 // bits 16-27: the lower 12 bits of the font pointer
2203 // bit 28: 'isGlyphId'
2206 ret |= (KOutlineGlyphIdHashMask & outlineId.iId);
2207 ret |= (KOutlineFontPtrHashMask & (((TUint32)outlineId.iFont) << 16));
2212 TBool CHintedOutlineCache::IdIdentity(const THintedOutlineId &id1, const THintedOutlineId &id2)
2214 return id1.iId == id2.iId && id1.iFont == id2.iFont;
2219 CFontStore::CFontStore(RHeap* aHeap):
2220 iKPixelWidthInTwips(KDefaultPixelWidthInTwips),
2221 iKPixelHeightInTwips(KDefaultPixelHeightInTwips),
2224 iFontStoreFileList(KDefaultArrayGranularity), // list of EPOC Bitmap font files loaded
2225 iTypefaceList(KDefaultArrayGranularity),
2226 iFontBitmapList(KDefaultArrayGranularity),
2227 iTypefaceFontBitmapList(KDefaultArrayGranularity),
2228 iOpenFontFileList(KDefaultArrayGranularity), // list of 'Open Font' files loaded
2229 iOpenFontRasterizerList(KDefaultArrayGranularity), // open rasterizers, in load order
2231 iDefaultBitmapType(EMonochromeGlyphBitmap),
2232 iShaperFactoryList(KDefaultArrayGranularity),
2233 iOpenFontShaperCacheMemUsage(0),
2234 iNumberOfShaperCaches(0),
2235 iOpenFontTypefaceSupportList(KDefaultArrayGranularity), // list of Open Font typefaces available
2236 iUniqueFontIdCount(0) // used to give every font a unique id
2240 void CFontStore::ConstructL()
2242 // Cache is placed in the shared heap
2243 iOpenFontSessionCacheList = (COpenFontSessionCacheList*)iHeap->AllocL(sizeof(COpenFontSessionCacheList));
2244 new(iOpenFontSessionCacheList) COpenFontSessionCacheList;
2246 CTypefaceStore::ConstructL();
2247 User::LeaveIfError(iFs.Connect());
2249 TMachineInfoV1Buf machineInfoBuffer;
2250 User::LeaveIfError(UserHal::MachineInfo(machineInfoBuffer));
2252 const TSize twipSize = machineInfoBuffer().iPhysicalScreenSize;
2253 const TSize pixelSize = machineInfoBuffer().iDisplaySizeInPixels;
2255 if (twipSize.iWidth > 0 && pixelSize.iWidth > 0)
2256 iKPixelWidthInTwips = twipSize.iWidth * 1000 / pixelSize.iWidth;
2258 if (twipSize.iHeight > 0 && pixelSize.iHeight > 0)
2259 iKPixelHeightInTwips = twipSize.iHeight * 1000 / pixelSize.iHeight;
2261 iCacheMemMon = new(ELeave) TFontTableGlyphOutlineCacheMemMonitor;
2262 iUnhintedOutlineCache = new(ELeave) CUnhintedOutlineCache(iHeap, *iCacheMemMon);
2263 iHintedOutlineCache = new(ELeave) CHintedOutlineCache(iHeap, *iCacheMemMon);
2264 iFontTableCache = new(ELeave) CFontTableCache(iHeap, *iCacheMemMon);
2268 /** Creates a new CFontStore object.
2270 Sets iKPixelWidthInTwips and iKPixelHeightInTwips.
2272 Sets the default bitmap type, used when getting bitmap fonts, to EMonochromeGlyphBitmap.
2274 Also initialises other private member variable values .
2276 @param aHeap A pointer to the heap class used for memory allocation.
2277 @leave KErrNoMemory Insufficient memory available on the heap. */
2278 EXPORT_C CFontStore *CFontStore::NewL(RHeap* aHeap)
2280 User::LeaveIfNull(aHeap);
2281 CFontStore *fontstore = new(ELeave) CFontStore(aHeap);
2282 CleanupStack::PushL(fontstore);
2283 fontstore->ConstructL();
2284 CleanupStack::Pop(fontstore);
2289 EXPORT_C CFontStore::~CFontStore()
2291 // Remove All font files, and Reset associated arrays
2292 RemoveFile(KNullUid);
2293 iOpenFontRasterizerList.ResetAndDestroy();
2294 iShaperFactoryList.ResetAndDestroy();
2295 if (iOpenFontSessionCacheList)
2297 iOpenFontSessionCacheList->Delete(iHeap);
2298 iHeap->Free(iOpenFontSessionCacheList);
2302 delete iFontTableCache;
2303 delete iUnhintedOutlineCache;
2304 delete iHintedOutlineCache;
2305 delete iCacheMemMon;
2309 // local utility functions
2310 // reads bytes from file, if the requested number of bytes are not available it leaves
2311 void ReadFromFileL(RFile& aFile, TDes8& aDes, TInt aLength)
2313 User::LeaveIfError(aFile.Read(aDes, aLength));
2314 if (aDes.Length() != aLength)
2316 OstTrace0( TRACE_DUMP, _READFROMFILEL, "EOF reading structure from font file, Leave(KErrCorrupt)" );
2317 User::Leave(KErrCorrupt);
2321 // local function(s) to read values from buffer & validate them
2322 TUint TtfTableTagFromBufferL(TDes8& aDes)
2325 for (TUint index = 0; index < 4;)
2327 TUint temp = static_cast<TUint>(aDes[index++]);
2328 // must be ASCII character between 32 & 126 inclusive (per Apple's TTF specification document)
2329 if ( (temp < 32) || (temp > 126) )
2331 OstTrace1( TRACE_DUMP, _TTFTABLETAGFROMBUFFERL, "invalid ASCII character (0x%x) in ttf table tag, Leave(KErrCorrupt)", temp);
2332 User::Leave(KErrCorrupt);
2334 value = (value << 8) | temp;
2339 /* Sanity check for TrueType Font, checks that the font tables are sensible.
2341 void CFontStore::SanityCheckForTtfL(RFile& aFontFile, TUint aFontFileSize, TBool aStrictChecking)
2343 OstTraceExt2( TRACE_DUMP, CFONTSTORE_SANITYCHECKFORTTFL, "TTF File Size is %u (0x%x) bytes", aFontFileSize, aFontFileSize );
2344 // check the Offset Table at the start of the file
2345 TBuf8<16> fileBuffer;
2347 ReadFromFileL(aFontFile, fileBuffer, 12);
2348 TUint numTables = (fileBuffer[4] << 8) | (fileBuffer[5]);
2349 TUint searchRange = (fileBuffer[6] << 8) | (fileBuffer[7]);
2350 TUint entrySelector = (fileBuffer[8] << 8) | (fileBuffer[9]);
2351 TUint rangeShift = (fileBuffer[10] << 8) | (fileBuffer[11]);
2353 const TInt tableStart = 12 + (numTables << 4); // lowest possible address for actual table data
2355 if ( (numTables == 0) || (numTables & 0xF0000000) || (tableStart > aFontFileSize) )
2357 OstTrace1( TRACE_DUMP, DUP1_CFONTSTORE_SANITYCHECKFORTTFL, "# of tables (%d) in ttf is invalid, Leave(KErrCorrupt)", numTables );
2358 User::Leave(KErrCorrupt);
2361 #if defined(_DEBUG) && defined(VERBOSE_DEBUG)
2362 // scalar type is 0x00010000 for Windows fonts, other possible values include 0x74727565 and 0x74797031: not checked
2363 TUint scalarType = (fileBuffer[0] << 24) | (fileBuffer[1] << 16) | (fileBuffer[2] << 8) | (fileBuffer[3]);
2364 RDebug::Print(_L("ttf scalarType is 0x%x, # of tables is %u\n"), scalarType, numTables);
2365 RDebug::Print(_L("searchRange is 0x%x, entrySelector is 0x%x, rangeShift is 0x%x\n"),
2366 searchRange, entrySelector, rangeShift);
2369 // check searchRange, entrySelector & rangeShift values
2370 // (some not quite TTF files fail the rangeShift check)
2371 if ( (searchRange < 16) || (entrySelector > 24)
2372 || (aStrictChecking && (rangeShift != ( (numTables << 4) - searchRange )) ) )
2374 OstTraceExt4( TRACE_DUMP, DUP2_CFONTSTORE_SANITYCHECKFORTTFL, "searchRange (0x%x), entrySelector (0x%x) or rangeShift (0x%x) invalid for numTables (%d), Leave(KErrCorrupt)",
2375 searchRange, entrySelector, rangeShift, numTables );
2376 User::Leave(KErrCorrupt);
2379 // entrySelector is defined as Log2(Maximum power of 2 <= nmumTables)
2380 TUint exp = 1 << entrySelector; // log to exponent
2381 if ( (numTables < exp) || (numTables > (exp << 1)) )
2383 OstTraceExt2( TRACE_DUMP, DUP3_CFONTSTORE_SANITYCHECKFORTTFL, "entrySelector (0x%x) wrong for numTables(%d), Leave(KErrCorrupt)",
2384 entrySelector, numTables );
2385 User::Leave(KErrCorrupt);
2388 // easy checks on the table directory
2389 TInt totalFontSize = tableStart; // accumulated total directories plus table sizes
2390 TInt highestTableEnd = 0; // highest value found for table start plus table length
2391 TUint lastTableTag = 0; // to check that tags are in order
2395 { // each entry is 16 bytes, (though we don't check the checksum)
2396 ReadFromFileL(aFontFile, fileBuffer, 16);
2397 TUint tableTag = TtfTableTagFromBufferL(fileBuffer);
2398 TUint offset = (fileBuffer[8] << 24) | (fileBuffer[9] << 16) | (fileBuffer[10] << 8) | (fileBuffer[11]);
2399 TUint length = (fileBuffer[12] << 24) | (fileBuffer[13] << 16) | (fileBuffer[14] << 8) | (fileBuffer[15]);
2401 #if defined(_DEBUG) && defined(VERBOSE_DEBUG)
2402 RDebug::Print(_L("ttf table tag ('%c%c%c%c'): offset is 0x%x, length is 0x%x\n"),
2403 tableTag >> 24, (tableTag >> 16) & 0x7F, (tableTag >> 8) & 0x7F, tableTag & 0x7F,
2406 length = (length + 3) & ~3; // round up, all tables must be a multiple of 4 bytes for checksumming
2408 // table Tags must be unique & in order
2409 if (tableTag <= lastTableTag)
2411 OstTraceExt4( TRACE_DUMP, DUP4_CFONTSTORE_SANITYCHECKFORTTFL, "ttf table tag ('%c%c%c%c') is out of order, Leave(KErrCorrupt)",
2412 tableTag >> 24, (tableTag >> 16) & 0x7F, (tableTag >> 8) & 0x7F, tableTag & 0x7F);
2413 User::Leave(KErrCorrupt);
2417 // the offset must be 4-byte aligned, and after the table directory
2418 // offset + length must be bigger than the start offset (!)
2419 TInt end = length + offset;
2420 if ( (offset & 3) || (offset < tableStart) || (length == 0) || (end < offset) || (end > aFontFileSize))
2422 OstTraceExt2( TRACE_DUMP, DUP5_CFONTSTORE_SANITYCHECKFORTTFL, "offset (0x%x) or length (0x%x) are bad, Leave(KErrCorrupt)",
2424 User::Leave(KErrCorrupt);
2427 lastTableTag = tableTag;
2428 totalFontSize += length;
2429 if (end > highestTableEnd)
2431 highestTableEnd = end;
2434 while (++tableNum < numTables);
2436 #if defined(_DEBUG) && defined(VERBOSE_DEBUG)
2437 RDebug::Print(_L("last address used by any table is 0x%x, Minimum font file size to hold all tables is 0x%x\n"),
2438 highestTableEnd, totalFontSize);
2441 // for single font files highestTableEnd & totalFontSize should be the same
2442 if (highestTableEnd != totalFontSize)
2444 OstTraceExt2( TRACE_DUMP, DUP6_CFONTSTORE_SANITYCHECKFORTTFL, "Total Font Size (0x%x) is different from end of the last table (0x%x), Leave(KErrCorrupt)",
2445 highestTableEnd, totalFontSize);
2446 User::Leave(KErrCorrupt);
2450 /* Sanity checks on font files, currently only knows about TrueType Font files: .ttf and .otf
2451 Protects FBserv / the client and the rasterizer plug-in from grossly corrupt data.
2452 @leave KErrCorrupt if the font tables are daft
2454 void CFontStore::SanityCheckFontFileL(TParse& aParse)
2457 // try to open the file and getting the file size
2459 const TInt openError = fontFile.Open(iFs, aParse.FullName(), EFileRead | EFileShareReadersOnly);
2461 if (KErrNone != openError)
2463 const TDesC& fileName = aParse.FullName();
2464 RDebug::Print(_L("Sanity checking font file \"%S\", file open gave error %d\n"), &fileName, openError);
2467 User::LeaveIfError(openError);
2468 CleanupClosePushL(fontFile);
2469 TInt fontFileSize = 0;
2470 User::LeaveIfError(fontFile.Size(fontFileSize));
2472 if (fontFileSize == 0)
2473 { // no font can be zero length!
2475 RDebug::Print(_L("font file size (%i) is zero\n"), fontFileSize);
2477 User::Leave(KErrCorrupt);
2481 const TDesC& fileExt = aParse.Ext();
2483 _LIT(KFntStoreTrueTypeExtension,".ttf");
2485 _LIT(KFntStoreOpenTypeExtension,".otf");
2486 // other font files that follow TTF format
2487 _LIT(KFntStoreCccFontFileExtension,".ccc");
2489 if ( (0 == fileExt.CompareF(KFntStoreTrueTypeExtension)) || (0 == fileExt.CompareF(KFntStoreOpenTypeExtension)) )
2490 { // uses TrueType file format, perform strict format check
2491 SanityCheckForTtfL(fontFile, fontFileSize, ETrue);
2493 else if (0 == fileExt.CompareF(KFntStoreCccFontFileExtension))
2494 { // uses nearly TrueType file format, perform slightly less strict format check
2495 SanityCheckForTtfL(fontFile, fontFileSize, EFalse);
2498 // extendible if required for other font file types ...
2501 CleanupStack::PopAndDestroy(&fontFile);
2505 /** Finds or creates a font file object to support a font file. The specified font
2506 file must be accessible to any process, i.e. not located inside an
2507 application's private directory.
2509 If an appropriate font file object exists then no new open font file is created.
2510 In this case the reference count of the font file object is incremented.
2514 If aName is recognised as an open font file, creates a COpenFontFile, which
2515 will manage the font file specified by aName, and adds it to the file store's
2516 list of open font files.
2518 The list of open font files is used when getting the nearest font for a font
2519 specification (i.e. by the GetNearestFont...() functions of this class) if
2520 the font is generated via a rasterizer.
2522 The appropriate rasterizer, which supports the font format of the font file,
2523 is used to generate the open font file using COpenFontRasterizer::NewFontFileL().
2525 If aName is not recognised as an open font file then CFontStoreFile tries to open
2526 the file as a Symbian Bitmap font.
2528 @param aName The full path and filename of the font file to be supported.
2529 @return The UID of the font file object supporting aName.
2530 @leave KErrNotSupported if the file is not recognised at all
2531 @leave KErrCorrupt if the font file data does not make sense
2532 @leave or another system-wide error
2534 EXPORT_C TUid CFontStore::AddFileL(const TDesC& aName)
2536 TParse fontFilename;
2537 User::LeaveIfError(iFs.Parse(aName, fontFilename));
2539 // increment reference count if font file is already loaded
2540 TUid fontUid = KNullUid;
2542 if (IncRefCountOfLoadedFont(fontFilename, fontUid))
2547 // Do not validate fonts on Z: (assumed to be ROM created with valid fonts)
2548 if (!FileIsOnZ(fontFilename))
2550 // file is not open - check that the file exists and has a plausible content
2551 SanityCheckFontFileL(fontFilename);
2554 AddSanityCheckedFontL(fontFilename, fontUid);
2560 Finds or creates a font file object to support a font file.
2561 @param aFileName The filename to check
2562 @param aUid The list to check
2563 @see CFontStore::AddFileL
2565 void CFontStore::AddSanityCheckedFontL(const TParse& aFileName, TUid& aUid)
2567 // Try loading the file as an Open Font
2568 if (!LoadFileAsOpenFontL(aFileName, aUid))
2570 // It could not be recognised as an Open Font file so load it as an EPOC bitmap font file.
2571 // (This always succeeds or Leaves.)
2572 aUid = LoadFileAsBitmapFontL(aFileName);
2577 // Remove a Font File - called via the Cleanup Stack if a leave occurs during font install
2578 void CFontStore::CleanupRemoveFontFile(TAny* aCleanupInfo)
2580 TCleanupRemoveFontFile* cleanupInfo = (TCleanupRemoveFontFile *) aCleanupInfo;
2581 cleanupInfo->iFontStore->RemoveFile(cleanupInfo->iFontUid);
2585 /** Search through the rasterizers for one that will open the font filename.
2587 Can leave if the rasterizer encounters an error, such as unexpected end of file, nonsense data, no memory.
2589 @param aName full filename to open
2590 @param aFontUid set to the font file UID if it is already loaded
2591 @return ETrue if the font file is loaded, otherwise EFalse
2594 TBool CFontStore::LoadFileAsOpenFontL(const TParse& aFileName, TUid& aFontUid)
2596 const TDesC& fullName = aFileName.FullName();
2598 // ask each of the rasterizers in turn to create a COpenFontFile object.
2599 const TInt rasterizerCount = iOpenFontRasterizerList.Count();
2600 for (TInt index = 0; index < rasterizerCount; index++)
2602 COpenFontFile* openFontFile = iOpenFontRasterizerList[index]->NewFontFileL(iOpenFontUid, fullName, iFs);
2603 if (NULL != openFontFile)
2605 /* Uids for Open Fonts are allocated in order; the
2606 one for the COpenFontFile just created won't match any existing one.
2607 (When a file is removed, the fake Uid will match, because the one that was returned here is used.)
2609 CleanupStack::PushL(openFontFile);
2610 openFontFile->SetFontStoreL(this);
2611 iOpenFontFileList.AppendL(openFontFile);
2612 openFontFile->IncRefCount();
2613 CleanupStack::Pop(openFontFile);
2615 TInt typefaceAddError = AddTypefacesToSupportList(openFontFile);
2616 if (typefaceAddError)
2619 RemoveFile(openFontFile->Uid());
2621 User::Leave(typefaceAddError);
2625 iOpenFontUid is the fake Uid used for new font files. It is made modulo a 'zillion' (2^28)
2626 so that it cannot conflict with real Uids, which are >= 2^28. It starts at 1 so that
2627 it does not conflict with the value 0 (KNullUid) which is used as a sentinel in
2628 CFontStore::RemoveFileL.
2631 iOpenFontUid = iOpenFontUid % 0x1000000;
2633 aFontUid = openFontFile->Uid();
2641 /** Search loaded fonts for filename, and increment the reference count
2642 @param aParse full filename to search for
2643 @return the font file UID
2644 @leave KErrNotSupported or another system wide error code
2647 TUid CFontStore::LoadFileAsBitmapFontL(const TParse& aParse)
2649 // open the file, presuming it is a bitmap font
2650 CFontStoreFile* fontStoreFile = CFontStoreFile::NewL(aParse, iFs);
2652 // See if a font with this UID is already open
2653 TInt match = FindBitmapFontFileIndexByUid(fontStoreFile->iCollectionUid);
2654 if (match != KErrNotFound) // The file is open.
2655 { // close the new duplicate, inc the reference count
2656 delete fontStoreFile;
2657 fontStoreFile = iFontStoreFileList[match];
2658 fontStoreFile->iUsageCount++;
2662 CleanupStack::PushL(fontStoreFile);
2663 iFontStoreFileList.AppendL(fontStoreFile);
2664 CleanupStack::Pop(fontStoreFile);
2666 // special object to removes the font file if a leave occurs during font install
2667 TCleanupRemoveFontFile cleanupHelper(this, fontStoreFile->iCollectionUid);
2668 CleanupStack::PushL(TCleanupItem(CleanupRemoveFontFile, &cleanupHelper));
2669 // install the new font
2670 InternalizeFontStoreFileL(fontStoreFile, fontStoreFile->iFontVersion);
2671 CleanupStack::Pop(&cleanupHelper); // CleanupRemoveFontFile
2673 return fontStoreFile->iCollectionUid;
2677 /** Search open Bitmap font files for matching UID
2678 @param aUid UID to search for
2679 @return The index of the matching item in iFontStoreFileList[] array, or KErrNotFound
2682 TInt CFontStore::FindBitmapFontFileIndexByUid(TUid aUid)
2684 const TInt fontFileCount = iFontStoreFileList.Count();
2685 for (TInt index = 0; index < fontFileCount; index++)
2687 if (iFontStoreFileList[index]->iCollectionUid == aUid)
2692 return KErrNotFound;
2696 /** Search loaded fonts for filename, and increment the reference count
2697 @param aName full filename to search for
2698 @param aFontUid set to the font file UID if it is already loaded
2699 @return ETrue if the font file is already loaded, otherwise EFalse
2702 TBool CFontStore::IncRefCountOfLoadedFont(const TParse& aFileName, TUid& aFontUid)
2704 const TDesC& fullName = aFileName.FullName();
2706 // Is it already in the Open Font list? Compare by full filename, not (fake) Uid;
2707 const TInt openFontCount = iOpenFontFileList.Count();
2709 for (i = 0; i < openFontCount; ++i)
2711 COpenFontFile* openFontFile = iOpenFontFileList[i];
2712 if (fullName.CompareF(openFontFile->FileName()) == 0)
2714 // Open Font file already loaded
2715 openFontFile->IncRefCount();
2716 aFontUid = openFontFile->Uid();
2721 // already open as an EPOC bitmap font file?
2722 const TInt fontFileCount = iFontStoreFileList.Count();
2723 for (i = 0; i < fontFileCount; i++)
2725 CFontStoreFile* fontStoreFile = iFontStoreFileList[i];
2726 if (fullName.CompareF(fontStoreFile->FullName()) == 0)
2728 // font file already loaded
2729 ++(fontStoreFile->iUsageCount);
2730 aFontUid = fontStoreFile->iCollectionUid;
2738 /** Releases a hold on one or all font file objects (COpenFontFiles or CFontStoreFiles).
2740 If aFileUid identifies a font file object, then the reference count for this
2741 object is decremented. If this brings the reference count down to zero then
2742 the font file object and typefaces associated with this file are removed from
2743 the font store, provided no fonts associated with this file are being accessed.
2744 If one or more fonts are being accessed then the file removal request will be ignored.
2746 If, on the other hand, aFileUid's value is NULL, then all font file objects
2747 are removed, along with all fonts and typefaces in the font store, provided
2748 that no fonts in the font store are being accessed (i.e. iFontAccess is empty),
2749 otherwise it has no effect.
2751 (If aFileUid is invalid, then no objects are removed.)
2753 @param aFileUid UID of a hold on a font file object to be released, or KNullUid
2754 if all font file objects are to be removed.
2756 EXPORT_C void CFontStore::RemoveFile(TUid aFileUid)
2759 if (aFileUid == KNullUid) // this means 'delete all files'
2763 TInt count = iFontAccess->Count();
2764 for (TInt i = 0; i < count; i++)
2765 if((*iFontAccess)[i].iAccessCount)
2768 if (iFontTableCache && iFontTableCache->HasOutstandingRefCount())
2770 // disallow font file removal if any font tables are still cached
2774 iTypefaceList.ResetAndDestroy();
2775 count = iFontBitmapList.Count();
2776 for (TInt i = 0; i < count; i++)
2777 iFontBitmapList[i]->Release();
2778 iFontBitmapList.Reset();
2779 iTypefaceFontBitmapList.Reset();
2780 iFontStoreFileList.ResetAndDestroy();
2781 iOpenFontFileList.ResetAndDestroy();
2782 iOpenFontTypefaceSupportList.ResetAndDestroy();
2786 // See if it's an Open Font file.
2787 count = iOpenFontFileList.Count();
2788 for (i = 0; i < count; i++)
2790 TInt fontAccessCount;
2791 if (iOpenFontFileList[i]->Uid() == aFileUid)
2794 { // Check to see if there are any references before we consider deleting
2795 fontAccessCount = iFontAccess->Count();
2796 for (TInt kk = 0; kk < fontAccessCount; ++kk)
2798 CBitmapFont* bitmapFont = reinterpret_cast<CBitmapFont*>((*iFontAccess)[kk].iFont);
2799 COpenFont* openFont = bitmapFont->OpenFont();
2800 if (openFont && openFont->File()->Uid() == aFileUid )
2802 if ((*iFontAccess)[kk].iAccessCount > 0)
2803 return; // Outstanding reference found, so ignoring file removal request
2806 } // Safe to proceed with removing file
2807 // also check if there are outstanding references to any
2808 // table in that file.
2809 if (iFontTableCache && iFontTableCache->HasOutstandingRefCountWithUid(aFileUid))
2811 return; // outstanding reference to font table found.
2814 // Safe to proceed with removing file
2815 if (iOpenFontFileList[i]->DecRefCount())
2816 { // unload the font file
2817 RemoveTypefacesFromSupportList(iOpenFontFileList[i]);
2818 //linked fonts deleted from this destructor
2819 delete iOpenFontFileList[i];
2820 iOpenFontFileList.Delete(i);
2826 // Finds first fontstorefile with correct id
2827 TInt index = FindBitmapFontFileIndexByUid(aFileUid);
2828 if (index != KErrNotFound) // Checks fontstore file has been found
2830 iFontStoreFileList[index]->iUsageCount--;
2831 if (!iFontStoreFileList[index]->iUsageCount)
2833 TInt tfcount = iTypefaceFontBitmapList.Count();
2834 for (i=tfcount-1; i>=0; i--)
2835 if (aFileUid == iTypefaceFontBitmapList[i].iFontBitmap->FontStoreFile()->iCollectionUid)
2836 iTypefaceFontBitmapList.Delete(i);
2837 count = iFontBitmapList.Count();
2838 for (i=count-1; i>=0; i--)
2841 if (aFileUid==iFontBitmapList[i]->FontStoreFile()->iCollectionUid)
2843 iFontBitmapList[i]->Release();
2844 iFontBitmapList.Delete(i);
2847 count = iTypefaceList.Count();
2848 for (i=count-1; i>=0; i--)
2850 TBool inlist=EFalse;
2851 tfcount = iTypefaceFontBitmapList.Count();
2852 for (TInt j=0; j<tfcount; j++)
2853 if (iTypefaceList[i] == iTypefaceFontBitmapList[j].iTypeface)
2857 delete iTypefaceList[i];
2858 iTypefaceList.Delete(i);
2861 delete iFontStoreFileList[index];
2862 iFontStoreFileList.Delete(index);
2871 EXPORT_C TInt CFontStore::GetNearestFontInTwips(CFont*& aFont, const TFontSpec& aFontSpec)
2873 return GetNearestFontToDesignHeightInTwips(aFont, aFontSpec);
2877 Gets the font which is the nearest to the given font specification.
2879 Note that this deprecated function is replaced by the new @c GetNearestFontToDesignHeightInTwips()
2880 yielding (virtually) the same result. However clients are strongly encouraged to use the new
2881 @c GetNearestFontToMaxHeightInTwips() function instead. This will guarantee that every
2882 character within any given text string will fit within the given amount of twips, whereas the design
2883 height is an aesthetic unit decided by the font designer without strict physical meaning, which
2884 may result in cropped characters.
2886 @param aFont On return, contains a pointer to the nearest font.
2887 @param aFontSpec The specification of the font to be matched.
2888 @return KErrNone if successful; a system-wide error code otherwise.
2890 @deprecated Use GetNearestFontToDesignHeightInTwips
2892 EXPORT_C TInt CFontStore::GetNearestFontInTwips(CFont*& aFont, const TOpenFontSpec& aFontSpec)
2894 return GetNearestFontToDesignHeightInTwips(aFont, aFontSpec);
2900 EXPORT_C TInt CFontStore::GetNearestFontToDesignHeightInTwips(CFont*& aFont, const TFontSpec& aFontSpec)
2902 TOpenFontSpec spec(aFontSpec);
2903 spec.SetHeight(VerticalTwipsToPixels(spec.Height()));
2904 return GetNearestFontToDesignHeightInPixels(aFont, spec);
2908 Gets the font which is the nearest to the given font specification.
2910 This new function replaces the deprecated @c GetNearestFontInTwips() yielding (virtually) the
2911 same result. However clients are strongly encouraged to use the new
2912 @c GetNearestFontToMaxHeightInTwips() function instead. This will guarantee that every
2913 character within any given text string will fit within the given amount of twips, whereas the design
2914 height is an aesthetic unit decided by the font designer without strict physical meaning, which
2915 may result in cropped characters.
2917 @param aFont On return, contains a pointer to the nearest font.
2918 @param aFontSpec The specification of the font to be matched.
2919 @return KErrNone if successful; a system-wide error code otherwise.
2923 EXPORT_C TInt CFontStore::GetNearestFontToDesignHeightInTwips(CFont*& aFont, const TOpenFontSpec& aFontSpec)
2925 TOpenFontSpec spec = aFontSpec;
2926 spec.SetHeight(VerticalTwipsToPixels(spec.Height()));
2927 return GetNearestFontToDesignHeightInPixels(aFont, spec);
2933 EXPORT_C TInt CFontStore::GetNearestFontToMaxHeightInTwips(CFont*& aFont, const TFontSpec& aFontSpec, TInt aMaxHeight)
2935 TOpenFontSpec spec(aFontSpec);
2936 spec.SetHeight(VerticalTwipsToPixels(spec.Height()));
2937 return GetNearestFontToMaxHeightInPixels(aFont, spec, VerticalTwipsToPixels(aMaxHeight));
2941 Gets the font which is the nearest to the given font specification.
2943 The font and bitmap server returns a pointer to the nearest matching font
2944 from those available. Matches to max height of font - this does its best
2945 to return a font that will fit within the maximum height specified (but
2946 note that variations due to hinting algorithms may rarely result in this
2947 height being exceeded by up to one pixel). Problems can also be
2948 encountered with bitmap fonts where the typeface exists but doesn't have
2949 a font small enough.
2951 @param aFont On return, contains a pointer to the nearest font.
2952 @param aFontSpec The specification of the font to be matched.
2953 @param aMaxHeight The maximum height within which the font must fit. If maximum height
2954 is greater than 1024 pixels, the function returns KErrTooBig. And returns KErrArgument
2955 if equals to 1 pixel. This overrides the height specified in aFontSpec.
2956 @return KErrNone if successful; a system-wide error code otherwise.
2960 EXPORT_C TInt CFontStore::GetNearestFontToMaxHeightInTwips(CFont*& aFont, const TOpenFontSpec& aFontSpec, TInt aMaxHeight)
2962 TOpenFontSpec spec = aFontSpec;
2963 spec.SetHeight(VerticalTwipsToPixels(spec.Height()));
2964 return GetNearestFontToMaxHeightInPixels(aFont, spec, VerticalTwipsToPixels(aMaxHeight));
2968 /** Local utility method to compare two font specs; the higher the return value, the better the match.
2969 It is not clear how to reliably test for symbol fonts or language coverage because some
2970 TOpenFontSpecs are created from bitmap TFontSpecs that do not have this info
2972 TInt MatchFontSpecsInPixels(
2973 const TOpenFontSpec& aCandidateFontSpec,
2974 const TOpenFontSpec& aIdealFontSpec,
2975 TInt aCandidateMaxHeight,
2976 TInt aIdealMaxHeight)
2978 // scores for matching (or similar) font attributes:
2979 const TInt KFontMatchScoreForName = 10;
2980 // favour fonts with heights closer together
2981 const TInt KFontMaxScoreForHeight = 10;
2982 // A match on both italic-ness and presence of forward slant factor is worth 2 points.
2983 const TInt KFontMatchScoreForExactItalicAndSlant = 2;
2984 // A match between italic-ness in one font and presence of forward slant factor in the other is worth 1 point.
2985 const TInt KFontSimilarScoreForItalicAndSlant = 1;
2986 const TInt KFontMatchScoreForBold = 2;
2987 const TInt KFontMatchScoreForBitmapType = 2;
2988 // A match between outline or shadow effect in one font with other is worth 2 points. Its same as matching for bitmaptype.
2989 const TInt KFontMatchScoreForOutlineOrShadow = 2;
2990 // The monospaced/proportional status is rated higher at 3 because it has a major effect on the look and layout
2991 const TInt KFontMatchScoreForMonoSpace = 3;
2992 // Whether the font is serifed or not has a smaller effect on the look and layout so it is only rated at 1
2993 const TInt KFontMatchScoreForSerif = 1;
2997 // Favour perfect name and height matches.
2998 if (0 == aCandidateFontSpec.Name().CompareF(aIdealFontSpec.Name()))
3000 score += KFontMatchScoreForName;
3003 // Check for max height if given, otherwise height in font spec
3004 TInt height_diff = 0;
3005 if (aCandidateMaxHeight && aIdealMaxHeight)
3007 if (aIdealMaxHeight < aCandidateMaxHeight)
3009 height_diff = aIdealMaxHeight - aCandidateMaxHeight;
3013 height_diff = aIdealFontSpec.Height() - aCandidateFontSpec.Height();
3014 if (0 > height_diff)
3015 height_diff = -height_diff;
3017 score += KFontMaxScoreForHeight - height_diff;
3019 if (aCandidateFontSpec.IsItalic() == aIdealFontSpec.IsItalic() &&
3020 (0 < aCandidateFontSpec.SlantFactor()) == (0 < aIdealFontSpec.SlantFactor()))
3022 score += KFontMatchScoreForExactItalicAndSlant;
3024 else if ((aCandidateFontSpec.IsItalic() && 0 < aIdealFontSpec.SlantFactor()) ||
3025 (aIdealFontSpec.IsItalic() && 0 < aCandidateFontSpec.SlantFactor()))
3027 score += KFontSimilarScoreForItalicAndSlant;
3030 if (aCandidateFontSpec.IsBold() == aIdealFontSpec.IsBold())
3032 score += KFontMatchScoreForBold;
3035 TUint effectsFlag = aIdealFontSpec.Effects() & aCandidateFontSpec.Effects();
3036 TBool isShadowOutlineEffects = EFalse;
3038 if(effectsFlag & FontEffect::EOutline)
3040 score += KFontMatchScoreForOutlineOrShadow;
3041 isShadowOutlineEffects = ETrue;
3043 if(effectsFlag & FontEffect::EDropShadow)
3045 score += KFontMatchScoreForOutlineOrShadow;
3046 isShadowOutlineEffects = ETrue;
3049 //Match for bitmap glyph type only when effects are off.
3050 //BitmapType in aIdealFontSpec will be set to EFourColourBlendGlyphBitmap by rasterizer only
3051 //when any of the effects (outline/shadow) are on and if it supports outline and shadow fonts.
3052 if(!isShadowOutlineEffects && (aCandidateFontSpec.BitmapType() == aIdealFontSpec.BitmapType()))
3054 score += KFontMatchScoreForBitmapType;
3056 if (aCandidateFontSpec.IsMonoWidth() == aIdealFontSpec.IsMonoWidth())
3058 score += KFontMatchScoreForMonoSpace;
3060 if (aCandidateFontSpec.IsSerif() == aIdealFontSpec.IsSerif())
3062 score += KFontMatchScoreForSerif;
3070 Find and load the nearest Open Font by
3071 1. using aDesiredFontSpec to check if its already loaded,
3072 2. using aActualFontSpec to partially match and create a new font.
3073 Partial match means typeface name must match, other attributes need not match.
3074 Font must fit vertically within the specified max height if given.
3076 @param aFont Output, is the returned font.
3077 @param aActualFontSpec Output, is used to represent the returned font and changed to twips.
3078 @param aDesiredFontSpec Input, the desired font specification
3079 @param aMaxHeight Input, the maximum height in Pixels, or 0
3080 @post if any Open Fonts are available this will always return something
3082 void CFontStore::GetNearestOpenFontInPixelsL(
3084 TOpenFontSpec& aActualFontSpec,
3085 const TOpenFontSpec& aDesiredFontSpec,
3088 // Set the baseline offset appropriately for superscript or subscript.
3090 algstyle.iBaselineOffsetInPixels = BaselineOffset(aActualFontSpec.Height(), aActualFontSpec.PrintPosition());
3092 // Determine if an open font with a perfect match is already loaded.
3093 if (IsFontLoaded(aFont, algstyle, aDesiredFontSpec, aMaxHeight))
3095 aActualFontSpec = aDesiredFontSpec;
3098 { // If not, find the nearest match for aActualFontSpec.
3099 COpenFont* nearestFont = NULL;
3101 // fast search, if DO_LOADFONT_OPTIMIZATION is defined, search loaded font names for match
3102 TInt errorName=GetNearestOpenFontInPixelsByFontName(nearestFont, aActualFontSpec, aDesiredFontSpec, aMaxHeight);
3103 TInt errorSimilar=KErrNone;
3107 errorSimilar=GetNearestOpenFontInPixelsBySimilarity(nearestFont, aActualFontSpec, aDesiredFontSpec, aMaxHeight);
3110 // If an imperfect match was found, is it already loaded? If not, create a new CBitmapFont.
3114 // Results of everything above are stored in nearestFont, and aActualFontSpec
3115 // First check if the not-exactly-matched font is already loaded
3116 // aMaxHeight is 0 to prevent duplicate CBitmapFontObjects being created
3118 if (IsFontLoaded(aFont, algstyle, aActualFontSpec, 0))
3124 // Set the specification of the nearest match in twips.
3125 TOpenFontSpec openFontSpec(aActualFontSpec);
3126 openFontSpec.SetHeight(VerticalPixelsToTwips(openFontSpec.Height()));
3127 CleanupStack::PushL(nearestFont);
3128 aFont = NewFontL(openFontSpec, algstyle, nearestFont);
3129 CleanupStack::Pop(nearestFont);
3134 User::LeaveIfError(errorSimilar);
3135 User::LeaveIfError(errorName);
3141 /** Using the Desired Font Name try to find a matching font.
3143 @param aNearestOpenFont Output, nearest matching open font
3144 @param aActualFontSpec Output, is used to represent the returned font
3145 @param aDesiredFontSpec Input, the desired font specification
3146 @param aMaxHeight Input, the maximum height in Pixels, or 0
3148 #if(DO_LOADFONT_OPTIMIZATION)
3149 TInt CFontStore::GetNearestOpenFontInPixelsByFontName(
3150 COpenFont*& aOpenFont,
3151 TOpenFontSpec& aActualFontSpec,
3152 const TOpenFontSpec& aDesiredFontSpec,
3155 TOpenFontSpec actualFontSpec;
3156 COpenFont* nearestFont = NULL;
3158 if (aMaxHeight == 0 && aDesiredFontSpec.Name().Length() > 0) // check if it is a request for OpenFont
3160 TPtrC requestedName = aDesiredFontSpec.Name();
3161 // Typeface files may contain all those typefaces in a family, or may contain only some.
3162 // The optimization first tries the ShortFullName of the typeface in case the typefaces are
3163 // put into separate files.
3165 // First check FullName. The following assumes that there are never two COpenFontFiles in the
3166 // list with the same ShortFullName. So italic and bold flags are not checked.
3168 const TInt openFontFileCount = iOpenFontFileList.Count();
3170 TInt typicalError = KErrNone;
3171 for (index = 0; index < openFontFileCount; index++)
3173 COpenFontFile *pFile = iOpenFontFileList[index];
3174 const TOpenFontFaceAttrib &faceAttrib = pFile->FaceAttrib(0);
3176 // Use short names. They are truncated to the same length as the request in TTypeface
3177 if ((faceAttrib.ShortFullName().CompareF(requestedName)==0) &&
3178 (faceAttrib.IsBold() == aActualFontSpec.IsBold()) &&
3179 (faceAttrib.IsItalic() == aActualFontSpec.IsItalic()) )
3181 TInt error=pFile->GetNearestFontToDesignHeightInPixels(
3182 iHeap, iOpenFontSessionCacheList, aActualFontSpec, iKPixelWidthInTwips,
3183 iKPixelHeightInTwips, nearestFont, actualFontSpec);
3185 // search has finished if a match was found
3188 // need to copy the actual to the value that is going to be used down below
3189 // to make a new font
3190 aOpenFont = nearestFont;
3191 aActualFontSpec = actualFontSpec;
3204 // If the FullName match above has failed, then the request is being made by
3205 // something other than a full name (assuming typeface is present).
3206 // Although there may be more than one typeface in a file,
3207 // It is not possible to conclude that ALL typefaces of the family are in one file.
3208 // So to be safe, checks are made on italic and bold, possibly downgrading the optimization.
3209 // Use short names. They are truncated to the same length as the request in TTypeface
3210 for (index = 0; index < openFontFileCount; index++)
3212 COpenFontFile *pFile = iOpenFontFileList[index];
3213 const TOpenFontFaceAttrib &faceAttrib = pFile->FaceAttrib(0);
3215 if( (faceAttrib.ShortFamilyName().CompareF(requestedName) == 0) &&
3216 (faceAttrib.IsItalic() == aDesiredFontSpec.IsItalic()) &&
3217 (faceAttrib.IsBold() == aDesiredFontSpec.IsBold()) )
3219 TInt error=pFile->GetNearestFontToDesignHeightInPixels(
3220 iHeap, iOpenFontSessionCacheList, aActualFontSpec, iKPixelWidthInTwips,
3221 iKPixelHeightInTwips, nearestFont, actualFontSpec);
3223 // search has finished if a match was found
3226 // need to copy the actual to the value that is going to be used down below
3227 // to make a new font
3228 aOpenFont = nearestFont;
3229 aActualFontSpec = actualFontSpec;
3242 return typicalError;
3248 TInt CFontStore::GetNearestOpenFontInPixelsByFontName(
3249 COpenFont*& /* aOpenFont */,
3250 TOpenFontSpec& /* aActualFontSpec */,
3251 const TOpenFontSpec& /* aDesiredFontSpec */,
3252 TInt /* aMaxHeight*/)
3259 /** Using the Desired Font Name try to find a matching font.
3261 @param aNearestOpenFont Output, nearest matching open font
3262 @param aActualFontSpec Output, is used to represent the returned font
3263 @param aDesiredFontSpec Input, the desired font specification
3264 @param aMaxHeight Input, the maximum height in Pixels, or 0
3266 TInt CFontStore::GetNearestOpenFontInPixelsBySimilarity(
3267 COpenFont*& aNearestOpenFont,
3268 TOpenFontSpec& aActualFontSpec,
3269 const TOpenFontSpec& aDesiredFontSpec,
3272 const TInt openFontFileCount = iOpenFontFileList.Count();
3273 TOpenFontSpec nearestFontSpec;
3274 COpenFont* nearestFont = NULL;
3275 TInt nearestMatch = 0;
3276 TInt typicalError=KErrNone;
3277 for (TInt index = 0; index < openFontFileCount; index++)
3279 // ask font file for its best match, if any
3280 COpenFont* candidateFont = NULL;
3281 TOpenFontSpec actualFontSpec;
3282 TInt lastError=KErrNone;
3285 lastError=iOpenFontFileList[index]->GetNearestFontToMaxHeightInPixels(
3286 iHeap, iOpenFontSessionCacheList, aActualFontSpec, iKPixelWidthInTwips,
3287 iKPixelHeightInTwips, candidateFont, actualFontSpec, aMaxHeight);
3291 lastError=iOpenFontFileList[index]->GetNearestFontToDesignHeightInPixels(
3292 iHeap, iOpenFontSessionCacheList, aActualFontSpec, iKPixelWidthInTwips,
3293 iKPixelHeightInTwips, candidateFont, actualFontSpec);
3296 // hold on to the best overall match
3299 const TInt candidateMatch = MatchFontSpecsInPixels(
3300 actualFontSpec, aDesiredFontSpec, candidateFont->FontMaxHeight(), aMaxHeight);
3302 if (NULL == nearestFont || candidateMatch > nearestMatch)
3308 nearestFont = candidateFont;
3309 nearestMatch = candidateMatch;
3310 nearestFontSpec = actualFontSpec;
3314 // Font match is no better than the current nearestFont
3316 // Note this object is newed in GetNearestFontInPixels each time
3317 // a matching font is found.
3318 delete candidateFont;
3325 typicalError=lastError;
3330 if (nearestFont != NULL)
3332 aNearestOpenFont = nearestFont;
3333 aActualFontSpec = nearestFontSpec;
3338 return typicalError;
3344 Get the nearest bitmap font to aFontSpec and place it in aFont. Font must
3345 fit vertically inside specified maximum height if given. GetNearestTypeface is
3346 called which insists that there is at least one typeface. This function will always
3347 succeed unless there is an out-of-memory error or other abnormal error.
3348 Change aFontSpec to represent the returned font and change it to twips.
3350 void CFontStore::GetNearestBitmapFontInPixelsL(
3352 TFontSpec& aFontSpec,
3355 aFontSpec.iTypeface = *GetNearestTypeface(aFontSpec.iTypeface);
3356 TTypefaceFontBitmap tffb = GetNearestTypefaceFontBitmap(aFontSpec, aMaxHeight);
3357 const TInt height = tffb.HeightInPixels();
3358 if (aFontSpec.iFontStyle.PrintPosition() != EPrintPosNormal)
3360 aFontSpec.iHeight = SuperSubHeight(height, aFontSpec.iFontStyle.PrintPosition());
3361 tffb = GetNearestTypefaceFontBitmap(aFontSpec, aMaxHeight);
3363 aFontSpec.iHeight = height;
3366 EStrokeWeightBold == aFontSpec.iFontStyle.StrokeWeight() &&
3367 EStrokeWeightNormal == tffb.iFontBitmap->StrokeWeight());
3368 algstyle.SetIsItalic(
3369 EPostureItalic == aFontSpec.iFontStyle.Posture() &&
3370 EPostureUpright == tffb.iFontBitmap->Posture());
3371 algstyle.SetIsMono(!aFontSpec.iTypeface.IsProportional() && tffb.iFontBitmap->IsProportional());
3373 ((tffb.iWidthFactor * tffb.iFontBitmap->FontStoreFile()->iKPixelAspectRatio * iKPixelWidthInTwips) + (500 * iKPixelHeightInTwips)) / (1000 * iKPixelHeightInTwips);
3376 algstyle.SetWidthFactor(widthfactor);
3377 algstyle.SetHeightFactor( tffb.iHeightFactor );
3378 algstyle.iBaselineOffsetInPixels = BaselineOffset(height, aFontSpec.iFontStyle.PrintPosition());
3379 if (IsFontLoaded(aFont, algstyle, aFontSpec, tffb.iFontBitmap->iUid))
3381 TFontSpec spec(aFontSpec);
3382 spec.iHeight = VerticalPixelsToTwips(height);
3383 spec.iFontStyle.SetBitmapType(EMonochromeGlyphBitmap);
3384 aFont = NewFontL(spec, algstyle, tffb.iFontBitmap);
3388 Gets the font which is the nearest to the given font specification.
3390 Note that this deprecated function is replaced by the new @c GetNearestFontToDesignHeightInPixels()
3391 yielding (virtually) the same result. However clients are strongly encouraged to use the new
3392 @c GetNearestFontToMaxHeightInPixels() function instead. This will guarantee that every
3393 character within any given text string will fit within the given amount of pixels, whereas the design
3394 height is an aesthetic unit decided by the font designer without strict physical meaning, which
3395 may result in cropped characters.
3397 @param aFont On return, contains a pointer to the nearest font.
3398 @param aFontSpec The specification of the font to be matched.
3399 @return KErrNone if successful; a system-wide error code otherwise.
3401 @deprecated Use GetNearestFontToDesignHeightInPixels
3403 EXPORT_C TInt CFontStore::GetNearestFontInPixels(CFont*& aFont, const TFontSpec& aFontSpec)
3405 return GetNearestFontToDesignHeightInPixels(aFont, aFontSpec);
3409 Gets the font which is the nearest to the given font specification.
3411 Note that this deprecated function is replaced by the new @c GetNearestFontToDesignHeightInPixels()
3412 yielding (virtually) the same result. However clients are strongly encouraged to use the new
3413 @c GetNearestFontToMaxHeightInPixels() function instead. This will guarantee that every
3414 character within any given text string will fit within the given amount of pixels, whereas the design
3415 height is an aesthetic unit decided by the font designer without strict physical meaning, which
3416 may result in cropped characters.
3418 @param aFont On return, contains a pointer to the nearest font.
3419 @param aFontSpec The specification of the font to be matched.
3420 @return KErrNone if successful; a system-wide error code otherwise.
3422 @deprecated Use GetNearestFontToDesignHeightInPixels
3424 EXPORT_C TInt CFontStore::GetNearestFontInPixels(CFont*& aFont, const TOpenFontSpec& aFontSpec)
3426 return GetNearestFontToDesignHeightInPixels(aFont, aFontSpec);
3430 Gets the font which is the nearest to the given font specification.
3432 This new function replaces the deprecated @c GetNearestFontInPixels() yielding (virtually) the
3433 same result. However clients are strongly encouraged to use the new
3434 @c GetNearestFontToMaxHeightInPixels() function instead. This will guarantee that every
3435 character within any given text string will fit within the given amount of pixels, whereas the design
3436 height is an aesthetic unit decided by the font designer without strict physical meaning, which
3437 may result in cropped characters.
3439 @param aFont On return, contains a pointer to the nearest font.
3440 @param aFontSpec The specification of the font to be matched.
3441 @return KErrNone if successful; a system-wide error code otherwise.
3445 EXPORT_C TInt CFontStore::GetNearestFontToDesignHeightInPixels(CFont*& aFont, const TFontSpec& aFontSpec)
3447 TOpenFontSpec spec(aFontSpec);
3448 return GetNearestFontToDesignHeightInPixels(aFont, spec);
3452 Gets the font which is the nearest to the given font specification.
3454 This new function replaces the deprecated @c GetNearestFontInPixels() yielding (virtually) the
3455 same result. However clients are strongly encouraged to use the new
3456 @c GetNearestFontToMaxHeightInPixels() function instead. This will guarantee that every
3457 character within any given text string will fit within the given amount of pixels, whereas the design
3458 height is an aesthetic unit decided by the font designer without strict physical meaning, which
3459 may result in cropped characters.
3461 @param aFont On return, contains a pointer to the nearest font.
3462 @param aFontSpec The specification of the font to be matched.
3463 @return KErrNone if successful; a system-wide error code otherwise.
3467 EXPORT_C TInt CFontStore::GetNearestFontToDesignHeightInPixels(CFont*& aFont, const TOpenFontSpec& aFontSpec)
3469 return GetNearestFontInPixels(aFont, aFontSpec, 0);
3473 Gets the font which is the nearest to the given font specification.
3475 The font and bitmap server returns a pointer to the nearest matching font
3476 from those available. Matches to max height of font - this does its best
3477 to return a font that will fit within the maximum height specified (but
3478 note that variations due to hinting algorithms may rarely result in this
3479 height being exceeded by up to one pixel). Problems can also be
3480 encountered with bitmap fonts where the typeface exists but doesn't have
3481 a font small enough.
3483 @param aFont On return, contains a pointer to the nearest font.
3484 @param aFontSpec The specification of the font to be matched.
3485 @param aMaxHeight The maximum height within which the font must fit. If maximum height
3486 is greater than 1024 pixels, the function returns KErrTooBig. And returns KErrArgument
3487 if equals to 1 pixel. This overrides the height specified in aFontSpec.
3488 @return KErrNone if successful; a system-wide error code otherwise.
3492 EXPORT_C TInt CFontStore::GetNearestFontToMaxHeightInPixels(CFont*& aFont, const TFontSpec& aFontSpec, TInt aMaxHeight)
3494 TOpenFontSpec spec(aFontSpec);
3495 return GetNearestFontToMaxHeightInPixels(aFont, spec, aMaxHeight);
3499 Gets the font which is the nearest to the given font specification.
3501 The font and bitmap server returns a pointer to the nearest matching font
3502 from those available. Matches to max height of font - this does its best
3503 to return a font that will fit within the maximum height specified (but
3504 note that variations due to hinting algorithms may rarely result in this
3505 height being exceeded by up to one pixel). Problems can also be
3506 encountered with bitmap fonts where the typeface exists but doesn't have
3507 a font small enough.
3509 @param aFont On return, contains a pointer to the nearest font.
3510 @param aFontSpec The specification of the font to be matched.
3511 @param aMaxHeight The maximum height within which the font must fit. If maximum height
3512 is greater than 1024 pixels, the function returns KErrTooBig. And returns KErrArgument
3513 if equals to 1 pixel. This overrides the height specified in aFontSpec.
3514 @return KErrNone if successful; a system-wide error code otherwise.
3518 EXPORT_C TInt CFontStore::GetNearestFontToMaxHeightInPixels(CFont*& aFont, const TOpenFontSpec& aFontSpec, TInt aMaxHeight)
3520 if (KMaxFontHeightInPixels < aMaxHeight)
3524 if (aMaxHeight > 0 && aMaxHeight < KMinFontHeightInPixels)
3526 return KErrArgument;
3528 return GetNearestFontInPixels(aFont, aFontSpec, aMaxHeight);
3531 TInt CFontStore::GetNearestFontInPixels(
3533 const TOpenFontSpec& aDesiredFontSpec,
3538 // Determine the ideal version of the font spec.
3539 TOpenFontSpec originalFontSpec = aDesiredFontSpec;
3540 originalFontSpec.CompensateForAspectRatio(iKPixelWidthInTwips, iKPixelHeightInTwips);
3541 TOpenFontSpec desiredFontSpec = originalFontSpec;
3542 if (EDefaultGlyphBitmap == desiredFontSpec.BitmapType())
3544 desiredFontSpec.SetBitmapType(iDefaultBitmapType);
3546 if (EPrintPosNormal != desiredFontSpec.PrintPosition())
3548 desiredFontSpec.SetHeight(SuperSubHeight(desiredFontSpec.Height(), desiredFontSpec.PrintPosition()));
3550 TOpenFontSpec actualOpenFontSpec = desiredFontSpec;
3552 // Try to get an open font.
3553 CFont* openFont = NULL;
3554 TRAPD(error, GetNearestOpenFontInPixelsL(
3555 openFont, actualOpenFontSpec, desiredFontSpec, aMaxHeight));
3557 // Try to get a bitmap font - if getting open font failed or the match was not perfect.
3558 CFont* bitmapFont = NULL;
3559 TInt errorBitmap=KErrNone;
3560 TOpenFontSpec actualBitmapFontSpec;
3561 if (error || !openFont || actualOpenFontSpec != desiredFontSpec)
3564 originalFontSpec.GetTFontSpec(f);
3565 if (iTypefaceList.Count() > 0)
3567 TRAP(errorBitmap, GetNearestBitmapFontInPixelsL(bitmapFont, f, aMaxHeight));
3569 actualBitmapFontSpec = f;
3570 actualBitmapFontSpec.CompensateForAspectRatio(iKPixelWidthInTwips, iKPixelHeightInTwips);
3573 //If both attempts fail then there is nothing more we can do...
3574 if (!openFont && !bitmapFont)
3576 //If an error caused no fonts to be returned then forward the error
3582 // Choose the best candidate
3583 if (NULL == openFont && NULL == bitmapFont)
3585 // Try to get an open font again - unnamed font.
3586 // See COpenFontFile::GetNearestFontHelper - how it works with unnamed fonts.
3587 actualOpenFontSpec.SetName(KNullDesC);
3588 TRAP(error, GetNearestOpenFontInPixelsL(
3589 openFont, actualOpenFontSpec, desiredFontSpec, aMaxHeight));
3590 if (KErrNone == error && openFont)
3597 OstTraceExt2( TRACE_FATAL, CFONTSTORE_GETNEARESTFONTINPIXELS, "GetNearestOpenFontInPixelsL() return %d, openFont is 0x%x, Panic(EFntNoFontFound)",
3598 error, (unsigned int)openFont);
3599 __ASSERT_DEBUG(0, Panic(EFntNoFontFound));
3603 else if (NULL == openFont)
3605 if (actualBitmapFontSpec.Name().CompareF(desiredFontSpec.Name()) != 0)
3607 // Try to get the nearest open font - because no exact bitmap font match for typeface name
3608 actualOpenFontSpec.SetName(KNullDesC);
3609 desiredFontSpec.SetName(KNullDesC);
3610 TRAPD(errorOpen, GetNearestOpenFontInPixelsL(
3611 openFont, actualOpenFontSpec, desiredFontSpec, aMaxHeight));
3612 if (KErrNone == errorOpen && openFont)
3615 ReleaseFont(bitmapFont);
3623 else if (NULL == bitmapFont)
3630 // Pick the closest match; for backward compatibility prefer a bitmap font if there is a dead heat.
3631 const TInt open_match = MatchFontSpecsInPixels(
3632 actualOpenFontSpec, desiredFontSpec, openFont->FontMaxHeight(), aMaxHeight);
3633 const TInt bitmap_match = MatchFontSpecsInPixels(
3634 actualBitmapFontSpec, desiredFontSpec, bitmapFont->FontMaxHeight(), aMaxHeight);
3635 if (open_match > bitmap_match)
3638 ReleaseFont(bitmapFont);
3643 ReleaseFont(openFont);
3649 /** Gets a bitmap font using the given font UID and algorithmic style.
3651 Tries to find a bitmap font in the font store with the given UID. If successful,
3652 the given algorithmic style is applied to the font and this font (which may
3653 be a suitable one already existing in the store, or may be a newly generated
3654 font) is stored in aFont. If unsuccessful then no font is stored in aFont.
3656 @param aFont On return, a device-dependent font.
3657 @param aUid A bitmap font UID.
3658 @param aAlgStyle An algorithmic style to apply to the font.
3659 @return KErrNone if the font is found, KErrNotFound if the font is not found,
3660 or another system-wide error code. */
3661 EXPORT_C TInt CFontStore::GetFontById(
3664 const TAlgStyle& aAlgStyle)
3667 CFontBitmap* fontbitmap = GetFontBitmapById(aUid);
3670 return KErrNotFound;
3673 const TInt height = fontbitmap->iCellHeightInPixels * aAlgStyle.HeightFactor();
3675 fontspec.iHeight=height; //Otherwise IsFontLoaded() compares with zero height!!!
3676 fontspec.iTypeface.SetIsProportional(!aAlgStyle.IsMono() && fontbitmap->IsProportional());
3677 if (aAlgStyle.IsBold() || EStrokeWeightBold == fontbitmap->StrokeWeight())
3679 fontspec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
3681 if (aAlgStyle.IsItalic() || EPostureItalic == fontbitmap->Posture())
3683 fontspec.iFontStyle.SetPosture(EPostureItalic);
3685 if (IsFontLoaded(aFont, aAlgStyle, fontspec, fontbitmap->iUid))
3690 // Fill in the typeface by finding a typeface with the same font bitmap.
3691 fontspec.iHeight = VerticalPixelsToTwips(height);
3692 const TInt n = iTypefaceFontBitmapList.Count();
3693 for (TInt i = 0; i < n; i++)
3695 if (iTypefaceFontBitmapList[i].iFontBitmap == fontbitmap)
3697 fontspec.iTypeface = *iTypefaceFontBitmapList[i].iTypeface;
3701 TRAPD(ret, aFont = NewFontL(fontspec, aAlgStyle, fontbitmap));
3705 /** Gets the number of typefaces held in the font store.
3707 Note that this includes both open font typefaces and non-scalable typefaces.
3709 @return The number of supported typefaces. */
3710 EXPORT_C TInt CFontStore::NumTypefaces() const
3712 return iTypefaceList.Count() + iOpenFontTypefaceSupportList.Count();
3715 /** Gets a typeface support object for the typeface in the font store represented
3718 Returns benignly with an empty TTypefaceSupport if the index is too high;
3719 this can happen if another process removes a typeface after the first process
3720 has already got the number of typefaces. However, if the aTypefaceIndex<0
3721 the function panics with EFntTypefaceIndexOutOfRange.
3723 @param aTypefaceSupport On return, a typeface support object.
3724 @param aTypefaceIndex An index number representing a typeface, which is valid
3725 if in the range 0 to (NumTypefaces() - 1). */
3726 EXPORT_C void CFontStore::TypefaceSupport(TTypefaceSupport &aTypefaceSupport,TInt aTypefaceIndex) const
3728 if (aTypefaceIndex < 0)
3729 Panic(EFntTypefaceIndexOutOfRange);
3732 Return benignly with an empty TTypefaceSupport if the index is too high; this can happen if another
3733 process removes a font after the first process has already got the number of typefaces.
3735 int typefaces = NumTypefaces();
3736 if (aTypefaceIndex >= typefaces)
3738 aTypefaceSupport = TTypefaceSupport();
3742 //now return Typeface Support for Open Fonts
3743 if (aTypefaceIndex >= iTypefaceList.Count())
3745 // copy Open Font typeface details
3746 aTypefaceSupport = *iOpenFontTypefaceSupportList[aTypefaceIndex - iTypefaceList.Count()]->TypefaceSupport();
3750 if (!((aTypefaceIndex >= 0) && (aTypefaceIndex < iTypefaceList.Count())))
3752 OstTraceExt2( TRACE_FATAL, CFONTSTORE_TYPEFACESUPPORT, "aTypefaceIndex=%d, iTypefaceList.Count()=%d Panic(EFntTypefaceIndexOutOfRange)",
3753 aTypefaceIndex, iTypefaceList.Count());
3754 __ASSERT_DEBUG(0,Panic(EFntTypefaceIndexOutOfRange));
3756 TTypeface* typeface = iTypefaceList[aTypefaceIndex];
3757 aTypefaceSupport.iTypeface = *typeface;
3758 TInt count = iTypefaceFontBitmapList.Count();
3760 for(i = 0; i < count && iTypefaceFontBitmapList[i].iTypeface != typeface; i++)
3761 { // Finds first fontbitmap with correct typeface
3763 aTypefaceSupport.iMinHeightInTwips = VerticalPixelsToTwips(iTypefaceFontBitmapList[i].HeightInPixels());
3764 aTypefaceSupport.iNumHeights=0;
3766 for(; (i<count) && (typeface == iTypefaceFontBitmapList[i].iTypeface); i++)
3767 if (height != iTypefaceFontBitmapList[i].HeightInPixels())
3769 height = iTypefaceFontBitmapList[i].HeightInPixels();
3770 aTypefaceSupport.iNumHeights++;
3772 aTypefaceSupport.iMaxHeightInTwips=VerticalPixelsToTwips(height);
3773 aTypefaceSupport.iIsScalable = EFalse;
3776 /** Returns a font height, in twips, for a certain typeface and height index.
3778 The font height is a height allowed for the typeface represented by aTypefaceIndex.
3779 The height returned increases with aHeightIndex.
3781 If aTypefaceIndex<0 the function panics with EFntTypefaceIndexOutOfRange.
3782 If aTypefaceIndex is greater than the number of typefaces or aHeightIndex<0
3783 then the function returns 0. If aHeightIndex is greater than the number of
3784 heights then the function returns the biggest height.
3786 @param aTypefaceIndex An index number representing a typeface, which is valid
3787 in the range 0 to (NumTypefaces() - 1).
3788 @param aHeightIndex A font height index number, which is valid in the range
3789 0 to (TTypefaceSupport::iNumHeights - 1). Note that the typeface support object
3790 for the typeface can be got using TypefaceSupport().
3791 @return The height of a font, in twips.
3792 @see TypefaceSupport()
3794 EXPORT_C TInt CFontStore::FontHeightInTwips(TInt aTypefaceIndex,TInt aHeightIndex) const
3796 if (aTypefaceIndex >= iTypefaceList.Count())
3798 // it's an Open Font managed by a COpenFontFile
3799 if (aTypefaceIndex >= NumTypefaces() || aHeightIndex < 0)
3802 const CTypefaceSupportInfo* supportInfo = iOpenFontTypefaceSupportList[aTypefaceIndex - iTypefaceList.Count()];
3803 TInt i = Min( supportInfo->NearestPointSizeIndex() + aHeightIndex,
3804 KOpenFontSizeArrayCount - 1);
3806 return gOpenFontSizeInTwipsArray[i];
3810 return VerticalPixelsToTwips(FontHeightInPixels(aTypefaceIndex,aHeightIndex));
3814 /** Returns a font height, in pixels, for a certain typeface and height index.
3816 The font height is a height allowed for the typeface represented by aTypefaceIndex.
3817 The height returned increases with aHeightIndex.
3819 If aTypefaceIndex<0 the function panics with EFntTypefaceIndexOutOfRange.
3820 If aTypefaceIndex is greater than the number of typefaces or aHeightIndex<0
3821 then the function returns 0. If aHeightIndex is greater than the number of
3822 heights then the function returns the biggest height.
3824 @param aTypefaceIndex An index number representing a typeface, which is valid
3825 in the range 0 to (NumTypefaces() - 1).
3826 @param aHeightIndex A font height index number, which is valid in the range
3827 0 to (TTypefaceSupport::iNumHeights - 1). Note that the typeface support object
3828 for the typeface can be got using TypefaceSupport().
3829 @return The height of a font, in pixels.
3830 @see TypefaceSupport()
3832 EXPORT_C TInt CFontStore::FontHeightInPixels(TInt aTypefaceIndex,TInt aHeightIndex) const
3835 if (aTypefaceIndex >= iTypefaceList.Count()) // it's an Open Font managed by a COpenFontFile
3836 return VerticalTwipsToPixels(FontHeightInTwips(aTypefaceIndex,aHeightIndex));
3839 if (aTypefaceIndex < 0)
3840 Panic(EFntTypefaceIndexOutOfRange);
3841 TTypeface* typeface = iTypefaceList[aTypefaceIndex];
3842 TInt count = iTypefaceFontBitmapList.Count();
3844 for(i=0; (i < count) && (iTypefaceFontBitmapList[i].iTypeface != typeface); i++)
3845 { // Finds first fontbitmap with correct typeface
3848 for(; (i<count) && (iTypefaceFontBitmapList[i].iTypeface==typeface)
3849 && (h<=aHeightIndex); i++)
3850 if (height != iTypefaceFontBitmapList[i].HeightInPixels())
3852 height = iTypefaceFontBitmapList[i].HeightInPixels();
3859 void CFontStore::InternalizeFontStoreFileL(CFontStoreFile* aFontStoreFile, TInt aFontVersion)
3861 RStoreReadStream stream;
3862 stream.OpenLC(*aFontStoreFile->iFileStore,aFontStoreFile->iDataStreamId);
3863 TInt i, size = stream.ReadInt32L();
3864 TInt opsPerformed=0;
3865 for (i=0; i<size; i++)
3867 // font is placed in shared heap
3868 CFontBitmap* fontbitmap=(CFontBitmap*)iHeap->AllocL(sizeof(CFontBitmap));
3869 new(fontbitmap) CFontBitmap(iHeap,aFontStoreFile);
3870 CleanupReleasePushL(*fontbitmap);
3871 fontbitmap->InternalizeL(stream, aFontVersion);
3872 if (GetFontBitmapById(fontbitmap->iUid))
3874 fontbitmap->Release();
3878 iFontBitmapList.AppendL(fontbitmap);
3881 // safely internalized & owned
3882 CleanupStack::Pop(fontbitmap);
3884 size = stream.ReadInt32L();
3885 for (i=0; i<size; i++)
3887 TTypeface* typeface=new(ELeave) TTypeface;
3888 CleanupStack::PushL(typeface);
3889 typeface->InternalizeL(stream);
3890 TInt index,count=iTypefaceList.Count();
3891 for (index=0; (index<count) && typeface->iName.CompareF(iTypefaceList[index]->iName); index++)
3892 { // Looks to see if typeface is already in list
3894 if (index == count) // If typeface not in list
3896 iTypefaceList.AppendL(typeface);
3897 index = iTypefaceList.Count()-1;
3899 CleanupStack::Pop(); // typeface
3903 CleanupStack::Pop(); // typeface
3905 typeface=iTypefaceList[index];
3907 TInt num = stream.ReadInt32L();
3908 for (TInt j=0; j<num; j++)
3912 CFontBitmap* fontbitmap = GetFontBitmapById(uid);
3915 OstTrace0( TRACE_FATAL, CFONTSTORE_INTERNALIZEFONTSTOREFILEL, "Panic(EFntFontBitmapNotLoaded)" );
3916 __ASSERT_DEBUG(0,Panic(EFntFontBitmapNotLoaded));
3919 User::LeaveIfNull(fontbitmap);
3921 TTypefaceFontBitmap typefacefontbitmap(iTypefaceList[index],fontbitmap);
3922 typefacefontbitmap.iWidthFactor=stream.ReadInt8L();
3923 typefacefontbitmap.iHeightFactor=stream.ReadInt8L();
3924 count=iTypefaceFontBitmapList.Count();
3933 for (pos=0; (pos<count) && (iTypefaceFontBitmapList[pos].iTypeface != typeface); pos++)
3934 { // Finds position of first fontbitmap with same typeface
3936 for (; (pos<count) && (iTypefaceFontBitmapList[pos].iTypeface == typeface)
3937 && (iTypefaceFontBitmapList[pos].HeightInPixels()<typefacefontbitmap.HeightInPixels()); pos++)
3940 for (; (pos<count) && (iTypefaceFontBitmapList[pos].iTypeface == typeface)
3941 && (iTypefaceFontBitmapList[pos].HeightInPixels()==typefacefontbitmap.HeightInPixels())
3942 && (iTypefaceFontBitmapList[pos].iFontBitmap->Posture()<fontbitmap->Posture()); pos++)
3943 { // Finds position after fontbitmap with same height
3945 for (; (pos<count) && (iTypefaceFontBitmapList[pos].iTypeface == typeface)
3946 && (iTypefaceFontBitmapList[pos].HeightInPixels()==typefacefontbitmap.HeightInPixels())
3947 && (iTypefaceFontBitmapList[pos].iFontBitmap->StrokeWeight()<fontbitmap->StrokeWeight()); pos++)
3948 { // Finds position after fontbitmap with same height
3951 TTypefaceFontBitmap* tfbAtPos=(pos==count)
3953 : &iTypefaceFontBitmapList[pos];
3955 || tfbAtPos->iTypeface!=typeface
3956 || tfbAtPos->HeightInPixels()!=typefacefontbitmap.HeightInPixels()
3957 || tfbAtPos->iFontBitmap->Posture()!=fontbitmap->Posture()
3958 || tfbAtPos->iFontBitmap->StrokeWeight()!=fontbitmap->StrokeWeight()
3959 || tfbAtPos->iWidthFactor!=typefacefontbitmap.iWidthFactor
3960 || tfbAtPos->iHeightFactor!=typefacefontbitmap.iHeightFactor
3963 iTypefaceFontBitmapList.InsertL(pos,typefacefontbitmap);
3968 CleanupStack::PopAndDestroy(); // stream
3970 User::Leave(KErrAlreadyExists);
3973 TTypeface* CFontStore::GetNearestTypeface(const TTypeface& aTypeface) const
3975 TInt index,count = iTypefaceList.Count();
3978 OstTrace1( TRACE_FATAL, CFONTSTORE_GETNEARESTTYPEFACE, "count=%d, Panic(EFntNoTypefaces)", count );
3979 __ASSERT_DEBUG(0,Panic(EFntNoTypefaces));
3981 for (index=0; (index<count) && aTypeface.iName.CompareF(iTypefaceList[index]->iName); index++)
3982 { // tries matching typeface name
3986 if (!aTypeface.IsSymbol())
3988 for (index=0; (index<count) && ((iTypefaceList[index]->IsSymbol()) ||
3989 (aTypeface.IsProportional() != iTypefaceList[index]->IsProportional()) ||
3990 (aTypeface.IsSerif() != iTypefaceList[index]->IsSerif())); index++)
3991 { // tries matching typeface flags
3994 for (index=0; (index<count) && ((iTypefaceList[index]->IsSymbol()) ||
3995 (aTypeface.IsProportional()!=iTypefaceList[index]->IsProportional())); index++)
3996 { // tries matching typeface flags
3999 for (index=0; (index<count) && iTypefaceList[index]->IsSymbol(); index++)
4000 { // finds first non-symbol typeface
4005 for (index=0; (index<count) && (!iTypefaceList[index]->IsSymbol()); index++)
4006 { // finds first symbol typeface
4013 return iTypefaceList[index];
4016 TTypefaceFontBitmap CFontStore::GetNearestTypefaceFontBitmap(const TFontSpec& aFontSpecInPixels, TInt aMaxHeight)
4018 TTypefaceFontBitmap typefacefontbitmap;
4019 TInt count = iTypefaceFontBitmapList.Count();
4022 OstTrace1( TRACE_FATAL, CFONTSTORE_GETNEARESTTYPEFACEFONTBITMAP, "count=%d, Panic(EFntNoTypefaceFontBitmaps)", count );
4023 __ASSERT_DEBUG(0, Panic(EFntNoTypefaceFontBitmaps));
4027 // Assumes there is at least one fontbitmap per typeface
4028 for (i = 0; (i < count) && !(aFontSpecInPixels.iTypeface == *iTypefaceFontBitmapList[i].iTypeface); i++)
4029 { // Finds first fontbitmap with correct typeface
4033 OstTraceExt2( TRACE_FATAL, DUP1_CFONTSTORE_GETNEARESTTYPEFACEFONTBITMAP, "i=%d, count=%d, Panic(EFntTypefaceHasNoFontBitmaps)", i, count );
4034 __ASSERT_DEBUG(i < count, Panic(EFntTypefaceHasNoFontBitmaps));
4036 TTypeface* typeface = iTypefaceFontBitmapList[i].iTypeface;
4039 { // need to check against max height
4040 for (j = i; (j < count) && (iTypefaceFontBitmapList[ j ].iTypeface == typeface)
4041 && (iTypefaceFontBitmapList[j].iFontBitmap->FontMaxHeight() <= aMaxHeight); j++)
4043 if (iTypefaceFontBitmapList[j].HeightInPixels() != height)
4045 height = iTypefaceFontBitmapList[j].HeightInPixels();
4051 { // just check against height
4052 for (j = i; (j < count) && (iTypefaceFontBitmapList[j].iTypeface == typeface)
4053 && (iTypefaceFontBitmapList[j].HeightInPixels() <= aFontSpecInPixels.iHeight); j++)
4055 if (iTypefaceFontBitmapList[j].HeightInPixels() != height)
4057 height = iTypefaceFontBitmapList[j].HeightInPixels();
4062 for (j = i; (j < count) && (iTypefaceFontBitmapList[j].iTypeface == typeface)
4063 && (iTypefaceFontBitmapList[j].HeightInPixels() == height); j++)
4064 { // Finds position after fontbitmap correct posture
4065 if ((iTypefaceFontBitmapList[j].iFontBitmap->Posture() <= aFontSpecInPixels.iFontStyle.Posture()) &&
4066 (iTypefaceFontBitmapList[j].iFontBitmap->StrokeWeight() <= aFontSpecInPixels.iFontStyle.StrokeWeight()))
4069 typefacefontbitmap = iTypefaceFontBitmapList[i];
4070 return typefacefontbitmap;
4073 CFontBitmap* CFontStore::GetFontBitmapById(TUid aUid)
4075 CFontBitmap* fontbitmap = NULL;
4076 TInt i, count = iFontBitmapList.Count();
4077 for (i = 0; (i < count) && (aUid != iFontBitmapList[i]->iUid); i++)
4078 { // finds matching font bitmap
4080 if (i<count) // bitmap found
4081 fontbitmap = iFontBitmapList[i];
4085 /** The method uses the fontspec and algorithmic style only.
4086 The Uid is not used for Open Fonts. They all have a Uid of 0.
4088 TBool CFontStore::IsFontLoaded(
4090 const TAlgStyle& aAlgStyle,
4091 const TOpenFontSpec& aFontSpecInPixels,
4092 TInt aMaxHeight) const
4095 aFontSpecInPixels.GetTFontSpec(fontSpec);
4096 return IsFontLoaded(aFont, aAlgStyle, fontSpec, TUid::Uid(0), aMaxHeight);
4099 //stub functions to help optimise IsFontLoaded.
4100 //These shims are more efficient than a pointer-to-member.
4101 static TInt GetHeightShimMaxHeight(CFont* aFont) { return aFont->FontMaxHeight(); }
4102 static TInt GetHeightShimHeightPixels(CFont* aFont) { return aFont->HeightInPixels(); }
4105 Font spec comparison is based on
4106 1. Max height if its given, otherwise design height
4107 2. All other attributes in TFontSpec
4109 @see CFbsTypefaceStore::IsFontLoaded
4110 @see CPdrTypefaceStore::IsFontLoaded
4112 TBool CFontStore::IsFontLoaded(
4114 const TAlgStyle& aAlgStyle,
4115 const TFontSpec& aFontSpecInPixels,
4117 TInt aMaxHeight) const
4118 { //It is not worth copying iFontAccess to frame as it doesn't get register optimised.
4119 const TInt count = iFontAccess->Count();
4120 const TInt reqHeight = aMaxHeight ? aMaxHeight : aFontSpecInPixels.iHeight;
4121 TInt (*heightFn)(CFont*) = aMaxHeight ? GetHeightShimMaxHeight : GetHeightShimHeightPixels;
4122 for (TInt i = 0; i < count; i++)
4124 CBitmapFont* bitmapFont = reinterpret_cast<CBitmapFont*>((*iFontAccess)[i].iFont);
4125 if (bitmapFont->Uid() != aUid ||
4126 bitmapFont->iAlgStyle != aAlgStyle ||
4127 heightFn(bitmapFont) != reqHeight
4132 TFontSpec fontSpec = bitmapFont->FontSpecInTwips();
4133 if ( fontSpec.iFontStyle == aFontSpecInPixels.iFontStyle &&
4134 fontSpec.iTypeface.iName == aFontSpecInPixels.iTypeface.iName
4137 (*iFontAccess)[i].iAccessCount++;
4138 aFont = static_cast<CFont*>(bitmapFont);
4145 CBitmapFont* CFontStore::NewFontL(
4146 const TFontSpec& aFontSpecInTwips,
4147 const TAlgStyle& aAlgStyle,
4148 CFontBitmap* aFontBitmap)
4150 CBitmapFont* f = CBitmapFont::NewL(iHeap, aFontSpecInTwips, aAlgStyle, aFontBitmap);
4151 CleanupStack::PushL(f);
4153 CleanupStack::Pop();
4154 f->SetUniqueFontId(++iUniqueFontIdCount);
4158 CBitmapFont* CFontStore::NewFontL(
4159 const TOpenFontSpec& aFontSpecInTwips,
4160 const TAlgStyle& aAlgStyle,
4161 COpenFont* aOpenFont)
4164 aFontSpecInTwips.GetTFontSpec(spec);
4165 CBitmapFont* f = CBitmapFont::NewL(iHeap, spec, aAlgStyle, aOpenFont);
4166 CleanupStack::PushL(f);
4168 CleanupStack::Pop();
4169 f->SetUniqueFontId(++iUniqueFontIdCount);
4173 // This function is biased towards rounding up
4174 // The cutoff is effectively at one-third of a pixel
4175 // This is to match VerticalTwipsToPixels(...)
4176 TInt CFontStore::VerticalPixelsToTwips(TInt aPixelHeight) const
4178 return ((aPixelHeight * iKPixelHeightInTwips) + 667) / 1000; // Rounds up above one-third of a pixel
4181 // This function is biased towards rounding down
4182 // The cutoff is effectively at two-thirds of a twip
4183 // This is to support the legacy system of rounding down
4184 // but with a sanity-check cutoff to round up past two-thirds
4185 TInt CFontStore::VerticalTwipsToPixels(TInt aTwipsHeight) const
4187 if (!iKPixelHeightInTwips)
4189 OstTrace0( TRACE_FATAL, CFONTSTORE_VERTICALTWIPSTOPIXELS, "Panic(EFntKPixelHeightInTwipsZero)" );
4190 __ASSERT_DEBUG(0, Panic(EFntKPixelHeightInTwipsZero));
4192 return ((aTwipsHeight * 1000) + (iKPixelHeightInTwips / 3)) / iKPixelHeightInTwips; // Rounds down below two-thirds of a twip
4195 /** Installs and takes ownership of an Open Font rasterizer.
4197 @param aRasterizer A pointer to an Open Font rasterizer. */
4198 EXPORT_C void CFontStore::InstallRasterizerL(COpenFontRasterizer* aRasterizer)
4200 iOpenFontRasterizerList.AppendL(aRasterizer);
4203 /** Install and takes ownership of the shaper
4205 @param aShaperFactory A pointer to a shaper factory. */
4206 EXPORT_C void CFontStore::InstallShaperFactoryL(CShaperFactory* aShaperFactory)
4208 iShaperFactoryList.AppendL(aShaperFactory);
4211 /** Deletes the glyph cache belonging to a particular client.
4213 Called by ~CFbClient().
4215 @param aSessionHandle A session handle. */
4216 EXPORT_C void CFontStore::DeleteSessionCache(TInt aSessionHandle)
4218 iOpenFontSessionCacheList->DeleteCache(iHeap,aSessionHandle);
4221 const CArrayPtrFlat<CShaperFactory>* CFontStore::ShaperFactoryList() const
4223 return &iShaperFactoryList;
4226 /** Returns the list of session caches owned by the COpenFonts
4227 @internalComponent */
4228 COpenFontSessionCacheList* CFontStore::GetSessionCacheList()
4230 return iOpenFontSessionCacheList;
4233 /** Returns the total cache memory used by all the COpenFonts in the system
4234 @return Total cache memory usage
4237 TInt CFontStore::GetShaperCacheMemUsage()
4239 return iOpenFontShaperCacheMemUsage;
4242 /** Updates the total cache memory used by all the COpenFonts in the system
4243 @param aUsage New value of total cache memory usage
4246 void CFontStore::SetShaperCacheMemUsage(TInt aUsage)
4248 iOpenFontShaperCacheMemUsage = aUsage;
4251 /** Returns the list of COpenFontFiles owned by the CFontStore object
4254 CArrayPtrFlat<COpenFontFile>* CFontStore::GetOpenFontFileList()
4256 return &iOpenFontFileList;
4259 void CFontStore::IncNumShaperCaches()
4261 iNumberOfShaperCaches++;
4264 void CFontStore::DecNumShaperCaches()
4266 iNumberOfShaperCaches--;
4269 TInt CFontStore::GetNumShaperCaches()
4271 return iNumberOfShaperCaches;
4275 /** Adds the typeface( of the currently added openfont file from the store) to Open Font System typefaces Supported List
4276 ignoring duplicate family names.
4277 1. Prior to adding the entry into the typefaceList, it is searched whether already exists or not
4278 2. If it is found only its reference count is incremented.
4279 3. If it is not found then its reference count is set to 1 and added that entry into the typefacelist.
4280 4. If 0 typefaces are added then KErrAlreadyExists is returned causing the new font to be unloaded.
4281 @return KErrNone is successful, otherwise a system wide error code
4284 TInt CFontStore::AddTypefacesToSupportList(COpenFontFile* aOpenFontFile)
4286 TInt faceCount = aOpenFontFile->FaceCount();
4287 CTypefaceSupportInfo* typefaceFamily = NULL;
4288 TInt error = KErrNone;
4290 // go through all fonts, stop early if an error
4291 for (TInt faceIndex = 0; (faceIndex < faceCount) && (error == KErrNone); ++faceIndex)
4293 //Preparing the Supported Typeface Entry
4294 if (typefaceFamily == NULL)
4295 { // need a new typeface object
4296 typefaceFamily = new CTypefaceSupportInfo();
4297 if (typefaceFamily == NULL)
4299 error = KErrNoMemory;
4304 // initialise for next type face
4305 const TOpenFontFaceAttrib& faceAttrib = aOpenFontFile->FaceAttrib(faceIndex);
4306 typefaceFamily->SetTypefaceInfo(faceAttrib, VerticalPixelsToTwips(faceAttrib.MinSizeInPixels()));
4308 TInt fontPos = -1; // an invalid index
4309 TInt findError = iOpenFontTypefaceSupportList.FindInOrder(typefaceFamily, fontPos, CTypefaceSupportInfo::CompareFontNames);
4312 if (findError == KErrNotFound)
4314 // back reference to the font file
4315 error = typefaceFamily->AddFontFilePtr(aOpenFontFile);
4316 if (error == KErrNone)
4317 { // transfer ownership
4318 error = iOpenFontTypefaceSupportList.Insert(typefaceFamily, fontPos);
4319 if (error == KErrNone)
4321 typefaceFamily = NULL;
4328 // back reference to the new font file (allowed to fail with KErrAlreadyExists)
4329 TInt addError = iOpenFontTypefaceSupportList[fontPos]->AddUniqueFontFilePtr(aOpenFontFile,faceAttrib);
4330 if (addError==KErrNone)
4334 else if (addError == KErrInUse )
4336 //remove typeface from loaded font file????
4338 else if (addError != KErrAlreadyExists )
4342 //else KErrAlreadyExists because loaded by a lower-indexed face in this font file, so faces won't be zero.
4346 if (typefaceFamily != NULL)
4348 delete typefaceFamily;
4350 if (facesAdded==0 && error==KErrNone)
4352 error= KErrAlreadyExists;
4355 // check that array is in order
4356 const TInt countTypefaceFamilies = iOpenFontTypefaceSupportList.Count();
4357 for (TInt fontPos = 0; fontPos < countTypefaceFamilies - 1; ++fontPos)
4359 TInt cmp = CTypefaceSupportInfo::CompareFontNames(*iOpenFontTypefaceSupportList[fontPos], *iOpenFontTypefaceSupportList[fontPos+1]);
4368 /** Removes the typefaces from the Support List corresponding to the fontfile removed from
4371 1. Searching in the typefacesupportList for pointer references to the font file.
4372 2. If the file is referenced by the typeface family remove the reference.
4373 3. If typeface family no has any implementations remove the family
4376 void CFontStore::RemoveTypefacesFromSupportList(COpenFontFile* aOpenFontFile)
4378 const TInt countTypefaceFamilies = iOpenFontTypefaceSupportList.Count();
4380 // search typeface families
4381 for (TInt fontPos = countTypefaceFamilies - 1; fontPos >= 0; --fontPos)
4383 CTypefaceSupportInfo* fontInfo = iOpenFontTypefaceSupportList[fontPos];
4385 // look for back pointer to this Font File
4386 TInt fontFileIndex = fontInfo->FindFontFilePtr(aOpenFontFile);
4388 if (fontFileIndex > KErrNotFound)
4390 if (fontInfo->RemoveFontFilePtr(fontFileIndex))
4391 { // last implementation of the family, so delete it
4393 iOpenFontTypefaceSupportList.Remove(fontPos);
4400 This function checks the supplied typeface name against the existing bitmap and open
4401 typefaces, to see if it present.
4403 @param aName The name of the typeface family name to be checked.
4404 @return ETrue if the typeface is present, EFalse otherwise.
4409 EXPORT_C TBool CFontStore::HaveTypefaceFamilyName(const TDesC& aName)
4411 //there are two lists for typefaces
4412 //not supporting linked fonts here
4414 //first list is open fonts
4415 TInt count = iOpenFontTypefaceSupportList.Count();
4416 for (TInt index=count-1;index>=0;index--)
4418 if (aName.CompareF(iOpenFontTypefaceSupportList[index]->iSupport.iTypeface.iName)==0)
4422 //now look through bitmap fonts
4423 count = iTypefaceList.Count();
4424 for (TInt index=count-1;index>=0;index--)
4426 if (aName.CompareF(iTypefaceList[index]->iName)==0)
4437 EXPORT_C TInt CFontStore::CreateLinkedTypeface(const TLinkedTypefaceSpecificationArgs &aLinkedTypefaceSpec, TInt aSession, TInt& aId)
4441 TRAP(err,retErr = CreateLinkedTypefaceL(aLinkedTypefaceSpec,aSession,aId));
4452 /* this function is used to create the linked typeface, the linked typeface is created on
4453 * the font and bitmap server heap, not the shared heap.
4455 TInt CFontStore::CreateLinkedTypefaceL(const TLinkedTypefaceSpecificationArgs &aLinkedTypefaceSpec, TInt /*aSession*/, TInt& /*aId*/)
4456 //reconstuct a CLinkedTypefaceSpecification - could store as T type, but then the
4457 // maximum size would be used for every linked typeface
4460 const TAny* extensionPtr = FontLinkingInterface();
4462 if (extensionPtr == NULL)
4463 return KErrNotSupported;
4465 //Convert the TLinkedTypefaceSpecification args into the
4466 //COpenFontLinkedTypefaceSpecification recognised by the rasteriser
4467 COpenFontLinkedTypefaceSpecification* spec =
4468 COpenFontLinkedTypefaceSpecification::NewLC(aLinkedTypefaceSpec);
4470 TInt err = ValidateLinkedFontSpecificationL(*spec, EFalse);
4472 if (err == KErrNone)
4474 GenerateLinkedFontFileL(*spec, extensionPtr, EFalse);
4477 CleanupStack::PopAndDestroy(spec);
4483 Retrieve the specification from a linked typeface; the name of the typeface should be specified in the parameter.
4485 @param aLinkedTypefaceSpec An empty linked typeface spec containing the name of the typeface to be retrieved.
4487 @leave One of the system wide error codes.
4489 EXPORT_C void CFontStore::GetLinkedTypefaceL(TLinkedTypefaceSpecificationArgs &aLinkedTypefaceSpec)
4491 const TAny* extensionPtr = FontLinkingInterface();
4493 if (extensionPtr == NULL)
4494 User::Leave(KErrNotSupported);
4496 MOpenFontLinkedTypefaceExtension* linkedExt = (MOpenFontLinkedTypefaceExtension*)extensionPtr;
4498 //Check whether the font is loaded
4499 CTypefaceSupportInfo* supinfo;
4500 TTypefaceSupport support;
4501 COpenFontFile* fetchFont=NULL;
4502 for (TInt count=0;count<(iOpenFontTypefaceSupportList.Count());count++)
4504 supinfo = iOpenFontTypefaceSupportList[count];
4505 support = supinfo->iSupport;
4507 if (aLinkedTypefaceSpec.iName==support.iTypeface.iName)
4509 fetchFont = supinfo->iOpenFontFilePtrArray[0];
4514 if (fetchFont==NULL)
4516 User::Leave(KErrNotFound);
4519 COpenFontLinkedTypefaceSpecification* typefaceSpec = COpenFontLinkedTypefaceSpecification::NewLC(aLinkedTypefaceSpec.iName);
4520 TFileName fetchFile = fetchFont->FileName();
4521 linkedExt->GetLinkedTypefaceSpecificationL(fetchFile, *typefaceSpec);
4522 aLinkedTypefaceSpec = *typefaceSpec;
4523 CleanupStack::PopAndDestroy(typefaceSpec);
4528 Updates an existing linked typeface to a new specification.
4530 @param aLinkedTypefaceSpec The new specification for the typeface
4532 @leave KErrNotSupported Font linking is not supported by any of the installed rasterizers
4533 @leave One of the system wide error codes.
4535 EXPORT_C void CFontStore::UpdateLinkedTypefaceL(const TLinkedTypefaceSpecificationArgs& aLinkedTypefaceSpec)
4537 const TAny* extensionPtr = FontLinkingInterface();
4539 if (extensionPtr == NULL)
4540 User::Leave(KErrNotSupported);
4542 //Convert the TLinkedTypefaceSpecification args into the
4543 //COpenFontLinkedTypefaceSpecification recognised by the rasteriser
4544 COpenFontLinkedTypefaceSpecification* spec =
4545 COpenFontLinkedTypefaceSpecification::NewLC(aLinkedTypefaceSpec);
4547 TInt err = ValidateLinkedFontSpecificationL(*spec, ETrue);
4548 User::LeaveIfError(err);
4550 GenerateLinkedFontFileL(*spec, extensionPtr, ETrue);
4552 CleanupStack::PopAndDestroy(spec);
4557 Performs the loading of font files at boot time. This is a three stage procedure.
4559 1. Copies linked fonts to be updated from their temporary directory into the linked fonts folder
4560 2. Loads all the linked fonts from the linked fonts folder.
4561 3. Loads all remaining font files from *:\resource\fonts
4563 EXPORT_C void CFontStore::LoadFontsAtStartupL()
4565 //First copy any updated linked fonts from their temporary dir to the linked font dir
4566 CFileMan* fm = CFileMan::NewL(iFs);
4567 CleanupStack::PushL(fm);
4569 //Get the fbserv private folder
4570 TBuf<KMaxPrivatePathLength> privPath;
4571 iFs.PrivatePath(privPath);
4573 //Construct the linked font dir path
4574 TBuf<KMaxLinkedFontPathLength> linkedFontDir;
4575 linkedFontDir.Format(KLinkedFontFileFolder, KLinkedFontDrive, &privPath);
4577 //Construct the linked font temp dir path
4578 TBuf<KMaxLinkedFontPathLength> linkedFontTempDir;
4579 linkedFontTempDir.Append(linkedFontDir);
4580 linkedFontTempDir.Append(KLinkedFontFileTempFolder);
4582 //Copy the temp folder into the main folder
4583 TInt err = fm->Copy(linkedFontTempDir, linkedFontDir, CFileMan::EOverWrite);
4585 if (err == KErrNone)
4587 //If sucessful copying remove the temp folder
4588 //A leave is not thrown as the empty directory remaining is not a significant enough
4589 //to prevent fbserv from starting
4590 fm->RmDir(linkedFontTempDir);
4593 CleanupStack::PopAndDestroy(fm);
4596 LoadFontsL(linkedFontDir);
4598 //Load the remaining fonts
4599 LoadFontsL(KFBSERVFontDirSecure);
4603 Returns the pointer to the first rasterizer supporting font linking (KUidLinkedTypefaceRasterizerExtension).
4605 const TAny* CFontStore::FontLinkingInterface() const
4607 TInt rastcount = iOpenFontRasterizerList.Count();
4608 COpenFontRasterizer* rast;
4609 TAny* extensionPtr = NULL;
4611 //Check each rasterizer in turn to check it supports the extended interface.
4612 //In reality there should only be one but multiple rasterizers are supported.
4613 for (TInt i = 0 ; i != rastcount ; i++)
4615 rast = iOpenFontRasterizerList[i];
4616 rast->ExtendedInterface(KUidLinkedTypefaceRasterizerExtension, extensionPtr);
4618 if (extensionPtr != NULL)
4622 return extensionPtr;
4626 Validates the linked font specification passed as a parameter.
4628 @param aSpec The specification to be validated
4629 @param aOverwrite ETrue if this is an update operation, EFalse otherwise
4631 TInt CFontStore::ValidateLinkedFontSpecificationL(COpenFontLinkedTypefaceSpecification& aSpec, TBool aOverwrite) const
4633 //see if the typeface is an existing regular typeface.
4636 TInt numberTypefaces = iTypefaceList.Count();
4639 for (c=0;c<numberTypefaces;c++)
4641 TTypeface* ptr=(iTypefaceList)[c];
4643 /* only comparing on the name */
4644 if (0== ptr->iName.CompareF(aSpec.Name()))
4646 //A typeface with this name is already loaded
4647 return KErrAlreadyExists;
4651 TInt numberOpenFontFiles = iOpenFontFileList.Count();
4652 for (c=0;c<numberOpenFontFiles;c++)
4654 COpenFontFile* ptr=(iOpenFontFileList)[c];
4656 numberTypefaces= ptr->FaceCount();
4658 for (c2=0;c2<numberTypefaces;c2++)
4660 const TOpenFontFaceAttrib& attrib = ptr->FaceAttrib(c2);
4662 /* only comparing on the name */
4663 if (0== attrib.ShortFullName().CompareF(aSpec.Name()))
4665 //have a matching name, return error
4666 return KErrAlreadyExists;
4668 if (0== attrib.ShortFamilyName().CompareF(aSpec.Name()))
4670 //have a matching name, return error
4671 return KErrAlreadyExists;
4676 //For each element, check whether the typeface exists and add the correct filename to the spec if it does
4677 TInt numTypefaces = aSpec.TypefaceCount();
4679 COpenFontLinkedTypefaceElementSpec* element;
4681 for (TInt counter=0;counter<numTypefaces;counter++)
4683 element = aSpec.Typeface(counter);
4685 if (GetFontFilePath(element->ElementName(), fileName))
4687 element->SetFileNameL(fileName);
4691 return KErrNotFound;
4699 Sends the specification to the font rasterizer to be created/updated.
4701 @param aSpec The linked font specification
4702 @param aExtension The extension interface of the chosen rasterizer
4703 @param aUpdate ETrue if the file is being updated, EFalse if it should be created
4705 @leave KErrNotFound Attempting to update a file which does not exist
4707 void CFontStore::GenerateLinkedFontFileL(COpenFontLinkedTypefaceSpecification& aSpec, const TAny* aExtension, TBool aUpdate)
4709 MOpenFontLinkedTypefaceExtension* linkedExt = (MOpenFontLinkedTypefaceExtension*)aExtension;
4711 //Generate the filename for the linked font file (excluding the extension
4712 //and the .) which are appended by the rasterizer.
4714 User::LeaveIfError(iFs.PrivatePath(privPath));
4716 fn.Format(KLinkedFontFileFolder, KLinkedFontDrive, &privPath);
4718 //Choose the correct path to write the file to
4721 fn.Append(KLinkedFontFileTempFolder);
4724 // Create the directory if it does not exist
4725 TInt result = iFs.MkDirAll(fn);
4726 if (result != KErrAlreadyExists)
4728 User::LeaveIfError(result);
4731 //Append the linked font filename to the path for the rasterizer.
4732 fn.Append(aSpec.Name());
4734 // If we are updating, check that the file is a linked typeface before attempting the update.
4738 TBool exists = GetFontFilePath(aSpec.Name(), fn);
4742 COpenFontLinkedTypefaceSpecification* tempSpec = COpenFontLinkedTypefaceSpecification::NewLC(aSpec.Name());
4743 TRAPD(ret, linkedExt->GetLinkedTypefaceSpecificationL(fn, *tempSpec));
4744 User::LeaveIfError(ret);
4745 CleanupStack::PopAndDestroy(tempSpec);
4749 User::Leave(KErrNotFound);
4753 //Use the rasterizer extension to create the linked typeface
4754 linkedExt->CreateLinkedTypefaceL(aSpec, fn);
4756 // Load the new linked typeface
4764 Function called at system startup to find and load all fonts in the specified
4765 folder. The value of the folder will be the secure Data-caged private folder
4766 named "\resource\fonts".
4768 The first font of a given name overrides subsequent ones.
4770 The search order is: Y:, X:, W:, ..., C:, B:, A:, Z:
4773 @param aFontsDir The directory search pattern
4775 void CFontStore::LoadFontsL(const TDesC& aFontsDir)
4778 _LIT(KLoadStarted, "CFontStore::LoadFontsL Started.\r\n");
4779 RDebug::Print(KLoadStarted);
4780 TUint32 loadStartTime = StartTiming();
4783 RArray<TParse> fontsToLoad;
4784 CleanupClosePushL(fontsToLoad);
4785 TFindFile fileFinder(iFs);
4786 CDir* foundFileList = NULL;
4788 _LIT(KFBSERVFontFilePattern, "*");
4789 TInt findFileComplete = fileFinder.FindWildByDir(KFBSERVFontFilePattern, aFontsDir, foundFileList);
4791 while (!findFileComplete)
4793 CleanupStack::PushL(foundFileList);
4794 const TInt foundFileCount = foundFileList->Count();
4795 const TDesC& pathInfo = fileFinder.File();
4797 // Build a list of fonts to be loaded eliminating duplicate filenames.
4798 for (TInt ii = 0; ii < foundFileCount; ii++)
4800 TParse fullFontFileName;
4801 if (fullFontFileName.Set((*foundFileList)[ii].iName, &pathInfo, NULL) == KErrNone)
4803 // If the font has not already been loaded, validate it then add it to the list.
4804 if (!FileIsInList(fullFontFileName, fontsToLoad))
4806 // Do not validate fonts on Z: (assumed to be ROM created with valid fonts)
4807 if (FileIsOnZ(fullFontFileName))
4809 fontsToLoad.AppendL(fullFontFileName);
4813 // Test font before loading
4814 TRAPD(err, SanityCheckFontFileL(fullFontFileName))
4815 if (KErrNone == err)
4818 fontsToLoad.AppendL(fullFontFileName);
4822 _LIT(KCorruptFont, "CFontStore::LoadFontsL %S could not be loaded.\r\n");
4823 RDebug::Print(KCorruptFont, &fullFontFileName.FullName());
4830 CleanupStack::PopAndDestroy(foundFileList);
4831 findFileComplete = fileFinder.FindWild(foundFileList);
4834 // Load the fonts in reverse order (i.e. Z:, A: to Y:) this causes
4835 // fonts on Z: to take priority over fonts on A: to Y: when the internal
4836 // font names are identical.
4837 TInt kk = fontsToLoad.Count();
4840 TUid fontUid = KNullUid;
4842 // Load this font as a new font, and add it to the list of loaded fonts
4843 TRAPD(addFileError, AddSanityCheckedFontL(fontsToLoad[kk], fontUid));
4846 _LIT(KLoadedFont, "CFontStore::LoadFontsL failed with error %i to load font, filename: %S\r\n");
4847 RDebug::Print(KLoadedFont, addFileError, &(fontsToLoad[kk].FullName()));
4852 // NOTE: This is to make testing of confirming what fonts are loaded a little easier as there is no
4853 // easy way to get this information from outside the server.
4854 _LIT(KLoadedFont, "CFontStore::LoadFontsL loaded font filename: %S\r\n");
4855 RDebug::Print(KLoadedFont, &(fontsToLoad[kk].FullName()));
4861 TUint32 loadTime = FinishTimingL(loadStartTime);
4862 _LIT(KLoadEnded, "CFontStore::LoadFontsL Finished. Took: %dus\r\n");
4863 RDebug::Print(KLoadEnded, loadTime);
4865 CleanupStack::PopAndDestroy(&fontsToLoad);
4868 Retrieves the full path and filename of the font with the specified name. This function
4869 searches through all open font files currently loaded by font store.
4871 @param aFontName The full name of the font to search for
4872 @param aFilePath An empty descriptor to have the file name filled in
4874 @return ETrue if the font is found; EFalse if not
4876 EXPORT_C TBool CFontStore::GetFontFilePath(const TDesC& aFontName, TFileName& aFilePath) const
4878 TInt numTypefaces = iOpenFontFileList.Count();
4879 COpenFontFile* thisFile;
4880 TOpenFontFaceAttrib faceAttrib;
4882 //For every (Truetype) font file
4883 for (TInt i = 0 ; i != numTypefaces ; i++)
4885 thisFile = iOpenFontFileList[i];
4887 //For every face within this file
4888 for (TInt face = 0 ; face != thisFile->FaceCount() ; face++)
4890 faceAttrib = thisFile->FaceAttrib(face);
4891 if (faceAttrib.FullName().CompareF(aFontName) == 0)
4893 aFilePath = thisFile->FileName();
4901 TInt CFontStore::CacheFontTable(TUid aFileUid, TUint32 aTag,
4902 TAny *&aContent, TInt aLength)
4904 return iFontTableCache->Append(aFileUid, aTag, aContent, aLength);
4907 TInt CFontStore::FindFontTableInCache(TUid aFileUid, TUint32 aTag,
4908 TAny *&aContent, TInt &aLength)
4911 return iFontTableCache->Find(aFileUid, aTag, aContent, aLength, &id);
4914 TInt CFontStore::IncreaseUnhintedOutlineRefCount(const TUnhintedOutlineId &aOutlineId,
4915 TInt aSessionHandle)
4917 return iUnhintedOutlineCache->IncRefCount(aOutlineId, aSessionHandle);
4920 TInt CFontStore::IncreaseHintedOutlineRefCount(const THintedOutlineId &aOutlineId,
4921 TInt aSessionHandle)
4923 return iHintedOutlineCache->IncRefCount(aOutlineId, aSessionHandle);
4926 TInt CFontStore::IncFontTableRefCount(TUid aFileUid, TUint32 aTag,
4927 TInt aSessionHandle)
4929 return iFontTableCache->IncRefCount(aFileUid, aTag, aSessionHandle);
4932 TInt CFontStore::DecFontTableRefCount(TUid aFileUid, TUint32 aTag,
4933 TInt aSessionHandle)
4935 return iFontTableCache->DecRefCount(aFileUid, aTag, aSessionHandle);
4938 TInt CFontStore::CacheUnhintedOutline(const TUnhintedOutlineId &aOutlineId, TAny * aData,
4939 TInt aLength, TAny *&aOutline, TInt &aLen)
4941 return iUnhintedOutlineCache->CacheUnhintedOutline(aOutlineId, aData, aLength,
4945 TInt CFontStore::CacheHintedOutline(const THintedOutlineId &aOutlineId,
4946 TAny * aData, TInt aLength, TAny *&aOutline, TInt &aLen)
4948 return iHintedOutlineCache->CacheHintedOutline(aOutlineId, aData, aLength,
4952 TInt CFontStore::ReleaseUnhintedOutline(const TUnhintedOutlineId &aOutlineId,
4953 TInt aSessionHandle)
4955 return iUnhintedOutlineCache->DecRefCount(aOutlineId, aSessionHandle);
4958 TInt CFontStore::ReleaseHintedOutline(const THintedOutlineId &aOutlineId,
4959 TInt aSessionHandle)
4961 return iHintedOutlineCache->DecRefCount(aOutlineId, aSessionHandle);
4964 TInt CFontStore::ReleaseFontTable(TUid aFileUid, TUint32 aTag,
4965 TInt aSessionHandle)
4967 return iFontTableCache->DecRefCount(aFileUid, aTag, aSessionHandle);
4970 TInt CFontStore::FindUnhintedOutlineInCache(const TUnhintedOutlineId &aOutlineId, TAny *&aData,
4973 return iUnhintedOutlineCache->Find(aOutlineId, aData, aLength);
4976 TInt CFontStore::FindHintedOutlineInCache(const THintedOutlineId &aOutlineId,
4977 TAny *&aData, TInt &aLength)
4979 return iHintedOutlineCache->Find(aOutlineId, aData, aLength);
4982 void CFontStore::CleanupCacheOnOpenFontRemoval(COpenFont *aFont)
4984 iHintedOutlineCache->CleanupCacheOnOpenFontRemoval(aFont);
4985 //iUnhintedOutlineCache.OnOpenFontRemoval(aFont);
4988 void CFontStore::CleanupCacheOnOpenFontFileRemoval(COpenFontFile *aFontFile)
4990 iUnhintedOutlineCache->CleanupCacheOnOpenFontFileRemoval(aFontFile);
4991 iFontTableCache->CleanupCacheOnOpenFontFileRemoval(aFontFile);
4994 /** Clean up font table and glyph outline caches when an FBS session is terminated.
4995 * All the reference counts related to that session are cleared.
4996 @param aSession: Input. A pointer to the terminating session.
4997 @return always returns KErrNone.
5001 void CFontStore::CleanupCacheOnFbsSessionTermination(TInt aSessionHandle)
5003 iHintedOutlineCache->CleanupCacheOnFbsSessionTermination(aSessionHandle);
5004 iUnhintedOutlineCache->CleanupCacheOnFbsSessionTermination(aSessionHandle);
5005 iFontTableCache->CleanupCacheOnFbsSessionTermination(aSessionHandle);
5009 void TFontTableGlyphOutlineCacheMemMonitor::Inc(TInt aBytes)
5014 void TFontTableGlyphOutlineCacheMemMonitor::Dec(TInt aBytes)
5019 TInt TFontTableGlyphOutlineCacheMemMonitor::GetMemUsage()
5024 TFontTableGlyphOutlineCacheMemMonitor::TFontTableGlyphOutlineCacheMemMonitor():
5030 TUnhintedOutlineId::TUnhintedOutlineId(TUid aFileUid, TInt aFaceIndex, TUint aId):
5031 iFileUid(aFileUid), iFaceIndex(aFaceIndex), iId(aId)
5033 // a null constructor;
5036 THintedOutlineId::THintedOutlineId(COpenFont *aFont, TUint aId):
5037 iFont(aFont), iId(aId)
5039 // a null constructor;
5044 Returns a timestamp for use by FinishTimingL().
5045 @return The timestamp.
5048 TUint32 StartTiming(void)
5050 return User::FastCounter();
5054 Returns the time difference between a given time and now in microseconds.
5055 @param aStartTime The start time returned by calling StartTiming()
5056 @return The time difference in microseconds.
5059 TUint32 FinishTimingL(TUint32 aStartTime)
5062 TUint32 endtime = User::FastCounter();
5063 User::LeaveIfError(HAL::Get(HALData::EFastCounterFrequency, freq));
5064 TUint32 diff = endtime - aStartTime;
5065 TInt64 diffTime = (1000000 * TInt64(diff)) / (TInt64)freq;
5066 return TUint32(diffTime);
5071 Returns true if the filename passed in is on the Z: drive
5072 @param aFileName The filename to check
5073 @return ETrue if the file is on Z:
5075 TBool FileIsOnZ(TParse& aFileName)
5079 const TDesC& fileDrive = aFileName.Drive();
5081 if (0 == fileDrive.CompareF(KZDrive))
5091 Returns true if the filename passed in is in the supplied list
5092 @param aFileName The filename to check
5093 @param aList The list to check
5094 @return ETrue if the file is in the list
5096 TBool FileIsInList(TParse& aFileName, RArray<TParse>& aList)
5098 TBool inList = EFalse;
5100 TInt jj = aList.Count();
5103 TPtrC shortFilename = aFileName.NameAndExt();
5104 if (shortFilename.CompareF( aList[jj].NameAndExt() ) == 0)
5107 _LIT(KEclipsesFont, "CFontStore::FileIsInList %S eclipses %S\r\n");
5108 RDebug::Print(KEclipsesFont, &aList[jj].FullName(), &aFileName.FullName());