os/textandloc/fontservices/fontstore/src/FNTSTORE.CPP
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/textandloc/fontservices/fontstore/src/FNTSTORE.CPP	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,5116 @@
     1.4 +/*
     1.5 +* Copyright (c) 1995-2010 Nokia Corporation and/or its subsidiary(-ies).
     1.6 +* All rights reserved.
     1.7 +* This component and the accompanying materials are made available
     1.8 +* under the terms of "Eclipse Public License v1.0"
     1.9 +* which accompanies this distribution, and is available
    1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.11 +*
    1.12 +* Initial Contributors:
    1.13 +* Nokia Corporation - initial contribution.
    1.14 +*
    1.15 +* Contributors:
    1.16 +*
    1.17 +* Description: 
    1.18 +*
    1.19 +*/
    1.20 +
    1.21 +
    1.22 +#include <e32hal.h>
    1.23 +#include <hal.h>
    1.24 +#include <s32file.h>
    1.25 +#include <graphics/shapeimpl.h>
    1.26 +#include <fntstore.h>
    1.27 +#include "FNTBODY.H"
    1.28 +#include "FNTSTD.H"
    1.29 +#include <graphics/shaperparams.h>
    1.30 +
    1.31 +#define DO_LOADFONT_OPTIMIZATION 1
    1.32 +#include <linkedfonts.h>
    1.33 +#include "linkedfontsprivate.h"
    1.34 +#include "openfontsprivate.h"
    1.35 +#include <openfontlinkedtypefaceelementspec.h>
    1.36 +#include <graphics/openfontlinkedtypefaceextension.h>
    1.37 +#include <graphics/openfontlinkedtypefacespecification.h>
    1.38 +#include <graphics/openfontrasterizer.h>
    1.39 +#include <graphics/openfontconstants.h>
    1.40 +
    1.41 +#include "OstTraceDefinitions.h"
    1.42 +#ifdef OST_TRACE_COMPILER_IN_USE
    1.43 +#include "FNTSTORETraces.h"
    1.44 +#endif
    1.45 +
    1.46 +
    1.47 +static const TUint32 KOutlineGlyphIdHashMask = 0x0000ffff;
    1.48 +static const TUint32 KOutlineFileUidHashMask = 0x00ff0000;
    1.49 +static const TUint32 KOutlineFaceIndexHashMask = 0x0f000000;
    1.50 +static const TUint32 KOutlineFontPtrHashMask = 0x0fff0000;
    1.51 +
    1.52 +// uncomment to enable some verbose debug prints
    1.53 +//#define VERBOSE_DEBUG 1
    1.54 +
    1.55 +
    1.56 +/**  These constants set the default pixel width and height, in Twips x1000.
    1.57 + Hal Data information overrides this if it is available. EDisplayXPixels & EDisplayXTwips, 
    1.58 + EDisplayYPixels & EDisplayYTwips values are required respectively.
    1.59 +
    1.60 + (11860 is approx equivalent to 120 pixels per inch.)
    1.61 +@internalComponent
    1.62 +*/
    1.63 +const TInt KDefaultPixelWidthInTwips = 11860;
    1.64 +const TInt KDefaultPixelHeightInTwips = 11860;
    1.65 +
    1.66 +// default granularity for arrays
    1.67 +const TInt KDefaultArrayGranularity = 8;
    1.68 +
    1.69 +/* Maximum height of a character bitmap. When font height in pixel is 1024, each 
    1.70 +character bitmap is equal to (roughly) 1024 x 1024 x 8 bits/pixel = 1 MB.
    1.71 +@internalComponent
    1.72 +*/
    1.73 +const TInt KMaxFontHeightInPixels = 1024;
    1.74 +
    1.75 +/* Minimum height of font in pixels that can be displayed on the screen.
    1.76 +@internalComponent
    1.77 +*/
    1.78 +const TInt KMinFontHeightInPixels = 2;
    1.79 +/**
    1.80 +The arbitrary list of sizes, in points, returned for scaleable fonts.
    1.81 +We can't return 2^32 - 1 sizes, or something that reflect the fact
    1.82 +that any size is okay, because a UI will probably try to create a listbox containing all the sizes.
    1.83 +
    1.84 +Array stored in Twips as that is the only form of the value currently used.
    1.85 +@internalComponent
    1.86 +*/
    1.87 +#define POINTSIZE_IN_TWIPS(p)	((p) * 20)
    1.88 +const TInt gOpenFontSizeInTwipsArray[] =
    1.89 +	{
    1.90 +	// 4pt-18pt in steps of 1pt (15 sizes)
    1.91 +	POINTSIZE_IN_TWIPS(4), POINTSIZE_IN_TWIPS(5), POINTSIZE_IN_TWIPS(6),
    1.92 +	POINTSIZE_IN_TWIPS(7), POINTSIZE_IN_TWIPS(8), POINTSIZE_IN_TWIPS(9),
    1.93 +	POINTSIZE_IN_TWIPS(10), POINTSIZE_IN_TWIPS(11), POINTSIZE_IN_TWIPS(12),
    1.94 +	POINTSIZE_IN_TWIPS(13), POINTSIZE_IN_TWIPS(14), POINTSIZE_IN_TWIPS(15),
    1.95 +	POINTSIZE_IN_TWIPS(16), POINTSIZE_IN_TWIPS(17), POINTSIZE_IN_TWIPS(18),
    1.96 +	// 20pt-36pt in steps of 2pt (9 sizes)
    1.97 +	POINTSIZE_IN_TWIPS(20), POINTSIZE_IN_TWIPS(22), POINTSIZE_IN_TWIPS(24),
    1.98 +	POINTSIZE_IN_TWIPS(26), POINTSIZE_IN_TWIPS(28), POINTSIZE_IN_TWIPS(30),
    1.99 +	POINTSIZE_IN_TWIPS(32), POINTSIZE_IN_TWIPS(34), POINTSIZE_IN_TWIPS(36),
   1.100 +	// 40pt-72pt in steps of 4pt (9 sizes)
   1.101 +	POINTSIZE_IN_TWIPS(40), POINTSIZE_IN_TWIPS(44), POINTSIZE_IN_TWIPS(48),
   1.102 +	POINTSIZE_IN_TWIPS(52), POINTSIZE_IN_TWIPS(56), POINTSIZE_IN_TWIPS(60),
   1.103 +	POINTSIZE_IN_TWIPS(64), POINTSIZE_IN_TWIPS(68), POINTSIZE_IN_TWIPS(72),
   1.104 +	// 80pt-144pt in steps of 8pt (9 sizes)
   1.105 +	POINTSIZE_IN_TWIPS(80), POINTSIZE_IN_TWIPS(88), POINTSIZE_IN_TWIPS(96),
   1.106 +	POINTSIZE_IN_TWIPS(104), POINTSIZE_IN_TWIPS(112), POINTSIZE_IN_TWIPS(120),
   1.107 +	POINTSIZE_IN_TWIPS(128), POINTSIZE_IN_TWIPS(136), POINTSIZE_IN_TWIPS(144)
   1.108 +	};
   1.109 +
   1.110 +const TInt KOpenFontSizeArrayCount = sizeof(gOpenFontSizeInTwipsArray) / sizeof(gOpenFontSizeInTwipsArray[0]);
   1.111 +
   1.112 +/**
   1.113 +@internalTechnology
   1.114 + The folder used to store linked fonts; the character represents the system drive
   1.115 + location and the descriptor contains the private path of fbserv.
   1.116 + */
   1.117 +_LIT(KLinkedFontFileFolder, "%c:%Slfonts\\");
   1.118 +
   1.119 +/**
   1.120 +@internalTechnology
   1.121 + The folder used to store updated linked fonts; the descriptor should be formatted
   1.122 + with the formatted version of KLinkedFontFileFolder. Files will be moved from this
   1.123 + folder to KLinkedFontFileFolder at boot time before the font loading procedure.
   1.124 + */
   1.125 +_LIT(KLinkedFontFileTempFolder, "update\\");
   1.126 +
   1.127 +/**
   1.128 +The font search string. The Y: directory prefix forces the search to 
   1.129 +start with drive Y:. The drives will be searched in the order Y: to A: then Z:
   1.130 +*/
   1.131 +_LIT(KFBSERVFontDirSecure, "y:\\resource\\fonts\\");
   1.132 +
   1.133 +/**The maximum length of the linked font folder path*/
   1.134 +const TInt KMaxLinkedFontPathLength = 36;
   1.135 +
   1.136 +/**The maximum length of a private path*/
   1.137 +const TInt KMaxPrivatePathLength = 19;
   1.138 +
   1.139 +/** Container for TTypefaceSupport that describes an Open Font family.
   1.140 +
   1.141 +There is an implicit assumption that all fonts in the family will have the same attributes
   1.142 +as the first instance found.  E.g. that the range of font heights is the same. 
   1.143 +
   1.144 +An array of pointers to the COpenFontFile file objects that hold fonts in this family
   1.145 +also provides reference counting for the object.
   1.146 +
   1.147 +@internalComponent
   1.148 +*/
   1.149 +NONSHARABLE_CLASS(CTypefaceSupportInfo) : public CBase
   1.150 +	{
   1.151 +public:
   1.152 +	CTypefaceSupportInfo();
   1.153 +	inline TInt AddFontFilePtr(COpenFontFile* aOpenFontFile);
   1.154 +	inline TInt AddUniqueFontFilePtr(COpenFontFile* aOpenFontFile,const TOpenFontFaceAttrib& aFaceAttrib);
   1.155 +	inline TInt FindFontFilePtr(COpenFontFile* aOpenFontFile);
   1.156 +	inline TBool RemoveFontFilePtr(TInt aIndex);
   1.157 +	void SetTypefaceInfo(const TOpenFontFaceAttrib& aFaceAttrib, TInt aMinHeightInTwips);
   1.158 +	inline const TTypefaceSupport* TypefaceSupport() const;
   1.159 +	inline TInt NearestPointSizeIndex() const;
   1.160 +	static TInt CompareFontNames(const CTypefaceSupportInfo& aTypeface1, const CTypefaceSupportInfo& aTypeface2);
   1.161 +	~CTypefaceSupportInfo();
   1.162 +
   1.163 +public:
   1.164 +	TTypefaceSupport iSupport;
   1.165 +	// pointers back to the COpenFontFile object which has one or more typefaces in this family
   1.166 +	RPointerArray<COpenFontFile> iOpenFontFilePtrArray;
   1.167 +	// nearest standard point size index;
   1.168 +	TInt iNearestPointSizeIndex;
   1.169 +	};
   1.170 +
   1.171 +
   1.172 +/** helper class used with the cleanup stack
   1.173 +@internalComponent
   1.174 +*/
   1.175 +class TCleanupRemoveFontFile
   1.176 +	{
   1.177 +public:
   1.178 +	inline TCleanupRemoveFontFile(CFontStore* aFontStore, TUid aFontUid);
   1.179 +public:
   1.180 +	CFontStore* iFontStore;
   1.181 +	TUid iFontUid;
   1.182 +	};
   1.183 +
   1.184 +
   1.185 +// declare static functions
   1.186 +static TInt MatchFontSpecsInPixels(const TOpenFontSpec& aCandidateFontSpec,
   1.187 +	const TOpenFontSpec& aIdealFontSpec, TInt aCandidateMaxHeight = 0, TInt aIdealMaxHeight = 0);
   1.188 +static void ReadFromFileL(RFile& aFile, TDes8& aDes, TInt aLength);
   1.189 +static TUint TtfTableTagFromBufferL(TDes8& aDes);
   1.190 +
   1.191 +#ifdef _DEBUG
   1.192 +static TUint32 StartTiming(void);
   1.193 +static TUint32 FinishTimingL(TUint32 startTime);
   1.194 +#endif
   1.195 +
   1.196 +static TBool FileIsOnZ(TParse& aFileName);
   1.197 +static TBool FileIsInList(TParse& aFileName, RArray<TParse>& aList);
   1.198 +
   1.199 +
   1.200 +/** Helper function for converting a pointer to an offset from the passed
   1.201 +heap base. Use OffsetToPointer() to convert the returned offset back to a
   1.202 +useable pointer.
   1.203 +@param aAny A pointer to be converted to an offset.
   1.204 +@param aHeapBase The heap base of the current process.
   1.205 +@return An offset representing the passed pointer that can be converted
   1.206 +back to a pointer using the function OffsetToPointer(). 
   1.207 +@see OffsetToPointer()
   1.208 + */
   1.209 +LOCAL_C TInt PointerToOffset(const TAny* aAny, TUint8* aHeapBase)
   1.210 +    {
   1.211 +    if (aAny && aHeapBase)
   1.212 +        {
   1.213 +        return reinterpret_cast<TInt>(aAny) - reinterpret_cast<TInt>(aHeapBase);
   1.214 +        }
   1.215 +    return 0;
   1.216 +    }
   1.217 +
   1.218 +/** Helper function for converting an offset (that was calculated using
   1.219 +PointerToOffset()) back to a pointer relative to the passed heap base.
   1.220 +@param aOffset The offset to be converted to a pointer.
   1.221 +@param aHeapBase The heap base of the current process.
   1.222 +@return A pointer relative to the passed heap base.
   1.223 +@see PointerToOffset()
   1.224 + */
   1.225 +LOCAL_C TAny* OffsetToPointer(TInt aOffset, TUint8* aHeapBase)
   1.226 +    {
   1.227 +    if (aOffset && aHeapBase)
   1.228 +        {
   1.229 +        return reinterpret_cast<TAny*>(aOffset + reinterpret_cast<TInt>(aHeapBase));
   1.230 +        }
   1.231 +    return NULL;
   1.232 +    }
   1.233 +
   1.234 +
   1.235 +// CTypefaceSupportInfo
   1.236 +CTypefaceSupportInfo::CTypefaceSupportInfo()
   1.237 +	{
   1.238 +	}
   1.239 +
   1.240 +
   1.241 +CTypefaceSupportInfo::~CTypefaceSupportInfo()
   1.242 +	{ // no ownership of font files, so just Close the array
   1.243 +	iOpenFontFilePtrArray.Close();
   1.244 +	}
   1.245 +
   1.246 +
   1.247 +/** Add a back pointer to an Open Font file, in sorted order.
   1.248 +@param aOpenFontFile font file that has a typeface in this family.
   1.249 +@return KErrNone if added, KErrAlreadyExists if file is already referenced, or KErrNoMemory.
   1.250 +@internalComponent
   1.251 +*/
   1.252 +TInt CTypefaceSupportInfo::AddFontFilePtr(COpenFontFile* aOpenFontFile)
   1.253 +	{
   1.254 +	return iOpenFontFilePtrArray.InsertInAddressOrder(aOpenFontFile);
   1.255 +	}
   1.256 +
   1.257 +/** Add a back pointer to an Open Font file, in sorted order, but only if the font details are unique.
   1.258 +@param aOpenFontFile font file that has a typeface in this family.
   1.259 +@return KErrNone if added, KErrInUse if another file already defines this, KErrAlreadyExists if file is already referenced, or KErrNoMemory.
   1.260 +@internalComponent
   1.261 +*/
   1.262 +TInt CTypefaceSupportInfo::AddUniqueFontFilePtr(COpenFontFile* aOpenFontFile,const TOpenFontFaceAttrib& aFaceAttrib)
   1.263 +	{
   1.264 +#ifdef _DEBUG	
   1.265 +	_LIT(KLoadedFont, "TypefaceSupport: already loaded font: %S\n");
   1.266 +#endif
   1.267 +	
   1.268 +	TPtrC findName=aFaceAttrib.FullName();
   1.269 +	for (TInt i=0,maxi=iOpenFontFilePtrArray.Count();i<maxi;i++)
   1.270 +		{	//Do any of the fonts already registered with this family already provide this specific font?
   1.271 +		COpenFontFile* cmpFont=iOpenFontFilePtrArray[i];
   1.272 +		if (cmpFont==aOpenFontFile)
   1.273 +			{   //Another specific font in this font file has already been added to this family
   1.274 +				//InsertInAddressOrder would detect this.
   1.275 +#ifdef _DEBUG
   1.276 +				RDebug::Print(KLoadedFont, &findName);
   1.277 +#endif
   1.278 +				return KErrAlreadyExists;	
   1.279 +			}
   1.280 +		else
   1.281 +			{
   1.282 +			for (TInt j=0,maxj=cmpFont->FaceCount();j<maxj;j++)
   1.283 +				{	//The expectation is that open fonts will only have 1 face per file, so this loop is 1-pass generally.
   1.284 +				const TOpenFontFaceAttrib& cmpFace=cmpFont->FaceAttrib(j);
   1.285 +				TPtrC cmpName=cmpFace.FullName();
   1.286 +				if (cmpName==findName)
   1.287 +					{
   1.288 +#ifdef _DEBUG
   1.289 +					RDebug::Print(KLoadedFont, &findName);
   1.290 +#endif
   1.291 +					return KErrInUse;
   1.292 +					}
   1.293 +				}
   1.294 +			}
   1.295 +		}
   1.296 +	return iOpenFontFilePtrArray.InsertInAddressOrder(aOpenFontFile);
   1.297 +	}
   1.298 +
   1.299 +/** Check font family for back pointer to an Open Font file.
   1.300 +@param aOpenFontFile font file that may have a typeface in this family.
   1.301 +@return KErrNotFound or the index of pointer
   1.302 +@internalComponent
   1.303 +*/
   1.304 +TInt CTypefaceSupportInfo::FindFontFilePtr(COpenFontFile* aOpenFontFile)
   1.305 +	{
   1.306 +	return iOpenFontFilePtrArray.FindInAddressOrder(aOpenFontFile);
   1.307 +	}
   1.308 +
   1.309 +
   1.310 +/** Remove a font file back pointer.
   1.311 +@param aIndex the index of pointer, from FindFontFilePtr()
   1.312 +@return ETrue if there are no more implementations of the font family
   1.313 +@internalComponent
   1.314 +*/
   1.315 +TBool CTypefaceSupportInfo::RemoveFontFilePtr(TInt aIndex)
   1.316 +	{
   1.317 +	iOpenFontFilePtrArray.Remove(aIndex);
   1.318 +	return iOpenFontFilePtrArray.Count() == 0;
   1.319 +	}
   1.320 +
   1.321 +
   1.322 +/** Set the details of the typeface family.
   1.323 +@param aFaceAttrib typeface to parameterise.
   1.324 +@internalComponent
   1.325 +*/
   1.326 +void CTypefaceSupportInfo::SetTypefaceInfo(const TOpenFontFaceAttrib& aFaceAttrib, TInt aMinHeightInTwips)
   1.327 +	{
   1.328 +	iSupport.iTypeface.iName = aFaceAttrib.ShortFamilyName();
   1.329 +	iSupport.iTypeface.SetIsProportional(!aFaceAttrib.IsMonoWidth());
   1.330 +	iSupport.iTypeface.SetIsSerif(aFaceAttrib.IsSerif());
   1.331 +	iSupport.iTypeface.SetIsSymbol(aFaceAttrib.IsSymbol());
   1.332 +
   1.333 +	// Find minimum size in twips then find the next higher standard size.
   1.334 +	iSupport.iMinHeightInTwips = aMinHeightInTwips;
   1.335 +	TInt fontSizeIndex = 0;
   1.336 +	for (; fontSizeIndex < KOpenFontSizeArrayCount; ++fontSizeIndex)
   1.337 +		{
   1.338 +		const TInt KMinHeightInTwips = gOpenFontSizeInTwipsArray[fontSizeIndex];
   1.339 +		if (aMinHeightInTwips <= KMinHeightInTwips)
   1.340 +			{
   1.341 +			aMinHeightInTwips = KMinHeightInTwips;
   1.342 +			break;
   1.343 +			}
   1.344 +		}
   1.345 +	iNearestPointSizeIndex = fontSizeIndex;
   1.346 +	iSupport.iMaxHeightInTwips = Max(gOpenFontSizeInTwipsArray[KOpenFontSizeArrayCount - 1], iSupport.iMinHeightInTwips);
   1.347 +	iSupport.iNumHeights = Max(1,KOpenFontSizeArrayCount - iNearestPointSizeIndex);
   1.348 +	iSupport.iIsScalable = TRUE;
   1.349 +	}
   1.350 +
   1.351 +
   1.352 +/** Get the details of the typeface family.
   1.353 +@internalComponent
   1.354 +*/
   1.355 +const TTypefaceSupport* CTypefaceSupportInfo::TypefaceSupport() const
   1.356 +	{
   1.357 +	return &iSupport;
   1.358 +	}
   1.359 +	
   1.360 +/** Get the Nearest Standard Point Size Index.
   1.361 +@internalComponent
   1.362 +*/
   1.363 +TInt CTypefaceSupportInfo::NearestPointSizeIndex() const
   1.364 +	{
   1.365 +	return iNearestPointSizeIndex;
   1.366 +	}
   1.367 +
   1.368 +// for InsertInOrder
   1.369 +TInt CTypefaceSupportInfo::CompareFontNames(const CTypefaceSupportInfo& aTypeface1, const CTypefaceSupportInfo& aTypeface2)
   1.370 +	{
   1.371 +	return aTypeface1.iSupport.iTypeface.iName.CompareF(aTypeface2.iSupport.iTypeface.iName);
   1.372 +	}
   1.373 +
   1.374 +
   1.375 +// TCleanupRemoveFontFile
   1.376 +TCleanupRemoveFontFile::TCleanupRemoveFontFile(CFontStore* aFontStore, TUid aFontUid) :
   1.377 +	iFontStore(aFontStore), iFontUid(aFontUid)
   1.378 +	{
   1.379 +	}
   1.380 +
   1.381 +
   1.382 +TBitmapFontCharacterOffset::TBitmapFontCharacterOffset()
   1.383 + :	iBitmapOffset(0)
   1.384 +	{}
   1.385 +
   1.386 +void TBitmapFontCharacterOffset::InternalizeL(RReadStream& aStream)
   1.387 +	{
   1.388 +	iBitmapOffset = aStream.ReadUint16L();
   1.389 +	};
   1.390 +
   1.391 +EXPORT_C TCharacterMetrics::TCharacterMetrics()
   1.392 + :	iAscentInPixels(0),
   1.393 +	iHeightInPixels(0),
   1.394 +	iLeftAdjustInPixels(0),
   1.395 +	iMoveInPixels(0),
   1.396 +	iRightAdjustInPixels(0)
   1.397 +	{
   1.398 +	}
   1.399 +
   1.400 +TBitmapFontCharacterMetrics::TBitmapFontCharacterMetrics()
   1.401 + :	iAscentInPixels(0),
   1.402 +	iHeightInPixels(0),
   1.403 +	iLeftAdjustInPixels(0),
   1.404 +	iMoveInPixels(0),
   1.405 +	iRightAdjustInPixels(0)
   1.406 +	{
   1.407 +	}
   1.408 +
   1.409 +void TBitmapFontCharacterMetrics::InternalizeL(RReadStream& aStream)
   1.410 +	{
   1.411 +	iAscentInPixels = aStream.ReadInt8L();
   1.412 +	iHeightInPixels = aStream.ReadInt8L();
   1.413 +	iLeftAdjustInPixels = aStream.ReadInt8L();
   1.414 +	iMoveInPixels = aStream.ReadInt8L();
   1.415 +	iRightAdjustInPixels = aStream.ReadInt8L();
   1.416 +	}
   1.417 +
   1.418 +/** Constructor. */
   1.419 +EXPORT_C TAlgStyle::TAlgStyle()
   1.420 + :	iBaselineOffsetInPixels(0),
   1.421 +	iFlags(0),
   1.422 +	iWidthFactor(1),
   1.423 +	iHeightFactor(1)
   1.424 +	{
   1.425 +	}
   1.426 +
   1.427 +/** Sets whether the font is bold.
   1.428 +
   1.429 +@param aIsBold ETrue if the font is bold; otherwise EFalse. */
   1.430 +EXPORT_C void TAlgStyle::SetIsBold(TBool aIsBold)
   1.431 +	{
   1.432 +	if (aIsBold)
   1.433 +		iFlags |= EBold;
   1.434 +	else
   1.435 +		iFlags &= ~EBold;
   1.436 +	}
   1.437 +
   1.438 +/** Sets whether the font is italic.
   1.439 +
   1.440 +@param aIsItalic ETrue if the font is italic; otherwise EFalse. */
   1.441 +EXPORT_C void TAlgStyle::SetIsItalic(TBool aIsItalic)
   1.442 +	{
   1.443 +	if (aIsItalic)
   1.444 +		iFlags |= EItalic;
   1.445 +	else
   1.446 +		iFlags &= ~EItalic;
   1.447 +	}
   1.448 +
   1.449 +/** Sets whether the font is mono width - i.e. all characters have the same width.
   1.450 +
   1.451 +@param aIsMono ETrue if the font is mono width; otherwise EFalse. */
   1.452 +EXPORT_C void TAlgStyle::SetIsMono(TBool aIsMono)
   1.453 +	{
   1.454 +	if (aIsMono)
   1.455 +		iFlags|=EMono;
   1.456 +	else
   1.457 +		iFlags&=~EMono;
   1.458 +	}
   1.459 +
   1.460 +/** Sets the width factor.
   1.461 +
   1.462 +@param aWidthFactor A width factor. */
   1.463 +EXPORT_C void TAlgStyle::SetWidthFactor(TInt aWidthFactor)
   1.464 +	{
   1.465 +	iWidthFactor=(TInt8) aWidthFactor;
   1.466 +	}
   1.467 +
   1.468 +/** Sets the height factor.
   1.469 +
   1.470 +@param aHeightFactor A height factor. */
   1.471 +EXPORT_C void TAlgStyle::SetHeightFactor(TInt aHeightFactor)
   1.472 +	{
   1.473 +	iHeightFactor=(TInt8) aHeightFactor;
   1.474 +	}
   1.475 +
   1.476 +/** Returns whether the font is bold.
   1.477 +
   1.478 +@return ETrue if the font is bold; otherwise EFalse. */
   1.479 +EXPORT_C TBool TAlgStyle::IsBold() const
   1.480 +	{
   1.481 +	return iFlags&EBold;
   1.482 +	}
   1.483 +
   1.484 +/** Returns whether the font is italic.
   1.485 +
   1.486 +@return ETrue if the font is italic; otherwise EFalse. */
   1.487 +EXPORT_C TBool TAlgStyle::IsItalic() const
   1.488 +	{
   1.489 +	return iFlags&EItalic;
   1.490 +	}
   1.491 +
   1.492 +/** Returns whether the font is mono - i.e. all characters have the same width.
   1.493 +
   1.494 +@return ETrue if the font is mono; otherwise EFalse. */
   1.495 +EXPORT_C TBool TAlgStyle::IsMono() const
   1.496 +	{
   1.497 +	return iFlags&EMono;
   1.498 +	}
   1.499 +
   1.500 +/** Returns the width factor.
   1.501 +
   1.502 +@return A width factor. */
   1.503 +EXPORT_C TInt TAlgStyle::WidthFactor() const
   1.504 +	{
   1.505 +	return iWidthFactor;
   1.506 +	}
   1.507 +
   1.508 +/** Returns the height factor.
   1.509 +
   1.510 +@return A height factor. */
   1.511 +EXPORT_C TInt TAlgStyle::HeightFactor() const
   1.512 +	{
   1.513 +	return iHeightFactor;
   1.514 +	}
   1.515 +
   1.516 +EXPORT_C TBool TAlgStyle::operator==(const TAlgStyle& aAlgStyle) const
   1.517 +	{
   1.518 +	return (iFlags==aAlgStyle.iFlags) && 
   1.519 +	       (iWidthFactor==aAlgStyle.iWidthFactor) &&
   1.520 +	       (iHeightFactor==aAlgStyle.iHeightFactor) &&
   1.521 +	       (iBaselineOffsetInPixels==aAlgStyle.iBaselineOffsetInPixels);
   1.522 +	}
   1.523 +
   1.524 +/**
   1.525 +@internalTechnology
   1.526 +*/
   1.527 +TBool TAlgStyle::operator!=(const TAlgStyle& aAlgStyle) const
   1.528 +	{
   1.529 +	return !this->operator==(aAlgStyle);
   1.530 +	}
   1.531 +
   1.532 +CBitmapFont::CBitmapFont(
   1.533 +	RHeap*				aHeap,
   1.534 +	const TFontSpec&	aFontSpecInTwips,
   1.535 +	const TAlgStyle&	aAlgStyle,
   1.536 +	CFontBitmap*		aFontBitmap):
   1.537 +	iFontSpecInTwips(aFontSpecInTwips),
   1.538 +	iAlgStyle(aAlgStyle),
   1.539 +	iHeap(aHeap)
   1.540 +	{
   1.541 +	iFontBitmapOffset = (TInt) ((TUint)(aFontBitmap) - (TUint)(this));
   1.542 +	}
   1.543 +
   1.544 +CBitmapFont::CBitmapFont(
   1.545 +	RHeap*				aHeap,
   1.546 +	const TFontSpec&	aFontSpecInTwips,
   1.547 +	const TAlgStyle&	aAlgStyle,
   1.548 +	COpenFont*			aOpenFont):
   1.549 +	iFontSpecInTwips(aFontSpecInTwips),
   1.550 +	iAlgStyle(aAlgStyle),
   1.551 +	iHeap(aHeap)
   1.552 +	{
   1.553 +    // Set iOpenFont to be the offset of aOpenFont from the address of CBitmapFont.
   1.554 +    // In order to be able to identify iOpenFont as an offset instead of a pointer,
   1.555 +    // bitwise or the offset with 1.  Pointers will always be word aligned (and therefore even).
   1.556 +    if (aOpenFont)
   1.557 +        {
   1.558 +        __ASSERT_DEBUG(!(reinterpret_cast<TInt>(aOpenFont) & 1), Panic(EFntPointerNotByteAligned));
   1.559 +        iOpenFont = reinterpret_cast<COpenFont*>((reinterpret_cast<TInt>(aOpenFont) - reinterpret_cast<TInt>(this)) | 1);
   1.560 +        }
   1.561 +    else
   1.562 +        {
   1.563 +        iOpenFont = NULL;
   1.564 +        }
   1.565 +	}
   1.566 +
   1.567 +/** This member is private and not intended for use. */
   1.568 +void CBitmapFont::ConstructL()
   1.569 +	{
   1.570 +	if (!IsOpenFont())
   1.571 +		FontBitmap()->UseL();
   1.572 +	}
   1.573 +
   1.574 +/** This member is private and not intended for use. */
   1.575 +CBitmapFont::~CBitmapFont()
   1.576 +	{	
   1.577 +	if (!IsOpenFont() && iFontBitmapOffset)
   1.578 +		FontBitmap()->Release();
   1.579 +	else if (IsOpenFont())
   1.580 +		delete OpenFont();
   1.581 +	}	
   1.582 +
   1.583 +CBitmapFont* CBitmapFont::NewL(
   1.584 +	RHeap*				aHeap,
   1.585 +	const TFontSpec&	aFontSpecInTwips,
   1.586 +	const TAlgStyle&	aAlgStyle,
   1.587 +	CFontBitmap*		aFontBitmap)
   1.588 +	{
   1.589 +	// font is placed in shared heap
   1.590 +	CBitmapFont* f = (CBitmapFont*) aHeap->AllocL(sizeof(CBitmapFont));
   1.591 +	new(f) CBitmapFont(aHeap, aFontSpecInTwips, aAlgStyle, aFontBitmap);
   1.592 +	CleanupStack::PushL(f);
   1.593 +	f->ConstructL();
   1.594 +	CleanupStack::Pop(f);
   1.595 +	return f;
   1.596 +	}
   1.597 +
   1.598 +CBitmapFont* CBitmapFont::NewL(
   1.599 +	RHeap*				aHeap,
   1.600 +	const TFontSpec&	aFontSpecInTwips,
   1.601 +	const TAlgStyle&	aAlgStyle,
   1.602 +	COpenFont*			aOpenFont)
   1.603 +	{
   1.604 +	// font is placed in shared heap
   1.605 +	CBitmapFont* f = (CBitmapFont*) aHeap->AllocL(sizeof(CBitmapFont));
   1.606 +	new(f) CBitmapFont(aHeap,aFontSpecInTwips,aAlgStyle,aOpenFont);
   1.607 +	return f;
   1.608 +	}
   1.609 +	
   1.610 +/** Returns the font type identifier:KCBitmapFontUidVal.
   1.611 +
   1.612 +@return The font type identifier. */
   1.613 +EXPORT_C TUid CBitmapFont::DoTypeUid() const
   1.614 +	{
   1.615 +	return TUid::Uid(KCBitmapFontUidVal);
   1.616 +	}
   1.617 +
   1.618 +/** Returns a font identifier.
   1.619 +
   1.620 +If it uses an open font the UID returned has a value of zero. Otherwise it 
   1.621 +has the UID value of the CFontBitmap it uses.
   1.622 +
   1.623 +@return A font identifier. */
   1.624 +TUid CBitmapFont::Uid() const
   1.625 +	{
   1.626 +	if (IsOpenFont())
   1.627 +		return TUid::Uid(0);	
   1.628 +	else
   1.629 +		return FontBitmap()->iUid;
   1.630 +	}
   1.631 +
   1.632 +/** Returns the font height in pixels.
   1.633 +For an open font this will be the design height (notional rather than exact).
   1.634 +
   1.635 +@return Font height in pixels.
   1.636 +@see FontMaxHeight()
   1.637 +*/
   1.638 +EXPORT_C TInt CBitmapFont::DoHeightInPixels() const
   1.639 +	{
   1.640 +	if (IsOpenFont())
   1.641 +		return Height(OpenFont()->Metrics().Size());	
   1.642 +	else
   1.643 +		return Height(FontBitmap()->iCellHeightInPixels);
   1.644 +	}
   1.645 +
   1.646 +/** Returns the font ascent in pixels.
   1.647 +
   1.648 +The ascent is usually the height of a Latin capital letter above the baseline.
   1.649 +For an open font, the returned value is likely to be inaccurate.
   1.650 +Don't rely on it to get exact metrics at the pixel level.
   1.651 +
   1.652 +@return Font ascent in pixels.
   1.653 +@see FontCapitalAscent()
   1.654 +@see FontMaxAscent()
   1.655 +*/
   1.656 +EXPORT_C TInt CBitmapFont::DoAscentInPixels() const
   1.657 +	{
   1.658 +	if (IsOpenFont())
   1.659 +		return Height(OpenFont()->Metrics().Ascent());	
   1.660 +	else
   1.661 +		return Height(FontBitmap()->iAscentInPixels);
   1.662 +	}
   1.663 +
   1.664 +/** Returns the width, in pixels, of the given character.
   1.665 +
   1.666 +If all characters have the same width (i.e. the font is mono - an attribute 
   1.667 +stored in iAlgStyle) then this is the maximum normal width, returned using 
   1.668 +MaxNormalCharWidthInPixels().
   1.669 +
   1.670 +Note: For OpenType fonts this function returns the horizontal advance of
   1.671 +the character, which may be different from the actual width.
   1.672 +
   1.673 +@param aChar A character.
   1.674 +@return The character width in pixels. */
   1.675 +EXPORT_C TInt CBitmapFont::DoCharWidthInPixels(TChar aChar) const
   1.676 +	{
   1.677 +	const TUint8* bytes;
   1.678 +	if (iAlgStyle.IsMono())
   1.679 +		return MaxNormalCharWidthInPixels();
   1.680 +	else
   1.681 +		return Width(CharacterMetrics(aChar,bytes).iMoveInPixels);
   1.682 +	}
   1.683 +
   1.684 +/** Returns the width, in pixels, of the given text.
   1.685 +
   1.686 +@param aText Text string.
   1.687 +@return Width of the text in pixels. */
   1.688 +EXPORT_C TInt CBitmapFont::DoTextWidthInPixels(const TDesC &aText) const
   1.689 +	{
   1.690 +	TMeasureTextInput* dummy = NULL;
   1.691 +	return DoTextWidthInPixels(aText, dummy);
   1.692 +	}
   1.693 +
   1.694 +/** Returns the width, in pixels, of the given text.
   1.695 +
   1.696 +@param aText Text string.
   1.697 +@return Width of the text in pixels. */
   1.698 +TInt CBitmapFont::DoTextWidthInPixels(const TDesC &aText, const TMeasureTextInput* aParam) const
   1.699 +	{
   1.700 +	TMeasureTextOutput output;
   1.701 +	TInt advance_width = MeasureText(aText,aParam,&output);
   1.702 +	return Max(advance_width,output.iBounds.Width());
   1.703 +	}
   1.704 +
   1.705 +
   1.706 +/** Returns the baseline offset in pixels, as stored in iAlgStyle.
   1.707 +
   1.708 +@return The baseline offset in pixels. */
   1.709 +EXPORT_C TInt CBitmapFont::DoBaselineOffsetInPixels() const
   1.710 +	{
   1.711 +	return iAlgStyle.iBaselineOffsetInPixels;
   1.712 +	}
   1.713 +
   1.714 +/** Returns the number of whole characters of aText, starting from the beginning, 
   1.715 +that fit into the given pixel width.
   1.716 +
   1.717 +@param aText A text string.
   1.718 +@param aWidthInPixels A width in pixels.
   1.719 +@return The number of whole characters of aText that fit into aWidthInPixels.
   1.720 +*/
   1.721 +EXPORT_C TInt CBitmapFont::DoTextCount(const TDesC &aText,TInt aWidthInPixels) const
   1.722 +	{
   1.723 +	TInt count = 0;
   1.724 +	const TInt length = aText.Length();
   1.725 +	TInt width = 0;
   1.726 +	// accumulate text width character by character, until target is reached or exceeded
   1.727 +	TInt widthDiff = aWidthInPixels - width;
   1.728 +	while ( (widthDiff > 0) && (length > count) )
   1.729 +		{ 
   1.730 +		width += TextWidthInPixels(aText.Mid(count,1));
   1.731 +		widthDiff = aWidthInPixels - width;
   1.732 +		if (widthDiff >= 0)
   1.733 +			{ // width <= aWidthInPixels
   1.734 +			++count;
   1.735 +			}
   1.736 +		}
   1.737 +	return count;
   1.738 +	}
   1.739 +
   1.740 +/** Returns the number of whole characters of aText, starting from the beginning, 
   1.741 +that fit into the given pixel width, and gets the excess width.
   1.742 +
   1.743 +@param aText A text descriptor.
   1.744 +@param aWidthInPixels A width in pixels.
   1.745 +@param aExcessWidthInPixels On return, the width left over of aWidthInPixels 
   1.746 +after the maximum possible whole number of characters of aText have been fit 
   1.747 +into it.
   1.748 +@return The number of whole characters of aText that fit into aWidthInPixels. */
   1.749 +EXPORT_C TInt CBitmapFont::DoTextCount(const TDesC &aText,TInt aWidthInPixels,TInt &aExcessWidthInPixels) const
   1.750 +	{
   1.751 +	TInt count = TextCount(aText,aWidthInPixels);
   1.752 +	aExcessWidthInPixels = aWidthInPixels - TextWidthInPixels(aText.Left(count));
   1.753 +	return count;
   1.754 +	}
   1.755 +
   1.756 +/** Returns the font's maximum character width in pixels.
   1.757 +
   1.758 +@return The maximum character width in pixels. */
   1.759 +EXPORT_C TInt CBitmapFont::DoMaxCharWidthInPixels() const
   1.760 +	{
   1.761 +	if (IsOpenFont())
   1.762 +		return Width(OpenFont()->Metrics().MaxWidth());	
   1.763 +	else
   1.764 +		return Width(FontBitmap()->iMaxCharWidthInPixels);
   1.765 +	}
   1.766 +
   1.767 +/** Returns the font's normal maximum character width in pixels.
   1.768 +
   1.769 +Note that when a CFontBitmap is used this value is the same as the maximum 
   1.770 +character width in pixels returned by MaxCharWidthInPixels(), but when a COpenFont 
   1.771 +is used the value may be different.
   1.772 +
   1.773 +@return The normal maximum character width in pixels. */
   1.774 +EXPORT_C TInt CBitmapFont::DoMaxNormalCharWidthInPixels() const
   1.775 +	{
   1.776 +	if (IsOpenFont())
   1.777 +		return Width(OpenFont()->Metrics().MaxWidth());
   1.778 +	else
   1.779 +		return Width(FontBitmap()->iMaxNormalCharWidthInPixels);
   1.780 +	}
   1.781 +
   1.782 +/** Returns the device-independent font specification for the font.
   1.783 +
   1.784 +Note that this is set when the bitmap font object is constructed.
   1.785 +
   1.786 +@return A font specification. */
   1.787 +EXPORT_C TFontSpec CBitmapFont::DoFontSpecInTwips() const
   1.788 +	{
   1.789 +	return iFontSpecInTwips;
   1.790 +	}
   1.791 +
   1.792 +
   1.793 +/** Attempts to rasterize a character (aCode) into a data area (aGlyphData) in 
   1.794 +shared memory.
   1.795 +
   1.796 +This works only for open fonts: where the bitmap font object is using a COpenFont.
   1.797 +
   1.798 +Bitmap fonts are deemed to be fully rasterized after they have been loaded 
   1.799 +from file. 
   1.800 +
   1.801 +Returns ETrue if the character was successfully rasterized or was already 
   1.802 +in the cache. This function can be called only by the server; rasterization 
   1.803 +uses memory and other resources (e.g., file handles) owned by the server. 
   1.804 +
   1.805 +@param aSessionHandle A session handle for the open font system.
   1.806 +@param aCode A character code.
   1.807 +@param aGlyphData A data area in shared memory.
   1.808 +@return ETrue if the character was successfully rasterized or was already in 
   1.809 +the cache; otherwise EFalse. */
   1.810 +EXPORT_C TBool CBitmapFont::Rasterize(TInt aSessionHandle, TInt aCode, TOpenFontGlyphData* aGlyphData) const
   1.811 +	{
   1.812 +	if (IsOpenFont())
   1.813 +		return OpenFont()->Rasterize(aSessionHandle, aCode, aGlyphData);
   1.814 +	else
   1.815 +		return EFalse;
   1.816 +	}
   1.817 +
   1.818 +/** Gets a pointer to a bitmap and the metrics for a specified character, but only 
   1.819 +if a CFontBitmap is being used by the bitmap font object.
   1.820 +
   1.821 +This function does not work when a COpenFont is being used, but GetCharacterData() 
   1.822 +can be used instead.
   1.823 +
   1.824 +If the specified character does not exist in the font then the bitmap pointer 
   1.825 +and character metrics are gotten for a replacement character, KReplacementCharacter.
   1.826 +
   1.827 +@param aCode A character code.
   1.828 +@param aBytes On return, a pointer to the bitmap for the specified character.
   1.829 +@return Metrics for the specified character. */
   1.830 +EXPORT_C TCharacterMetrics CBitmapFont::CharacterMetrics(TInt aCode,const TUint8*& aBytes) const
   1.831 +	{
   1.832 +	/*
   1.833 +	This function does not work for Open Fonts because the character data need not be
   1.834 +	shared between sessions and a session handle is needed; GetCharacterData should be used instead.
   1.835 +	*/
   1.836 +	if (IsOpenFont())
   1.837 +		{
   1.838 +		aBytes = NULL;
   1.839 +		return TCharacterMetrics();
   1.840 +		}
   1.841 +
   1.842 +	TBitmapFontCharacterMetrics bitmap_font_metrics = FontBitmap()->CharacterMetrics(aCode,aBytes);
   1.843 +
   1.844 +	// Substitute the replacement character if this character doesn't exist in the font.
   1.845 +	if (aBytes == NULL)
   1.846 +		bitmap_font_metrics = FontBitmap()->CharacterMetrics(KReplacementCharacter,aBytes);
   1.847 +
   1.848 +	TCharacterMetrics metrics;
   1.849 +	metrics.iAscentInPixels = bitmap_font_metrics.iAscentInPixels;
   1.850 +	metrics.iHeightInPixels = bitmap_font_metrics.iHeightInPixels;
   1.851 +	metrics.iLeftAdjustInPixels = bitmap_font_metrics.iLeftAdjustInPixels;
   1.852 +	metrics.iMoveInPixels = bitmap_font_metrics.iMoveInPixels;
   1.853 +	metrics.iRightAdjustInPixels = bitmap_font_metrics.iRightAdjustInPixels;
   1.854 +	
   1.855 +	if (iAlgStyle.IsMono())
   1.856 +		{
   1.857 +		TInt width = metrics.iMoveInPixels - metrics.iLeftAdjustInPixels - metrics.iRightAdjustInPixels;
   1.858 +		metrics.iMoveInPixels = FontBitmap()->iMaxNormalCharWidthInPixels;
   1.859 +		metrics.iLeftAdjustInPixels = (TInt16)((metrics.iMoveInPixels - width) / 2);
   1.860 +		metrics.iRightAdjustInPixels = (TInt16)(metrics.iMoveInPixels - width - metrics.iLeftAdjustInPixels);
   1.861 +		}
   1.862 +
   1.863 +	return metrics;	 // N.B. Not doubled for double height and double width.
   1.864 +	}
   1.865 +
   1.866 + 
   1.867 +/** Gets a pointer to a bitmap and the metrics for a specified character.
   1.868 +
   1.869 +Note that this function calls CharacterMetrics() if a CFontBitmap is being 
   1.870 +used by the bitmap font object, and maps the TCharacterMetrics values returned 
   1.871 +by that function to aMetrics.
   1.872 +
   1.873 +If the function fails to get the bitmap and metric values (because the character 
   1.874 +is in an open font and has not yet been rasterized) returns EFalse.
   1.875 +
   1.876 +@param aSessionHandle A session handle for the open font system.
   1.877 +@param aCode A character code.
   1.878 +@param aMetrics On return, metrics for the specified character.
   1.879 +@param aBitmap On return, a pointer to the bitmap for the specified character.
   1.880 +@return ETrue if successful, otherwise EFalse. */
   1.881 +EXPORT_C TBool CBitmapFont::GetCharacterData(TInt aSessionHandle,TInt aCode,
   1.882 +											 TOpenFontCharMetrics& aMetrics,const TUint8*& aBitmap) const
   1.883 +	{
   1.884 +	if (IsOpenFont())
   1.885 +		{
   1.886 +		const TOpenFontCharMetrics* nm;
   1.887 +		if (OpenFont()->GetCharacterData(aSessionHandle,aCode,nm,aBitmap))
   1.888 +			{
   1.889 +			aMetrics = *nm;
   1.890 +			return ETrue;
   1.891 +			}
   1.892 +		else
   1.893 +			return EFalse;
   1.894 +		}
   1.895 +	else
   1.896 +		{
   1.897 +		TCharacterMetrics m = CharacterMetrics(aCode,aBitmap);
   1.898 +		aMetrics = TOpenFontCharMetrics(m);
   1.899 +		return ETrue;
   1.900 +		}
   1.901 +	}
   1.902 +
   1.903 +/** Gets the open font metrics. 
   1.904 +
   1.905 +These metrics distinguish between maximum character height and depth and typographic 
   1.906 +ascent and descent, so that the clipping rectangle for text can be distinguished 
   1.907 +from the distance to neighbouring baselines. 
   1.908 +
   1.909 +@param aMetrics Open font metrics. */
   1.910 + 
   1.911 +EXPORT_C void CBitmapFont::GetFontMetrics(TOpenFontMetrics& aMetrics) const
   1.912 +	{
   1.913 +	if (IsOpenFont())
   1.914 +		aMetrics = OpenFont()->Metrics();
   1.915 +	else
   1.916 +		{
   1.917 +		new(&aMetrics) TOpenFontMetrics;
   1.918 +		aMetrics.SetSize(CBitmapFont::DoHeightInPixels());
   1.919 +		aMetrics.SetAscent(CBitmapFont::DoAscentInPixels());
   1.920 +		aMetrics.SetDescent(aMetrics.Size() - aMetrics.Ascent());
   1.921 +		aMetrics.SetMaxHeight(aMetrics.Ascent());
   1.922 +		aMetrics.SetMaxDepth(aMetrics.Descent());
   1.923 +		aMetrics.SetMaxWidth(CBitmapFont::DoMaxCharWidthInPixels());
   1.924 +		}
   1.925 +	}
   1.926 +
   1.927 + 
   1.928 +/** Gets the open font typeface attributes if possible. 
   1.929 +
   1.930 +At present no attempt is made to sythesize these attributes for bitmap fonts 
   1.931 +(CFontBitmaps). 
   1.932 +
   1.933 +@param aAttrib On return, the open font typeface attributes.
   1.934 +@return ETrue if successful; EFalse if not possible to get the open font typeface 
   1.935 +attributes. */
   1.936 +EXPORT_C TBool CBitmapFont::GetFaceAttrib(TOpenFontFaceAttrib& aAttrib) const
   1.937 +	{
   1.938 +	if (IsOpenFont())
   1.939 +		{
   1.940 +		const TOpenFontFaceAttrib* a = OpenFont()->FaceAttrib();
   1.941 +		if (a)
   1.942 +			{
   1.943 +			aAttrib = *a;
   1.944 +			return ETrue;
   1.945 +			}
   1.946 +		}
   1.947 +	return EFalse;
   1.948 +	}
   1.949 +
   1.950 +/** Gets encoding if a bitmap font (a CFontBitmap) is used.
   1.951 +
   1.952 +@return Bitmap encoding value. */
   1.953 +EXPORT_C TInt CBitmapFont::BitmapEncoding() const
   1.954 +	{
   1.955 +	if (IsOpenFont())
   1.956 +		return 0;
   1.957 +	else
   1.958 +		return FontBitmap()->iBitmapEncoding;
   1.959 +	}
   1.960 +
   1.961 +/** Gets whether the open or bitmap font has the specified character.
   1.962 +
   1.963 +@param aCode A character code.
   1.964 +@return ETrue if the font has the specified character; otherwise EFalse. */
   1.965 +EXPORT_C TBool CBitmapFont::HasCharacterL(TInt aCode) const
   1.966 +	{
   1.967 +	if (IsOpenFont())
   1.968 +		return OpenFont()->HasCharacterL(aCode);
   1.969 +	else
   1.970 +		{
   1.971 +		const TUint8* bytes;
   1.972 +		FontBitmap()->CharacterMetrics(aCode,bytes);
   1.973 +		return (bytes != NULL);
   1.974 +		}
   1.975 +	}
   1.976 +
   1.977 +/** Gets whether the specified character needs to be rasterised.
   1.978 +
   1.979 +False is returned if it is a bitmap font (a CFontBitmap) being used by the 
   1.980 +bitmap font object (so no rasterization is required) or if is an open font 
   1.981 +(a COpenFont) and the character has been rasterized.
   1.982 +
   1.983 +@param aSessionHandle A session handle for the open font system.
   1.984 +@param aCode A character code.
   1.985 +@return ETrue if the character needs to be rasterized; otherwise EFalse. */
   1.986 +EXPORT_C TBool CBitmapFont::CharacterNeedsToBeRasterized(TInt aSessionHandle,TInt aCode) const
   1.987 +	{
   1.988 +	if (IsOpenFont())
   1.989 +		return OpenFont()->CharacterNeedsToBeRasterized(aSessionHandle,aCode);
   1.990 +	else
   1.991 +		return FALSE;	// characters in bitmap fonts do not need to be rasterized	
   1.992 +	}
   1.993 +
   1.994 +/** Turns text into glyph codes and positions.
   1.995 +@param aText The Unicode text to shape plus context
   1.996 +@return The output shape header from the per-font cache, or 0 on failure.
   1.997 +@internalTechnology
   1.998 +*/
   1.999 +EXPORT_C TShapeHeader* CBitmapFont::ShapeTextL(const TDesC16& aText,
  1.1000 +	TInt aSessionHandle, const TShapeMessageParameters& aParams)
  1.1001 +	{
  1.1002 +	TShapeHeader* shape = 0;
  1.1003 +
  1.1004 +	if(IsOpenFont())
  1.1005 +		{
  1.1006 +		// get the data in a CShaper::TInput for the shaper
  1.1007 +		CShaper::TInput input;
  1.1008 +		input.iText = &aText;
  1.1009 +		input.iStart = aParams.iStart;
  1.1010 +		input.iEnd = aParams.iEnd;
  1.1011 +		input.iScript= aParams.iScript;
  1.1012 +		input.iLanguage = aParams.iLanguage;
  1.1013 +		input.iMaximumAdvance = KMaxTInt;
  1.1014 +		input.iFlags = 0;
  1.1015 +		input.iSessionHandle = aSessionHandle;
  1.1016 +		input.iReserved1 = 0;
  1.1017 +
  1.1018 +		TFontShapeFunctionParameters params;
  1.1019 +		params.iEnd = input.iEnd;
  1.1020 +		params.iLanguage = input.iLanguage;
  1.1021 +		params.iScript = input.iScript;
  1.1022 +		params.iStart = input.iStart;
  1.1023 +		params.iText = input.iText;
  1.1024 +		
  1.1025 +		COpenFont* openFont = OpenFont();
  1.1026 +		
  1.1027 +		//if already exist just increase the reference count for that session
  1.1028 +		shape = openFont->GetShapedData(aSessionHandle,&params);
  1.1029 +		
  1.1030 +		if (shape == NULL)
  1.1031 +			{
  1.1032 +			if (!openFont->HasShaper()
  1.1033 + 				|| (openFont->HasShaper() && ( 
  1.1034 + 				(TUint32)(openFont->GetShaper()->ExtendedInterface(KUidShaperGetScript)) != input.iScript
  1.1035 + 				|| (TUint32)(openFont->GetShaper()->ExtendedInterface(KUidShaperGetLang)) != input.iLanguage)))
  1.1036 +				{ // Install the shaper
  1.1037 +				openFont->DeleteShaper();
  1.1038 +				InstallOpenFontShaper(openFont, input);
  1.1039 +				}
  1.1040 +
  1.1041 +			if (openFont->HasShaper())
  1.1042 +				{
  1.1043 +				TInt error = openFont->GetShaper()->ShapeText(shape, input, iHeap);
  1.1044 +				if (error != KErrNone)
  1.1045 +					User::Leave(error);
  1.1046 +				
  1.1047 +				// Put this into the session cache
  1.1048 +				TShapeHeader* cached_header = openFont->InsertShapedDataIntoCache(aSessionHandle,&params, shape);
  1.1049 +				if (!cached_header)
  1.1050 +					User::LeaveNoMemory();
  1.1051 +				iHeap->Free(shape);
  1.1052 +				shape = cached_header;
  1.1053 +				}
  1.1054 +			}
  1.1055 +		}
  1.1056 +	return shape;
  1.1057 +	}
  1.1058 +
  1.1059 +
  1.1060 +void CBitmapFont::InstallOpenFontShaper(COpenFont* aOpenFont, CShaper::TInput& aShaperInput)
  1.1061 +	{
  1.1062 +	CShaper* shaper = NULL;
  1.1063 +	const CArrayPtrFlat<CShaperFactory>* shaperFactoryList = aOpenFont->File()->GetFontStore()->ShaperFactoryList();
  1.1064 +
  1.1065 +	TInt factoryCount = shaperFactoryList->Count();
  1.1066 +	for (TInt index = 0; index < factoryCount; index++)
  1.1067 +		{
  1.1068 +		TRAPD(err, shaper = (*shaperFactoryList)[index]->NewShaperL(this,
  1.1069 +				aShaperInput.iScript, aShaperInput.iLanguage,  iHeap));
  1.1070 +		if (err == KErrNone)
  1.1071 +			{
  1.1072 +			aOpenFont->SetShaper(shaper);
  1.1073 +			OstTrace0( TRACE_IMPORTANT, CBITMAPFONT_INSTALLOPENFONTSHAPER, "A shaper is installed" );
  1.1074 +			break;
  1.1075 +			}
  1.1076 +		}
  1.1077 +	}
  1.1078 +
  1.1079 +
  1.1080 +/** Frees the memory taken up as a result of shaping
  1.1081 +@internalTechnology */
  1.1082 +EXPORT_C void CBitmapFont::DeleteShape(TInt aSessionHandle,TShapeHeader* aHeader)
  1.1083 +	{
  1.1084 +	//safe to assume aHeader is never NULL?
  1.1085 +	if (IsOpenFont())
  1.1086 +		{
  1.1087 +		//we just need to decrease the reference count, no deletion here
  1.1088 +		//as the entry in cache can still be reused by other client
  1.1089 +		//only in the case where the memory is full, the freeing will
  1.1090 +		//delete any cache entry that is not referenced at all
  1.1091 +		TInt ret=OpenFont()->DecrementCachedRefCount(aSessionHandle,aHeader);
  1.1092 +		//panic in debug mode if trying to delete something that is not there.
  1.1093 +		if ((ret != KErrNone) && (ret != KErrNotFound))
  1.1094 +		    {
  1.1095 +		    OstTrace1( TRACE_FATAL, CBITMAPFONT_DELETESHAPE, "OpenFont()->DecrementCachedRefCount() return %d, Invariant", ret);
  1.1096 +		    __ASSERT_DEBUG(0, User::Invariant());
  1.1097 +		    }
  1.1098 +		}
  1.1099 +	}
  1.1100 +
  1.1101 +EXPORT_C void CBitmapFont::operator delete(TAny *aThis)
  1.1102 +	{
  1.1103 +	if (((CBitmapFont *)aThis)->iHeap)
  1.1104 +		((CBitmapFont *)aThis)->iHeap->Free(aThis);
  1.1105 +	}
  1.1106 +
  1.1107 +TInt CBitmapFont::Width(TInt aNum) const
  1.1108 +	{
  1.1109 +	TInt widthfactor=iAlgStyle.WidthFactor();
  1.1110 +	return ((widthfactor==1)? aNum: aNum*widthfactor);
  1.1111 +	}
  1.1112 +
  1.1113 +TInt CBitmapFont::Height(TInt aNum) const
  1.1114 +	{
  1.1115 +	TInt heightfactor=iAlgStyle.HeightFactor();
  1.1116 +	return ((heightfactor==1)? aNum: aNum*heightfactor);
  1.1117 +	}
  1.1118 +
  1.1119 +CFontBitmap* CBitmapFont::FontBitmap() const
  1.1120 +/** This member is private and not intended for use. */
  1.1121 +	{
  1.1122 +	if (IsOpenFont())
  1.1123 +	    {
  1.1124 +	    OstTrace0( TRACE_FATAL, CBITMAPFONT_FONTBITMAP, "Panic(EFntTypefaceHasNoFontBitmaps)" );
  1.1125 +	    __ASSERT_ALWAYS(0, Panic(EFntTypefaceHasNoFontBitmaps));
  1.1126 +	    }
  1.1127 +    if(iFontBitmapOffset)
  1.1128 +        return reinterpret_cast<CFontBitmap*>(reinterpret_cast<TInt>(this)+iFontBitmapOffset);
  1.1129 +    else
  1.1130 +        return NULL;
  1.1131 +	}
  1.1132 +
  1.1133 +/** Gets a font table.
  1.1134 +@param aTag: Input. The name of the font table.
  1.1135 +@param aTableContent: Output. To return the address of the table content.
  1.1136 +@param aLength: Output. To return the length (in bytes) of the table.
  1.1137 +@param aSessionHandle: Input. A handle to the session requesting this table.
  1.1138 +@return KErrNone on success, specific error code on failure.
  1.1139 +@internalTechnology
  1.1140 +*/
  1.1141 +EXPORT_C TInt CBitmapFont::GetFontTable(TUint32 aTag, TAny *&aTableContent, 
  1.1142 +        TInt &aLength, TInt aSessionHandle) 
  1.1143 +    {
  1.1144 +    COpenFont *fontPtr = NULL;
  1.1145 +    if (IsOpenFont())
  1.1146 +        fontPtr = OpenFont();
  1.1147 +    else
  1.1148 +        return KErrNotSupported;
  1.1149 +    
  1.1150 +    // try to find it in cache.
  1.1151 +    CFontStore *fntStore = fontPtr->File()->GetFontStore();
  1.1152 +    TUid fileUid = fontPtr->File()->Uid();
  1.1153 +    TInt ret = fntStore->FindFontTableInCache(fileUid, aTag, aTableContent, aLength);
  1.1154 +    if (KErrNone == ret)
  1.1155 +        {
  1.1156 +        ret = fntStore->IncFontTableRefCount(fileUid, aTag, aSessionHandle);
  1.1157 +        return ret;
  1.1158 +        }
  1.1159 +    
  1.1160 +    // font table not found in cache.
  1.1161 +    ret = fontPtr->GetFontTable(aTag, aTableContent, aLength);
  1.1162 +    if (KErrNone == ret)
  1.1163 +        {
  1.1164 +        ret = fntStore->CacheFontTable(fileUid, aTag, aTableContent, aLength);
  1.1165 +        if (KErrNone == ret)
  1.1166 +            {
  1.1167 +            ret = fntStore->IncFontTableRefCount(fileUid, aTag, aSessionHandle);
  1.1168 +            }
  1.1169 +        else 
  1.1170 +            {
  1.1171 +            aTableContent = NULL;
  1.1172 +            }
  1.1173 +        }
  1.1174 +    
  1.1175 +    return ret;
  1.1176 +    }
  1.1177 +
  1.1178 +/** Release a font table. Decrement its reference count. Remove from cache if 
  1.1179 + * reference decreases to zero.
  1.1180 +@param aTag: Input. The name of the font table to be released.
  1.1181 +@param aSessionHandle: Input. Handle to the session releasing this table.
  1.1182 +@return KErrNone on success, specific error code on failure.
  1.1183 +@internalTechnology
  1.1184 +*/
  1.1185 +EXPORT_C void CBitmapFont::ReleaseFontTable(TUint32 aTag, 
  1.1186 +        TInt aSessionHandle)
  1.1187 +    {
  1.1188 +    COpenFont *fontPtr = NULL;
  1.1189 +    if (IsOpenFont())
  1.1190 +        fontPtr = OpenFont();
  1.1191 +    else
  1.1192 +        return;
  1.1193 +    
  1.1194 +    CFontStore *fntStore = fontPtr->File()->GetFontStore();
  1.1195 +    TUid fileUid = fontPtr->File()->Uid();
  1.1196 +    fntStore->ReleaseFontTable(fileUid, aTag, aSessionHandle);
  1.1197 +    }
  1.1198 +
  1.1199 +
  1.1200 +/** Release a number of glyph outlines. Decrement their reference count.
  1.1201 + * Remove it from cache if reference count decreases to zero.
  1.1202 +@param aCount: Input. Number of outlines to be released.
  1.1203 +@param aCodes: Input. An array of codes. Its interpretation depends on the parameter
  1.1204 +    'aIsGlyphId' (see below).
  1.1205 +@param aIsGlyphId: Input. When aIsGlyphId==ETrue, 'aCodes' is an array of glyph ID's.
  1.1206 +    When aIsGlyphId==EFalse, 'aCodes' is an array of Unicode values.
  1.1207 +@param aHinted: Input. To indicate if the outlines are hinted or unhinted.
  1.1208 +@param aSessionHandle: Input. Handle to the session releasing the outlines.
  1.1209 +@return KErrNone on success, specific error code on failure.
  1.1210 +@internalTechnology
  1.1211 +*/
  1.1212 +EXPORT_C void CBitmapFont::ReleaseGlyphOutlines(TInt aCount, const TUint *aCodes, 
  1.1213 +        TBool aHinted, TInt aSessionHandle)
  1.1214 +    {
  1.1215 +    COpenFont *fontPtr = NULL;
  1.1216 +        if (IsOpenFont())
  1.1217 +            fontPtr = OpenFont();
  1.1218 +        else
  1.1219 +            return;
  1.1220 +    
  1.1221 +    CFontStore *fontStore = fontPtr->File()->GetFontStore();
  1.1222 +    
  1.1223 +    for (TInt i = 0; i < aCount; ++i)
  1.1224 +        {
  1.1225 +        if (aHinted)
  1.1226 +            {
  1.1227 +            THintedOutlineId outlineId(fontPtr, aCodes[i]);
  1.1228 +            fontStore->ReleaseHintedOutline(outlineId, aSessionHandle);
  1.1229 +            }
  1.1230 +        else
  1.1231 +            {
  1.1232 +            TInt faceId = fontPtr->FaceIndex();
  1.1233 +            TUnhintedOutlineId outlineId(fontPtr->File()->Uid(), faceId, aCodes[i]);
  1.1234 +            fontStore->ReleaseUnhintedOutline(outlineId, aSessionHandle);
  1.1235 +            }
  1.1236 +        }
  1.1237 +    }
  1.1238 +
  1.1239 +/** Gets a font table.
  1.1240 +@param aCode: Input. An glyph code. Its interpretation depends on the parameter
  1.1241 +    'aIsGlyphId' (see below).
  1.1242 +@param aIsGlyphId: Input. When aIsGlyphId==ETrue, 'aCode' is a glyph ID.
  1.1243 +    When aIsGlyphId==EFalse, 'aCode' is a Unicode values.
  1.1244 +@param aHinted: Input. To indicate if hinted or unhinted outline is needed.
  1.1245 +@param aOutline: Output. A 'void*' pointer, pointing to the outline in memory.
  1.1246 +@param aLength: Output. A TInt, recording the lenght (in bytes) of the outline.
  1.1247 +@param aSessionHandle: Input. Handle to the session requesting this outline.
  1.1248 +@return KErrNone on success, specific error code on failure.
  1.1249 +@internalTechnology
  1.1250 +*/
  1.1251 +EXPORT_C TInt CBitmapFont::GetGlyphOutline(TUint aCode, 
  1.1252 +        TBool aHinted, TAny *&aOutline, TInt &aLength, TInt aSessionHandle)
  1.1253 +    {
  1.1254 +    COpenFont *fontPtr = NULL;
  1.1255 +        if (IsOpenFont())
  1.1256 +            fontPtr = OpenFont();
  1.1257 +        else
  1.1258 +            return KErrNotSupported;
  1.1259 +    
  1.1260 +    CFontStore *fontStore = fontPtr->File()->GetFontStore();
  1.1261 +    TAny *outlineData = NULL; 
  1.1262 +    TInt len = KErrGeneral;
  1.1263 +    TInt ret = KErrNone;
  1.1264 +    if (!aHinted)
  1.1265 +        {
  1.1266 +        TInt faceId = fontPtr->FaceIndex();
  1.1267 +        TUnhintedOutlineId outlineId(fontPtr->File()->Uid(), faceId, aCode);
  1.1268 +        ret = fontStore->FindUnhintedOutlineInCache(outlineId, outlineData, len);
  1.1269 +        if (KErrNotFound == ret)
  1.1270 +            {
  1.1271 +            TAny* tmpOutline = 0; 
  1.1272 +            TInt tmpLen = 0;
  1.1273 +            ret = fontPtr->GetGlyphOutline(aCode, aHinted, tmpOutline, tmpLen);
  1.1274 +            if (KErrNone == ret)
  1.1275 +                {
  1.1276 +                fontStore->CacheUnhintedOutline(outlineId,
  1.1277 +                        tmpOutline, (TInt)tmpLen, outlineData, len);
  1.1278 +                }
  1.1279 +            User::Free(tmpOutline);
  1.1280 +            }
  1.1281 +        if (KErrNone == ret)
  1.1282 +            {
  1.1283 +            fontStore->IncreaseUnhintedOutlineRefCount(outlineId, aSessionHandle);
  1.1284 +            }
  1.1285 +        }
  1.1286 +    else 
  1.1287 +        {
  1.1288 +        THintedOutlineId outlineId(fontPtr, aCode);
  1.1289 +        ret = fontStore->FindHintedOutlineInCache(outlineId, outlineData, len);
  1.1290 +        if (KErrNotFound == ret)
  1.1291 +            {
  1.1292 +            TAny* tmpOutline = 0; 
  1.1293 +            TInt tmpLen = 0;
  1.1294 +            ret = fontPtr->GetGlyphOutline(aCode, aHinted, tmpOutline, tmpLen);
  1.1295 +            if (KErrNone == ret)
  1.1296 +                {
  1.1297 +                fontStore->CacheHintedOutline(outlineId,
  1.1298 +                        tmpOutline, (TInt)tmpLen, outlineData, len);
  1.1299 +                }
  1.1300 +            User::Free(tmpOutline);
  1.1301 +            }
  1.1302 +        if (KErrNone == ret)
  1.1303 +            {
  1.1304 +            fontStore->IncreaseHintedOutlineRefCount(outlineId, aSessionHandle);
  1.1305 +            }
  1.1306 +        }
  1.1307 +    
  1.1308 +    aOutline = outlineData;
  1.1309 +    aLength = len;    
  1.1310 +    return KErrNone;
  1.1311 +    }
  1.1312 +
  1.1313 +EXPORT_C TUint32 CBitmapFont::UniqueFontId()
  1.1314 +	{
  1.1315 +	return iUniqueFontId;
  1.1316 +	}
  1.1317 +
  1.1318 +void CBitmapFont::SetUniqueFontId(TUint32 aUniqueFontId)
  1.1319 +	{
  1.1320 +	iUniqueFontId = aUniqueFontId;	
  1.1321 +	}
  1.1322 +
  1.1323 +/** API extension system that enables the caller to access a particular API
  1.1324 +extension function. As an overload of this function in a derived class
  1.1325 +it calls its immediate parent implementation for any extension function Uid
  1.1326 +that it does not recognize and handle.
  1.1327 +@param aInterfaceId UID of the required extension function
  1.1328 +@param aParam Pointer to an arbitrary parameter block that can be used to
  1.1329 +provide and/or return information to/from the particular extension function,
  1.1330 +defaults to NULL.
  1.1331 +@return Integer return value from extension function
  1.1332 +@internalTechnology
  1.1333 +@released
  1.1334 +*/
  1.1335 +EXPORT_C TInt CBitmapFont::DoExtendedFunction(TUid aFunctionId, TAny* aParam) const
  1.1336 +	{
  1.1337 +	if (KFontCapitalAscent == aFunctionId)
  1.1338 +		{
  1.1339 +		return Height(IsOpenFont() ? OpenFont()->FontCapitalAscent() : FontBitmap()->FontCapitalAscent());
  1.1340 +		}
  1.1341 +	else if (KFontMaxAscent == aFunctionId)
  1.1342 +		{
  1.1343 +		return Height(IsOpenFont() ? OpenFont()->FontMaxAscent() : FontBitmap()->FontMaxAscent());
  1.1344 +		}
  1.1345 +	else if (KFontStandardDescent == aFunctionId)
  1.1346 +		{
  1.1347 +		return Height(IsOpenFont() ? OpenFont()->FontStandardDescent() : FontBitmap()->FontStandardDescent());
  1.1348 +		}
  1.1349 +	else if (KFontMaxDescent == aFunctionId)
  1.1350 +		{
  1.1351 +		return Height(IsOpenFont() ? OpenFont()->FontMaxDescent() : FontBitmap()->FontMaxDescent());
  1.1352 +		}
  1.1353 +	else if (KFontLineGap == aFunctionId)
  1.1354 +		{
  1.1355 +		return Height(IsOpenFont() ? OpenFont()->FontLineGap() : FontBitmap()->FontLineGap());
  1.1356 +		}
  1.1357 +	
  1.1358 +	return CFont::DoExtendedFunction(aFunctionId, aParam);
  1.1359 +	}
  1.1360 +
  1.1361 +
  1.1362 +CFontTableCacheItem::CFontTableCacheItem(TUid &aFileUid, const TUint32 aTag, 
  1.1363 +        TInt aOffset, TInt aLength): iFileUid(aFileUid), iTag(aTag),
  1.1364 +        iOffset(aOffset), iLength(aLength)
  1.1365 +    {
  1.1366 +    // a null constructor
  1.1367 +    }
  1.1368 +
  1.1369 +CFontTableCacheItem::~CFontTableCacheItem()
  1.1370 +    {
  1.1371 +    iUsers.ResetAndDestroy();
  1.1372 +    iUsers.Close();
  1.1373 +    }
  1.1374 +    
  1.1375 +TBool CFontTableCacheItem::HasOutstandingRefCount()
  1.1376 +    {
  1.1377 +    TInt count = iUsers.Count();
  1.1378 +    for (TInt j = 0; j < count; ++j)
  1.1379 +        {
  1.1380 +        if (iUsers[j]->iRefCount > 0) 
  1.1381 +            {
  1.1382 +            return ETrue;
  1.1383 +            }
  1.1384 +        }
  1.1385 +    return EFalse;
  1.1386 +    }
  1.1387 +
  1.1388 +
  1.1389 +TInt CFontTableCacheItem::FindUser(TInt aSessionHandle, TInt *id) 
  1.1390 +    {
  1.1391 +    TInt len = iUsers.Count();
  1.1392 +    for (TInt i = 0; i < len; ++i)
  1.1393 +        {
  1.1394 +        if (aSessionHandle == iUsers[i]->iSessionHandle)
  1.1395 +            {
  1.1396 +            *id = i;
  1.1397 +            return KErrNone;
  1.1398 +            }
  1.1399 +        }
  1.1400 +    return KErrNotFound;
  1.1401 +    }
  1.1402 +
  1.1403 +TInt CFontTableCacheItem::DecRefCount(TInt aSessionHandle)
  1.1404 +    {
  1.1405 +    TInt id = 0; 
  1.1406 +    TInt ret = FindUser(aSessionHandle, &id);
  1.1407 +    if (KErrNone == ret)
  1.1408 +        {
  1.1409 +        iUsers[id]->iRefCount--;
  1.1410 +        if (0 == iUsers[id]->iRefCount) 
  1.1411 +            {
  1.1412 +            delete iUsers[id];
  1.1413 +            iUsers.Remove(id);
  1.1414 +            }
  1.1415 +        return iUsers.Count();
  1.1416 +        }
  1.1417 +    return KErrNotFound;
  1.1418 +    }
  1.1419 +
  1.1420 +TInt CFontTableCacheItem::IncRefCount(TInt aSessionHandle)
  1.1421 +    {
  1.1422 +    TInt id = 0; 
  1.1423 +    TInt ret = FindUser(aSessionHandle, &id);
  1.1424 +    if (KErrNone == ret)
  1.1425 +        {
  1.1426 +        iUsers[id]->iRefCount++;
  1.1427 +        }
  1.1428 +    else
  1.1429 +        {
  1.1430 +        TCacheUserInfo *newUser = new TCacheUserInfo(aSessionHandle, 1);
  1.1431 +        if (NULL != newUser)
  1.1432 +            {
  1.1433 +            TRAP(ret, iUsers.AppendL(newUser));
  1.1434 +            }
  1.1435 +        else 
  1.1436 +            {
  1.1437 +            ret = KErrNoMemory;
  1.1438 +            }
  1.1439 +        //coverity[leaked_storage]
  1.1440 +        // The 'newUser' is kept in iUsers. It will be deleted in DecRefCount(). 
  1.1441 +        }
  1.1442 +    return ret;
  1.1443 +    }
  1.1444 +
  1.1445 +TInt CFontTableCache::Append(TUid aFileUid, TUint32 aTag, 
  1.1446 +        TAny *&aContent, TInt aLength) 
  1.1447 +    {
  1.1448 +    TInt ret = 0;
  1.1449 +    if ((TUint32)iCacheMemMon.GetMemUsage() >= KFontTable_GlyphOutline_CacheMaxMem)
  1.1450 +        {
  1.1451 +        RDebug::Printf("Table/Glyph cache full. Unable to add new item.");
  1.1452 +        return KErrNoMemory;
  1.1453 +        }
  1.1454 +    // make a copy of the table content on the shared heap.
  1.1455 +    TAny *sharedCopy = iHeap->Alloc(aLength);
  1.1456 +    if (NULL == sharedCopy) 
  1.1457 +        {
  1.1458 +        return KErrNoMemory;
  1.1459 +        }
  1.1460 +    
  1.1461 +    Mem::Copy(sharedCopy, aContent, aLength);
  1.1462 +
  1.1463 +    CFontTableCacheItem *newItem = NULL;
  1.1464 +    TInt offset = PointerToOffset(sharedCopy, iHeap->Base());
  1.1465 +    TRAP(ret, newItem = new(ELeave) CFontTableCacheItem(aFileUid, aTag, offset, aLength));
  1.1466 +    if (KErrNone != ret)
  1.1467 +        {
  1.1468 +        iHeap->Free(sharedCopy);
  1.1469 +        return ret;
  1.1470 +        }
  1.1471 +    
  1.1472 +    TRAP(ret, iCacheItems.AppendL(newItem));
  1.1473 +    if (KErrNone == ret)
  1.1474 +        {
  1.1475 +        // do not free 'aContent', because the mem is managed by
  1.1476 +        // rasterizer cache.
  1.1477 +        aContent = sharedCopy;
  1.1478 +        iCacheMemMon.Inc(aLength);
  1.1479 +        }
  1.1480 +    else 
  1.1481 +        {
  1.1482 +        iHeap->Free(sharedCopy);
  1.1483 +        }
  1.1484 +#ifdef _DEBUG
  1.1485 +    GetCacheState(__func__);
  1.1486 +#endif
  1.1487 +    return ret;
  1.1488 +    }
  1.1489 +
  1.1490 +TInt CFontTableCache::Find(TUid aFileUid, TUint32 aTag, TAny *&aContent, 
  1.1491 +        TInt &aLength, TInt *id)
  1.1492 +    {
  1.1493 +    *id = KErrNotFound;
  1.1494 +    TInt len = iCacheItems.Count();
  1.1495 +    
  1.1496 +    TInt ret = KErrNotFound;
  1.1497 +    for (TInt i = 0; i < len; ++i)
  1.1498 +        {
  1.1499 +        CFontTableCacheItem *item = iCacheItems[i]; 
  1.1500 +        if (item->iFileUid == aFileUid && item->iTag == aTag) 
  1.1501 +            {
  1.1502 +            aContent = OffsetToPointer(item->iOffset, iHeap->Base());
  1.1503 +            aLength = item->iLength;
  1.1504 +            *id = i;
  1.1505 +            ret = KErrNone;
  1.1506 +            break;
  1.1507 +            }
  1.1508 +        }
  1.1509 +    
  1.1510 +#ifdef _DEBUG
  1.1511 +    GetCacheState(__func__);
  1.1512 +#endif
  1.1513 +    return ret;
  1.1514 +    }
  1.1515 +
  1.1516 +CFontTableCache::CFontTableCache(RHeap *aHeap, TFontTableGlyphOutlineCacheMemMonitor &aMon): 
  1.1517 +    iCacheMemMon(aMon), iHeap(aHeap) 
  1.1518 +    {
  1.1519 +    // null constructor
  1.1520 +    }
  1.1521 +
  1.1522 +CFontTableCache::~CFontTableCache()
  1.1523 +    {
  1.1524 +    for (TInt i = 0; i < iCacheItems.Count(); ++i)
  1.1525 +        {
  1.1526 +        iHeap->Free(OffsetToPointer(iCacheItems[i]->iOffset, iHeap->Base()));
  1.1527 +        }
  1.1528 +    iCacheItems.ResetAndDestroy();
  1.1529 +    iCacheItems.Close();
  1.1530 +    }
  1.1531 +
  1.1532 +TInt CFontTableCache::IncRefCount(TUid aFileUid, TUint32 aTag, TInt aSessionHandle)
  1.1533 +    {
  1.1534 +    TAny *outline = NULL;
  1.1535 +    TInt len = 0;
  1.1536 +    TInt id = 0;
  1.1537 +    
  1.1538 +    TInt ret = Find(aFileUid, aTag, outline, len, &id);
  1.1539 +    if (KErrNone == ret)
  1.1540 +        {
  1.1541 +        ret = iCacheItems[id]->IncRefCount(aSessionHandle);
  1.1542 +        }
  1.1543 +    
  1.1544 +#ifdef _DEBUG
  1.1545 +    GetCacheState(__func__);
  1.1546 +#endif
  1.1547 +    return ret;
  1.1548 +    }
  1.1549 +
  1.1550 +TInt CFontTableCache::DecRefCount(TUid aFileUid, TUint32 aTag, TInt aSessionHandle)
  1.1551 +    {
  1.1552 +    TAny *outline = NULL;
  1.1553 +    TInt len = 0;
  1.1554 +    TInt id = 0;
  1.1555 +    
  1.1556 +    TInt ret = Find(aFileUid, aTag, outline, len, &id);
  1.1557 +    if (KErrNone == ret) 
  1.1558 +        {
  1.1559 +        TInt numUsers = iCacheItems[id]->DecRefCount(aSessionHandle);
  1.1560 +        if (0 == numUsers) 
  1.1561 +            {
  1.1562 +            // There is no outstanding reference to the cache item.
  1.1563 +            iHeap->Free(outline);
  1.1564 +            iCacheMemMon.Dec(len);
  1.1565 +            delete (iCacheItems[id]);
  1.1566 +            iCacheItems.Remove(id);
  1.1567 +            }
  1.1568 +        }
  1.1569 +    
  1.1570 +#ifdef _DEBUG
  1.1571 +    GetCacheState(__func__);
  1.1572 +#endif
  1.1573 +    return ret;
  1.1574 +    }
  1.1575 +
  1.1576 +TBool CFontTableCache::HasOutstandingRefCount() 
  1.1577 +    {
  1.1578 +    TInt len = iCacheItems.Count();
  1.1579 +   
  1.1580 +    for (TInt i = 0; i < len; ++i)
  1.1581 +        {
  1.1582 +        if (iCacheItems[i]->HasOutstandingRefCount())
  1.1583 +            {
  1.1584 +            return ETrue;
  1.1585 +            }
  1.1586 +        }
  1.1587 +    return EFalse;
  1.1588 +    }
  1.1589 +
  1.1590 +TBool CFontTableCache::HasOutstandingRefCountWithUid(TUid aFileUid)
  1.1591 +    {
  1.1592 +    TInt len = iCacheItems.Count();
  1.1593 +   
  1.1594 +    for (TInt i = 0; i < len; ++i)
  1.1595 +        {
  1.1596 +        if (iCacheItems[i]->iFileUid == aFileUid) 
  1.1597 +            {
  1.1598 +            if (iCacheItems[i]->HasOutstandingRefCount())
  1.1599 +                {
  1.1600 +                return ETrue;
  1.1601 +                }
  1.1602 +            }
  1.1603 +        }
  1.1604 +    return EFalse;
  1.1605 +    }
  1.1606 +
  1.1607 +void CFontTableCache::CleanupCacheOnOpenFontFileRemoval(COpenFontFile *)
  1.1608 +    {
  1.1609 +    // In CFontStore::RemoveFile(), a font file is not allowed to be removed if
  1.1610 +    // there are outstanding ref counts on any table in it. If that check passed 
  1.1611 +    // and this function is called, there shall be no cache item for that file.
  1.1612 +    
  1.1613 +    // Currently a cache item having a refcount of 0 is removed immediately.
  1.1614 +    // If this strategy is changed in the future, we may need to do some
  1.1615 +    // cleanup here.
  1.1616 +    }
  1.1617 +
  1.1618 +void CFontTableCache::CleanupCacheOnFbsSessionTermination(TInt aSessionHandle)
  1.1619 +    {
  1.1620 +    TInt len = iCacheItems.Count();
  1.1621 +   
  1.1622 +    for (TInt i = 0; i < len; ++i)
  1.1623 +        {
  1.1624 +        TInt id = -1;
  1.1625 +        if (KErrNone == iCacheItems[i]->FindUser(aSessionHandle, &id))
  1.1626 +            {
  1.1627 +            iCacheItems[i]->iUsers.Remove(id);
  1.1628 +            if (iCacheItems[i]->iUsers.Count() == 0)
  1.1629 +                {
  1.1630 +                iHeap->Free(OffsetToPointer(iCacheItems[i]->iOffset, iHeap->Base()));
  1.1631 +                iCacheMemMon.Dec(iCacheItems[i]->iLength);
  1.1632 +                delete iCacheItems[i];
  1.1633 +                iCacheItems.Remove(i);
  1.1634 +                }
  1.1635 +            }
  1.1636 +        }
  1.1637 +    }
  1.1638 +
  1.1639 +
  1.1640 +#ifdef _DEBUG
  1.1641 +TInt CFontTableCache::GetCacheState(const char *func) 
  1.1642 +    {
  1.1643 +    RDebug::Printf("%s called from %s: ", __func__, func);
  1.1644 +    TBuf<256> buf;
  1.1645 +    
  1.1646 +    int len = iCacheItems.Count();
  1.1647 +    int numTables = 0, numSessions = 0, totalRef = 0;
  1.1648 +    buf.Append(_L("Table cache: "));
  1.1649 +    for (int i = 0; i < len; ++i)
  1.1650 +        {
  1.1651 +        ++numTables;
  1.1652 +        TInt abc = iCacheItems[i]->iUsers.Count();
  1.1653 +        numSessions += abc;
  1.1654 +        for (int j = 0; j < abc; ++j)
  1.1655 +            {
  1.1656 +            totalRef += iCacheItems[i]->iUsers[j]->iRefCount;
  1.1657 +            }
  1.1658 +        }
  1.1659 +    if (0 == iCacheItems.Count())
  1.1660 +        {
  1.1661 +        buf.Append(_L("cache empty. "));
  1.1662 +        }
  1.1663 +    else 
  1.1664 +        {
  1.1665 +        buf.AppendFormat(_L("%d tables referenced by %d sessions, total ref count %d"),
  1.1666 +                numTables, numSessions, totalRef);
  1.1667 +        }
  1.1668 +    RDebug::RawPrint(buf);
  1.1669 +    return 0;
  1.1670 +    }
  1.1671 +#endif
  1.1672 +
  1.1673 +
  1.1674 +
  1.1675 +TInt COutlineCacheItem::FindUser(TInt aSessionHandle, TInt *id) 
  1.1676 +    {
  1.1677 +    TInt len = iUsers.Count();
  1.1678 +    for (TInt i = 0; i < len; ++i)
  1.1679 +        {
  1.1680 +        if (aSessionHandle == iUsers[i]->iSessionHandle)
  1.1681 +            {
  1.1682 +            *id = i;
  1.1683 +            return KErrNone;
  1.1684 +            }
  1.1685 +        }
  1.1686 +    return KErrNotFound;
  1.1687 +    }
  1.1688 +
  1.1689 +COutlineCacheItem::~COutlineCacheItem() 
  1.1690 +    { 
  1.1691 +    iUsers.ResetAndDestroy(); 
  1.1692 +    }
  1.1693 +
  1.1694 +COutlineCacheItem::COutlineCacheItem(TInt aOffset, TInt aLength):
  1.1695 +    iOffset(aOffset), iLength(aLength)
  1.1696 +    {
  1.1697 +    // a null constructor.
  1.1698 +    }
  1.1699 +
  1.1700 +TInt COutlineCacheItem::DecRefCount(TInt aSessionHandle)
  1.1701 +    {
  1.1702 +    TInt id = 0; 
  1.1703 +    TInt ret = FindUser(aSessionHandle, &id);
  1.1704 +    if (KErrNone == ret)
  1.1705 +        {
  1.1706 +        iUsers[id]->iRefCount--;
  1.1707 +        if (0 == iUsers[id]->iRefCount) 
  1.1708 +            {
  1.1709 +            delete iUsers[id];
  1.1710 +            iUsers.Remove(id);
  1.1711 +            }
  1.1712 +        return iUsers.Count();
  1.1713 +        }
  1.1714 +    return KErrNotFound;
  1.1715 +    }
  1.1716 +
  1.1717 +TInt COutlineCacheItem::IncRefCount(TInt aSessionHandle)
  1.1718 +    {
  1.1719 +    TInt id = 0; 
  1.1720 +    TInt ret = FindUser(aSessionHandle, &id);
  1.1721 +    if (KErrNone == ret)
  1.1722 +        {
  1.1723 +        iUsers[id]->iRefCount++;
  1.1724 +        }
  1.1725 +    else
  1.1726 +        {
  1.1727 +        TCacheUserInfo *newUser = new TCacheUserInfo(aSessionHandle, 1);
  1.1728 +        if (NULL != newUser)
  1.1729 +            {
  1.1730 +            TRAP(ret, iUsers.AppendL(newUser));
  1.1731 +            }
  1.1732 +        else 
  1.1733 +            {
  1.1734 +            ret = KErrNoMemory;
  1.1735 +            }
  1.1736 +        //coverity[leaked_storage]
  1.1737 +        // The 'newUser' is kept in iUsers. It will be deleted in DecRefCount().
  1.1738 +        }
  1.1739 +    return ret;
  1.1740 +    }
  1.1741 +
  1.1742 +#ifdef _DEBUG
  1.1743 +TInt CUnhintedOutlineCache::GetCacheState(const char *func)
  1.1744 +    {
  1.1745 +    RDebug::Printf("%s called from %s: ", __func__, func);
  1.1746 +    int numSessions = 0, totalRef = 0;
  1.1747 +    THashMapIter<TUnhintedOutlineId, COutlineCacheItem*> it(iItemIdMap);
  1.1748 +    it.NextValue();
  1.1749 +    while (it.CurrentValue())
  1.1750 +        {
  1.1751 +        COutlineCacheItem **data = it.CurrentValue();
  1.1752 +        int len = (*data)->iUsers.Count();
  1.1753 +        numSessions += len;
  1.1754 +        for (int j = 0; j < len; ++j)
  1.1755 +            {
  1.1756 +            totalRef += (*data)->iUsers[j]->iRefCount;
  1.1757 +            }
  1.1758 +        it.NextValue();
  1.1759 +        }
  1.1760 +    
  1.1761 +    TBuf<256> buf;
  1.1762 +    buf.Append(_L("Unhinted outline cache: "));
  1.1763 +    TInt numItems = iItemIdMap.Count();
  1.1764 +    if (0 == numItems)
  1.1765 +        {
  1.1766 +        buf.Append(_L("empty. "));
  1.1767 +        }
  1.1768 +    else 
  1.1769 +        {
  1.1770 +        buf.AppendFormat(_L("%d glyphs, %d sessions, total refcount %d"),
  1.1771 +                numItems, numSessions, totalRef);
  1.1772 +        }
  1.1773 +        
  1.1774 +    RDebug::RawPrint(buf);
  1.1775 +            
  1.1776 +    return 0;
  1.1777 +    }
  1.1778 +#endif
  1.1779 +
  1.1780 +CUnhintedOutlineCache::CUnhintedOutlineCache(RHeap *aHeap, TFontTableGlyphOutlineCacheMemMonitor &aMon):
  1.1781 +    iCacheMemMon(aMon), iHeap(aHeap), 
  1.1782 +    iItemIdMap(THashFunction32<TUnhintedOutlineId>(CUnhintedOutlineCache::IdHash),
  1.1783 +        TIdentityRelation<TUnhintedOutlineId>(CUnhintedOutlineCache::IdIdentity))
  1.1784 +    { 
  1.1785 +    
  1.1786 +    }
  1.1787 +
  1.1788 +CUnhintedOutlineCache::~CUnhintedOutlineCache()
  1.1789 +    {
  1.1790 +    THashMapIter<TUnhintedOutlineId, COutlineCacheItem*> it(iItemIdMap);
  1.1791 +    it.NextValue();
  1.1792 +    while (it.CurrentValue())
  1.1793 +        {
  1.1794 +        const TUnhintedOutlineId *outlineId = it.CurrentKey();
  1.1795 +        COutlineCacheItem **data = it.CurrentValue();
  1.1796 +        
  1.1797 +        // loop body here!
  1.1798 +        iHeap->Free(OffsetToPointer((*data)->iOffset, iHeap->Base()));
  1.1799 +        delete (*data);
  1.1800 +        iItemIdMap.Remove(*outlineId);
  1.1801 +        // end loop body
  1.1802 +        
  1.1803 +        it.NextValue();
  1.1804 +        }
  1.1805 +    return;
  1.1806 +    }
  1.1807 +
  1.1808 +
  1.1809 +TInt CUnhintedOutlineCache::CleanupCacheOnOpenFontFileRemoval(COpenFontFile *aFontFile)
  1.1810 +    {
  1.1811 +    TUid fileUid = aFontFile->Uid();
  1.1812 +    
  1.1813 +    THashMapIter<TUnhintedOutlineId, COutlineCacheItem*> it(iItemIdMap);
  1.1814 +    it.NextValue();
  1.1815 +    while (it.CurrentValue())
  1.1816 +        {
  1.1817 +        const TUnhintedOutlineId *outlineId = it.CurrentKey();
  1.1818 +        COutlineCacheItem **data = it.CurrentValue();
  1.1819 +        
  1.1820 +        // loop body here!
  1.1821 +        if (outlineId->iFileUid == fileUid)
  1.1822 +            {
  1.1823 +            iHeap->Free(OffsetToPointer((*data)->iOffset, iHeap->Base()));
  1.1824 +            iCacheMemMon.Dec((*data)->iLength);
  1.1825 +            delete (*data);
  1.1826 +            iItemIdMap.Remove(*outlineId);
  1.1827 +            }
  1.1828 +        // end loop body
  1.1829 +        
  1.1830 +        it.NextValue();
  1.1831 +        }
  1.1832 +    return KErrNone;
  1.1833 +    }
  1.1834 +
  1.1835 +TInt CUnhintedOutlineCache::CleanupCacheOnFbsSessionTermination(TInt aSessionHandle)
  1.1836 +    {
  1.1837 +    THashMapIter<TUnhintedOutlineId, COutlineCacheItem*> it(iItemIdMap);
  1.1838 +    it.NextValue();
  1.1839 +    while (it.CurrentValue())
  1.1840 +        {
  1.1841 +        const TUnhintedOutlineId *outlineId = it.CurrentKey();
  1.1842 +        COutlineCacheItem **data = it.CurrentValue();
  1.1843 +        
  1.1844 +        // loop body here!
  1.1845 +        TInt id = 0;
  1.1846 +        TInt ret = (*data)->FindUser(aSessionHandle, &id);
  1.1847 +        if (KErrNone == ret)
  1.1848 +            {
  1.1849 +            delete (*data)->iUsers[id];
  1.1850 +            (*data)->iUsers.Remove(id);
  1.1851 +            if (0 == (*data)->iUsers.Count())
  1.1852 +                {
  1.1853 +                iHeap->Free(OffsetToPointer((*data)->iOffset, iHeap->Base()));
  1.1854 +                iCacheMemMon.Dec((*data)->iLength);
  1.1855 +                delete (*data);
  1.1856 +                iItemIdMap.Remove(*outlineId);
  1.1857 +                }
  1.1858 +            }
  1.1859 +        // end loop body
  1.1860 +        
  1.1861 +        it.NextValue();
  1.1862 +        }
  1.1863 +    return KErrNone;
  1.1864 +    }
  1.1865 +
  1.1866 +
  1.1867 +TInt CUnhintedOutlineCache::CacheUnhintedOutline(const TUnhintedOutlineId &aOutlineId, 
  1.1868 +        TAny* const aData, const TInt aLength, TAny *&aOutline, TInt &aLen)
  1.1869 +    {
  1.1870 +#ifdef _DEBUG
  1.1871 +    GetCacheState(__func__);
  1.1872 +#endif
  1.1873 +    if ((TUint32)iCacheMemMon.GetMemUsage() >= KFontTable_GlyphOutline_CacheMaxMem)
  1.1874 +        {
  1.1875 +        RDebug::Printf("Table/Glyph cache full. Unable to add new item.");
  1.1876 +        return KErrNoMemory;
  1.1877 +        }
  1.1878 +    
  1.1879 +    aLen = KErrGeneral;
  1.1880 +    TInt ret1= KErrNone;
  1.1881 +
  1.1882 +    // make a copy of the outline data on the shared heap.
  1.1883 +    TAny *sharedCopy = iHeap->Alloc(aLength);
  1.1884 +    if (NULL == sharedCopy) 
  1.1885 +        {
  1.1886 +        return KErrNoMemory;
  1.1887 +        }
  1.1888 +    
  1.1889 +    Mem::Copy(sharedCopy, aData, aLength);
  1.1890 +
  1.1891 +    COutlineCacheItem *newItem = NULL;
  1.1892 +    TInt offset = PointerToOffset(sharedCopy, iHeap->Base());
  1.1893 +    TRAP(ret1, newItem = new(ELeave) COutlineCacheItem(offset, aLength));
  1.1894 +    if (KErrNone != ret1)
  1.1895 +        {
  1.1896 +        iHeap->Free(sharedCopy);
  1.1897 +        sharedCopy = NULL;
  1.1898 +        }
  1.1899 +    else 
  1.1900 +        {
  1.1901 +        TRAP(ret1, iItemIdMap.InsertL(aOutlineId, newItem));
  1.1902 +        if (KErrNone != ret1)
  1.1903 +            {
  1.1904 +            delete newItem;
  1.1905 +            iHeap->Free(sharedCopy);
  1.1906 +            sharedCopy = NULL;
  1.1907 +            }
  1.1908 +        else
  1.1909 +            {
  1.1910 +            iCacheMemMon.Inc(aLength);
  1.1911 +            aLen = aLength;
  1.1912 +            }
  1.1913 +        }
  1.1914 +    aOutline = sharedCopy;
  1.1915 +    return ret1;  
  1.1916 +    }
  1.1917 +
  1.1918 +TInt CUnhintedOutlineCache::IncRefCount(const TUnhintedOutlineId &aOutlineId,
  1.1919 +        TInt aSessionHandle)
  1.1920 +    {
  1.1921 +#ifdef _DEBUG
  1.1922 +    GetCacheState(__func__);
  1.1923 +#endif
  1.1924 +    COutlineCacheItem **ret = iItemIdMap.Find(aOutlineId);
  1.1925 +    if (NULL != ret)
  1.1926 +        {
  1.1927 +        (*ret)->IncRefCount(aSessionHandle);
  1.1928 +        }
  1.1929 +    return (NULL==ret?KErrNotFound:KErrNone);
  1.1930 +    }
  1.1931 +
  1.1932 +TInt CUnhintedOutlineCache::DecRefCount(const TUnhintedOutlineId &aOutlineId,
  1.1933 +        TInt aSessionHandle)
  1.1934 +    {
  1.1935 +#ifdef _DEBUG
  1.1936 +    GetCacheState(__func__);
  1.1937 +#endif
  1.1938 +    COutlineCacheItem **ret = iItemIdMap.Find(aOutlineId); 
  1.1939 +    if (NULL != ret) 
  1.1940 +        {
  1.1941 +        TInt numUsers = (*ret)->DecRefCount(aSessionHandle);
  1.1942 +        if (0 == numUsers) 
  1.1943 +            {
  1.1944 +            // There is no outstanding reference to the cache item.
  1.1945 +            iHeap->Free(OffsetToPointer((*ret)->iOffset, iHeap->Base()));
  1.1946 +            iCacheMemMon.Dec((*ret)->iLength);
  1.1947 +            delete (*ret);
  1.1948 +            iItemIdMap.Remove(aOutlineId);
  1.1949 +            }
  1.1950 +        }
  1.1951 +    return (NULL==ret?KErrNotFound:KErrNone);
  1.1952 +    }
  1.1953 +
  1.1954 +TInt CUnhintedOutlineCache::Find(const TUnhintedOutlineId &aOutlineId, TAny *&aData, 
  1.1955 +        TInt &aLength)
  1.1956 +    {
  1.1957 +    COutlineCacheItem **ret = iItemIdMap.Find(aOutlineId);
  1.1958 +    TInt ret2 = KErrNone;
  1.1959 +    if (NULL != ret)
  1.1960 +        {
  1.1961 +        aData = OffsetToPointer((*ret)->iOffset, iHeap->Base());
  1.1962 +        aLength = (*ret)->iLength;
  1.1963 +        }
  1.1964 +    else
  1.1965 +        {
  1.1966 +        ret2 = KErrNotFound;
  1.1967 +        }
  1.1968 +    return ret2;
  1.1969 +    }
  1.1970 +    
  1.1971 +  
  1.1972 +TUint32 CUnhintedOutlineCache::IdHash(const TUnhintedOutlineId &outlineId)
  1.1973 +    {
  1.1974 +    // The hash value: 
  1.1975 +    // bits 0-15: glyph id; 
  1.1976 +    // bits 16-23: lower 8 bit of font file uid
  1.1977 +    // bits 24-27: lower 4 bit of the face index
  1.1978 +    // bit 28: 'isGlyphId'
  1.1979 +    TUint32 ret = 0;
  1.1980 +    ret |= (outlineId.iId & KOutlineGlyphIdHashMask);
  1.1981 +    ret |= (KOutlineFileUidHashMask & (outlineId.iFileUid.iUid << 16));
  1.1982 +    ret |= (KOutlineFaceIndexHashMask & (outlineId.iFaceIndex << 24));
  1.1983 +    ret = (ret % 701);
  1.1984 +    return ret;
  1.1985 +    }
  1.1986 +
  1.1987 +TBool CUnhintedOutlineCache::IdIdentity(const TUnhintedOutlineId &id1, const TUnhintedOutlineId &id2)
  1.1988 +    {
  1.1989 +    return id1.iId == id2.iId && id1.iFaceIndex == id2.iFaceIndex &&
  1.1990 +            id1.iFileUid == id2.iFileUid;
  1.1991 +    }
  1.1992 +
  1.1993 +// hinted outline cache
  1.1994 +#ifdef _DEBUG
  1.1995 +TInt CHintedOutlineCache::GetCacheState(const char *func)
  1.1996 +    {
  1.1997 +    RDebug::Printf("%s called from %s: ", __func__, func);
  1.1998 +    int numSessions = 0, totalRef = 0;
  1.1999 +    THashMapIter<THintedOutlineId, COutlineCacheItem*> it(iItemIdMap);
  1.2000 +    it.NextValue();
  1.2001 +    while (it.CurrentValue())
  1.2002 +        {
  1.2003 +        COutlineCacheItem **data = it.CurrentValue();
  1.2004 +        int len = (*data)->iUsers.Count();
  1.2005 +        numSessions += len;
  1.2006 +        for (int j = 0; j < len; ++j)
  1.2007 +            {
  1.2008 +            totalRef += (*data)->iUsers[j]->iRefCount;
  1.2009 +            }
  1.2010 +        it.NextValue();
  1.2011 +        }
  1.2012 +    
  1.2013 +    TBuf<256> buf;
  1.2014 +    buf.Append(_L("Hinted outline cache: "));
  1.2015 +    TInt numItems = iItemIdMap.Count();
  1.2016 +    if (0 == numItems)
  1.2017 +        {
  1.2018 +        buf.Append(_L("empty. "));
  1.2019 +        }
  1.2020 +    else 
  1.2021 +        {
  1.2022 +        buf.AppendFormat(_L("%d glyphs, %d sessions, total refcount %d"),
  1.2023 +                numItems, numSessions, totalRef);
  1.2024 +        }
  1.2025 +        
  1.2026 +    RDebug::RawPrint(buf);
  1.2027 +            
  1.2028 +    return 0;
  1.2029 +    }
  1.2030 +#endif
  1.2031 +
  1.2032 +TInt CHintedOutlineCache::CleanupCacheOnOpenFontRemoval(COpenFont *aFont)
  1.2033 +    {
  1.2034 +    THashMapIter<THintedOutlineId, COutlineCacheItem*> it(iItemIdMap);
  1.2035 +    it.NextValue();
  1.2036 +    while (it.CurrentValue())
  1.2037 +        {
  1.2038 +        const THintedOutlineId *outlineId = it.CurrentKey();
  1.2039 +        COutlineCacheItem **data = it.CurrentValue();
  1.2040 +        
  1.2041 +        // loop body here!
  1.2042 +        if (outlineId->iFont == aFont)
  1.2043 +            {
  1.2044 +            iCacheMemMon.Dec((*data)->iLength);
  1.2045 +            iHeap->Free(OffsetToPointer((*data)->iOffset, iHeap->Base()));
  1.2046 +            delete (*data);
  1.2047 +            iItemIdMap.Remove(*outlineId);
  1.2048 +            }
  1.2049 +        // end loop body
  1.2050 +        
  1.2051 +        it.NextValue();
  1.2052 +        }
  1.2053 +    return KErrNone;
  1.2054 +    }
  1.2055 +
  1.2056 +TInt CHintedOutlineCache::CleanupCacheOnFbsSessionTermination(TInt aSessionHandle)
  1.2057 +    {
  1.2058 +    THashMapIter<THintedOutlineId, COutlineCacheItem*> it(iItemIdMap);
  1.2059 +    it.NextValue();
  1.2060 +    while (it.CurrentValue())
  1.2061 +        {
  1.2062 +        const THintedOutlineId *outlineId = it.CurrentKey();
  1.2063 +        COutlineCacheItem **data = it.CurrentValue();
  1.2064 +        
  1.2065 +        // loop body here!
  1.2066 +        TInt id = 0; 
  1.2067 +        TInt ret = (*data)->FindUser(aSessionHandle, &id);
  1.2068 +        if (KErrNone == ret)
  1.2069 +            {
  1.2070 +            delete (*data)->iUsers[id];
  1.2071 +            (*data)->iUsers.Remove(id);
  1.2072 +            if (0 == (*data)->iUsers.Count())
  1.2073 +                {
  1.2074 +                iCacheMemMon.Dec((*data)->iLength);
  1.2075 +                iHeap->Free(OffsetToPointer((*data)->iOffset, iHeap->Base()));
  1.2076 +                delete (*data);
  1.2077 +                iItemIdMap.Remove(*outlineId);
  1.2078 +                }
  1.2079 +            }
  1.2080 +        // end loop body
  1.2081 +        
  1.2082 +        it.NextValue();
  1.2083 +        }
  1.2084 +
  1.2085 +    return KErrNone;
  1.2086 +    }
  1.2087 +
  1.2088 +
  1.2089 +CHintedOutlineCache::CHintedOutlineCache(RHeap *aHeap, TFontTableGlyphOutlineCacheMemMonitor &aMon):
  1.2090 +    iCacheMemMon(aMon), iHeap(aHeap), 
  1.2091 +    iItemIdMap(THashFunction32<THintedOutlineId>(CHintedOutlineCache::IdHash),
  1.2092 +        TIdentityRelation<THintedOutlineId>(CHintedOutlineCache::IdIdentity)) 
  1.2093 +    { 
  1.2094 +    // a null constructor
  1.2095 +    }
  1.2096 +
  1.2097 +TInt CHintedOutlineCache::CacheHintedOutline(const THintedOutlineId &aOutlineId,
  1.2098 +        TAny* aData, TInt aLength, TAny *&aOutline, TInt &aLen)
  1.2099 +    {
  1.2100 +#ifdef _DEBUG
  1.2101 +    GetCacheState(__func__);
  1.2102 +#endif
  1.2103 +    if ((TUint32)iCacheMemMon.GetMemUsage() >= KFontTable_GlyphOutline_CacheMaxMem)
  1.2104 +        {
  1.2105 +        RDebug::Printf("Table/Glyph cache full. Unable to add new item.");
  1.2106 +        return KErrNoMemory;
  1.2107 +        }
  1.2108 +    
  1.2109 +    aLen = KErrGeneral;
  1.2110 +    TInt ret = KErrNone;
  1.2111 +    // make a copy of the outline data on the shared heap.
  1.2112 +    TAny *sharedCopy = iHeap->Alloc(aLength);
  1.2113 +    if (NULL == sharedCopy) 
  1.2114 +        {
  1.2115 +        return KErrNoMemory;
  1.2116 +        }
  1.2117 +    
  1.2118 +    Mem::Copy(sharedCopy, aData, aLength);
  1.2119 +
  1.2120 +    COutlineCacheItem *newItem = NULL;
  1.2121 +    TInt offset = PointerToOffset(sharedCopy, iHeap->Base());
  1.2122 +    TRAP(ret, newItem = new(ELeave) COutlineCacheItem(offset, aLength));
  1.2123 +    if (KErrNone != ret)
  1.2124 +        {
  1.2125 +        iHeap->Free(sharedCopy);
  1.2126 +        sharedCopy = NULL;
  1.2127 +        }
  1.2128 +    else 
  1.2129 +        {
  1.2130 +        TRAP(ret, iItemIdMap.InsertL(aOutlineId, newItem));
  1.2131 +        if (KErrNone != ret)
  1.2132 +            {
  1.2133 +            delete newItem;
  1.2134 +            iHeap->Free(sharedCopy);
  1.2135 +            sharedCopy = NULL;
  1.2136 +            }
  1.2137 +        else
  1.2138 +            {
  1.2139 +            iCacheMemMon.Inc(aLength);
  1.2140 +            aLen = aLength;
  1.2141 +            }
  1.2142 +        }
  1.2143 +    aOutline = sharedCopy;
  1.2144 +    return ret;
  1.2145 +    }
  1.2146 +
  1.2147 +TInt CHintedOutlineCache::IncRefCount(const THintedOutlineId &aOutlineId, 
  1.2148 +        TInt aSessionHandle)
  1.2149 +    {
  1.2150 +#ifdef _DEBUG
  1.2151 +    GetCacheState(__func__);
  1.2152 +#endif
  1.2153 +    COutlineCacheItem **data = iItemIdMap.Find(aOutlineId);
  1.2154 +    if (NULL != data)
  1.2155 +        {
  1.2156 +        (*data)->IncRefCount(aSessionHandle);
  1.2157 +        }
  1.2158 +    return (NULL==data?KErrNotFound:KErrNone);
  1.2159 +    }
  1.2160 +
  1.2161 +TInt CHintedOutlineCache::DecRefCount(const THintedOutlineId &aOutlineId,
  1.2162 +        TInt aSessionHandle)
  1.2163 +    {
  1.2164 +#ifdef _DEBUG
  1.2165 +    GetCacheState(__func__);
  1.2166 +#endif
  1.2167 +    COutlineCacheItem **data = iItemIdMap.Find(aOutlineId);
  1.2168 +    if (NULL != data) 
  1.2169 +        {
  1.2170 +        TInt numUsers = (*data)->DecRefCount(aSessionHandle);
  1.2171 +        if (0 == numUsers) 
  1.2172 +            {
  1.2173 +            // There is no outstanding reference to the cache item.
  1.2174 +            iCacheMemMon.Dec((*data)->iLength);
  1.2175 +            iHeap->Free(OffsetToPointer((*data)->iOffset, iHeap->Base()));
  1.2176 +            delete (*data);
  1.2177 +            iItemIdMap.Remove(aOutlineId);
  1.2178 +            }
  1.2179 +        }
  1.2180 +    return (NULL==data?KErrNotFound:KErrNone);
  1.2181 +    }
  1.2182 +
  1.2183 +TInt CHintedOutlineCache::Find(const THintedOutlineId &aOutlineId, 
  1.2184 +        TAny *&aData, TInt &aLength)
  1.2185 +    {
  1.2186 +    COutlineCacheItem **ret = iItemIdMap.Find(aOutlineId);
  1.2187 +    TInt ret2 = KErrNone;
  1.2188 +    if (NULL != ret)
  1.2189 +        {
  1.2190 +        aData = OffsetToPointer((*ret)->iOffset, iHeap->Base());
  1.2191 +        aLength = (*ret)->iLength;
  1.2192 +        }
  1.2193 +    else
  1.2194 +        {
  1.2195 +        ret2 = KErrNotFound;
  1.2196 +        }
  1.2197 +    return ret2;
  1.2198 +    }
  1.2199 +
  1.2200 +
  1.2201 +TUint32 CHintedOutlineCache::IdHash(const THintedOutlineId &outlineId)
  1.2202 +    {
  1.2203 +    // The hash value:
  1.2204 +    // bits 0-15: the outline id
  1.2205 +    // bits 16-27: the lower 12 bits of the font pointer
  1.2206 +    // bit 28: 'isGlyphId'
  1.2207 +    
  1.2208 +    TUint32 ret = 0;
  1.2209 +    ret |= (KOutlineGlyphIdHashMask & outlineId.iId);
  1.2210 +    ret |= (KOutlineFontPtrHashMask & (((TUint32)outlineId.iFont) << 16));
  1.2211 +    ret = ret % 701;
  1.2212 +    return ret;
  1.2213 +    }
  1.2214 +
  1.2215 +TBool CHintedOutlineCache::IdIdentity(const THintedOutlineId &id1, const THintedOutlineId &id2)
  1.2216 +    {
  1.2217 +    return id1.iId == id2.iId && id1.iFont == id2.iFont;
  1.2218 +    }
  1.2219 +// hinted cache
  1.2220 +
  1.2221 +
  1.2222 +CFontStore::CFontStore(RHeap* aHeap):
  1.2223 +	iKPixelWidthInTwips(KDefaultPixelWidthInTwips),
  1.2224 +	iKPixelHeightInTwips(KDefaultPixelHeightInTwips),
  1.2225 +	iFs(),
  1.2226 +	iHeap(aHeap),
  1.2227 +	iFontStoreFileList(KDefaultArrayGranularity),			// list of EPOC Bitmap font files loaded
  1.2228 +	iTypefaceList(KDefaultArrayGranularity),
  1.2229 +	iFontBitmapList(KDefaultArrayGranularity),
  1.2230 +	iTypefaceFontBitmapList(KDefaultArrayGranularity),
  1.2231 +	iOpenFontFileList(KDefaultArrayGranularity),			// list of 'Open Font' files loaded
  1.2232 +	iOpenFontRasterizerList(KDefaultArrayGranularity),		// open rasterizers, in load order
  1.2233 +	iOpenFontUid(1),
  1.2234 +	iDefaultBitmapType(EMonochromeGlyphBitmap),
  1.2235 +	iShaperFactoryList(KDefaultArrayGranularity),
  1.2236 +	iOpenFontShaperCacheMemUsage(0),
  1.2237 +	iNumberOfShaperCaches(0),
  1.2238 +	iOpenFontTypefaceSupportList(KDefaultArrayGranularity),	// list of Open Font typefaces available
  1.2239 +	iUniqueFontIdCount(0)									// used to give every font a unique id
  1.2240 +	{
  1.2241 +	}
  1.2242 +
  1.2243 +void CFontStore::ConstructL()
  1.2244 +	{
  1.2245 +	// Cache is placed in the shared heap
  1.2246 +	iOpenFontSessionCacheList = (COpenFontSessionCacheList*)iHeap->AllocL(sizeof(COpenFontSessionCacheList));
  1.2247 +	new(iOpenFontSessionCacheList) COpenFontSessionCacheList;
  1.2248 +
  1.2249 +	CTypefaceStore::ConstructL();
  1.2250 +	User::LeaveIfError(iFs.Connect());
  1.2251 +
  1.2252 +	TMachineInfoV1Buf machineInfoBuffer;
  1.2253 +	User::LeaveIfError(UserHal::MachineInfo(machineInfoBuffer));
  1.2254 +
  1.2255 +	const TSize twipSize = machineInfoBuffer().iPhysicalScreenSize;
  1.2256 +	const TSize pixelSize = machineInfoBuffer().iDisplaySizeInPixels;
  1.2257 +
  1.2258 +	if (twipSize.iWidth > 0 && pixelSize.iWidth > 0)
  1.2259 +		iKPixelWidthInTwips = twipSize.iWidth * 1000 / pixelSize.iWidth;
  1.2260 +
  1.2261 +	if (twipSize.iHeight > 0 && pixelSize.iHeight > 0)
  1.2262 +		iKPixelHeightInTwips = twipSize.iHeight * 1000 / pixelSize.iHeight;
  1.2263 +	
  1.2264 +	iCacheMemMon = new(ELeave) TFontTableGlyphOutlineCacheMemMonitor;
  1.2265 +	iUnhintedOutlineCache = new(ELeave) CUnhintedOutlineCache(iHeap, *iCacheMemMon);
  1.2266 +	iHintedOutlineCache = new(ELeave) CHintedOutlineCache(iHeap, *iCacheMemMon);
  1.2267 +	iFontTableCache = new(ELeave) CFontTableCache(iHeap, *iCacheMemMon);
  1.2268 +	
  1.2269 +	}
  1.2270 +
  1.2271 +/** Creates a new CFontStore object.
  1.2272 +
  1.2273 +Sets iKPixelWidthInTwips and iKPixelHeightInTwips.
  1.2274 +
  1.2275 +Sets the default bitmap type, used when getting bitmap fonts, to EMonochromeGlyphBitmap.
  1.2276 +
  1.2277 +Also initialises other private member variable values .
  1.2278 +
  1.2279 +@param aHeap A pointer to the heap class used for memory allocation.
  1.2280 +@leave KErrNoMemory Insufficient memory available on the heap. */
  1.2281 +EXPORT_C CFontStore *CFontStore::NewL(RHeap* aHeap)
  1.2282 +	{
  1.2283 +	User::LeaveIfNull(aHeap);
  1.2284 +	CFontStore *fontstore = new(ELeave) CFontStore(aHeap);
  1.2285 +	CleanupStack::PushL(fontstore);
  1.2286 +	fontstore->ConstructL();
  1.2287 +	CleanupStack::Pop(fontstore);
  1.2288 +	return fontstore;
  1.2289 +	}
  1.2290 +
  1.2291 +/** Destructor. */
  1.2292 +EXPORT_C CFontStore::~CFontStore()
  1.2293 +	{
  1.2294 +	// Remove All font files, and Reset associated arrays
  1.2295 +	RemoveFile(KNullUid);
  1.2296 +	iOpenFontRasterizerList.ResetAndDestroy();
  1.2297 +	iShaperFactoryList.ResetAndDestroy();
  1.2298 +	if (iOpenFontSessionCacheList)
  1.2299 +		{
  1.2300 +		iOpenFontSessionCacheList->Delete(iHeap);
  1.2301 +		iHeap->Free(iOpenFontSessionCacheList);
  1.2302 +		}
  1.2303 +	iFs.Close();
  1.2304 +	
  1.2305 +    delete iFontTableCache;
  1.2306 +    delete iUnhintedOutlineCache;
  1.2307 +    delete iHintedOutlineCache;
  1.2308 +    delete iCacheMemMon;
  1.2309 +	}
  1.2310 +
  1.2311 +
  1.2312 +// local utility functions
  1.2313 +// reads bytes from file, if the requested number of bytes are not available it leaves
  1.2314 +void ReadFromFileL(RFile& aFile, TDes8& aDes, TInt aLength)
  1.2315 +	{
  1.2316 +	User::LeaveIfError(aFile.Read(aDes, aLength));
  1.2317 +	if (aDes.Length() != aLength)
  1.2318 +		{
  1.2319 +		OstTrace0( TRACE_DUMP, _READFROMFILEL, "EOF reading structure from font file, Leave(KErrCorrupt)" );
  1.2320 +		User::Leave(KErrCorrupt);
  1.2321 +		}
  1.2322 +	}
  1.2323 +
  1.2324 +// local function(s) to read values from buffer & validate them
  1.2325 +TUint TtfTableTagFromBufferL(TDes8& aDes)
  1.2326 +	{
  1.2327 +	TUint value = 0;
  1.2328 +	for (TUint index = 0; index < 4;)
  1.2329 +		{
  1.2330 +		TUint temp = static_cast<TUint>(aDes[index++]);
  1.2331 +		// must be ASCII character between 32 & 126 inclusive (per Apple's TTF specification document)
  1.2332 +		if ( (temp < 32) || (temp > 126) )
  1.2333 +			{
  1.2334 +			OstTrace1( TRACE_DUMP, _TTFTABLETAGFROMBUFFERL, "invalid ASCII character (0x%x) in ttf table tag, Leave(KErrCorrupt)", temp);
  1.2335 +			User::Leave(KErrCorrupt);
  1.2336 +			}
  1.2337 +		value = (value << 8) | temp;
  1.2338 +		}
  1.2339 +	return value;
  1.2340 +	}
  1.2341 +
  1.2342 +/* Sanity check for TrueType Font, checks that the font tables are sensible.
  1.2343 +*/
  1.2344 +void CFontStore::SanityCheckForTtfL(RFile& aFontFile, TUint aFontFileSize, TBool aStrictChecking)
  1.2345 +	{
  1.2346 +	OstTraceExt2( TRACE_DUMP, CFONTSTORE_SANITYCHECKFORTTFL, "TTF File Size is %u (0x%x) bytes", aFontFileSize, aFontFileSize );
  1.2347 +	// check the Offset Table at the start of the file
  1.2348 +	TBuf8<16>	fileBuffer;
  1.2349 +
  1.2350 +	ReadFromFileL(aFontFile, fileBuffer, 12);
  1.2351 +	TUint numTables = (fileBuffer[4] << 8) | (fileBuffer[5]);
  1.2352 +	TUint searchRange = (fileBuffer[6] << 8) | (fileBuffer[7]);
  1.2353 +	TUint entrySelector = (fileBuffer[8] << 8) | (fileBuffer[9]);
  1.2354 +	TUint rangeShift = (fileBuffer[10] << 8) | (fileBuffer[11]);
  1.2355 +
  1.2356 +	const TInt tableStart = 12 + (numTables << 4);	// lowest possible address for actual table data
  1.2357 +
  1.2358 +	if ( (numTables == 0) || (numTables & 0xF0000000) || (tableStart > aFontFileSize) )
  1.2359 +		{
  1.2360 +		OstTrace1( TRACE_DUMP, DUP1_CFONTSTORE_SANITYCHECKFORTTFL, "# of tables (%d) in ttf is invalid, Leave(KErrCorrupt)", numTables );
  1.2361 +		User::Leave(KErrCorrupt);
  1.2362 +		}
  1.2363 +
  1.2364 +#if defined(_DEBUG) && defined(VERBOSE_DEBUG)
  1.2365 +	// scalar type is 0x00010000 for Windows fonts, other possible values include 0x74727565 and 0x74797031: not checked
  1.2366 +	TUint scalarType = (fileBuffer[0] << 24) | (fileBuffer[1] << 16) | (fileBuffer[2] << 8) | (fileBuffer[3]);
  1.2367 +	RDebug::Print(_L("ttf scalarType is 0x%x, # of tables is %u\n"), scalarType, numTables);
  1.2368 +	RDebug::Print(_L("searchRange is 0x%x, entrySelector is 0x%x, rangeShift is 0x%x\n"), 
  1.2369 +		searchRange, entrySelector, rangeShift);
  1.2370 +#endif
  1.2371 +
  1.2372 +	// check searchRange, entrySelector & rangeShift values
  1.2373 +	// (some not quite TTF files fail the rangeShift check)
  1.2374 +	if ( (searchRange < 16) || (entrySelector > 24)
  1.2375 +		|| (aStrictChecking && (rangeShift != ( (numTables << 4) - searchRange )) ) )
  1.2376 +		{
  1.2377 +		OstTraceExt4( TRACE_DUMP, DUP2_CFONTSTORE_SANITYCHECKFORTTFL, "searchRange (0x%x), entrySelector (0x%x) or rangeShift (0x%x) invalid for numTables (%d), Leave(KErrCorrupt)", 
  1.2378 +		        searchRange, entrySelector, rangeShift, numTables );
  1.2379 +		User::Leave(KErrCorrupt);
  1.2380 +		}
  1.2381 +
  1.2382 +	// entrySelector is defined as Log2(Maximum power of 2 <= nmumTables)
  1.2383 +	TUint exp = 1 << entrySelector;		// log to exponent
  1.2384 +	if ( (numTables < exp) || (numTables > (exp << 1)) )
  1.2385 +		{
  1.2386 +		OstTraceExt2( TRACE_DUMP, DUP3_CFONTSTORE_SANITYCHECKFORTTFL, "entrySelector (0x%x) wrong for numTables(%d), Leave(KErrCorrupt)", 
  1.2387 +		        entrySelector, numTables );
  1.2388 +		User::Leave(KErrCorrupt);
  1.2389 +		}
  1.2390 +
  1.2391 +	// easy checks on the table directory
  1.2392 +	TInt totalFontSize = tableStart;				// accumulated total directories plus table sizes
  1.2393 +	TInt highestTableEnd = 0;						// highest value found for table start plus table length
  1.2394 +	TUint lastTableTag = 0;							// to check that tags are in order
  1.2395 +	TInt tableNum = 0;
  1.2396 +
  1.2397 +	do 
  1.2398 +		{ // each entry is 16 bytes, (though we don't check the checksum)
  1.2399 +		ReadFromFileL(aFontFile, fileBuffer, 16);
  1.2400 +		TUint tableTag = TtfTableTagFromBufferL(fileBuffer);
  1.2401 +		TUint offset = (fileBuffer[8] << 24) | (fileBuffer[9] << 16) | (fileBuffer[10] << 8) | (fileBuffer[11]);
  1.2402 +		TUint length = (fileBuffer[12] << 24) | (fileBuffer[13] << 16) | (fileBuffer[14] << 8) | (fileBuffer[15]);
  1.2403 +
  1.2404 +#if defined(_DEBUG) && defined(VERBOSE_DEBUG)
  1.2405 +		RDebug::Print(_L("ttf table tag ('%c%c%c%c'): offset is 0x%x, length is 0x%x\n"), 
  1.2406 +			tableTag >> 24, (tableTag >> 16) & 0x7F, (tableTag >> 8) & 0x7F, tableTag & 0x7F, 
  1.2407 +			offset, length);
  1.2408 +#endif
  1.2409 +		length = (length + 3) & ~3;	// round up, all tables must be a multiple of 4 bytes for checksumming
  1.2410 +
  1.2411 +		// table Tags must be unique & in order
  1.2412 +		if (tableTag <= lastTableTag)
  1.2413 +			{
  1.2414 +			OstTraceExt4( TRACE_DUMP, DUP4_CFONTSTORE_SANITYCHECKFORTTFL, "ttf table tag ('%c%c%c%c') is out of order, Leave(KErrCorrupt)",
  1.2415 +			        tableTag >> 24, (tableTag >> 16) & 0x7F, (tableTag >> 8) & 0x7F, tableTag & 0x7F);
  1.2416 +			User::Leave(KErrCorrupt);
  1.2417 +			}
  1.2418 +
  1.2419 +
  1.2420 +		// the offset must be 4-byte aligned, and after the table directory
  1.2421 +		// offset + length must be bigger than the start offset (!)
  1.2422 +		TInt end = length + offset;
  1.2423 +		if ( (offset & 3) || (offset < tableStart) || (length == 0) || (end < offset) || (end > aFontFileSize))
  1.2424 +			{
  1.2425 +			OstTraceExt2( TRACE_DUMP, DUP5_CFONTSTORE_SANITYCHECKFORTTFL, "offset (0x%x) or length (0x%x) are bad, Leave(KErrCorrupt)",
  1.2426 +			        offset, length );
  1.2427 +			User::Leave(KErrCorrupt);
  1.2428 +			}
  1.2429 +
  1.2430 +		lastTableTag = tableTag;
  1.2431 +		totalFontSize += length;
  1.2432 +		if (end > highestTableEnd)
  1.2433 +			{
  1.2434 +			highestTableEnd = end;
  1.2435 +			}
  1.2436 +		}
  1.2437 +		while (++tableNum < numTables);
  1.2438 +
  1.2439 +#if defined(_DEBUG) && defined(VERBOSE_DEBUG)
  1.2440 +	RDebug::Print(_L("last address used by any table is 0x%x, Minimum font file size to hold all tables is 0x%x\n"), 
  1.2441 +			highestTableEnd, totalFontSize);
  1.2442 +#endif
  1.2443 +
  1.2444 +	// for single font files highestTableEnd & totalFontSize should be the same
  1.2445 +	if (highestTableEnd != totalFontSize)
  1.2446 +		{
  1.2447 +		OstTraceExt2( TRACE_DUMP, DUP6_CFONTSTORE_SANITYCHECKFORTTFL, "Total Font Size (0x%x) is different from end of the last table (0x%x), Leave(KErrCorrupt)",
  1.2448 +		        highestTableEnd, totalFontSize);
  1.2449 +		User::Leave(KErrCorrupt);
  1.2450 +		}
  1.2451 +	}
  1.2452 +
  1.2453 +/* Sanity checks on font files, currently only knows about TrueType Font files: .ttf and .otf
  1.2454 +Protects FBserv / the client and the rasterizer plug-in from grossly corrupt data.
  1.2455 +@leave KErrCorrupt if the font tables are daft
  1.2456 +*/
  1.2457 +void CFontStore::SanityCheckFontFileL(TParse& aParse)
  1.2458 +	{
  1.2459 +
  1.2460 +	// try to open the file and getting the file size
  1.2461 +	RFile fontFile;
  1.2462 +	const TInt openError = fontFile.Open(iFs, aParse.FullName(), EFileRead | EFileShareReadersOnly);
  1.2463 +#ifdef _DEBUG
  1.2464 +	if (KErrNone != openError)
  1.2465 +		{
  1.2466 +		const TDesC& fileName = aParse.FullName();
  1.2467 +		RDebug::Print(_L("Sanity checking font file \"%S\", file open gave error %d\n"), &fileName, openError);
  1.2468 +		}
  1.2469 +#endif
  1.2470 +	User::LeaveIfError(openError);
  1.2471 +	CleanupClosePushL(fontFile);
  1.2472 +	TInt fontFileSize = 0;
  1.2473 +	User::LeaveIfError(fontFile.Size(fontFileSize));
  1.2474 +
  1.2475 +	if (fontFileSize == 0)
  1.2476 +		{ // no font can be zero length!
  1.2477 +#ifdef _DEBUG
  1.2478 +		RDebug::Print(_L("font file size (%i) is zero\n"), fontFileSize);
  1.2479 +#endif
  1.2480 +		User::Leave(KErrCorrupt);
  1.2481 +		}
  1.2482 +	else
  1.2483 +		{
  1.2484 +		const TDesC& fileExt = aParse.Ext();
  1.2485 +		// TrueType fonts
  1.2486 +		_LIT(KFntStoreTrueTypeExtension,".ttf");
  1.2487 +		// OpenType fonts
  1.2488 +		_LIT(KFntStoreOpenTypeExtension,".otf");
  1.2489 +		// other font files that follow TTF format
  1.2490 +		_LIT(KFntStoreCccFontFileExtension,".ccc");
  1.2491 +
  1.2492 +		if ( (0 == fileExt.CompareF(KFntStoreTrueTypeExtension)) || (0 == fileExt.CompareF(KFntStoreOpenTypeExtension)) )
  1.2493 +			{ // uses TrueType file format, perform strict format check
  1.2494 +			SanityCheckForTtfL(fontFile, fontFileSize, ETrue);
  1.2495 +			}
  1.2496 +		else if (0 == fileExt.CompareF(KFntStoreCccFontFileExtension))
  1.2497 +			{ // uses nearly TrueType file format, perform slightly less strict format check
  1.2498 +			SanityCheckForTtfL(fontFile, fontFileSize, EFalse);
  1.2499 +			}
  1.2500 +
  1.2501 +		// extendible if required for other font file types ...
  1.2502 +		}
  1.2503 +
  1.2504 +	CleanupStack::PopAndDestroy(&fontFile);
  1.2505 +	}
  1.2506 +
  1.2507 +
  1.2508 +/** Finds or creates a font file object to support a font file. The specified font
  1.2509 +file must be accessible to any process, i.e. not located inside an
  1.2510 +application's private directory.
  1.2511 +
  1.2512 +If an appropriate font file object exists then no new open font file is created. 
  1.2513 +In this case the reference count of the font file object is incremented.
  1.2514 +
  1.2515 +Notes:
  1.2516 +
  1.2517 +If aName is recognised as an open font file, creates a COpenFontFile, which 
  1.2518 +will manage the font file specified by aName, and adds it to the file store's 
  1.2519 +list of open font files.
  1.2520 +
  1.2521 +The list of open font files is used when getting the nearest font for a font 
  1.2522 +specification (i.e. by the GetNearestFont...() functions of this class) if 
  1.2523 +the font is generated via a rasterizer.
  1.2524 +
  1.2525 +The appropriate rasterizer, which supports the font format of the font file, 
  1.2526 +is used to generate the open font file using COpenFontRasterizer::NewFontFileL().
  1.2527 +
  1.2528 +If aName is not recognised as an open font file then CFontStoreFile tries to open
  1.2529 +the file as a Symbian Bitmap font.
  1.2530 +
  1.2531 +@param aName The full path and filename of the font file to be supported.
  1.2532 +@return The UID of the font file object supporting aName.
  1.2533 +@leave KErrNotSupported if the file is not recognised at all
  1.2534 +@leave KErrCorrupt if the font file data does not make sense
  1.2535 +@leave or another system-wide error
  1.2536 +*/
  1.2537 +EXPORT_C TUid CFontStore::AddFileL(const TDesC& aName)
  1.2538 +	{
  1.2539 +	TParse fontFilename;
  1.2540 +	User::LeaveIfError(iFs.Parse(aName, fontFilename));
  1.2541 +
  1.2542 +	// increment reference count if font file is already loaded
  1.2543 +	TUid fontUid = KNullUid;
  1.2544 +
  1.2545 +	if (IncRefCountOfLoadedFont(fontFilename, fontUid))
  1.2546 +		{
  1.2547 +		return fontUid;
  1.2548 +		}
  1.2549 +
  1.2550 +	// Do not validate fonts on Z: (assumed to be ROM created with valid fonts)
  1.2551 +	if (!FileIsOnZ(fontFilename))
  1.2552 +		{
  1.2553 +		// file is not open - check that the file exists and has a plausible content
  1.2554 +		SanityCheckFontFileL(fontFilename);
  1.2555 +		}
  1.2556 +	
  1.2557 +	AddSanityCheckedFontL(fontFilename, fontUid);
  1.2558 +	
  1.2559 +	return fontUid;
  1.2560 +	}
  1.2561 +
  1.2562 +/**
  1.2563 +Finds or creates a font file object to support a font file.
  1.2564 +@param aFileName The filename to check
  1.2565 +@param aUid The list to check
  1.2566 +@see CFontStore::AddFileL
  1.2567 +*/
  1.2568 +void CFontStore::AddSanityCheckedFontL(const TParse& aFileName, TUid& aUid)
  1.2569 +	{
  1.2570 +	// Try loading the file as an Open Font
  1.2571 +	if (!LoadFileAsOpenFontL(aFileName, aUid))
  1.2572 +		{
  1.2573 +		// It could not be recognised as an Open Font file so load it as an EPOC bitmap font file.
  1.2574 +		// (This always succeeds or Leaves.)
  1.2575 +		aUid = LoadFileAsBitmapFontL(aFileName);
  1.2576 +		}
  1.2577 +	}
  1.2578 +
  1.2579 +
  1.2580 +// Remove a Font File - called via the Cleanup Stack if a leave occurs during font install
  1.2581 +void CFontStore::CleanupRemoveFontFile(TAny* aCleanupInfo)
  1.2582 +	{
  1.2583 +	TCleanupRemoveFontFile* cleanupInfo = (TCleanupRemoveFontFile *) aCleanupInfo;
  1.2584 +	cleanupInfo->iFontStore->RemoveFile(cleanupInfo->iFontUid);
  1.2585 +	}
  1.2586 +
  1.2587 +
  1.2588 +/** Search through the rasterizers for one that will open the font filename.
  1.2589 +
  1.2590 +Can leave if the rasterizer encounters an error, such as unexpected end of file, nonsense data, no memory.
  1.2591 +
  1.2592 +@param aName full filename to open
  1.2593 +@param aFontUid set to the font file UID if it is already loaded
  1.2594 +@return ETrue if the font file is loaded, otherwise EFalse
  1.2595 +@internalComponent
  1.2596 +*/
  1.2597 +TBool CFontStore::LoadFileAsOpenFontL(const TParse& aFileName, TUid& aFontUid)
  1.2598 +	{
  1.2599 +	const TDesC& fullName = aFileName.FullName();
  1.2600 +	
  1.2601 +	// ask each of the rasterizers in turn to create a COpenFontFile object.
  1.2602 +	const TInt rasterizerCount = iOpenFontRasterizerList.Count();
  1.2603 +	for (TInt index = 0; index < rasterizerCount; index++)
  1.2604 +		{
  1.2605 +		COpenFontFile* openFontFile = iOpenFontRasterizerList[index]->NewFontFileL(iOpenFontUid, fullName, iFs);
  1.2606 +		if (NULL != openFontFile)
  1.2607 +			{
  1.2608 +			/* Uids for Open Fonts are allocated in order; the
  1.2609 +			one for the COpenFontFile just created won't match any existing one.
  1.2610 +			(When a file is removed, the fake Uid will match, because the one that was returned here is used.)
  1.2611 +			*/
  1.2612 +			CleanupStack::PushL(openFontFile);
  1.2613 +			openFontFile->SetFontStoreL(this);
  1.2614 +			iOpenFontFileList.AppendL(openFontFile);
  1.2615 +			openFontFile->IncRefCount();
  1.2616 +			CleanupStack::Pop(openFontFile);
  1.2617 +
  1.2618 +			TInt typefaceAddError = AddTypefacesToSupportList(openFontFile);
  1.2619 +			if (typefaceAddError)
  1.2620 +				{
  1.2621 +				// cleanup
  1.2622 +				RemoveFile(openFontFile->Uid());
  1.2623 +				// throw the error
  1.2624 +				User::Leave(typefaceAddError);
  1.2625 +				}
  1.2626 +
  1.2627 +			/*
  1.2628 +			iOpenFontUid is the fake Uid used for new font files. It is made modulo a 'zillion' (2^28)
  1.2629 +			so that it cannot conflict with real Uids, which are >= 2^28. It starts at 1 so that
  1.2630 +			it does not conflict with the value 0 (KNullUid) which is used as a sentinel in
  1.2631 +			CFontStore::RemoveFileL.
  1.2632 +			*/
  1.2633 +			++iOpenFontUid;
  1.2634 +			iOpenFontUid = iOpenFontUid % 0x1000000;
  1.2635 +
  1.2636 +			aFontUid = openFontFile->Uid();
  1.2637 +			return ETrue;
  1.2638 +			}
  1.2639 +		}
  1.2640 +	return EFalse;
  1.2641 +	}
  1.2642 +
  1.2643 +
  1.2644 +/** Search loaded fonts for filename, and increment the reference count
  1.2645 +@param aParse full filename to search for
  1.2646 +@return the font file UID
  1.2647 +@leave KErrNotSupported or another system wide error code
  1.2648 +@internalComponent
  1.2649 +*/
  1.2650 +TUid CFontStore::LoadFileAsBitmapFontL(const TParse& aParse)
  1.2651 +	{
  1.2652 +	// open the file, presuming it is a bitmap font
  1.2653 +	CFontStoreFile* fontStoreFile = CFontStoreFile::NewL(aParse, iFs);
  1.2654 +
  1.2655 +	// See if a font with this UID is already open
  1.2656 +	TInt match = FindBitmapFontFileIndexByUid(fontStoreFile->iCollectionUid);
  1.2657 +	if (match != KErrNotFound) // The file is open.
  1.2658 +		{ // close the new duplicate, inc the reference count
  1.2659 +		delete fontStoreFile;
  1.2660 +		fontStoreFile = iFontStoreFileList[match];
  1.2661 +		fontStoreFile->iUsageCount++;
  1.2662 +		}
  1.2663 +	else
  1.2664 +		{
  1.2665 +		CleanupStack::PushL(fontStoreFile);
  1.2666 +		iFontStoreFileList.AppendL(fontStoreFile);
  1.2667 +		CleanupStack::Pop(fontStoreFile);
  1.2668 +
  1.2669 +		// special object to removes the font file if a leave occurs during font install
  1.2670 +		TCleanupRemoveFontFile cleanupHelper(this, fontStoreFile->iCollectionUid);
  1.2671 +		CleanupStack::PushL(TCleanupItem(CleanupRemoveFontFile, &cleanupHelper));
  1.2672 +		// install the new font
  1.2673 +		InternalizeFontStoreFileL(fontStoreFile, fontStoreFile->iFontVersion);
  1.2674 +		CleanupStack::Pop(&cleanupHelper); // CleanupRemoveFontFile
  1.2675 +		}
  1.2676 +	return fontStoreFile->iCollectionUid;
  1.2677 +	}
  1.2678 +
  1.2679 +
  1.2680 +/** Search open Bitmap font files for matching UID
  1.2681 +@param aUid UID to search for
  1.2682 +@return The index of the matching item in iFontStoreFileList[] array, or KErrNotFound
  1.2683 +@internalComponent
  1.2684 +*/
  1.2685 +TInt CFontStore::FindBitmapFontFileIndexByUid(TUid aUid)
  1.2686 +	{
  1.2687 +	const TInt fontFileCount = iFontStoreFileList.Count();
  1.2688 +	for (TInt index = 0; index < fontFileCount; index++)
  1.2689 +		{
  1.2690 +		if (iFontStoreFileList[index]->iCollectionUid == aUid)
  1.2691 +			{
  1.2692 +			return index;
  1.2693 +			}
  1.2694 +		}
  1.2695 +	return KErrNotFound;
  1.2696 +	}
  1.2697 +
  1.2698 +
  1.2699 +/** Search loaded fonts for filename, and increment the reference count
  1.2700 +@param aName full filename to search for
  1.2701 +@param aFontUid set to the font file UID if it is already loaded
  1.2702 +@return ETrue if the font file is already loaded, otherwise EFalse
  1.2703 +@internalComponent
  1.2704 +*/
  1.2705 +TBool CFontStore::IncRefCountOfLoadedFont(const TParse& aFileName, TUid& aFontUid)
  1.2706 +	{
  1.2707 +	const TDesC& fullName = aFileName.FullName();
  1.2708 +	
  1.2709 +	// Is it already in the Open Font list? Compare by full filename, not (fake) Uid;
  1.2710 +	const TInt openFontCount = iOpenFontFileList.Count();
  1.2711 +	TInt i = 0;
  1.2712 +	for (i = 0; i < openFontCount; ++i)
  1.2713 +		{
  1.2714 +		COpenFontFile* openFontFile = iOpenFontFileList[i];
  1.2715 +		if (fullName.CompareF(openFontFile->FileName()) == 0)
  1.2716 +			{
  1.2717 +			// Open Font file already loaded
  1.2718 +			openFontFile->IncRefCount();
  1.2719 +			aFontUid = openFontFile->Uid();
  1.2720 +			return ETrue;
  1.2721 +			}
  1.2722 +		}
  1.2723 +
  1.2724 +	// already open as an EPOC bitmap font file?
  1.2725 +	const TInt fontFileCount = iFontStoreFileList.Count();
  1.2726 +	for (i = 0; i < fontFileCount; i++)
  1.2727 +		{
  1.2728 +		CFontStoreFile* fontStoreFile = iFontStoreFileList[i];
  1.2729 +		if (fullName.CompareF(fontStoreFile->FullName()) == 0)
  1.2730 +			{
  1.2731 +			// font file already loaded
  1.2732 +			++(fontStoreFile->iUsageCount);
  1.2733 +			aFontUid = fontStoreFile->iCollectionUid;
  1.2734 +			return ETrue;
  1.2735 +			}
  1.2736 +		}
  1.2737 +	return EFalse;
  1.2738 +	}
  1.2739 +
  1.2740 +
  1.2741 +/** Releases a hold on one or all font file objects (COpenFontFiles or CFontStoreFiles).
  1.2742 +
  1.2743 +If aFileUid identifies a font file object, then the reference count for this 
  1.2744 +object is decremented. If this brings the reference count down to zero then 
  1.2745 +the font file object and typefaces associated with this file are removed from
  1.2746 +the font store, provided no fonts associated with this file are being accessed. 
  1.2747 +If one or more fonts are being accessed then the file removal request will be ignored.
  1.2748 +
  1.2749 +If, on the other hand, aFileUid's value is NULL, then all font file objects 
  1.2750 +are removed, along with all fonts and typefaces in the font store, provided
  1.2751 +that no fonts in the font store are being accessed (i.e. iFontAccess is empty),
  1.2752 +otherwise it has no effect.
  1.2753 +
  1.2754 +(If aFileUid is invalid, then no objects are removed.)
  1.2755 +
  1.2756 +@param aFileUid UID of a hold on a font file object to be released, or KNullUid
  1.2757 +if all font file objects are to be removed.
  1.2758 +*/
  1.2759 +EXPORT_C void CFontStore::RemoveFile(TUid aFileUid)
  1.2760 +	{
  1.2761 +	TInt i, count;
  1.2762 +	if (aFileUid == KNullUid)	// this means 'delete all files'
  1.2763 +		{
  1.2764 +		if(iFontAccess)
  1.2765 +			{
  1.2766 +			TInt count = iFontAccess->Count();		
  1.2767 +			for (TInt i = 0; i < count; i++)
  1.2768 +				if((*iFontAccess)[i].iAccessCount)
  1.2769 +					return;
  1.2770 +			}
  1.2771 +		if (iFontTableCache && iFontTableCache->HasOutstandingRefCount())
  1.2772 +		    {
  1.2773 +		    // disallow font file removal if any font tables are still cached
  1.2774 +		    return;
  1.2775 +		    }
  1.2776 +		
  1.2777 +		iTypefaceList.ResetAndDestroy();
  1.2778 +		count = iFontBitmapList.Count();
  1.2779 +		for (TInt i = 0; i < count; i++)
  1.2780 +			iFontBitmapList[i]->Release();
  1.2781 +		iFontBitmapList.Reset();
  1.2782 +		iTypefaceFontBitmapList.Reset();
  1.2783 +		iFontStoreFileList.ResetAndDestroy();
  1.2784 +		iOpenFontFileList.ResetAndDestroy();
  1.2785 +		iOpenFontTypefaceSupportList.ResetAndDestroy();
  1.2786 +		}
  1.2787 +	else
  1.2788 +		{
  1.2789 +		// See if it's an Open Font file.
  1.2790 +		count = iOpenFontFileList.Count();
  1.2791 +		for (i = 0; i < count; i++)
  1.2792 +			{
  1.2793 +			TInt fontAccessCount;
  1.2794 +			if (iOpenFontFileList[i]->Uid() == aFileUid)
  1.2795 +				{ // found the file
  1.2796 +				if (iFontAccess)
  1.2797 +					{ // Check to see if there are any references before we consider deleting
  1.2798 +					fontAccessCount = iFontAccess->Count();
  1.2799 +					for (TInt kk = 0; kk < fontAccessCount; ++kk)
  1.2800 +						{
  1.2801 +		  	  	  		CBitmapFont* bitmapFont = reinterpret_cast<CBitmapFont*>((*iFontAccess)[kk].iFont);
  1.2802 +		  	  	  		COpenFont* openFont = bitmapFont->OpenFont();
  1.2803 +		  	  	  		if (openFont && openFont->File()->Uid() == aFileUid )
  1.2804 +		  	  	  			{
  1.2805 +		  	  	  			if ((*iFontAccess)[kk].iAccessCount > 0) 
  1.2806 +		  	  	  				return; // Outstanding reference found, so ignoring file removal request
  1.2807 +		  	  	  			}
  1.2808 +						}
  1.2809 +					} // Safe to proceed with removing file
  1.2810 +				// also check if there are outstanding references to any 
  1.2811 +				// table in that file.
  1.2812 +				if (iFontTableCache && iFontTableCache->HasOutstandingRefCountWithUid(aFileUid))
  1.2813 +				    {
  1.2814 +				    return; // outstanding reference to font table found.
  1.2815 +				    }
  1.2816 +				
  1.2817 +				// Safe to proceed with removing file
  1.2818 +				if (iOpenFontFileList[i]->DecRefCount())
  1.2819 +					{ // unload the font file
  1.2820 +					RemoveTypefacesFromSupportList(iOpenFontFileList[i]);
  1.2821 +					//linked fonts deleted from this destructor
  1.2822 +					delete iOpenFontFileList[i];
  1.2823 +					iOpenFontFileList.Delete(i);
  1.2824 +					}
  1.2825 +				return;
  1.2826 +				}
  1.2827 +			}
  1.2828 +
  1.2829 +		// Finds first fontstorefile with correct id
  1.2830 +		TInt index = FindBitmapFontFileIndexByUid(aFileUid);
  1.2831 +		if (index != KErrNotFound)  //  Checks fontstore file has been found
  1.2832 +			{
  1.2833 +			iFontStoreFileList[index]->iUsageCount--;
  1.2834 +			if (!iFontStoreFileList[index]->iUsageCount)
  1.2835 +				{
  1.2836 +				TInt tfcount = iTypefaceFontBitmapList.Count();
  1.2837 +				for (i=tfcount-1; i>=0; i--)
  1.2838 +					if (aFileUid == iTypefaceFontBitmapList[i].iFontBitmap->FontStoreFile()->iCollectionUid)
  1.2839 +						iTypefaceFontBitmapList.Delete(i);
  1.2840 +				count = iFontBitmapList.Count();
  1.2841 +				for (i=count-1; i>=0; i--)
  1.2842 +					{
  1.2843 +					
  1.2844 +					if (aFileUid==iFontBitmapList[i]->FontStoreFile()->iCollectionUid)
  1.2845 +						{
  1.2846 +						iFontBitmapList[i]->Release();
  1.2847 +						iFontBitmapList.Delete(i);
  1.2848 +						}  
  1.2849 +					}
  1.2850 +				count = iTypefaceList.Count();
  1.2851 +				for (i=count-1; i>=0; i--)	
  1.2852 +					{
  1.2853 +					TBool inlist=EFalse;  
  1.2854 +					tfcount = iTypefaceFontBitmapList.Count();
  1.2855 +					for (TInt j=0; j<tfcount; j++)
  1.2856 +						if (iTypefaceList[i] == iTypefaceFontBitmapList[j].iTypeface)
  1.2857 +							inlist = ETrue;
  1.2858 +					if (!inlist)
  1.2859 +						{
  1.2860 +						delete iTypefaceList[i];
  1.2861 +						iTypefaceList.Delete(i);
  1.2862 +						}
  1.2863 +					}
  1.2864 +				delete iFontStoreFileList[index];
  1.2865 +				iFontStoreFileList.Delete(index);
  1.2866 +				}
  1.2867 +			}
  1.2868 +		}
  1.2869 +	}
  1.2870 +
  1.2871 +/**
  1.2872 +@publishedAll
  1.2873 +*/
  1.2874 +EXPORT_C TInt CFontStore::GetNearestFontInTwips(CFont*& aFont, const TFontSpec& aFontSpec)
  1.2875 +	{
  1.2876 +	return GetNearestFontToDesignHeightInTwips(aFont, aFontSpec);
  1.2877 +	}
  1.2878 +
  1.2879 +/**
  1.2880 +Gets the font which is the nearest to the given font specification.
  1.2881 +
  1.2882 +Note that this deprecated function is replaced by the new @c GetNearestFontToDesignHeightInTwips() 
  1.2883 +yielding (virtually) the same result. However clients are strongly encouraged to use the new
  1.2884 +@c GetNearestFontToMaxHeightInTwips() function instead. This will guarantee that every 
  1.2885 +character within any given text string will fit within the given amount of twips, whereas the design 
  1.2886 +height is an aesthetic unit decided by the font designer without strict physical meaning, which 
  1.2887 +may result in cropped characters.
  1.2888 +
  1.2889 +@param aFont On return, contains a pointer to the nearest font.
  1.2890 +@param aFontSpec The specification of the font to be matched.
  1.2891 +@return KErrNone if successful; a system-wide error code otherwise.
  1.2892 +@publishedAll
  1.2893 +@deprecated Use GetNearestFontToDesignHeightInTwips
  1.2894 +*/
  1.2895 +EXPORT_C TInt CFontStore::GetNearestFontInTwips(CFont*& aFont, const TOpenFontSpec& aFontSpec)
  1.2896 +	{
  1.2897 +	return GetNearestFontToDesignHeightInTwips(aFont, aFontSpec);
  1.2898 +	}
  1.2899 +
  1.2900 +/**
  1.2901 +@publishedAll
  1.2902 +*/
  1.2903 +EXPORT_C TInt CFontStore::GetNearestFontToDesignHeightInTwips(CFont*& aFont, const TFontSpec& aFontSpec)
  1.2904 +	{
  1.2905 +	TOpenFontSpec spec(aFontSpec);
  1.2906 +	spec.SetHeight(VerticalTwipsToPixels(spec.Height()));
  1.2907 +	return GetNearestFontToDesignHeightInPixels(aFont, spec);
  1.2908 +	}
  1.2909 +
  1.2910 +/**
  1.2911 +Gets the font which is the nearest to the given font specification.
  1.2912 +
  1.2913 +This new function replaces the deprecated @c GetNearestFontInTwips() yielding (virtually) the 
  1.2914 +same result. However clients are strongly encouraged to use the new
  1.2915 +@c GetNearestFontToMaxHeightInTwips() function instead. This will guarantee that every 
  1.2916 +character within any given text string will fit within the given amount of twips, whereas the design 
  1.2917 +height is an aesthetic unit decided by the font designer without strict physical meaning, which 
  1.2918 +may result in cropped characters.
  1.2919 +
  1.2920 +@param aFont On return, contains a pointer to the nearest font.
  1.2921 +@param aFontSpec The specification of the font to be matched.
  1.2922 +@return KErrNone if successful; a system-wide error code otherwise.
  1.2923 +@publishedAll
  1.2924 +@released
  1.2925 +*/
  1.2926 +EXPORT_C TInt CFontStore::GetNearestFontToDesignHeightInTwips(CFont*& aFont, const TOpenFontSpec& aFontSpec)
  1.2927 +	{
  1.2928 +	TOpenFontSpec spec = aFontSpec;
  1.2929 +	spec.SetHeight(VerticalTwipsToPixels(spec.Height()));
  1.2930 +	return GetNearestFontToDesignHeightInPixels(aFont, spec);
  1.2931 +	}
  1.2932 +
  1.2933 +/**
  1.2934 +@publishedAll
  1.2935 +*/
  1.2936 +EXPORT_C TInt CFontStore::GetNearestFontToMaxHeightInTwips(CFont*& aFont, const TFontSpec& aFontSpec, TInt aMaxHeight)
  1.2937 +	{
  1.2938 +	TOpenFontSpec spec(aFontSpec);
  1.2939 +	spec.SetHeight(VerticalTwipsToPixels(spec.Height()));
  1.2940 +	return GetNearestFontToMaxHeightInPixels(aFont, spec, VerticalTwipsToPixels(aMaxHeight));
  1.2941 +	}
  1.2942 +
  1.2943 +/**
  1.2944 +Gets the font which is the nearest to the given font specification.
  1.2945 +
  1.2946 +The font and bitmap server returns a pointer to the nearest matching font 
  1.2947 +from those available. Matches to max height of font - this does its best 
  1.2948 +to return a font that will fit within the maximum height specified (but 
  1.2949 +note that variations due to hinting algorithms may rarely result in this 
  1.2950 +height being exceeded by up to one pixel). Problems can also be 
  1.2951 +encountered with bitmap fonts where the typeface exists but doesn't have 
  1.2952 +a font small enough.
  1.2953 +
  1.2954 +@param aFont On return, contains a pointer to the nearest font.
  1.2955 +@param aFontSpec The specification of the font to be matched.
  1.2956 +@param aMaxHeight The maximum height within which the font must fit. If maximum height
  1.2957 +is greater than 1024 pixels, the function returns KErrTooBig. And returns KErrArgument
  1.2958 +if equals to 1 pixel. This overrides the height specified in aFontSpec.
  1.2959 +@return KErrNone if successful; a system-wide error code otherwise.
  1.2960 +@publishedAll
  1.2961 +@released
  1.2962 +*/
  1.2963 +EXPORT_C TInt CFontStore::GetNearestFontToMaxHeightInTwips(CFont*& aFont, const TOpenFontSpec& aFontSpec, TInt aMaxHeight)
  1.2964 +	{
  1.2965 +	TOpenFontSpec spec = aFontSpec;
  1.2966 +	spec.SetHeight(VerticalTwipsToPixels(spec.Height()));
  1.2967 +	return GetNearestFontToMaxHeightInPixels(aFont, spec, VerticalTwipsToPixels(aMaxHeight));
  1.2968 +	}
  1.2969 +
  1.2970 +
  1.2971 +/** Local utility method to compare two font specs; the higher the return value, the better the match.
  1.2972 +It is not clear how to reliably test for symbol fonts or language coverage because some
  1.2973 +TOpenFontSpecs are created from bitmap TFontSpecs that do not have this info
  1.2974 +*/
  1.2975 +TInt MatchFontSpecsInPixels(
  1.2976 +	const TOpenFontSpec&	aCandidateFontSpec,
  1.2977 +	const TOpenFontSpec&	aIdealFontSpec,
  1.2978 +	TInt					aCandidateMaxHeight,
  1.2979 +	TInt					aIdealMaxHeight)
  1.2980 +	{
  1.2981 +	// scores for matching (or similar) font attributes:
  1.2982 +	const TInt KFontMatchScoreForName = 10;
  1.2983 +	// favour fonts with heights closer together 
  1.2984 +	const TInt KFontMaxScoreForHeight = 10;
  1.2985 +	// A match on both italic-ness and presence of forward slant factor is worth 2 points.
  1.2986 +	const TInt KFontMatchScoreForExactItalicAndSlant = 2;
  1.2987 +	// A match between italic-ness in one font and presence of forward slant factor in the other is worth 1 point.
  1.2988 +	const TInt KFontSimilarScoreForItalicAndSlant = 1;
  1.2989 +	const TInt KFontMatchScoreForBold = 2;
  1.2990 +	const TInt KFontMatchScoreForBitmapType = 2;
  1.2991 +	// A match between outline or shadow effect in one font with other is worth 2 points. Its same as matching for bitmaptype.
  1.2992 +	const TInt KFontMatchScoreForOutlineOrShadow = 2;
  1.2993 +	// The monospaced/proportional status is rated higher at 3 because it has a major effect on the look and layout
  1.2994 +	const TInt KFontMatchScoreForMonoSpace = 3;
  1.2995 +	// Whether the font is serifed or not has a smaller effect on the look and layout so it is only rated at 1
  1.2996 +	const TInt KFontMatchScoreForSerif = 1;
  1.2997 +
  1.2998 +	TInt score = 0;
  1.2999 +
  1.3000 +	// Favour perfect name and height matches.	
  1.3001 +	if (0 == aCandidateFontSpec.Name().CompareF(aIdealFontSpec.Name()))
  1.3002 +		{
  1.3003 +		score += KFontMatchScoreForName;
  1.3004 +		}
  1.3005 +
  1.3006 +	// Check for max height if given, otherwise height in font spec
  1.3007 +	TInt height_diff = 0;
  1.3008 +	if (aCandidateMaxHeight && aIdealMaxHeight)
  1.3009 +		{
  1.3010 +		if (aIdealMaxHeight < aCandidateMaxHeight)
  1.3011 +			return 0;
  1.3012 +		height_diff = aIdealMaxHeight - aCandidateMaxHeight;
  1.3013 +		}
  1.3014 +	else
  1.3015 + 		{
  1.3016 +		height_diff = aIdealFontSpec.Height() - aCandidateFontSpec.Height();
  1.3017 +		if (0 > height_diff)
  1.3018 +			height_diff = -height_diff;
  1.3019 +		}
  1.3020 +	score += KFontMaxScoreForHeight - height_diff;
  1.3021 +
  1.3022 +	if (aCandidateFontSpec.IsItalic() == aIdealFontSpec.IsItalic() &&
  1.3023 +		(0 < aCandidateFontSpec.SlantFactor()) == (0 < aIdealFontSpec.SlantFactor()))
  1.3024 +		{
  1.3025 +		score += KFontMatchScoreForExactItalicAndSlant;
  1.3026 +		}
  1.3027 +	else if ((aCandidateFontSpec.IsItalic() && 0 < aIdealFontSpec.SlantFactor()) ||
  1.3028 +			 (aIdealFontSpec.IsItalic() && 0 < aCandidateFontSpec.SlantFactor()))
  1.3029 +		{
  1.3030 +		score += KFontSimilarScoreForItalicAndSlant;
  1.3031 +		}
  1.3032 +
  1.3033 +	if (aCandidateFontSpec.IsBold() == aIdealFontSpec.IsBold())
  1.3034 +		{
  1.3035 +		score += KFontMatchScoreForBold;
  1.3036 +		}
  1.3037 +	
  1.3038 +	TUint effectsFlag = aIdealFontSpec.Effects() & aCandidateFontSpec.Effects();
  1.3039 +	TBool isShadowOutlineEffects = EFalse;
  1.3040 +
  1.3041 +	if(effectsFlag & FontEffect::EOutline)
  1.3042 +		{
  1.3043 +		score += KFontMatchScoreForOutlineOrShadow;
  1.3044 +		isShadowOutlineEffects = ETrue;
  1.3045 +		}
  1.3046 +	if(effectsFlag & FontEffect::EDropShadow)
  1.3047 +		{
  1.3048 +		score += KFontMatchScoreForOutlineOrShadow;
  1.3049 +		isShadowOutlineEffects = ETrue;
  1.3050 +		}
  1.3051 +		
  1.3052 +	//Match for bitmap glyph type only when effects are off.
  1.3053 +	//BitmapType in aIdealFontSpec will be set to EFourColourBlendGlyphBitmap by rasterizer only
  1.3054 +	//when any of the effects (outline/shadow) are on and if it supports outline and shadow fonts.
  1.3055 +	if(!isShadowOutlineEffects && (aCandidateFontSpec.BitmapType() == aIdealFontSpec.BitmapType()))
  1.3056 +		{
  1.3057 +		score += KFontMatchScoreForBitmapType;
  1.3058 +		}
  1.3059 +	if (aCandidateFontSpec.IsMonoWidth() == aIdealFontSpec.IsMonoWidth())
  1.3060 +		{
  1.3061 +		score += KFontMatchScoreForMonoSpace;
  1.3062 +		}
  1.3063 +	if (aCandidateFontSpec.IsSerif() == aIdealFontSpec.IsSerif())
  1.3064 +		{
  1.3065 +		score += KFontMatchScoreForSerif;
  1.3066 +		}
  1.3067 +
  1.3068 +	return score;
  1.3069 +	}
  1.3070 +
  1.3071 +
  1.3072 +/**
  1.3073 +Find and load the nearest Open Font by
  1.3074 +1. using aDesiredFontSpec to check if its already loaded,
  1.3075 +2. using aActualFontSpec to partially match	and create a new font.
  1.3076 +Partial match means typeface name must match, other attributes need not match.
  1.3077 +Font must fit vertically within the specified max height if given.
  1.3078 +
  1.3079 +@param aFont Output, is the returned font.
  1.3080 +@param aActualFontSpec Output, is used to represent the returned font and changed to twips. 
  1.3081 +@param aDesiredFontSpec Input, the desired font specification
  1.3082 +@param aMaxHeight Input, the maximum height in Pixels, or 0
  1.3083 +@post if any Open Fonts are available this will always return something
  1.3084 +*/
  1.3085 +void CFontStore::GetNearestOpenFontInPixelsL(
  1.3086 +	CFont*&					aFont,
  1.3087 +	TOpenFontSpec&			aActualFontSpec,
  1.3088 +	const TOpenFontSpec&	aDesiredFontSpec,
  1.3089 +	TInt					aMaxHeight)
  1.3090 +	{
  1.3091 +	// Set the baseline offset appropriately for superscript or subscript.
  1.3092 +	TAlgStyle algstyle;
  1.3093 +	algstyle.iBaselineOffsetInPixels = BaselineOffset(aActualFontSpec.Height(), aActualFontSpec.PrintPosition());
  1.3094 +
  1.3095 +	// Determine if an open font with a perfect match is already loaded.
  1.3096 +	if (IsFontLoaded(aFont, algstyle, aDesiredFontSpec, aMaxHeight))
  1.3097 +		{
  1.3098 +		aActualFontSpec = aDesiredFontSpec;
  1.3099 +		}
  1.3100 +	else
  1.3101 +		{ // If not, find the nearest match for aActualFontSpec.
  1.3102 +		COpenFont* nearestFont = NULL;
  1.3103 +
  1.3104 +		// fast search, if DO_LOADFONT_OPTIMIZATION is defined, search loaded font names for match
  1.3105 +		TInt errorName=GetNearestOpenFontInPixelsByFontName(nearestFont, aActualFontSpec, aDesiredFontSpec, aMaxHeight);
  1.3106 +		TInt errorSimilar=KErrNone;
  1.3107 +
  1.3108 +		if (!nearestFont)
  1.3109 +			{
  1.3110 +			errorSimilar=GetNearestOpenFontInPixelsBySimilarity(nearestFont, aActualFontSpec, aDesiredFontSpec, aMaxHeight);
  1.3111 +			}
  1.3112 +
  1.3113 +		// If an imperfect match was found, is it already loaded? If not, create a new CBitmapFont.
  1.3114 +		if (nearestFont)
  1.3115 +			{
  1.3116 +			//
  1.3117 +			// Results of everything above are stored in nearestFont, and aActualFontSpec
  1.3118 +			// First check if the not-exactly-matched font is already loaded
  1.3119 +			// aMaxHeight is 0 to prevent duplicate CBitmapFontObjects being created
  1.3120 +			//
  1.3121 +			if (IsFontLoaded(aFont, algstyle, aActualFontSpec, 0))
  1.3122 +				{
  1.3123 +				delete nearestFont;
  1.3124 +				}
  1.3125 +			else
  1.3126 +				{
  1.3127 +				// Set the specification of the nearest match in twips.
  1.3128 +				TOpenFontSpec openFontSpec(aActualFontSpec);
  1.3129 +				openFontSpec.SetHeight(VerticalPixelsToTwips(openFontSpec.Height()));
  1.3130 +				CleanupStack::PushL(nearestFont);
  1.3131 +				aFont = NewFontL(openFontSpec, algstyle, nearestFont);
  1.3132 +				CleanupStack::Pop(nearestFont);
  1.3133 +				}
  1.3134 +			}
  1.3135 +		else
  1.3136 +			{
  1.3137 +			User::LeaveIfError(errorSimilar);
  1.3138 +			User::LeaveIfError(errorName);
  1.3139 +			}
  1.3140 +		}
  1.3141 +	}
  1.3142 +
  1.3143 +
  1.3144 +/** Using the Desired Font Name try to find a matching font.
  1.3145 +
  1.3146 +@param aNearestOpenFont Output, nearest matching open font
  1.3147 +@param aActualFontSpec Output, is used to represent the returned font 
  1.3148 +@param aDesiredFontSpec Input, the desired font specification
  1.3149 +@param aMaxHeight Input, the maximum height in Pixels, or 0
  1.3150 +*/
  1.3151 +#if(DO_LOADFONT_OPTIMIZATION)
  1.3152 +TInt CFontStore::GetNearestOpenFontInPixelsByFontName(
  1.3153 +	COpenFont*&				aOpenFont,
  1.3154 +	TOpenFontSpec&			aActualFontSpec,
  1.3155 +	const TOpenFontSpec&	aDesiredFontSpec,
  1.3156 +	TInt					aMaxHeight)
  1.3157 +	{
  1.3158 +	TOpenFontSpec actualFontSpec;
  1.3159 +	COpenFont* nearestFont = NULL;
  1.3160 +
  1.3161 +	if (aMaxHeight == 0 && aDesiredFontSpec.Name().Length() > 0)	// check if it is a request for OpenFont
  1.3162 +		{
  1.3163 +		TPtrC requestedName = aDesiredFontSpec.Name();
  1.3164 +		// Typeface files may contain all those typefaces in a family, or may contain only some.
  1.3165 +		// The optimization first tries the ShortFullName of the typeface in case the typefaces are
  1.3166 +		// put into separate files.
  1.3167 +		
  1.3168 +		// First check FullName. The following assumes that there are never two COpenFontFiles in the 
  1.3169 +		// list with the same ShortFullName. So italic and bold flags are not checked.
  1.3170 +
  1.3171 +		const TInt openFontFileCount = iOpenFontFileList.Count();
  1.3172 +		TInt index;
  1.3173 +		TInt typicalError = KErrNone;
  1.3174 +		for (index = 0; index < openFontFileCount; index++)
  1.3175 +			{
  1.3176 +			COpenFontFile *pFile = iOpenFontFileList[index]; 
  1.3177 +			const TOpenFontFaceAttrib &faceAttrib = pFile->FaceAttrib(0);
  1.3178 +			
  1.3179 +			// Use short names. They are truncated to the same length as the request in TTypeface
  1.3180 +			if ((faceAttrib.ShortFullName().CompareF(requestedName)==0) &&
  1.3181 +				(faceAttrib.IsBold() == aActualFontSpec.IsBold()) &&
  1.3182 +				(faceAttrib.IsItalic() == aActualFontSpec.IsItalic()) )			
  1.3183 +				{
  1.3184 +				TInt error=pFile->GetNearestFontToDesignHeightInPixels(
  1.3185 +					iHeap, iOpenFontSessionCacheList, aActualFontSpec, iKPixelWidthInTwips,
  1.3186 +					iKPixelHeightInTwips, nearestFont, actualFontSpec);				
  1.3187 +
  1.3188 +				// search has finished if a match was found
  1.3189 +				if (nearestFont)
  1.3190 +					{
  1.3191 +					// need to copy the actual to the value that is going to be used down below
  1.3192 +					// to make a new font
  1.3193 +					aOpenFont = nearestFont;
  1.3194 +					aActualFontSpec = actualFontSpec;
  1.3195 +					return KErrNone;
  1.3196 +					}
  1.3197 +				else
  1.3198 +					{
  1.3199 +					if (error)
  1.3200 +						{
  1.3201 +						typicalError=error;
  1.3202 +						}
  1.3203 +					}
  1.3204 +				}
  1.3205 +			}
  1.3206 +
  1.3207 +		// If the FullName match above has failed, then the request is being made by
  1.3208 +		// something other than a full name (assuming typeface is present).
  1.3209 +		// Although there may be more than one typeface in a file,
  1.3210 +		// It is not possible to conclude that ALL typefaces of the family are in one file.
  1.3211 +		// So to be safe, checks are made on italic and bold, possibly downgrading the optimization.
  1.3212 +		// Use short names. They are truncated to the same length as the request in TTypeface
  1.3213 +		for (index = 0; index < openFontFileCount; index++)
  1.3214 +			{
  1.3215 +			COpenFontFile *pFile = iOpenFontFileList[index]; 
  1.3216 +			const TOpenFontFaceAttrib &faceAttrib = pFile->FaceAttrib(0);
  1.3217 +
  1.3218 +			if(	(faceAttrib.ShortFamilyName().CompareF(requestedName) == 0) &&
  1.3219 +				(faceAttrib.IsItalic() == aDesiredFontSpec.IsItalic()) &&
  1.3220 +				(faceAttrib.IsBold() == aDesiredFontSpec.IsBold()) )	
  1.3221 +				{
  1.3222 +				TInt error=pFile->GetNearestFontToDesignHeightInPixels(
  1.3223 +					iHeap, iOpenFontSessionCacheList, aActualFontSpec, iKPixelWidthInTwips,
  1.3224 +					iKPixelHeightInTwips, nearestFont, actualFontSpec);
  1.3225 +
  1.3226 +				// search has finished if a match was found
  1.3227 +				if (nearestFont)
  1.3228 +					{
  1.3229 +					// need to copy the actual to the value that is going to be used down below
  1.3230 +					// to make a new font
  1.3231 +					aOpenFont = nearestFont;
  1.3232 +					aActualFontSpec = actualFontSpec;
  1.3233 +					return KErrNone;
  1.3234 +					}
  1.3235 +				else
  1.3236 +					{
  1.3237 +					if (error)
  1.3238 +						{
  1.3239 +						typicalError=error;
  1.3240 +						}
  1.3241 +					}
  1.3242 +				}
  1.3243 +			}
  1.3244 +		// no match
  1.3245 +		return typicalError;
  1.3246 +		}
  1.3247 +	// not open request
  1.3248 +	return KErrNone;
  1.3249 +	}
  1.3250 +#else
  1.3251 +TInt CFontStore::GetNearestOpenFontInPixelsByFontName(
  1.3252 +	COpenFont*&				/* aOpenFont */,
  1.3253 +	TOpenFontSpec&			/* aActualFontSpec */,
  1.3254 +	const TOpenFontSpec&	/* aDesiredFontSpec */,
  1.3255 +	TInt					/* aMaxHeight*/)
  1.3256 +	{ // no match
  1.3257 +	return KErrNone;
  1.3258 +	}
  1.3259 +#endif
  1.3260 +
  1.3261 +
  1.3262 +/** Using the Desired Font Name try to find a matching font.
  1.3263 +
  1.3264 +@param aNearestOpenFont Output, nearest matching open font
  1.3265 +@param aActualFontSpec Output, is used to represent the returned font 
  1.3266 +@param aDesiredFontSpec Input, the desired font specification
  1.3267 +@param aMaxHeight Input, the maximum height in Pixels, or 0
  1.3268 +*/
  1.3269 +TInt CFontStore::GetNearestOpenFontInPixelsBySimilarity(
  1.3270 +	COpenFont*&				aNearestOpenFont,
  1.3271 +	TOpenFontSpec&			aActualFontSpec,
  1.3272 +	const TOpenFontSpec&	aDesiredFontSpec,
  1.3273 +	TInt					aMaxHeight)
  1.3274 +	{
  1.3275 +	const TInt openFontFileCount = iOpenFontFileList.Count();
  1.3276 +	TOpenFontSpec nearestFontSpec;
  1.3277 +	COpenFont* nearestFont = NULL;
  1.3278 +	TInt nearestMatch = 0;
  1.3279 +    TInt typicalError=KErrNone;
  1.3280 +	for (TInt index = 0; index < openFontFileCount; index++)
  1.3281 +		{
  1.3282 +		// ask font file for its best match, if any
  1.3283 +		COpenFont* candidateFont = NULL;
  1.3284 +		TOpenFontSpec actualFontSpec;
  1.3285 +		TInt lastError=KErrNone;
  1.3286 +		if (aMaxHeight)
  1.3287 +			{
  1.3288 +			lastError=iOpenFontFileList[index]->GetNearestFontToMaxHeightInPixels(
  1.3289 +				iHeap, iOpenFontSessionCacheList, aActualFontSpec, iKPixelWidthInTwips,
  1.3290 +				iKPixelHeightInTwips, candidateFont, actualFontSpec, aMaxHeight);
  1.3291 +			}
  1.3292 +		else
  1.3293 +			{
  1.3294 +			lastError=iOpenFontFileList[index]->GetNearestFontToDesignHeightInPixels(
  1.3295 +				iHeap, iOpenFontSessionCacheList, aActualFontSpec, iKPixelWidthInTwips,
  1.3296 +				iKPixelHeightInTwips, candidateFont, actualFontSpec);
  1.3297 +			}
  1.3298 +
  1.3299 +		// hold on to the best overall match
  1.3300 +		if (candidateFont)
  1.3301 +			{
  1.3302 +			const TInt candidateMatch = MatchFontSpecsInPixels(
  1.3303 +				actualFontSpec, aDesiredFontSpec, candidateFont->FontMaxHeight(), aMaxHeight);
  1.3304 +
  1.3305 +			if (NULL == nearestFont || candidateMatch > nearestMatch)
  1.3306 +				{
  1.3307 +				if (nearestFont)
  1.3308 +					{
  1.3309 +					delete nearestFont;
  1.3310 +					}
  1.3311 +				nearestFont = candidateFont;
  1.3312 +				nearestMatch = candidateMatch;
  1.3313 +				nearestFontSpec	= actualFontSpec;
  1.3314 +				}
  1.3315 +			else
  1.3316 +				{
  1.3317 +				// Font match is no better than the current nearestFont
  1.3318 +				//
  1.3319 +				// Note this object is newed in GetNearestFontInPixels each time 
  1.3320 +				// a matching font is found.
  1.3321 +				delete candidateFont;
  1.3322 +				}
  1.3323 +			}
  1.3324 +		else
  1.3325 +			{
  1.3326 +			if (lastError)
  1.3327 +				{
  1.3328 +				typicalError=lastError;
  1.3329 +				}
  1.3330 +			}
  1.3331 +		}
  1.3332 +
  1.3333 +	if (nearestFont != NULL)
  1.3334 +		{ // result
  1.3335 +		aNearestOpenFont = nearestFont;
  1.3336 +		aActualFontSpec = nearestFontSpec;
  1.3337 +		return KErrNone;
  1.3338 +		}
  1.3339 +	else
  1.3340 +		{
  1.3341 +		return typicalError;
  1.3342 +		}
  1.3343 +	}
  1.3344 +
  1.3345 +
  1.3346 +/**
  1.3347 +Get the nearest bitmap font to aFontSpec and place it in aFont. Font must 
  1.3348 +fit vertically inside specified maximum height if given. GetNearestTypeface is
  1.3349 +called which insists that there is at least one typeface. This function will always 
  1.3350 +succeed unless there is an out-of-memory error or other abnormal error. 
  1.3351 +Change aFontSpec to represent the returned font and change it to twips.
  1.3352 +*/
  1.3353 +void CFontStore::GetNearestBitmapFontInPixelsL(
  1.3354 +	CFont*&		aFont,
  1.3355 +	TFontSpec&	aFontSpec,
  1.3356 +	TInt		aMaxHeight)
  1.3357 +	{
  1.3358 +	aFontSpec.iTypeface = *GetNearestTypeface(aFontSpec.iTypeface);
  1.3359 +	TTypefaceFontBitmap tffb = GetNearestTypefaceFontBitmap(aFontSpec, aMaxHeight);
  1.3360 +	const TInt height = tffb.HeightInPixels();
  1.3361 +	if (aFontSpec.iFontStyle.PrintPosition() != EPrintPosNormal)
  1.3362 +		{
  1.3363 +		aFontSpec.iHeight = SuperSubHeight(height, aFontSpec.iFontStyle.PrintPosition());
  1.3364 +		tffb = GetNearestTypefaceFontBitmap(aFontSpec, aMaxHeight);
  1.3365 +		}
  1.3366 +	aFontSpec.iHeight = height;
  1.3367 +	TAlgStyle algstyle;
  1.3368 +	algstyle.SetIsBold(
  1.3369 +		EStrokeWeightBold == aFontSpec.iFontStyle.StrokeWeight() &&
  1.3370 +		EStrokeWeightNormal == tffb.iFontBitmap->StrokeWeight());
  1.3371 +	algstyle.SetIsItalic(
  1.3372 +		EPostureItalic == aFontSpec.iFontStyle.Posture() &&
  1.3373 +		EPostureUpright == tffb.iFontBitmap->Posture());
  1.3374 +	algstyle.SetIsMono(!aFontSpec.iTypeface.IsProportional() && tffb.iFontBitmap->IsProportional());
  1.3375 +	TInt widthfactor =
  1.3376 +		((tffb.iWidthFactor * tffb.iFontBitmap->FontStoreFile()->iKPixelAspectRatio * iKPixelWidthInTwips) + (500 * iKPixelHeightInTwips)) / (1000 * iKPixelHeightInTwips);
  1.3377 +	if (!widthfactor)
  1.3378 +		widthfactor = 1;
  1.3379 +	algstyle.SetWidthFactor(widthfactor);
  1.3380 +	algstyle.SetHeightFactor( tffb.iHeightFactor );
  1.3381 +	algstyle.iBaselineOffsetInPixels = BaselineOffset(height, aFontSpec.iFontStyle.PrintPosition());
  1.3382 +	if (IsFontLoaded(aFont, algstyle, aFontSpec, tffb.iFontBitmap->iUid))
  1.3383 +		return;
  1.3384 +	TFontSpec spec(aFontSpec);
  1.3385 +	spec.iHeight = VerticalPixelsToTwips(height);
  1.3386 +	spec.iFontStyle.SetBitmapType(EMonochromeGlyphBitmap);
  1.3387 +	aFont = NewFontL(spec, algstyle, tffb.iFontBitmap);
  1.3388 +	}
  1.3389 +
  1.3390 +/**
  1.3391 +Gets the font which is the nearest to the given font specification.
  1.3392 +
  1.3393 +Note that this deprecated function is replaced by the new @c GetNearestFontToDesignHeightInPixels() 
  1.3394 +yielding (virtually) the same result. However clients are strongly encouraged to use the new
  1.3395 +@c GetNearestFontToMaxHeightInPixels() function instead. This will guarantee that every 
  1.3396 +character within any given text string will fit within the given amount of pixels, whereas the design 
  1.3397 +height is an aesthetic unit decided by the font designer without strict physical meaning, which 
  1.3398 +may result in cropped characters.
  1.3399 +
  1.3400 +@param aFont On return, contains a pointer to the nearest font.
  1.3401 +@param aFontSpec The specification of the font to be matched.
  1.3402 +@return KErrNone if successful; a system-wide error code otherwise.
  1.3403 +@publishedAll
  1.3404 +@deprecated Use GetNearestFontToDesignHeightInPixels
  1.3405 +*/
  1.3406 +EXPORT_C TInt CFontStore::GetNearestFontInPixels(CFont*& aFont, const TFontSpec& aFontSpec)
  1.3407 +	{
  1.3408 +	return GetNearestFontToDesignHeightInPixels(aFont, aFontSpec);
  1.3409 +	}
  1.3410 +
  1.3411 +/**
  1.3412 +Gets the font which is the nearest to the given font specification.
  1.3413 +
  1.3414 +Note that this deprecated function is replaced by the new @c GetNearestFontToDesignHeightInPixels() 
  1.3415 +yielding (virtually) the same result. However clients are strongly encouraged to use the new
  1.3416 +@c GetNearestFontToMaxHeightInPixels() function instead. This will guarantee that every 
  1.3417 +character within any given text string will fit within the given amount of pixels, whereas the design 
  1.3418 +height is an aesthetic unit decided by the font designer without strict physical meaning, which 
  1.3419 +may result in cropped characters.
  1.3420 +
  1.3421 +@param aFont On return, contains a pointer to the nearest font.
  1.3422 +@param aFontSpec The specification of the font to be matched.
  1.3423 +@return KErrNone if successful; a system-wide error code otherwise.
  1.3424 +@publishedAll
  1.3425 +@deprecated Use GetNearestFontToDesignHeightInPixels
  1.3426 +*/
  1.3427 +EXPORT_C TInt CFontStore::GetNearestFontInPixels(CFont*& aFont, const TOpenFontSpec& aFontSpec)
  1.3428 +	{
  1.3429 +	return GetNearestFontToDesignHeightInPixels(aFont, aFontSpec);
  1.3430 +	}
  1.3431 +
  1.3432 +/**
  1.3433 +Gets the font which is the nearest to the given font specification.
  1.3434 +
  1.3435 +This new function replaces the deprecated @c GetNearestFontInPixels() yielding (virtually) the 
  1.3436 +same result. However clients are strongly encouraged to use the new
  1.3437 +@c GetNearestFontToMaxHeightInPixels() function instead. This will guarantee that every 
  1.3438 +character within any given text string will fit within the given amount of pixels, whereas the design 
  1.3439 +height is an aesthetic unit decided by the font designer without strict physical meaning, which 
  1.3440 +may result in cropped characters.
  1.3441 +
  1.3442 +@param aFont On return, contains a pointer to the nearest font.
  1.3443 +@param aFontSpec The specification of the font to be matched.
  1.3444 +@return KErrNone if successful; a system-wide error code otherwise.
  1.3445 +@publishedAll
  1.3446 +@released
  1.3447 +*/
  1.3448 +EXPORT_C TInt CFontStore::GetNearestFontToDesignHeightInPixels(CFont*& aFont, const TFontSpec& aFontSpec)
  1.3449 +	{
  1.3450 +	TOpenFontSpec spec(aFontSpec);
  1.3451 +	return GetNearestFontToDesignHeightInPixels(aFont, spec);
  1.3452 +	}
  1.3453 +
  1.3454 +/**
  1.3455 +Gets the font which is the nearest to the given font specification.
  1.3456 +
  1.3457 +This new function replaces the deprecated @c GetNearestFontInPixels() yielding (virtually) the 
  1.3458 +same result. However clients are strongly encouraged to use the new
  1.3459 +@c GetNearestFontToMaxHeightInPixels() function instead. This will guarantee that every 
  1.3460 +character within any given text string will fit within the given amount of pixels, whereas the design 
  1.3461 +height is an aesthetic unit decided by the font designer without strict physical meaning, which 
  1.3462 +may result in cropped characters.
  1.3463 +
  1.3464 +@param aFont On return, contains a pointer to the nearest font.
  1.3465 +@param aFontSpec The specification of the font to be matched.
  1.3466 +@return KErrNone if successful; a system-wide error code otherwise.
  1.3467 +@publishedAll
  1.3468 +@released
  1.3469 +*/
  1.3470 +EXPORT_C TInt CFontStore::GetNearestFontToDesignHeightInPixels(CFont*& aFont, const TOpenFontSpec& aFontSpec)
  1.3471 +	{
  1.3472 +	return GetNearestFontInPixels(aFont, aFontSpec, 0);
  1.3473 +	}
  1.3474 +
  1.3475 +/**
  1.3476 +Gets the font which is the nearest to the given font specification.
  1.3477 +
  1.3478 +The font and bitmap server returns a pointer to the nearest matching font 
  1.3479 +from those available. Matches to max height of font - this does its best 
  1.3480 +to return a font that will fit within the maximum height specified (but 
  1.3481 +note that variations due to hinting algorithms may rarely result in this 
  1.3482 +height being exceeded by up to one pixel). Problems can also be 
  1.3483 +encountered with bitmap fonts where the typeface exists but doesn't have 
  1.3484 +a font small enough.
  1.3485 +
  1.3486 +@param aFont On return, contains a pointer to the nearest font.
  1.3487 +@param aFontSpec The specification of the font to be matched.
  1.3488 +@param aMaxHeight The maximum height within which the font must fit. If maximum height
  1.3489 +is greater than 1024 pixels, the function returns KErrTooBig. And returns KErrArgument
  1.3490 +if equals to 1 pixel. This overrides the height specified in aFontSpec.
  1.3491 +@return KErrNone if successful; a system-wide error code otherwise.
  1.3492 +@publishedAll
  1.3493 +@released
  1.3494 +*/
  1.3495 +EXPORT_C TInt CFontStore::GetNearestFontToMaxHeightInPixels(CFont*& aFont, const TFontSpec& aFontSpec, TInt aMaxHeight)
  1.3496 +	{
  1.3497 +	TOpenFontSpec spec(aFontSpec);
  1.3498 +	return GetNearestFontToMaxHeightInPixels(aFont, spec, aMaxHeight);
  1.3499 +	}
  1.3500 +
  1.3501 +/**
  1.3502 +Gets the font which is the nearest to the given font specification.
  1.3503 +
  1.3504 +The font and bitmap server returns a pointer to the nearest matching font 
  1.3505 +from those available. Matches to max height of font - this does its best 
  1.3506 +to return a font that will fit within the maximum height specified (but 
  1.3507 +note that variations due to hinting algorithms may rarely result in this 
  1.3508 +height being exceeded by up to one pixel). Problems can also be 
  1.3509 +encountered with bitmap fonts where the typeface exists but doesn't have 
  1.3510 +a font small enough.
  1.3511 +
  1.3512 +@param aFont On return, contains a pointer to the nearest font.
  1.3513 +@param aFontSpec The specification of the font to be matched.
  1.3514 +@param aMaxHeight The maximum height within which the font must fit. If maximum height
  1.3515 +is greater than 1024 pixels, the function returns KErrTooBig. And returns KErrArgument
  1.3516 +if equals to 1 pixel. This overrides the height specified in aFontSpec.
  1.3517 +@return KErrNone if successful; a system-wide error code otherwise.
  1.3518 +@publishedAll
  1.3519 +@released
  1.3520 +*/
  1.3521 +EXPORT_C TInt CFontStore::GetNearestFontToMaxHeightInPixels(CFont*& aFont, const TOpenFontSpec& aFontSpec, TInt aMaxHeight)
  1.3522 +	{
  1.3523 +	if (KMaxFontHeightInPixels < aMaxHeight)
  1.3524 +		{
  1.3525 +		return KErrTooBig;
  1.3526 +		}
  1.3527 +	if (aMaxHeight > 0 && aMaxHeight < KMinFontHeightInPixels)
  1.3528 +		{
  1.3529 +		return KErrArgument;
  1.3530 +		}
  1.3531 +	return GetNearestFontInPixels(aFont, aFontSpec, aMaxHeight);
  1.3532 +	}
  1.3533 +
  1.3534 +TInt CFontStore::GetNearestFontInPixels(
  1.3535 +	CFont*&					aFont,
  1.3536 +	const TOpenFontSpec&	aDesiredFontSpec,
  1.3537 +	TInt					aMaxHeight)
  1.3538 +	{
  1.3539 +	aFont = NULL;
  1.3540 +
  1.3541 +	// Determine the ideal version of the font spec.
  1.3542 +	TOpenFontSpec originalFontSpec = aDesiredFontSpec;
  1.3543 +	originalFontSpec.CompensateForAspectRatio(iKPixelWidthInTwips, iKPixelHeightInTwips);
  1.3544 +	TOpenFontSpec desiredFontSpec = originalFontSpec;
  1.3545 +	if (EDefaultGlyphBitmap == desiredFontSpec.BitmapType())
  1.3546 +		{
  1.3547 +		desiredFontSpec.SetBitmapType(iDefaultBitmapType);
  1.3548 +		}
  1.3549 +	if (EPrintPosNormal != desiredFontSpec.PrintPosition())
  1.3550 +		{
  1.3551 +		desiredFontSpec.SetHeight(SuperSubHeight(desiredFontSpec.Height(), desiredFontSpec.PrintPosition()));
  1.3552 +		}
  1.3553 +	TOpenFontSpec actualOpenFontSpec = desiredFontSpec;
  1.3554 +
  1.3555 +	// Try to get an open font.
  1.3556 +	CFont* openFont = NULL;
  1.3557 +	TRAPD(error, GetNearestOpenFontInPixelsL(
  1.3558 +		openFont, actualOpenFontSpec, desiredFontSpec, aMaxHeight));
  1.3559 +
  1.3560 +	// Try to get a bitmap font - if getting open font failed or the match was not perfect.
  1.3561 +	CFont* bitmapFont = NULL;
  1.3562 +	TInt errorBitmap=KErrNone;
  1.3563 +	TOpenFontSpec actualBitmapFontSpec;
  1.3564 +	if (error || !openFont || actualOpenFontSpec != desiredFontSpec)
  1.3565 +		{
  1.3566 +		TFontSpec f;
  1.3567 +		originalFontSpec.GetTFontSpec(f);
  1.3568 +		if (iTypefaceList.Count() > 0)
  1.3569 +			{
  1.3570 +			TRAP(errorBitmap, GetNearestBitmapFontInPixelsL(bitmapFont, f, aMaxHeight));
  1.3571 +			}
  1.3572 +		actualBitmapFontSpec = f;
  1.3573 +		actualBitmapFontSpec.CompensateForAspectRatio(iKPixelWidthInTwips, iKPixelHeightInTwips);
  1.3574 +		}
  1.3575 +
  1.3576 +	//If both attempts fail then there is nothing more we can do...
  1.3577 +	if (!openFont && !bitmapFont)
  1.3578 +		{
  1.3579 +		//If an error caused no fonts to be returned then forward the error
  1.3580 +		if (error)
  1.3581 +			return error;
  1.3582 +		if (errorBitmap)
  1.3583 +			return errorBitmap;
  1.3584 +		}
  1.3585 +	// Choose the best candidate
  1.3586 +	if (NULL == openFont && NULL == bitmapFont)
  1.3587 +		{
  1.3588 +		// Try to get an open font again - unnamed font.
  1.3589 +		// See COpenFontFile::GetNearestFontHelper - how it works with unnamed fonts.
  1.3590 +		actualOpenFontSpec.SetName(KNullDesC);
  1.3591 +		TRAP(error, GetNearestOpenFontInPixelsL(
  1.3592 +			openFont, actualOpenFontSpec, desiredFontSpec, aMaxHeight));
  1.3593 +		if (KErrNone == error && openFont)
  1.3594 +			{
  1.3595 +			aFont = openFont;
  1.3596 +			return KErrNone;
  1.3597 +			}
  1.3598 +		else
  1.3599 +			{
  1.3600 +			OstTraceExt2( TRACE_FATAL, CFONTSTORE_GETNEARESTFONTINPIXELS, "GetNearestOpenFontInPixelsL() return %d, openFont is 0x%x, Panic(EFntNoFontFound)",
  1.3601 +			        error, (unsigned int)openFont);
  1.3602 +			__ASSERT_DEBUG(0, Panic(EFntNoFontFound));
  1.3603 +			return KErrGeneral;
  1.3604 +			}
  1.3605 +		}
  1.3606 +	else if (NULL == openFont)
  1.3607 +		{
  1.3608 +		if (actualBitmapFontSpec.Name().CompareF(desiredFontSpec.Name()) != 0)
  1.3609 +			{
  1.3610 +			// Try to get the nearest open font - because no exact bitmap font match for typeface name
  1.3611 +			actualOpenFontSpec.SetName(KNullDesC);
  1.3612 +			desiredFontSpec.SetName(KNullDesC);
  1.3613 +			TRAPD(errorOpen, GetNearestOpenFontInPixelsL(
  1.3614 +				openFont, actualOpenFontSpec, desiredFontSpec, aMaxHeight));
  1.3615 +			if (KErrNone == errorOpen && openFont)
  1.3616 +				{
  1.3617 +				aFont = openFont;
  1.3618 +				ReleaseFont(bitmapFont);
  1.3619 +				}
  1.3620 +			}
  1.3621 +		if (aFont == NULL)
  1.3622 +			{
  1.3623 +			aFont = bitmapFont;
  1.3624 +			}
  1.3625 +		}
  1.3626 +	else if (NULL == bitmapFont)
  1.3627 +		{
  1.3628 +		aFont = openFont;
  1.3629 +		}
  1.3630 +
  1.3631 +	if (aFont == NULL)
  1.3632 +		{
  1.3633 +		// Pick the closest match; for backward compatibility prefer a bitmap font if there is a dead heat.
  1.3634 +		const TInt open_match = MatchFontSpecsInPixels(
  1.3635 +			actualOpenFontSpec, desiredFontSpec, openFont->FontMaxHeight(), aMaxHeight);
  1.3636 +		const TInt bitmap_match = MatchFontSpecsInPixels(
  1.3637 +			actualBitmapFontSpec, desiredFontSpec, bitmapFont->FontMaxHeight(), aMaxHeight);
  1.3638 +		if (open_match > bitmap_match)
  1.3639 +			{
  1.3640 +			aFont = openFont;
  1.3641 +			ReleaseFont(bitmapFont);
  1.3642 +			}
  1.3643 +		else
  1.3644 +			{
  1.3645 +			aFont = bitmapFont;
  1.3646 +			ReleaseFont(openFont);
  1.3647 +			}
  1.3648 +		}
  1.3649 +	return KErrNone;
  1.3650 +	}
  1.3651 +
  1.3652 +/** Gets a bitmap font using the given font UID and algorithmic style.
  1.3653 +
  1.3654 +Tries to find a bitmap font in the font store with the given UID. If successful, 
  1.3655 +the given algorithmic style is applied to the font and this font (which may 
  1.3656 +be a suitable one already existing in the store, or may be a newly generated 
  1.3657 +font) is stored in aFont. If unsuccessful then no font is stored in aFont.
  1.3658 +
  1.3659 +@param aFont On return, a device-dependent font.
  1.3660 +@param aUid A bitmap font UID.
  1.3661 +@param aAlgStyle An algorithmic style to apply to the font.
  1.3662 +@return KErrNone if the font is found, KErrNotFound if the font is not found, 
  1.3663 +or another system-wide error code. */
  1.3664 +EXPORT_C TInt CFontStore::GetFontById(
  1.3665 +	CFont*&				aFont,
  1.3666 +	TUid				aUid,
  1.3667 +	const TAlgStyle&	aAlgStyle)
  1.3668 +	{
  1.3669 +	aFont = NULL;
  1.3670 +	CFontBitmap* fontbitmap = GetFontBitmapById(aUid);
  1.3671 +	if (!fontbitmap)
  1.3672 +		{
  1.3673 +		return KErrNotFound;
  1.3674 +		}
  1.3675 +
  1.3676 +	const TInt height = fontbitmap->iCellHeightInPixels * aAlgStyle.HeightFactor();
  1.3677 +	TFontSpec fontspec;
  1.3678 +	fontspec.iHeight=height;	//Otherwise IsFontLoaded() compares with zero height!!!
  1.3679 +	fontspec.iTypeface.SetIsProportional(!aAlgStyle.IsMono() && fontbitmap->IsProportional());
  1.3680 +	if (aAlgStyle.IsBold() || EStrokeWeightBold == fontbitmap->StrokeWeight())
  1.3681 +		{
  1.3682 +		fontspec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
  1.3683 +		}
  1.3684 +	if (aAlgStyle.IsItalic() || EPostureItalic == fontbitmap->Posture())
  1.3685 +		{
  1.3686 +		fontspec.iFontStyle.SetPosture(EPostureItalic);
  1.3687 +		}
  1.3688 +	if (IsFontLoaded(aFont, aAlgStyle, fontspec, fontbitmap->iUid))
  1.3689 +		{
  1.3690 +		return KErrNone;
  1.3691 +		}
  1.3692 +
  1.3693 +	// Fill in the typeface by finding a typeface with the same font bitmap.
  1.3694 +	fontspec.iHeight = VerticalPixelsToTwips(height);
  1.3695 +	const TInt n = iTypefaceFontBitmapList.Count();
  1.3696 +	for (TInt i = 0; i < n; i++)
  1.3697 +		{
  1.3698 +		if (iTypefaceFontBitmapList[i].iFontBitmap == fontbitmap)
  1.3699 +			{
  1.3700 +			fontspec.iTypeface = *iTypefaceFontBitmapList[i].iTypeface;
  1.3701 +			break;
  1.3702 +			}
  1.3703 +		}
  1.3704 +	TRAPD(ret, aFont = NewFontL(fontspec, aAlgStyle, fontbitmap));
  1.3705 +	return ret;
  1.3706 +	}
  1.3707 +
  1.3708 +/** Gets the number of typefaces held in the font store.
  1.3709 +
  1.3710 +Note that this includes both open font typefaces and non-scalable typefaces.
  1.3711 +
  1.3712 +@return The number of supported typefaces. */
  1.3713 +EXPORT_C TInt CFontStore::NumTypefaces() const
  1.3714 +	{
  1.3715 +	return iTypefaceList.Count() + iOpenFontTypefaceSupportList.Count();
  1.3716 +	}
  1.3717 +
  1.3718 +/** Gets a typeface support object for the typeface in the font store represented 
  1.3719 +by the given index.
  1.3720 +
  1.3721 +Returns benignly with an empty TTypefaceSupport if the index is too high; 
  1.3722 +this can happen if another process removes a typeface after the first process 
  1.3723 +has already got the number of typefaces. However, if the aTypefaceIndex<0 
  1.3724 +the function panics with EFntTypefaceIndexOutOfRange.
  1.3725 +
  1.3726 +@param aTypefaceSupport On return, a typeface support object.
  1.3727 +@param aTypefaceIndex An index number representing a typeface, which is valid 
  1.3728 +if in the range 0 to (NumTypefaces() - 1). */
  1.3729 +EXPORT_C void CFontStore::TypefaceSupport(TTypefaceSupport &aTypefaceSupport,TInt aTypefaceIndex) const
  1.3730 +	{
  1.3731 +	if (aTypefaceIndex < 0)
  1.3732 +		Panic(EFntTypefaceIndexOutOfRange);
  1.3733 +
  1.3734 +	/*
  1.3735 +	Return benignly with an empty TTypefaceSupport if the index is too high; this can happen if another
  1.3736 +	process removes a font after the first process has already got the number of typefaces.
  1.3737 +	*/
  1.3738 +	int typefaces = NumTypefaces();
  1.3739 +	if (aTypefaceIndex >= typefaces)
  1.3740 +		{
  1.3741 +		aTypefaceSupport = TTypefaceSupport();
  1.3742 +		return;
  1.3743 +		}
  1.3744 +
  1.3745 +	//now return Typeface Support for Open Fonts
  1.3746 +	if (aTypefaceIndex >= iTypefaceList.Count())
  1.3747 +		{
  1.3748 +		// copy Open Font typeface details
  1.3749 +		aTypefaceSupport = *iOpenFontTypefaceSupportList[aTypefaceIndex - iTypefaceList.Count()]->TypefaceSupport();
  1.3750 +		return;
  1.3751 +		}
  1.3752 +	
  1.3753 +	if (!((aTypefaceIndex >= 0) && (aTypefaceIndex < iTypefaceList.Count())))
  1.3754 +	    {
  1.3755 +	    OstTraceExt2( TRACE_FATAL, CFONTSTORE_TYPEFACESUPPORT, "aTypefaceIndex=%d, iTypefaceList.Count()=%d Panic(EFntTypefaceIndexOutOfRange)",
  1.3756 +	            aTypefaceIndex, iTypefaceList.Count());
  1.3757 +	    __ASSERT_DEBUG(0,Panic(EFntTypefaceIndexOutOfRange));
  1.3758 +	    }
  1.3759 +	TTypeface* typeface = iTypefaceList[aTypefaceIndex];
  1.3760 +	aTypefaceSupport.iTypeface = *typeface;
  1.3761 +	TInt count = iTypefaceFontBitmapList.Count();
  1.3762 +	TInt i;
  1.3763 +	for(i = 0; i < count && iTypefaceFontBitmapList[i].iTypeface != typeface; i++)
  1.3764 +		{  // Finds first fontbitmap with correct typeface
  1.3765 +		}
  1.3766 +	aTypefaceSupport.iMinHeightInTwips = VerticalPixelsToTwips(iTypefaceFontBitmapList[i].HeightInPixels()); 
  1.3767 +	aTypefaceSupport.iNumHeights=0;
  1.3768 +	TInt height=0;
  1.3769 +	for(; (i<count) && (typeface == iTypefaceFontBitmapList[i].iTypeface); i++)
  1.3770 +		if (height != iTypefaceFontBitmapList[i].HeightInPixels())
  1.3771 +			{
  1.3772 +			height = iTypefaceFontBitmapList[i].HeightInPixels();
  1.3773 +			aTypefaceSupport.iNumHeights++;
  1.3774 +			}
  1.3775 +	aTypefaceSupport.iMaxHeightInTwips=VerticalPixelsToTwips(height);
  1.3776 +	aTypefaceSupport.iIsScalable = EFalse;
  1.3777 +	}
  1.3778 +
  1.3779 +/** Returns a font height, in twips, for a certain typeface and height index.
  1.3780 +
  1.3781 +The font height is a height allowed for the typeface represented by aTypefaceIndex. 
  1.3782 +The height returned increases with aHeightIndex.
  1.3783 +
  1.3784 +If aTypefaceIndex<0 the function panics with EFntTypefaceIndexOutOfRange. 
  1.3785 +If aTypefaceIndex is greater than the number of typefaces or aHeightIndex<0 
  1.3786 +then the function returns 0. If aHeightIndex is greater than the number of 
  1.3787 +heights then the function returns the biggest height. 
  1.3788 +
  1.3789 +@param aTypefaceIndex An index number representing a typeface, which is valid 
  1.3790 +in the range 0 to (NumTypefaces() - 1).
  1.3791 +@param aHeightIndex A font height index number, which is valid in the range 
  1.3792 +0 to (TTypefaceSupport::iNumHeights - 1). Note that the typeface support object 
  1.3793 +for the typeface can be got using TypefaceSupport(). 
  1.3794 +@return The height of a font, in twips.
  1.3795 +@see TypefaceSupport()
  1.3796 +*/
  1.3797 +EXPORT_C TInt CFontStore::FontHeightInTwips(TInt aTypefaceIndex,TInt aHeightIndex) const
  1.3798 +	{
  1.3799 +	if (aTypefaceIndex >= iTypefaceList.Count())
  1.3800 +		{
  1.3801 +		// it's an Open Font managed by a COpenFontFile
  1.3802 +		if (aTypefaceIndex >= NumTypefaces() || aHeightIndex < 0)
  1.3803 +			return 0;
  1.3804 +		
  1.3805 +		const CTypefaceSupportInfo* supportInfo = iOpenFontTypefaceSupportList[aTypefaceIndex - iTypefaceList.Count()];
  1.3806 +		TInt i = Min( supportInfo->NearestPointSizeIndex() + aHeightIndex, 
  1.3807 +					  KOpenFontSizeArrayCount - 1);
  1.3808 +
  1.3809 +		return gOpenFontSizeInTwipsArray[i];
  1.3810 +		}
  1.3811 +	else
  1.3812 +		{
  1.3813 +		return VerticalPixelsToTwips(FontHeightInPixels(aTypefaceIndex,aHeightIndex));
  1.3814 +		}
  1.3815 +	}
  1.3816 +
  1.3817 +/** Returns a font height, in pixels, for a certain typeface and height index.
  1.3818 +
  1.3819 +The font height is a height allowed for the typeface represented by aTypefaceIndex. 
  1.3820 +The height returned increases with aHeightIndex.
  1.3821 +
  1.3822 +If aTypefaceIndex<0 the function panics with EFntTypefaceIndexOutOfRange. 
  1.3823 +If aTypefaceIndex is greater than the number of typefaces or aHeightIndex<0 
  1.3824 +then the function returns 0. If aHeightIndex is greater than the number of 
  1.3825 +heights then the function returns the biggest height. 
  1.3826 +
  1.3827 +@param aTypefaceIndex An index number representing a typeface, which is valid 
  1.3828 +in the range 0 to (NumTypefaces() - 1).
  1.3829 +@param aHeightIndex A font height index number, which is valid in the range 
  1.3830 +0 to (TTypefaceSupport::iNumHeights - 1). Note that the typeface support object 
  1.3831 +for the typeface can be got using TypefaceSupport(). 
  1.3832 +@return The height of a font, in pixels.
  1.3833 +@see TypefaceSupport()
  1.3834 +*/
  1.3835 +EXPORT_C TInt CFontStore::FontHeightInPixels(TInt aTypefaceIndex,TInt aHeightIndex) const
  1.3836 +	{
  1.3837 +
  1.3838 +	if (aTypefaceIndex >= iTypefaceList.Count())	// it's an Open Font managed by a COpenFontFile
  1.3839 +		return VerticalTwipsToPixels(FontHeightInTwips(aTypefaceIndex,aHeightIndex));
  1.3840 +	else
  1.3841 +		{
  1.3842 +		if (aTypefaceIndex < 0)
  1.3843 +			Panic(EFntTypefaceIndexOutOfRange);
  1.3844 +		TTypeface* typeface = iTypefaceList[aTypefaceIndex];
  1.3845 +		TInt count = iTypefaceFontBitmapList.Count();
  1.3846 +		TInt i;
  1.3847 +		for(i=0; (i < count) && (iTypefaceFontBitmapList[i].iTypeface != typeface); i++)
  1.3848 +			{  // Finds first fontbitmap with correct typeface
  1.3849 +			}
  1.3850 +		TInt height=0,h=0;
  1.3851 +		for(; (i<count) && (iTypefaceFontBitmapList[i].iTypeface==typeface)
  1.3852 +						&& (h<=aHeightIndex); i++)
  1.3853 +			if (height != iTypefaceFontBitmapList[i].HeightInPixels())
  1.3854 +				{
  1.3855 +				height = iTypefaceFontBitmapList[i].HeightInPixels();
  1.3856 +				h++;
  1.3857 +				}
  1.3858 +		return height;
  1.3859 +		}
  1.3860 +	}
  1.3861 +
  1.3862 +void CFontStore::InternalizeFontStoreFileL(CFontStoreFile* aFontStoreFile, TInt aFontVersion)
  1.3863 +	{
  1.3864 +	RStoreReadStream stream;
  1.3865 +	stream.OpenLC(*aFontStoreFile->iFileStore,aFontStoreFile->iDataStreamId);
  1.3866 +	TInt i, size = stream.ReadInt32L();
  1.3867 +	TInt opsPerformed=0;
  1.3868 +	for (i=0; i<size; i++)
  1.3869 +		{
  1.3870 +		// font is placed in shared heap
  1.3871 +		CFontBitmap* fontbitmap=(CFontBitmap*)iHeap->AllocL(sizeof(CFontBitmap));
  1.3872 +		new(fontbitmap) CFontBitmap(iHeap,aFontStoreFile);
  1.3873 +		CleanupReleasePushL(*fontbitmap);
  1.3874 +		fontbitmap->InternalizeL(stream, aFontVersion);
  1.3875 +		if (GetFontBitmapById(fontbitmap->iUid))
  1.3876 +			{
  1.3877 +			fontbitmap->Release();
  1.3878 +			}
  1.3879 +		else
  1.3880 +			{
  1.3881 +			iFontBitmapList.AppendL(fontbitmap);
  1.3882 +			opsPerformed++;
  1.3883 +			}
  1.3884 +		// safely internalized & owned
  1.3885 +		CleanupStack::Pop(fontbitmap);
  1.3886 +		}
  1.3887 +	size = stream.ReadInt32L();
  1.3888 +	for (i=0; i<size; i++)
  1.3889 +		{
  1.3890 +		TTypeface* typeface=new(ELeave) TTypeface;
  1.3891 +		CleanupStack::PushL(typeface);
  1.3892 +		typeface->InternalizeL(stream);
  1.3893 +		TInt index,count=iTypefaceList.Count(); 		
  1.3894 +		for (index=0; (index<count) && typeface->iName.CompareF(iTypefaceList[index]->iName); index++)
  1.3895 +			{  // Looks to see if typeface is already in list
  1.3896 +			}
  1.3897 +		if (index == count) // If typeface not in list
  1.3898 +			{
  1.3899 +			iTypefaceList.AppendL(typeface);
  1.3900 +			index = iTypefaceList.Count()-1;
  1.3901 +			opsPerformed++;
  1.3902 +			CleanupStack::Pop();  // typeface
  1.3903 +			}
  1.3904 +		else
  1.3905 +			{
  1.3906 +			CleanupStack::Pop();  // typeface
  1.3907 +			delete typeface;
  1.3908 +			typeface=iTypefaceList[index];
  1.3909 +			}
  1.3910 +		TInt num = stream.ReadInt32L();
  1.3911 +		for (TInt j=0; j<num; j++)
  1.3912 +			{
  1.3913 +			TUid uid;
  1.3914 +			stream >> uid;
  1.3915 + 			CFontBitmap* fontbitmap = GetFontBitmapById(uid);
  1.3916 + 			if (!fontbitmap)
  1.3917 + 			    {
  1.3918 + 			    OstTrace0( TRACE_FATAL, CFONTSTORE_INTERNALIZEFONTSTOREFILEL, "Panic(EFntFontBitmapNotLoaded)" );
  1.3919 + 			   __ASSERT_DEBUG(0,Panic(EFntFontBitmapNotLoaded));
  1.3920 + 			    }
  1.3921 +#ifndef _DEBUG
  1.3922 +			User::LeaveIfNull(fontbitmap);
  1.3923 +#endif			
  1.3924 +			TTypefaceFontBitmap typefacefontbitmap(iTypefaceList[index],fontbitmap);
  1.3925 +			typefacefontbitmap.iWidthFactor=stream.ReadInt8L();
  1.3926 +			typefacefontbitmap.iHeightFactor=stream.ReadInt8L();
  1.3927 +			count=iTypefaceFontBitmapList.Count();
  1.3928 +			TInt pos;
  1.3929 +			if (index == count)
  1.3930 +				{
  1.3931 +				pos=count;
  1.3932 +				}
  1.3933 +			else
  1.3934 +				{
  1.3935 +				
  1.3936 +				for (pos=0; (pos<count) && (iTypefaceFontBitmapList[pos].iTypeface != typeface); pos++)
  1.3937 +					{  // Finds position of first fontbitmap with same typeface
  1.3938 +					}
  1.3939 +				for (; (pos<count) && (iTypefaceFontBitmapList[pos].iTypeface == typeface)
  1.3940 +				                   && (iTypefaceFontBitmapList[pos].HeightInPixels()<typefacefontbitmap.HeightInPixels()); pos++)
  1.3941 +					{
  1.3942 +					}
  1.3943 +				for (; (pos<count) &&  (iTypefaceFontBitmapList[pos].iTypeface == typeface)
  1.3944 +				                   &&  (iTypefaceFontBitmapList[pos].HeightInPixels()==typefacefontbitmap.HeightInPixels())
  1.3945 +				                   &&  (iTypefaceFontBitmapList[pos].iFontBitmap->Posture()<fontbitmap->Posture()); pos++)
  1.3946 +	       			{  // Finds position after fontbitmap with same height
  1.3947 +					}
  1.3948 +				for (; (pos<count) &&  (iTypefaceFontBitmapList[pos].iTypeface == typeface)
  1.3949 +				                   &&  (iTypefaceFontBitmapList[pos].HeightInPixels()==typefacefontbitmap.HeightInPixels())
  1.3950 +				                   &&  (iTypefaceFontBitmapList[pos].iFontBitmap->StrokeWeight()<fontbitmap->StrokeWeight()); pos++)
  1.3951 +	       			{  // Finds position after fontbitmap with same height
  1.3952 +					}
  1.3953 +				}
  1.3954 +			TTypefaceFontBitmap* tfbAtPos=(pos==count)
  1.3955 +											?	NULL
  1.3956 +											:	&iTypefaceFontBitmapList[pos];
  1.3957 +			if (	!tfbAtPos	
  1.3958 +				||	tfbAtPos->iTypeface!=typeface
  1.3959 +				||	tfbAtPos->HeightInPixels()!=typefacefontbitmap.HeightInPixels()
  1.3960 +				||	tfbAtPos->iFontBitmap->Posture()!=fontbitmap->Posture()
  1.3961 +				||	tfbAtPos->iFontBitmap->StrokeWeight()!=fontbitmap->StrokeWeight()
  1.3962 +				||	tfbAtPos->iWidthFactor!=typefacefontbitmap.iWidthFactor	
  1.3963 +				||	tfbAtPos->iHeightFactor!=typefacefontbitmap.iHeightFactor	
  1.3964 +				)
  1.3965 +				{
  1.3966 +				iTypefaceFontBitmapList.InsertL(pos,typefacefontbitmap);
  1.3967 +				opsPerformed++;
  1.3968 +				}
  1.3969 +			}
  1.3970 +		}
  1.3971 +		CleanupStack::PopAndDestroy(); // stream
  1.3972 +		if (!opsPerformed)
  1.3973 +			User::Leave(KErrAlreadyExists);
  1.3974 +	}
  1.3975 +
  1.3976 +TTypeface* CFontStore::GetNearestTypeface(const TTypeface& aTypeface) const
  1.3977 +	{
  1.3978 +	TInt index,count = iTypefaceList.Count();
  1.3979 +	if (count <= 0)
  1.3980 +	    {
  1.3981 +	    OstTrace1( TRACE_FATAL, CFONTSTORE_GETNEARESTTYPEFACE, "count=%d, Panic(EFntNoTypefaces)", count );
  1.3982 +	    __ASSERT_DEBUG(0,Panic(EFntNoTypefaces));
  1.3983 +	    }
  1.3984 +	for (index=0; (index<count) && aTypeface.iName.CompareF(iTypefaceList[index]->iName); index++)	  
  1.3985 +		{ // tries matching	typeface name
  1.3986 +		}
  1.3987 +	if (index==count)
  1.3988 +		{
  1.3989 +		if (!aTypeface.IsSymbol())
  1.3990 +			{
  1.3991 +			for (index=0; (index<count) && ((iTypefaceList[index]->IsSymbol()) ||
  1.3992 +			                                (aTypeface.IsProportional() != iTypefaceList[index]->IsProportional()) || 
  1.3993 +			                                (aTypeface.IsSerif() != iTypefaceList[index]->IsSerif())); index++)	  
  1.3994 +				{ // tries matching	typeface flags
  1.3995 +				}
  1.3996 +			if (index==count)
  1.3997 +				for (index=0; (index<count) && ((iTypefaceList[index]->IsSymbol()) ||
  1.3998 +				                                (aTypeface.IsProportional()!=iTypefaceList[index]->IsProportional())); index++)	  
  1.3999 +					{ // tries matching	typeface flags
  1.4000 +					}
  1.4001 +			if (index==count)
  1.4002 +				for (index=0; (index<count) && iTypefaceList[index]->IsSymbol(); index++)	  
  1.4003 +					{ // finds first non-symbol typeface
  1.4004 +					}
  1.4005 +			}
  1.4006 +		else
  1.4007 +			{
  1.4008 +			for (index=0; (index<count) && (!iTypefaceList[index]->IsSymbol()); index++)	  
  1.4009 +				{ // finds first symbol typeface
  1.4010 +				}
  1.4011 +			}
  1.4012 +		}
  1.4013 +
  1.4014 +	if (index==count)
  1.4015 +		index=0;
  1.4016 +	return iTypefaceList[index];
  1.4017 +	}
  1.4018 +
  1.4019 +TTypefaceFontBitmap CFontStore::GetNearestTypefaceFontBitmap(const TFontSpec& aFontSpecInPixels, TInt aMaxHeight)
  1.4020 +	{
  1.4021 +	TTypefaceFontBitmap typefacefontbitmap;
  1.4022 +	TInt count = iTypefaceFontBitmapList.Count();
  1.4023 +	if (count <= 0)
  1.4024 +	    {
  1.4025 +	    OstTrace1( TRACE_FATAL, CFONTSTORE_GETNEARESTTYPEFACEFONTBITMAP, "count=%d, Panic(EFntNoTypefaceFontBitmaps)", count );
  1.4026 +	    __ASSERT_DEBUG(0, Panic(EFntNoTypefaceFontBitmaps));
  1.4027 +	    }
  1.4028 +	TInt i;
  1.4029 +	TInt j;
  1.4030 +	// Assumes there is at least one fontbitmap per typeface
  1.4031 +	for (i = 0; (i < count) && !(aFontSpecInPixels.iTypeface == *iTypefaceFontBitmapList[i].iTypeface); i++)
  1.4032 +		{  // Finds first fontbitmap with correct typeface
  1.4033 +		}
  1.4034 +	if (i >= count)
  1.4035 +	    {
  1.4036 +	    OstTraceExt2( TRACE_FATAL, DUP1_CFONTSTORE_GETNEARESTTYPEFACEFONTBITMAP, "i=%d, count=%d, Panic(EFntTypefaceHasNoFontBitmaps)", i, count );
  1.4037 +	    __ASSERT_DEBUG(i < count, Panic(EFntTypefaceHasNoFontBitmaps));
  1.4038 +	    }
  1.4039 +	TTypeface* typeface = iTypefaceFontBitmapList[i].iTypeface;
  1.4040 +	TInt height = 0;
  1.4041 +	if (aMaxHeight > 0)
  1.4042 +		{ // need to check against max height
  1.4043 +		for (j = i; (j < count) && (iTypefaceFontBitmapList[ j ].iTypeface == typeface) 
  1.4044 +								&& (iTypefaceFontBitmapList[j].iFontBitmap->FontMaxHeight() <= aMaxHeight); j++)
  1.4045 +			{
  1.4046 +			if (iTypefaceFontBitmapList[j].HeightInPixels() != height)
  1.4047 +				{
  1.4048 +				height = iTypefaceFontBitmapList[j].HeightInPixels();
  1.4049 +				i = j;
  1.4050 +				}
  1.4051 +			}
  1.4052 +		}
  1.4053 +	else
  1.4054 +		{ // just check against height
  1.4055 +		for (j = i; (j < count) && (iTypefaceFontBitmapList[j].iTypeface == typeface)
  1.4056 +								&& (iTypefaceFontBitmapList[j].HeightInPixels() <= aFontSpecInPixels.iHeight); j++)
  1.4057 +			{
  1.4058 +			if (iTypefaceFontBitmapList[j].HeightInPixels() != height)
  1.4059 +				{
  1.4060 +				height = iTypefaceFontBitmapList[j].HeightInPixels();
  1.4061 +				i = j;
  1.4062 +				}
  1.4063 +			}
  1.4064 +		}
  1.4065 +	for (j = i; (j < count) && (iTypefaceFontBitmapList[j].iTypeface == typeface)
  1.4066 +							&& (iTypefaceFontBitmapList[j].HeightInPixels() == height); j++) 
  1.4067 +		{  // Finds position after fontbitmap correct posture
  1.4068 +		if ((iTypefaceFontBitmapList[j].iFontBitmap->Posture() <= aFontSpecInPixels.iFontStyle.Posture()) &&
  1.4069 +			(iTypefaceFontBitmapList[j].iFontBitmap->StrokeWeight() <= aFontSpecInPixels.iFontStyle.StrokeWeight()))
  1.4070 +			i = j;
  1.4071 +		}
  1.4072 +	typefacefontbitmap = iTypefaceFontBitmapList[i];		
  1.4073 +	return typefacefontbitmap;
  1.4074 +	}
  1.4075 +
  1.4076 +CFontBitmap* CFontStore::GetFontBitmapById(TUid aUid)
  1.4077 +	{
  1.4078 +	CFontBitmap* fontbitmap = NULL;
  1.4079 +	TInt i, count = iFontBitmapList.Count();
  1.4080 +	for (i = 0; (i < count) && (aUid != iFontBitmapList[i]->iUid); i++)
  1.4081 +		{ // finds matching font bitmap
  1.4082 +		}
  1.4083 +	if (i<count) // bitmap found
  1.4084 +		fontbitmap = iFontBitmapList[i];
  1.4085 +	return fontbitmap;				
  1.4086 +	}
  1.4087 +
  1.4088 +/** The method uses the fontspec and algorithmic style only.
  1.4089 +The Uid is not used for Open Fonts. They all have a Uid of 0.
  1.4090 +*/
  1.4091 +TBool CFontStore::IsFontLoaded(
  1.4092 +	CFont*&					aFont,
  1.4093 +	const TAlgStyle&		aAlgStyle,
  1.4094 +	const TOpenFontSpec&	aFontSpecInPixels,
  1.4095 +	TInt					aMaxHeight) const
  1.4096 +	{
  1.4097 +	TFontSpec fontSpec;
  1.4098 +	aFontSpecInPixels.GetTFontSpec(fontSpec);
  1.4099 +	return IsFontLoaded(aFont, aAlgStyle, fontSpec, TUid::Uid(0), aMaxHeight);
  1.4100 +	}
  1.4101 +
  1.4102 +//stub functions to help optimise IsFontLoaded.
  1.4103 +//These shims are more efficient than a pointer-to-member.
  1.4104 +static TInt GetHeightShimMaxHeight(CFont* aFont)	{	return	aFont->FontMaxHeight();		}
  1.4105 +static TInt GetHeightShimHeightPixels(CFont* aFont)	{	return	aFont->HeightInPixels();	}
  1.4106 +
  1.4107 +/**
  1.4108 +Font spec comparison is based on
  1.4109 +1. Max height if its given, otherwise design height
  1.4110 +2. All other attributes in TFontSpec
  1.4111 +
  1.4112 +@see CFbsTypefaceStore::IsFontLoaded
  1.4113 +@see CPdrTypefaceStore::IsFontLoaded
  1.4114 +*/
  1.4115 +TBool CFontStore::IsFontLoaded(
  1.4116 +	CFont*&				aFont,
  1.4117 +	const TAlgStyle&	aAlgStyle,
  1.4118 +	const TFontSpec&	aFontSpecInPixels,
  1.4119 +	TUid				aUid,
  1.4120 +	TInt				aMaxHeight) const
  1.4121 +	{	//It is not worth copying iFontAccess to frame as it doesn't get register optimised.
  1.4122 +	const TInt count = iFontAccess->Count();
  1.4123 +	const TInt reqHeight =  aMaxHeight ? aMaxHeight : aFontSpecInPixels.iHeight;
  1.4124 +	TInt (*heightFn)(CFont*) = aMaxHeight ? GetHeightShimMaxHeight : GetHeightShimHeightPixels;
  1.4125 +	for (TInt i = 0; i < count; i++)
  1.4126 +		{
  1.4127 +		CBitmapFont* bitmapFont = reinterpret_cast<CBitmapFont*>((*iFontAccess)[i].iFont);
  1.4128 +		if (bitmapFont->Uid() != aUid ||
  1.4129 +			bitmapFont->iAlgStyle != aAlgStyle	||
  1.4130 +			heightFn(bitmapFont) != reqHeight
  1.4131 +			)
  1.4132 +			{
  1.4133 +			continue;
  1.4134 +			}
  1.4135 +		TFontSpec fontSpec = bitmapFont->FontSpecInTwips();
  1.4136 +		if (	fontSpec.iFontStyle == aFontSpecInPixels.iFontStyle &&
  1.4137 +				fontSpec.iTypeface.iName == aFontSpecInPixels.iTypeface.iName
  1.4138 +			) 
  1.4139 +			{
  1.4140 +			(*iFontAccess)[i].iAccessCount++;
  1.4141 +			aFont = static_cast<CFont*>(bitmapFont);
  1.4142 +			return ETrue;
  1.4143 +			}
  1.4144 +		}
  1.4145 +	return EFalse;
  1.4146 +	}
  1.4147 +
  1.4148 +CBitmapFont* CFontStore::NewFontL(
  1.4149 +	const TFontSpec&	aFontSpecInTwips,
  1.4150 +	const TAlgStyle&	aAlgStyle,
  1.4151 +	CFontBitmap*		aFontBitmap)
  1.4152 +	{
  1.4153 +	CBitmapFont* f = CBitmapFont::NewL(iHeap, aFontSpecInTwips, aAlgStyle, aFontBitmap);
  1.4154 +	CleanupStack::PushL(f);
  1.4155 +	AddFontL(f);
  1.4156 +	CleanupStack::Pop();
  1.4157 +	f->SetUniqueFontId(++iUniqueFontIdCount);
  1.4158 +	return f;
  1.4159 +	}
  1.4160 +
  1.4161 +CBitmapFont* CFontStore::NewFontL(
  1.4162 +	const TOpenFontSpec&	aFontSpecInTwips,
  1.4163 +	const TAlgStyle&		aAlgStyle,
  1.4164 +	COpenFont*				aOpenFont)
  1.4165 +	{
  1.4166 +	TFontSpec spec;
  1.4167 +	aFontSpecInTwips.GetTFontSpec(spec);
  1.4168 +	CBitmapFont* f = CBitmapFont::NewL(iHeap, spec, aAlgStyle, aOpenFont);
  1.4169 +	CleanupStack::PushL(f);
  1.4170 +	AddFontL(f);
  1.4171 +	CleanupStack::Pop();
  1.4172 +	f->SetUniqueFontId(++iUniqueFontIdCount);
  1.4173 +	return f;
  1.4174 +	}
  1.4175 +
  1.4176 +// This function is biased towards rounding up
  1.4177 +// The cutoff is effectively at one-third of a pixel
  1.4178 +// This is to match VerticalTwipsToPixels(...)
  1.4179 +TInt CFontStore::VerticalPixelsToTwips(TInt aPixelHeight) const
  1.4180 +	{
  1.4181 +	return ((aPixelHeight * iKPixelHeightInTwips) + 667) / 1000; // Rounds up above one-third of a pixel
  1.4182 +	}
  1.4183 +
  1.4184 +// This function is biased towards rounding down
  1.4185 +// The cutoff is effectively at two-thirds of a twip
  1.4186 +// This is to support the legacy system of rounding down
  1.4187 +// but with a sanity-check cutoff to round up past two-thirds
  1.4188 +TInt CFontStore::VerticalTwipsToPixels(TInt aTwipsHeight) const
  1.4189 +	{
  1.4190 +	if (!iKPixelHeightInTwips)
  1.4191 +	    {
  1.4192 +	    OstTrace0( TRACE_FATAL, CFONTSTORE_VERTICALTWIPSTOPIXELS, "Panic(EFntKPixelHeightInTwipsZero)" );
  1.4193 +	    __ASSERT_DEBUG(0, Panic(EFntKPixelHeightInTwipsZero));
  1.4194 +	    }
  1.4195 +	return ((aTwipsHeight * 1000) + (iKPixelHeightInTwips / 3)) / iKPixelHeightInTwips;  // Rounds down below two-thirds of a twip
  1.4196 +	}
  1.4197 +
  1.4198 +/** Installs and takes ownership of an Open Font rasterizer.
  1.4199 +
  1.4200 +@param aRasterizer A pointer to an Open Font rasterizer. */
  1.4201 +EXPORT_C void CFontStore::InstallRasterizerL(COpenFontRasterizer* aRasterizer)
  1.4202 +	{
  1.4203 +	iOpenFontRasterizerList.AppendL(aRasterizer);
  1.4204 +	}
  1.4205 +	
  1.4206 +/** Install and takes ownership of the shaper
  1.4207 +
  1.4208 +@param aShaperFactory A pointer to a shaper factory. */
  1.4209 +EXPORT_C void CFontStore::InstallShaperFactoryL(CShaperFactory* aShaperFactory)
  1.4210 +	{
  1.4211 +	iShaperFactoryList.AppendL(aShaperFactory);
  1.4212 +	}
  1.4213 +
  1.4214 +/** Deletes the glyph cache belonging to a particular client. 
  1.4215 +
  1.4216 +Called by ~CFbClient().
  1.4217 +
  1.4218 +@param aSessionHandle A session handle. */
  1.4219 +EXPORT_C void CFontStore::DeleteSessionCache(TInt aSessionHandle)
  1.4220 +	{
  1.4221 +	iOpenFontSessionCacheList->DeleteCache(iHeap,aSessionHandle);
  1.4222 +	}
  1.4223 +
  1.4224 +const CArrayPtrFlat<CShaperFactory>* CFontStore::ShaperFactoryList() const
  1.4225 +	{
  1.4226 +	return &iShaperFactoryList;
  1.4227 +	}
  1.4228 +
  1.4229 +/** Returns the list of session caches owned by the COpenFonts
  1.4230 +@internalComponent */
  1.4231 +COpenFontSessionCacheList* CFontStore::GetSessionCacheList()
  1.4232 +	{
  1.4233 +	return iOpenFontSessionCacheList;
  1.4234 +	}
  1.4235 +	
  1.4236 +/** Returns the total cache memory used by all the COpenFonts in the system 
  1.4237 + 	@return Total cache memory usage
  1.4238 +	@internalComponent 
  1.4239 +*/	
  1.4240 +TInt CFontStore::GetShaperCacheMemUsage()
  1.4241 +	{
  1.4242 +	return iOpenFontShaperCacheMemUsage;
  1.4243 +	}
  1.4244 +	
  1.4245 +/** Updates the total cache memory used by all the COpenFonts in the system
  1.4246 + 	@param aUsage New value of total cache memory usage
  1.4247 +	@internalComponent
  1.4248 +*/	
  1.4249 +void CFontStore::SetShaperCacheMemUsage(TInt aUsage)
  1.4250 +	{
  1.4251 +	iOpenFontShaperCacheMemUsage = aUsage;
  1.4252 +	}
  1.4253 +	
  1.4254 +/** Returns the list of COpenFontFiles owned by the CFontStore object
  1.4255 +	@internalComponent
  1.4256 +*/	
  1.4257 +CArrayPtrFlat<COpenFontFile>* CFontStore::GetOpenFontFileList()
  1.4258 +	{
  1.4259 +	return &iOpenFontFileList;
  1.4260 +	}
  1.4261 +
  1.4262 +void CFontStore::IncNumShaperCaches()
  1.4263 +	{
  1.4264 +	iNumberOfShaperCaches++;
  1.4265 +	}
  1.4266 +	
  1.4267 +void CFontStore::DecNumShaperCaches()
  1.4268 +	{
  1.4269 +	iNumberOfShaperCaches--;
  1.4270 +	}
  1.4271 +
  1.4272 +TInt CFontStore::GetNumShaperCaches()
  1.4273 +	{
  1.4274 +	return iNumberOfShaperCaches;
  1.4275 +	}
  1.4276 +
  1.4277 +
  1.4278 +/** Adds the typeface( of the currently added openfont file from the store) to Open Font System typefaces Supported List
  1.4279 +ignoring duplicate family names.
  1.4280 +1. Prior to adding the entry into the typefaceList, it is searched whether already exists or not
  1.4281 +2. If it is found only its reference count is incremented.
  1.4282 +3. If it is not found then its reference count is set to 1 and added that entry into the typefacelist.
  1.4283 +4. If 0 typefaces are added then KErrAlreadyExists is returned causing the new font to be unloaded.
  1.4284 +@return KErrNone is successful, otherwise a system wide error code
  1.4285 +@internalComponent
  1.4286 +*/
  1.4287 +TInt CFontStore::AddTypefacesToSupportList(COpenFontFile* aOpenFontFile)
  1.4288 +	{
  1.4289 +	TInt faceCount = aOpenFontFile->FaceCount();
  1.4290 +	CTypefaceSupportInfo* typefaceFamily = NULL;
  1.4291 +	TInt error = KErrNone;
  1.4292 +	TBool facesAdded=0;
  1.4293 +	// go through all fonts, stop early if an error
  1.4294 +	for (TInt faceIndex = 0; (faceIndex < faceCount) && (error == KErrNone); ++faceIndex)
  1.4295 +		{
  1.4296 +		//Preparing the Supported Typeface Entry
  1.4297 +		if (typefaceFamily == NULL)
  1.4298 +			{ // need a new typeface object
  1.4299 +			typefaceFamily = new CTypefaceSupportInfo();
  1.4300 +			if (typefaceFamily == NULL)
  1.4301 +				{ // failed
  1.4302 +				error = KErrNoMemory;
  1.4303 +				break;
  1.4304 +				}
  1.4305 +			}
  1.4306 +
  1.4307 +		// initialise for next type face
  1.4308 +		const TOpenFontFaceAttrib& faceAttrib = aOpenFontFile->FaceAttrib(faceIndex);
  1.4309 +		typefaceFamily->SetTypefaceInfo(faceAttrib, VerticalPixelsToTwips(faceAttrib.MinSizeInPixels()));
  1.4310 +
  1.4311 +		TInt fontPos = -1;	// an invalid index
  1.4312 +		TInt findError = iOpenFontTypefaceSupportList.FindInOrder(typefaceFamily, fontPos, CTypefaceSupportInfo::CompareFontNames);
  1.4313 + 
  1.4314 +		// new font family?
  1.4315 +		if (findError == KErrNotFound)
  1.4316 +			{
  1.4317 +			// back reference to the font file
  1.4318 +			error = typefaceFamily->AddFontFilePtr(aOpenFontFile);
  1.4319 +			if (error == KErrNone)
  1.4320 +				{ // transfer ownership
  1.4321 +				error = iOpenFontTypefaceSupportList.Insert(typefaceFamily, fontPos);
  1.4322 +				if (error == KErrNone)
  1.4323 +					{
  1.4324 +					typefaceFamily = NULL;
  1.4325 +					facesAdded++;					
  1.4326 +					}
  1.4327 +				}
  1.4328 +			}
  1.4329 +		else
  1.4330 +			{
  1.4331 +			// back reference to the new font file (allowed to fail with KErrAlreadyExists)
  1.4332 +			TInt addError = iOpenFontTypefaceSupportList[fontPos]->AddUniqueFontFilePtr(aOpenFontFile,faceAttrib);
  1.4333 +			if (addError==KErrNone)
  1.4334 +				{
  1.4335 +				facesAdded++;
  1.4336 +				}
  1.4337 +			else if (addError == KErrInUse )
  1.4338 +				{
  1.4339 +				//remove typeface from loaded font file????
  1.4340 +				}
  1.4341 +			else if (addError != KErrAlreadyExists )
  1.4342 +				{
  1.4343 +				error = addError;
  1.4344 +				}
  1.4345 +			//else KErrAlreadyExists because loaded by a lower-indexed face in this font file, so faces won't be zero.
  1.4346 +			}
  1.4347 +		}
  1.4348 +
  1.4349 +	if (typefaceFamily != NULL)
  1.4350 +		{
  1.4351 +		delete typefaceFamily;
  1.4352 +		}
  1.4353 +	if (facesAdded==0 && error==KErrNone)
  1.4354 +		{
  1.4355 +			error= KErrAlreadyExists;
  1.4356 +		}
  1.4357 +#ifdef _DEBUG
  1.4358 +	// check that array is in order
  1.4359 +	const TInt countTypefaceFamilies = iOpenFontTypefaceSupportList.Count();
  1.4360 +	for (TInt fontPos = 0; fontPos < countTypefaceFamilies - 1; ++fontPos)
  1.4361 +		{
  1.4362 +		TInt cmp = CTypefaceSupportInfo::CompareFontNames(*iOpenFontTypefaceSupportList[fontPos], *iOpenFontTypefaceSupportList[fontPos+1]);
  1.4363 +		ASSERT(cmp < 0);
  1.4364 +		}
  1.4365 +#endif
  1.4366 +
  1.4367 +	return error;
  1.4368 +	}
  1.4369 +
  1.4370 +
  1.4371 +/** Removes the typefaces from the Support List corresponding to the fontfile removed from
  1.4372 +	the fontstore
  1.4373 +This is done by 
  1.4374 +1. Searching in the typefacesupportList for pointer references to the font file.
  1.4375 +2. If the file is referenced by the typeface family remove the reference.
  1.4376 +3. If typeface family no has any implementations remove the family
  1.4377 +@internalComponent
  1.4378 +*/
  1.4379 +void CFontStore::RemoveTypefacesFromSupportList(COpenFontFile* aOpenFontFile)
  1.4380 +	{
  1.4381 +	const TInt countTypefaceFamilies = iOpenFontTypefaceSupportList.Count();
  1.4382 +
  1.4383 +	// search typeface families
  1.4384 +	for (TInt fontPos = countTypefaceFamilies - 1; fontPos >= 0; --fontPos)
  1.4385 +		{
  1.4386 +		CTypefaceSupportInfo* fontInfo = iOpenFontTypefaceSupportList[fontPos];
  1.4387 +
  1.4388 +		// look for back pointer to this Font File
  1.4389 +		TInt fontFileIndex = fontInfo->FindFontFilePtr(aOpenFontFile);
  1.4390 +
  1.4391 +		if (fontFileIndex > KErrNotFound)
  1.4392 +			{ // remove pointer
  1.4393 +			if (fontInfo->RemoveFontFilePtr(fontFileIndex))
  1.4394 +				{ // last implementation of the family, so delete it
  1.4395 +				delete fontInfo;
  1.4396 +				iOpenFontTypefaceSupportList.Remove(fontPos);
  1.4397 +				}
  1.4398 +			}
  1.4399 +		}
  1.4400 +	}
  1.4401 +
  1.4402 +/**
  1.4403 +This function checks the supplied typeface name against the existing bitmap and open 
  1.4404 +typefaces, to see if it present.
  1.4405 +
  1.4406 +@param aName The name of the typeface family name to be checked. 
  1.4407 +@return ETrue if the typeface is present, EFalse otherwise.
  1.4408 +
  1.4409 +@released
  1.4410 +@internalTechnology 
  1.4411 +*/
  1.4412 +EXPORT_C TBool CFontStore::HaveTypefaceFamilyName(const TDesC& aName)
  1.4413 +	{
  1.4414 +	//there are two lists for typefaces
  1.4415 +	//not supporting linked fonts here
  1.4416 +	
  1.4417 +	//first list is open fonts
  1.4418 +	TInt count = iOpenFontTypefaceSupportList.Count();
  1.4419 +	for (TInt index=count-1;index>=0;index--)
  1.4420 +		{
  1.4421 +		if (aName.CompareF(iOpenFontTypefaceSupportList[index]->iSupport.iTypeface.iName)==0)
  1.4422 +			return ETrue;
  1.4423 +		}
  1.4424 +
  1.4425 +	//now look through bitmap fonts
  1.4426 +	count = iTypefaceList.Count();
  1.4427 +	for (TInt index=count-1;index>=0;index--)
  1.4428 +		{
  1.4429 +		if (aName.CompareF(iTypefaceList[index]->iName)==0)
  1.4430 +			return ETrue;
  1.4431 +		}
  1.4432 +
  1.4433 +	return EFalse;
  1.4434 +	}
  1.4435 +
  1.4436 +/**
  1.4437 +@internalTechnology
  1.4438 +@released
  1.4439 +*/
  1.4440 +EXPORT_C TInt CFontStore::CreateLinkedTypeface(const TLinkedTypefaceSpecificationArgs &aLinkedTypefaceSpec, TInt aSession, TInt& aId)
  1.4441 +	{
  1.4442 +	TInt err;
  1.4443 +	TInt retErr=0;
  1.4444 +	TRAP(err,retErr = CreateLinkedTypefaceL(aLinkedTypefaceSpec,aSession,aId));
  1.4445 +	if (err!=KErrNone)
  1.4446 +		{	
  1.4447 +		return err;
  1.4448 +		}
  1.4449 +	else
  1.4450 +		{
  1.4451 +		return retErr;	
  1.4452 +		}
  1.4453 +	}
  1.4454 +
  1.4455 +/* this function is used to create the linked typeface, the linked typeface is created on
  1.4456 + * the font and bitmap server heap, not the shared heap.
  1.4457 + */	
  1.4458 +TInt CFontStore::CreateLinkedTypefaceL(const TLinkedTypefaceSpecificationArgs &aLinkedTypefaceSpec, TInt /*aSession*/, TInt& /*aId*/)	
  1.4459 +	//reconstuct a CLinkedTypefaceSpecification - could store as T type, but then the
  1.4460 +	// maximum size would be used for every linked typeface
  1.4461 +	//
  1.4462 +	{
  1.4463 +	const TAny* extensionPtr = FontLinkingInterface();
  1.4464 +	
  1.4465 +	if (extensionPtr == NULL)
  1.4466 +		return KErrNotSupported;
  1.4467 +	
  1.4468 +	//Convert the TLinkedTypefaceSpecification args into the
  1.4469 +	//COpenFontLinkedTypefaceSpecification recognised by the rasteriser 
  1.4470 +	COpenFontLinkedTypefaceSpecification* spec = 
  1.4471 +		COpenFontLinkedTypefaceSpecification::NewLC(aLinkedTypefaceSpec);
  1.4472 +	
  1.4473 +	TInt err = ValidateLinkedFontSpecificationL(*spec, EFalse);
  1.4474 +	
  1.4475 +	if (err == KErrNone)
  1.4476 +    {
  1.4477 +		GenerateLinkedFontFileL(*spec, extensionPtr, EFalse);
  1.4478 +    }
  1.4479 +
  1.4480 +	CleanupStack::PopAndDestroy(spec);
  1.4481 +	return err;
  1.4482 +	}
  1.4483 +
  1.4484 +/*
  1.4485 +@internalTechnology
  1.4486 +Retrieve the specification from a linked typeface; the name of the typeface should be specified in the parameter.
  1.4487 +
  1.4488 +@param aLinkedTypefaceSpec An empty linked typeface spec containing the name of the typeface to be retrieved.
  1.4489 +
  1.4490 +@leave One of the system wide error codes.
  1.4491 +*/
  1.4492 +EXPORT_C void CFontStore::GetLinkedTypefaceL(TLinkedTypefaceSpecificationArgs &aLinkedTypefaceSpec)
  1.4493 +	{
  1.4494 +	const TAny* extensionPtr = FontLinkingInterface();
  1.4495 +	
  1.4496 +	if (extensionPtr == NULL)
  1.4497 +		User::Leave(KErrNotSupported);
  1.4498 +
  1.4499 +	MOpenFontLinkedTypefaceExtension* linkedExt = (MOpenFontLinkedTypefaceExtension*)extensionPtr;
  1.4500 +	
  1.4501 +	//Check whether the font is loaded
  1.4502 +	CTypefaceSupportInfo* supinfo;
  1.4503 +	TTypefaceSupport support;
  1.4504 +	COpenFontFile* fetchFont=NULL;
  1.4505 +	for (TInt count=0;count<(iOpenFontTypefaceSupportList.Count());count++)
  1.4506 +		{
  1.4507 +		supinfo = iOpenFontTypefaceSupportList[count];
  1.4508 +		support = supinfo->iSupport;			
  1.4509 +		
  1.4510 +		if (aLinkedTypefaceSpec.iName==support.iTypeface.iName)
  1.4511 +			{
  1.4512 +			fetchFont = supinfo->iOpenFontFilePtrArray[0];
  1.4513 +			
  1.4514 +			break;	
  1.4515 +			}
  1.4516 +		}
  1.4517 +	if (fetchFont==NULL)
  1.4518 +		{
  1.4519 +		User::Leave(KErrNotFound);	
  1.4520 +		}
  1.4521 +
  1.4522 +	COpenFontLinkedTypefaceSpecification* typefaceSpec = COpenFontLinkedTypefaceSpecification::NewLC(aLinkedTypefaceSpec.iName);
  1.4523 +	TFileName fetchFile = fetchFont->FileName();
  1.4524 +	linkedExt->GetLinkedTypefaceSpecificationL(fetchFile, *typefaceSpec);
  1.4525 +	aLinkedTypefaceSpec = *typefaceSpec;
  1.4526 +	CleanupStack::PopAndDestroy(typefaceSpec);
  1.4527 +	}
  1.4528 +
  1.4529 +/*
  1.4530 +@internalTechnology
  1.4531 +Updates an existing linked typeface to a new specification.
  1.4532 +
  1.4533 +@param aLinkedTypefaceSpec The new specification for the typeface
  1.4534 +
  1.4535 +@leave KErrNotSupported Font linking is not supported by any of the installed rasterizers
  1.4536 +@leave One of the system wide error codes.
  1.4537 +*/
  1.4538 +EXPORT_C void CFontStore::UpdateLinkedTypefaceL(const TLinkedTypefaceSpecificationArgs& aLinkedTypefaceSpec)
  1.4539 +	{
  1.4540 +	const TAny* extensionPtr = FontLinkingInterface();
  1.4541 +	
  1.4542 +	if (extensionPtr == NULL)
  1.4543 +		User::Leave(KErrNotSupported);
  1.4544 +	
  1.4545 +	//Convert the TLinkedTypefaceSpecification args into the
  1.4546 +	//COpenFontLinkedTypefaceSpecification recognised by the rasteriser 
  1.4547 +	COpenFontLinkedTypefaceSpecification* spec = 
  1.4548 +		COpenFontLinkedTypefaceSpecification::NewLC(aLinkedTypefaceSpec);
  1.4549 +	
  1.4550 +	TInt err = ValidateLinkedFontSpecificationL(*spec, ETrue);
  1.4551 +	User::LeaveIfError(err);
  1.4552 +	
  1.4553 +	GenerateLinkedFontFileL(*spec, extensionPtr, ETrue);
  1.4554 +
  1.4555 +	CleanupStack::PopAndDestroy(spec);
  1.4556 +	}
  1.4557 +
  1.4558 +/**
  1.4559 +@internalTechnology
  1.4560 +Performs the loading of font files at boot time. This is a three stage procedure.
  1.4561 +
  1.4562 +1. Copies linked fonts to be updated from their temporary directory into the linked fonts folder
  1.4563 +2. Loads all the linked fonts from the linked fonts folder.
  1.4564 +3. Loads all remaining font files from *:\resource\fonts
  1.4565 + */
  1.4566 +EXPORT_C void CFontStore::LoadFontsAtStartupL()
  1.4567 +	{
  1.4568 +	//First copy any updated linked fonts from their temporary dir to the linked font dir
  1.4569 +	CFileMan* fm = CFileMan::NewL(iFs);
  1.4570 +	CleanupStack::PushL(fm);
  1.4571 +	
  1.4572 +	//Get the fbserv private folder
  1.4573 +	TBuf<KMaxPrivatePathLength> privPath;
  1.4574 +	iFs.PrivatePath(privPath);
  1.4575 +	
  1.4576 +	//Construct the linked font dir path
  1.4577 +	TBuf<KMaxLinkedFontPathLength> linkedFontDir;
  1.4578 +	linkedFontDir.Format(KLinkedFontFileFolder, KLinkedFontDrive, &privPath);
  1.4579 +	
  1.4580 +	//Construct the linked font temp dir path
  1.4581 +	TBuf<KMaxLinkedFontPathLength> linkedFontTempDir;
  1.4582 +	linkedFontTempDir.Append(linkedFontDir);
  1.4583 +	linkedFontTempDir.Append(KLinkedFontFileTempFolder);
  1.4584 +	
  1.4585 +	//Copy the temp folder into the main folder
  1.4586 +	TInt err = fm->Copy(linkedFontTempDir, linkedFontDir, CFileMan::EOverWrite);
  1.4587 +
  1.4588 +	if (err == KErrNone)
  1.4589 +		{
  1.4590 +		//If sucessful copying remove the temp folder
  1.4591 +		//A leave is not thrown as the empty directory remaining is not a significant enough
  1.4592 +		//to prevent fbserv from starting
  1.4593 +		fm->RmDir(linkedFontTempDir);
  1.4594 +		}
  1.4595 +	 
  1.4596 +	CleanupStack::PopAndDestroy(fm);
  1.4597 +	
  1.4598 +	//Load Linked Fonts
  1.4599 +	LoadFontsL(linkedFontDir);
  1.4600 +	
  1.4601 +	//Load the remaining fonts
  1.4602 +	LoadFontsL(KFBSERVFontDirSecure);
  1.4603 +	}
  1.4604 +/**
  1.4605 +@internalTechnology
  1.4606 +Returns the pointer to the first rasterizer supporting font linking (KUidLinkedTypefaceRasterizerExtension).
  1.4607 +*/
  1.4608 +const TAny* CFontStore::FontLinkingInterface() const
  1.4609 +	{
  1.4610 +	TInt rastcount = iOpenFontRasterizerList.Count();
  1.4611 +	COpenFontRasterizer* rast;
  1.4612 +	TAny* extensionPtr = NULL;
  1.4613 +	
  1.4614 +	//Check each rasterizer in turn to check it supports the extended interface.
  1.4615 +	//In reality there should only be one but multiple rasterizers are supported.
  1.4616 +	for (TInt i = 0 ; i != rastcount ; i++)
  1.4617 +		{
  1.4618 +		rast = iOpenFontRasterizerList[i];
  1.4619 +		rast->ExtendedInterface(KUidLinkedTypefaceRasterizerExtension, extensionPtr);
  1.4620 +		
  1.4621 +		if (extensionPtr != NULL)
  1.4622 +			break;
  1.4623 +		}
  1.4624 +	
  1.4625 +	return extensionPtr;
  1.4626 +	}
  1.4627 +
  1.4628 +/**
  1.4629 +Validates the linked font specification passed as a parameter.
  1.4630 +
  1.4631 +@param aSpec The specification to be validated
  1.4632 +@param aOverwrite ETrue if this is an update operation, EFalse otherwise
  1.4633 +*/
  1.4634 +TInt CFontStore::ValidateLinkedFontSpecificationL(COpenFontLinkedTypefaceSpecification& aSpec, TBool aOverwrite) const
  1.4635 +	{
  1.4636 +	//see if the typeface is an existing regular typeface.
  1.4637 +	if (!aOverwrite)
  1.4638 +		{
  1.4639 +		TInt numberTypefaces = iTypefaceList.Count();
  1.4640 +		TInt c;
  1.4641 +		
  1.4642 +		for (c=0;c<numberTypefaces;c++)
  1.4643 +			{
  1.4644 +			TTypeface* ptr=(iTypefaceList)[c];
  1.4645 +			
  1.4646 +			/* only comparing on the name */
  1.4647 +			if (0== ptr->iName.CompareF(aSpec.Name()))
  1.4648 +				{
  1.4649 +				//A typeface with this name is already loaded
  1.4650 +				return KErrAlreadyExists;
  1.4651 +				}
  1.4652 +			}
  1.4653 +			
  1.4654 +		TInt numberOpenFontFiles = iOpenFontFileList.Count();
  1.4655 +		for (c=0;c<numberOpenFontFiles;c++)
  1.4656 +			{
  1.4657 +			COpenFontFile* ptr=(iOpenFontFileList)[c];
  1.4658 +			
  1.4659 +			numberTypefaces= ptr->FaceCount();
  1.4660 +			TInt c2;
  1.4661 +			for (c2=0;c2<numberTypefaces;c2++)
  1.4662 +				{
  1.4663 +				const TOpenFontFaceAttrib& attrib = ptr->FaceAttrib(c2);
  1.4664 +
  1.4665 +				/* only comparing on the name */
  1.4666 +				if (0== attrib.ShortFullName().CompareF(aSpec.Name()))
  1.4667 +					{
  1.4668 +					//have a matching name, return error
  1.4669 +					return KErrAlreadyExists;
  1.4670 +					}
  1.4671 +				if (0== attrib.ShortFamilyName().CompareF(aSpec.Name()))
  1.4672 +					{
  1.4673 +					//have a matching name, return error
  1.4674 +					return KErrAlreadyExists;
  1.4675 +					}	
  1.4676 +				}
  1.4677 +			}
  1.4678 +		}
  1.4679 +		//For each element, check whether the typeface exists and add the correct filename to the spec if it does
  1.4680 +		TInt numTypefaces = aSpec.TypefaceCount();
  1.4681 +		TFileName fileName;
  1.4682 +		COpenFontLinkedTypefaceElementSpec* element;
  1.4683 +		
  1.4684 +		for (TInt counter=0;counter<numTypefaces;counter++)
  1.4685 +			{
  1.4686 +			element = aSpec.Typeface(counter);
  1.4687 +			
  1.4688 +			if (GetFontFilePath(element->ElementName(), fileName))
  1.4689 +				{
  1.4690 +				element->SetFileNameL(fileName);
  1.4691 +				}
  1.4692 +			else
  1.4693 +				{
  1.4694 +				return KErrNotFound;
  1.4695 +				}
  1.4696 +			}
  1.4697 +		return KErrNone;
  1.4698 +	}
  1.4699 +
  1.4700 +
  1.4701 +/**
  1.4702 +Sends the specification to the font rasterizer to be created/updated.
  1.4703 +
  1.4704 +@param aSpec The linked font specification
  1.4705 +@param aExtension The extension interface of the chosen rasterizer
  1.4706 +@param aUpdate ETrue if the file is being updated, EFalse if it should be created
  1.4707 +
  1.4708 +@leave KErrNotFound Attempting to update a file which does not exist
  1.4709 + */
  1.4710 +void CFontStore::GenerateLinkedFontFileL(COpenFontLinkedTypefaceSpecification& aSpec, const TAny* aExtension, TBool aUpdate)
  1.4711 +	{
  1.4712 +	MOpenFontLinkedTypefaceExtension* linkedExt = (MOpenFontLinkedTypefaceExtension*)aExtension;
  1.4713 +
  1.4714 +	//Generate the filename for the linked font file (excluding the extension
  1.4715 +	//and the .) which are appended by the rasterizer.
  1.4716 +	TFileName privPath;
  1.4717 +	User::LeaveIfError(iFs.PrivatePath(privPath));
  1.4718 +	TFileName fn;
  1.4719 +	fn.Format(KLinkedFontFileFolder, KLinkedFontDrive, &privPath);
  1.4720 +	
  1.4721 +	//Choose the correct path to write the file to
  1.4722 +	if (aUpdate)
  1.4723 +		{
  1.4724 +		fn.Append(KLinkedFontFileTempFolder);
  1.4725 +		}
  1.4726 +	
  1.4727 +	// Create the directory if it does not exist
  1.4728 +	TInt result = iFs.MkDirAll(fn);
  1.4729 +	if (result != KErrAlreadyExists)
  1.4730 +		{
  1.4731 +		User::LeaveIfError(result);
  1.4732 +		}
  1.4733 +	
  1.4734 +	//Append the linked font filename to the path for the rasterizer.
  1.4735 +	fn.Append(aSpec.Name());
  1.4736 +	
  1.4737 +	// If we are updating, check that the file is a linked typeface before attempting the update.
  1.4738 +	if (aUpdate)
  1.4739 +		{
  1.4740 +		TFileName fn;
  1.4741 +		TBool exists = GetFontFilePath(aSpec.Name(), fn);
  1.4742 +		
  1.4743 +		if (exists)
  1.4744 +			{
  1.4745 +			COpenFontLinkedTypefaceSpecification* tempSpec = COpenFontLinkedTypefaceSpecification::NewLC(aSpec.Name());
  1.4746 +			TRAPD(ret, linkedExt->GetLinkedTypefaceSpecificationL(fn, *tempSpec));
  1.4747 +			User::LeaveIfError(ret);
  1.4748 +			CleanupStack::PopAndDestroy(tempSpec);
  1.4749 +			}
  1.4750 +		else
  1.4751 +			{
  1.4752 +			User::Leave(KErrNotFound);
  1.4753 +			}
  1.4754 +		}
  1.4755 +	
  1.4756 +	//Use the rasterizer extension to create the linked typeface
  1.4757 +	linkedExt->CreateLinkedTypefaceL(aSpec, fn);
  1.4758 +	
  1.4759 +	// Load the new linked typeface
  1.4760 +	if (!aUpdate)
  1.4761 +		{
  1.4762 +		AddFileL(fn);
  1.4763 +		}
  1.4764 +	}
  1.4765 +
  1.4766 +/**
  1.4767 +Function called at system startup to find and load all fonts in the specified 
  1.4768 +folder. The value of the folder will be the secure Data-caged private folder 
  1.4769 +named "\resource\fonts". 
  1.4770 +
  1.4771 +The first font of a given name overrides subsequent ones. 
  1.4772 +
  1.4773 +The search order is: Y:, X:, W:, ..., C:, B:, A:, Z:
  1.4774 +
  1.4775 +@see TFindFile 
  1.4776 +@param aFontsDir The directory search pattern 
  1.4777 + */
  1.4778 +void CFontStore::LoadFontsL(const TDesC& aFontsDir)
  1.4779 +	{
  1.4780 +#ifdef _DEBUG
  1.4781 +	_LIT(KLoadStarted, "CFontStore::LoadFontsL Started.\r\n");
  1.4782 +	RDebug::Print(KLoadStarted);
  1.4783 +	TUint32	loadStartTime = StartTiming();
  1.4784 +#endif
  1.4785 +	
  1.4786 +	RArray<TParse> fontsToLoad;
  1.4787 +	CleanupClosePushL(fontsToLoad);
  1.4788 +	TFindFile fileFinder(iFs);
  1.4789 +	CDir* foundFileList = NULL;
  1.4790 +
  1.4791 +	_LIT(KFBSERVFontFilePattern, "*");
  1.4792 +	TInt findFileComplete = fileFinder.FindWildByDir(KFBSERVFontFilePattern, aFontsDir, foundFileList);
  1.4793 +
  1.4794 +	while (!findFileComplete)
  1.4795 +		{
  1.4796 +		CleanupStack::PushL(foundFileList);
  1.4797 +		const TInt foundFileCount = foundFileList->Count();
  1.4798 +		const TDesC& pathInfo = fileFinder.File();
  1.4799 +		
  1.4800 +		// Build a list of fonts to be loaded eliminating duplicate filenames. 
  1.4801 +		for (TInt ii = 0; ii < foundFileCount; ii++)
  1.4802 +			{
  1.4803 +			TParse fullFontFileName;
  1.4804 +			if (fullFontFileName.Set((*foundFileList)[ii].iName, &pathInfo, NULL) == KErrNone)
  1.4805 +				{
  1.4806 +				// If the font has not already been loaded, validate it then add it to the list.
  1.4807 +				if (!FileIsInList(fullFontFileName, fontsToLoad))
  1.4808 +					{
  1.4809 +					// Do not validate fonts on Z: (assumed to be ROM created with valid fonts)
  1.4810 +					if (FileIsOnZ(fullFontFileName))
  1.4811 +						{
  1.4812 +						fontsToLoad.AppendL(fullFontFileName);
  1.4813 +						}
  1.4814 +					else
  1.4815 +						{
  1.4816 +						// Test font before loading
  1.4817 +						TRAPD(err, SanityCheckFontFileL(fullFontFileName))
  1.4818 +						if (KErrNone == err)
  1.4819 +							{
  1.4820 +							// Add file 
  1.4821 +							fontsToLoad.AppendL(fullFontFileName);
  1.4822 +							}
  1.4823 +						else
  1.4824 +							{
  1.4825 +							_LIT(KCorruptFont, "CFontStore::LoadFontsL %S could not be loaded.\r\n");
  1.4826 +							RDebug::Print(KCorruptFont, &fullFontFileName.FullName());
  1.4827 +							}
  1.4828 +						}
  1.4829 +					}
  1.4830 +				}
  1.4831 +			}
  1.4832 +
  1.4833 +		CleanupStack::PopAndDestroy(foundFileList);
  1.4834 +		findFileComplete = fileFinder.FindWild(foundFileList);
  1.4835 +		}
  1.4836 +	
  1.4837 +	// Load the fonts in reverse order (i.e. Z:, A: to Y:) this causes
  1.4838 +	// fonts on Z: to take priority over fonts on A: to Y: when the internal 
  1.4839 +	// font names are identical.
  1.4840 +	TInt kk = fontsToLoad.Count();
  1.4841 +	while(kk--)
  1.4842 +		{
  1.4843 +		TUid fontUid = KNullUid;
  1.4844 +		
  1.4845 +		// Load this font as a new font, and add it to the list of loaded fonts
  1.4846 +		TRAPD(addFileError, AddSanityCheckedFontL(fontsToLoad[kk], fontUid));
  1.4847 +		if (addFileError)
  1.4848 +			{
  1.4849 +			_LIT(KLoadedFont, "CFontStore::LoadFontsL failed with error %i to load font, filename: %S\r\n");
  1.4850 +			RDebug::Print(KLoadedFont, addFileError, &(fontsToLoad[kk].FullName()));
  1.4851 +			}
  1.4852 +#ifdef _DEBUG
  1.4853 +		else
  1.4854 +			{
  1.4855 +			// NOTE: This is to make testing of confirming what fonts are loaded a little easier as there is no 
  1.4856 +			//		 easy way to get this information from outside the server.
  1.4857 +			_LIT(KLoadedFont, "CFontStore::LoadFontsL loaded font filename: %S\r\n");
  1.4858 +			RDebug::Print(KLoadedFont, &(fontsToLoad[kk].FullName()));
  1.4859 +			}
  1.4860 +#endif
  1.4861 +		}
  1.4862 +	
  1.4863 +#ifdef _DEBUG
  1.4864 +	TUint32 loadTime = FinishTimingL(loadStartTime);
  1.4865 +	_LIT(KLoadEnded, "CFontStore::LoadFontsL Finished. Took: %dus\r\n");
  1.4866 +	RDebug::Print(KLoadEnded, loadTime);
  1.4867 +#endif
  1.4868 +	CleanupStack::PopAndDestroy(&fontsToLoad);
  1.4869 +	}
  1.4870 +/**
  1.4871 +Retrieves the full path and filename of the font with the specified name. This function
  1.4872 +searches through all open font files currently loaded by font store.
  1.4873 +
  1.4874 +@param aFontName The full name of the font to search for
  1.4875 +@param aFilePath An empty descriptor to have the file name filled in
  1.4876 +
  1.4877 +@return ETrue if the font is found; EFalse if not
  1.4878 +*/
  1.4879 +EXPORT_C TBool CFontStore::GetFontFilePath(const TDesC& aFontName, TFileName& aFilePath) const
  1.4880 +	{
  1.4881 +	TInt numTypefaces = iOpenFontFileList.Count();
  1.4882 +	COpenFontFile* thisFile;
  1.4883 +	TOpenFontFaceAttrib faceAttrib;
  1.4884 +	
  1.4885 +	//For every (Truetype) font file
  1.4886 +	for (TInt i = 0 ; i != numTypefaces ; i++)
  1.4887 +		{
  1.4888 +		thisFile = iOpenFontFileList[i];
  1.4889 +		
  1.4890 +		//For every face within this file
  1.4891 +		for (TInt face = 0 ; face != thisFile->FaceCount() ; face++)
  1.4892 +			{
  1.4893 +			faceAttrib = thisFile->FaceAttrib(face);
  1.4894 +			if (faceAttrib.FullName().CompareF(aFontName) == 0)
  1.4895 +				{
  1.4896 +				aFilePath = thisFile->FileName();
  1.4897 +				return ETrue;
  1.4898 +				}
  1.4899 +			}
  1.4900 +		}
  1.4901 +	return EFalse;	
  1.4902 +	}
  1.4903 +
  1.4904 +TInt CFontStore::CacheFontTable(TUid aFileUid, TUint32 aTag, 
  1.4905 +        TAny *&aContent, TInt aLength)
  1.4906 +    {
  1.4907 +    return iFontTableCache->Append(aFileUid, aTag, aContent, aLength);
  1.4908 +    }
  1.4909 +
  1.4910 +TInt CFontStore::FindFontTableInCache(TUid aFileUid, TUint32 aTag, 
  1.4911 +        TAny *&aContent, TInt &aLength)
  1.4912 +    {
  1.4913 +    TInt id;
  1.4914 +    return iFontTableCache->Find(aFileUid, aTag, aContent, aLength, &id);
  1.4915 +    }
  1.4916 +
  1.4917 +TInt CFontStore::IncreaseUnhintedOutlineRefCount(const TUnhintedOutlineId &aOutlineId, 
  1.4918 +        TInt aSessionHandle)
  1.4919 +    {
  1.4920 +    return iUnhintedOutlineCache->IncRefCount(aOutlineId, aSessionHandle);
  1.4921 +    }
  1.4922 +
  1.4923 +TInt CFontStore::IncreaseHintedOutlineRefCount(const THintedOutlineId &aOutlineId,
  1.4924 +        TInt aSessionHandle)
  1.4925 +    {
  1.4926 +    return iHintedOutlineCache->IncRefCount(aOutlineId, aSessionHandle);
  1.4927 +    }
  1.4928 +
  1.4929 +TInt CFontStore::IncFontTableRefCount(TUid aFileUid, TUint32 aTag, 
  1.4930 +        TInt aSessionHandle)
  1.4931 +    {
  1.4932 +    return iFontTableCache->IncRefCount(aFileUid, aTag, aSessionHandle);
  1.4933 +    }
  1.4934 +
  1.4935 +TInt CFontStore::DecFontTableRefCount(TUid aFileUid, TUint32 aTag, 
  1.4936 +        TInt aSessionHandle)
  1.4937 +    {
  1.4938 +    return iFontTableCache->DecRefCount(aFileUid, aTag, aSessionHandle);
  1.4939 +    }
  1.4940 +
  1.4941 +TInt CFontStore::CacheUnhintedOutline(const TUnhintedOutlineId &aOutlineId, TAny * aData, 
  1.4942 +        TInt aLength, TAny *&aOutline, TInt &aLen)
  1.4943 +    {
  1.4944 +    return iUnhintedOutlineCache->CacheUnhintedOutline(aOutlineId, aData, aLength, 
  1.4945 +            aOutline, aLen);
  1.4946 +    }
  1.4947 +
  1.4948 +TInt CFontStore::CacheHintedOutline(const THintedOutlineId &aOutlineId,
  1.4949 +        TAny * aData, TInt aLength, TAny *&aOutline, TInt &aLen)
  1.4950 +    {
  1.4951 +    return iHintedOutlineCache->CacheHintedOutline(aOutlineId, aData, aLength,
  1.4952 +            aOutline, aLen);
  1.4953 +    }
  1.4954 +
  1.4955 +TInt CFontStore::ReleaseUnhintedOutline(const TUnhintedOutlineId &aOutlineId, 
  1.4956 +        TInt aSessionHandle)
  1.4957 +    {
  1.4958 +    return iUnhintedOutlineCache->DecRefCount(aOutlineId, aSessionHandle);    
  1.4959 +    }
  1.4960 +
  1.4961 +TInt CFontStore::ReleaseHintedOutline(const THintedOutlineId &aOutlineId,
  1.4962 +        TInt aSessionHandle)
  1.4963 +    {
  1.4964 +    return iHintedOutlineCache->DecRefCount(aOutlineId, aSessionHandle);    
  1.4965 +    }
  1.4966 +
  1.4967 +TInt CFontStore::ReleaseFontTable(TUid aFileUid, TUint32 aTag, 
  1.4968 +        TInt aSessionHandle)
  1.4969 +    {
  1.4970 +    return iFontTableCache->DecRefCount(aFileUid, aTag, aSessionHandle);
  1.4971 +    }
  1.4972 +
  1.4973 +TInt CFontStore::FindUnhintedOutlineInCache(const TUnhintedOutlineId &aOutlineId, TAny *&aData, 
  1.4974 +        TInt &aLength)
  1.4975 +    {
  1.4976 +    return iUnhintedOutlineCache->Find(aOutlineId, aData, aLength);
  1.4977 +    }
  1.4978 +
  1.4979 +TInt CFontStore::FindHintedOutlineInCache(const THintedOutlineId &aOutlineId, 
  1.4980 +        TAny *&aData, TInt &aLength)
  1.4981 +    {
  1.4982 +    return iHintedOutlineCache->Find(aOutlineId, aData, aLength);
  1.4983 +    }
  1.4984 +
  1.4985 +void CFontStore::CleanupCacheOnOpenFontRemoval(COpenFont *aFont)
  1.4986 +    {
  1.4987 +    iHintedOutlineCache->CleanupCacheOnOpenFontRemoval(aFont);
  1.4988 +    //iUnhintedOutlineCache.OnOpenFontRemoval(aFont);
  1.4989 +    }
  1.4990 +
  1.4991 +void CFontStore::CleanupCacheOnOpenFontFileRemoval(COpenFontFile *aFontFile) 
  1.4992 +    {
  1.4993 +    iUnhintedOutlineCache->CleanupCacheOnOpenFontFileRemoval(aFontFile);
  1.4994 +    iFontTableCache->CleanupCacheOnOpenFontFileRemoval(aFontFile);
  1.4995 +    }
  1.4996 +
  1.4997 +/** Clean up font table and glyph outline caches when an FBS session is terminated.
  1.4998 + * All the reference counts related to that session are cleared.
  1.4999 +@param aSession: Input. A pointer to the terminating session.
  1.5000 +@return always returns KErrNone.
  1.5001 +@internalTechnology
  1.5002 +*/
  1.5003 +EXPORT_C
  1.5004 +void CFontStore::CleanupCacheOnFbsSessionTermination(TInt aSessionHandle)
  1.5005 +    {
  1.5006 +    iHintedOutlineCache->CleanupCacheOnFbsSessionTermination(aSessionHandle);
  1.5007 +    iUnhintedOutlineCache->CleanupCacheOnFbsSessionTermination(aSessionHandle);
  1.5008 +    iFontTableCache->CleanupCacheOnFbsSessionTermination(aSessionHandle);
  1.5009 +    }
  1.5010 +
  1.5011 +
  1.5012 +void TFontTableGlyphOutlineCacheMemMonitor::Inc(TInt aBytes)
  1.5013 +    {
  1.5014 +    iBytes += aBytes;
  1.5015 +    }
  1.5016 +
  1.5017 +void TFontTableGlyphOutlineCacheMemMonitor::Dec(TInt aBytes)
  1.5018 +    {
  1.5019 +    iBytes -= aBytes;
  1.5020 +    }
  1.5021 +
  1.5022 +TInt TFontTableGlyphOutlineCacheMemMonitor::GetMemUsage()
  1.5023 +    {
  1.5024 +    return iBytes;
  1.5025 +    }
  1.5026 +
  1.5027 +TFontTableGlyphOutlineCacheMemMonitor::TFontTableGlyphOutlineCacheMemMonitor(): 
  1.5028 +    iBytes(0) 
  1.5029 +    {
  1.5030 +    // null constructor
  1.5031 +    }
  1.5032 +
  1.5033 +TUnhintedOutlineId::TUnhintedOutlineId(TUid aFileUid, TInt aFaceIndex, TUint aId):
  1.5034 +iFileUid(aFileUid), iFaceIndex(aFaceIndex), iId(aId)
  1.5035 +    {
  1.5036 +    // a null constructor;
  1.5037 +    }
  1.5038 +
  1.5039 +THintedOutlineId::THintedOutlineId(COpenFont *aFont, TUint aId):
  1.5040 +iFont(aFont), iId(aId)
  1.5041 +    {
  1.5042 +    // a null constructor;
  1.5043 +    }
  1.5044 +
  1.5045 +#ifdef _DEBUG
  1.5046 +/**
  1.5047 +Returns a timestamp for use by FinishTimingL().
  1.5048 +@return The timestamp.
  1.5049 +@see FinishTimingL
  1.5050 +*/
  1.5051 +TUint32 StartTiming(void)
  1.5052 +	{
  1.5053 +	return User::FastCounter();
  1.5054 +	}
  1.5055 +
  1.5056 +/**
  1.5057 +Returns the time difference between a given time and now in microseconds.
  1.5058 +@param aStartTime The start time returned by calling StartTiming()
  1.5059 +@return The time difference in microseconds.
  1.5060 +@see StartTiming()
  1.5061 +*/
  1.5062 +TUint32 FinishTimingL(TUint32 aStartTime)
  1.5063 +	{
  1.5064 +	TInt freq = 0;
  1.5065 +	TUint32 endtime = User::FastCounter();
  1.5066 +	User::LeaveIfError(HAL::Get(HALData::EFastCounterFrequency, freq));
  1.5067 +	TUint32 diff = endtime - aStartTime;
  1.5068 +	TInt64 diffTime = (1000000 * TInt64(diff)) / (TInt64)freq;
  1.5069 +	return TUint32(diffTime);
  1.5070 +	}
  1.5071 +#endif
  1.5072 +
  1.5073 +/**
  1.5074 +Returns true if the filename passed in is on the Z: drive
  1.5075 +@param aFileName The filename to check
  1.5076 +@return ETrue if the file is on Z:
  1.5077 +*/
  1.5078 +TBool FileIsOnZ(TParse& aFileName)
  1.5079 +	{
  1.5080 +	TBool onZ = EFalse;
  1.5081 +	
  1.5082 +	const TDesC& fileDrive = aFileName.Drive();
  1.5083 +	_LIT(KZDrive,"z:");
  1.5084 +	if (0 == fileDrive.CompareF(KZDrive))
  1.5085 +		{
  1.5086 +		onZ = ETrue;
  1.5087 +		}
  1.5088 +	
  1.5089 +	return onZ;
  1.5090 +	}
  1.5091 +
  1.5092 +
  1.5093 +/**
  1.5094 +Returns true if the filename passed in is in the supplied list
  1.5095 +@param aFileName The filename to check
  1.5096 +@param aList The list to check
  1.5097 +@return ETrue if the file is in the list
  1.5098 +*/
  1.5099 +TBool FileIsInList(TParse& aFileName, RArray<TParse>& aList)
  1.5100 +	{
  1.5101 +	TBool inList = EFalse;
  1.5102 +	
  1.5103 +	TInt jj = aList.Count();
  1.5104 +	while(jj--)
  1.5105 +		{
  1.5106 +		TPtrC shortFilename = aFileName.NameAndExt();
  1.5107 +		if (shortFilename.CompareF( aList[jj].NameAndExt() ) == 0)
  1.5108 +			{
  1.5109 +#ifdef _DEBUG
  1.5110 +			_LIT(KEclipsesFont, "CFontStore::FileIsInList %S eclipses %S\r\n");
  1.5111 +			RDebug::Print(KEclipsesFont, &aList[jj].FullName(), &aFileName.FullName());
  1.5112 +#endif
  1.5113 +			inList = ETrue;
  1.5114 +			break;
  1.5115 +			}
  1.5116 +		}
  1.5117 +	
  1.5118 +	return inList;
  1.5119 +	}