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,¶ms);
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,¶ms, 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 + }