1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/textandloc/fontservices/fontstore/src/OPENFONT.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,2195 @@
1.4 +/*
1.5 +* Copyright (c) 2003-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 <fntstore.h>
1.23 +#include <gdi.h>
1.24 +#include "FNTSTD.H"
1.25 +#include <graphics/shapeimpl.h>
1.26 +#include "ShaperCache.H"
1.27 +#include "openfontsprivate.h"
1.28 +#include <linkedfonts.h>
1.29 +#include "linkedfontsprivate.h"
1.30 +#include <graphics/openfontrasterizer.h>
1.31 +#include <graphics/gdi/glyphsample.h>
1.32 +#include <e32math.h>
1.33 +
1.34 +#include "OstTraceDefinitions.h"
1.35 +#ifdef OST_TRACE_COMPILER_IN_USE
1.36 +#include "OPENFONTTraces.h"
1.37 +#endif
1.38 +
1.39 +
1.40 +const TInt KSessionCacheEntries = 512;
1.41 +const TInt KDefaultSlantFactor = 20480;
1.42 +const TInt KOneIn16Dot16FixedPointFormat = 65536;
1.43 +
1.44 +template<class T>
1.45 +ROffsetArray<T>::ROffsetArray()
1.46 + : iOffset(0), iCount(0)
1.47 + {}
1.48 +
1.49 +template<class T>
1.50 +TInt ROffsetArray<T>::Create(RHeap* aHeap, TInt aCount)
1.51 + {
1.52 + if (iOffset != 0)
1.53 + {
1.54 + return KErrAlreadyExists;
1.55 + }
1.56 + TAny* p = aHeap->AllocZ(aCount * sizeof(TInt));
1.57 + if (p == NULL)
1.58 + {
1.59 + return KErrNoMemory;
1.60 + }
1.61 + iOffset = (TInt)p - (TInt)this;
1.62 + iCount = aCount;
1.63 + return KErrNone;
1.64 + }
1.65 +
1.66 +template<class T>
1.67 +void ROffsetArray<T>::Close(RHeap* aHeap)
1.68 + {
1.69 + if (iOffset != 0)
1.70 + {
1.71 + aHeap->Free(PtrAdd(this, iOffset));
1.72 + }
1.73 + iOffset = 0;
1.74 + iCount = 0;
1.75 + }
1.76 +
1.77 +template<class T>
1.78 +TInt ROffsetArray<T>::Count() const
1.79 + {
1.80 + return iCount;
1.81 + }
1.82 +
1.83 +template<class T>
1.84 +T* ROffsetArray<T>::operator[](TInt aIndex) const
1.85 + {
1.86 + TInt e = ((TInt*)PtrAdd(this, iOffset))[aIndex];
1.87 + return e != 0 ? (T*)PtrAdd(this, e) : NULL;
1.88 + }
1.89 +
1.90 +template<class T>
1.91 +void ROffsetArray<T>::SetAt(TInt aIndex, T* aEntry)
1.92 + {
1.93 + ((TInt*)PtrAdd(this, iOffset))[aIndex] = aEntry ? (TInt)aEntry - (TInt)this : 0;
1.94 + }
1.95 +
1.96 +
1.97 +/*COpenFontGlyphCache*/
1.98 +
1.99 +TShapeHeader* COpenFontGlyphCache::SearchShaperCache(TInt aSessionHandle, TFontShapeFunctionParameters*& aParams)
1.100 + {
1.101 + if (iShaperCacheSentinel == NULL)
1.102 + return NULL;
1.103 + COpenFontShaperCacheEntry* searchNode = iShaperCacheSentinel->iNext;
1.104 +
1.105 + TInt start = aParams->iStart;
1.106 + TInt end = aParams->iEnd;
1.107 + TInt script = aParams->iScript;
1.108 + const TUint16* text = (TUint16*)aParams->iText->Ptr();
1.109 + TUint16* cachedText;
1.110 + const TUint16* copyOfText;
1.111 + TInt noOfChars = end - start;
1.112 + TInt textIsSame = 1;
1.113 + while (searchNode != iShaperCacheSentinel)
1.114 + {
1.115 + //Future work: add Script check for further script support
1.116 + //Future work: add Language check for further language support
1.117 + if ((searchNode->iEnd == end) && (searchNode->iStart == start) && (searchNode->iScript == script))
1.118 + {
1.119 + // Check for the entire text (within the context) coming in.
1.120 + TInt i = 0;
1.121 + copyOfText = text + start;
1.122 + cachedText = (TUint16*)searchNode->iText + searchNode->iStart;
1.123 + textIsSame = 1;
1.124 + while (i < noOfChars && textIsSame != 0)
1.125 + {
1.126 + if (*cachedText != *copyOfText)
1.127 + textIsSame = 0;
1.128 + i++;
1.129 + copyOfText++;
1.130 + cachedText++;
1.131 + };
1.132 +
1.133 + if (textIsSame)
1.134 + {
1.135 + if (searchNode == iShaperCacheSentinel->iNext)
1.136 + {
1.137 + // now we need to update the reference count here for that session
1.138 + if (searchNode->IncRefCount(aSessionHandle) != KErrNone)
1.139 + return NULL;
1.140 + return iShaperCacheSentinel->iNext->iShapeHeader;
1.141 + }
1.142 + // We have found a node, now put that node to the top of the list as the most recently used node
1.143 + searchNode->iPrevious->iNext = searchNode->iNext;
1.144 + searchNode->iNext->iPrevious = searchNode->iPrevious;
1.145 +
1.146 + searchNode->iNext = iShaperCacheSentinel->iNext;
1.147 + iShaperCacheSentinel->iNext->iPrevious = searchNode;
1.148 + iShaperCacheSentinel->iNext = searchNode;
1.149 + searchNode->iPrevious = iShaperCacheSentinel;
1.150 + if (searchNode->IncRefCount(aSessionHandle)!= KErrNone)
1.151 + return NULL;
1.152 + return searchNode->iShapeHeader;
1.153 + }
1.154 + }
1.155 + searchNode = searchNode->iNext;
1.156 + }
1.157 + return NULL;
1.158 + }
1.159 +
1.160 +TShapeHeader* COpenFontGlyphCache::Insert(TInt aSessionHandle, RHeap* aHeap, CShaper::TInput aInput, TShapeHeader* aShapeHeader, TInt& aAddedBytes)
1.161 + {
1.162 + TInt heapSizeBefAloc = 0;
1.163 + aHeap->AllocSize(heapSizeBefAloc);
1.164 +
1.165 + COpenFontShaperCacheEntry* new_entry;
1.166 + new_entry = COpenFontShaperCacheEntry::New(aHeap, aInput, aShapeHeader);
1.167 + if (new_entry != NULL)
1.168 + {
1.169 + // increase the reference count for this
1.170 + TInt ret=new_entry->IncRefCount(aSessionHandle);
1.171 + if (ret != KErrNone)
1.172 + {
1.173 + //no memory here
1.174 + COpenFontShaperCacheEntry::Delete(aHeap, new_entry);
1.175 + return NULL;
1.176 + }
1.177 + new_entry->iNext = iShaperCacheSentinel->iNext;
1.178 + iShaperCacheSentinel->iNext->iPrevious = new_entry;
1.179 + iShaperCacheSentinel->iNext = new_entry;
1.180 + new_entry->iPrevious = iShaperCacheSentinel;
1.181 +
1.182 + iNumberOfShaperCacheEntries++;
1.183 + TInt heapSizeOnAloc = 0;
1.184 + aHeap->AllocSize(heapSizeOnAloc);
1.185 + aAddedBytes = heapSizeOnAloc - heapSizeBefAloc;
1.186 +
1.187 + // Update the amount of memory used in creation of a new entry
1.188 + iShapingInfoCacheMemory += heapSizeOnAloc - heapSizeBefAloc;
1.189 +
1.190 + return new_entry->iShapeHeader;
1.191 + }
1.192 + return NULL;
1.193 + }
1.194 +
1.195 +/**
1.196 +Searches from the least recently used towards the most recently used
1.197 +and try to free entry that is no longer referenced
1.198 +*/
1.199 +TInt COpenFontGlyphCache::DeleteLeastRecentlyUsedEntry(RHeap* aHeap)
1.200 + {
1.201 + // start from the least recently used
1.202 + COpenFontShaperCacheEntry* deleteNode = iShaperCacheSentinel->iPrevious;
1.203 +
1.204 + // if empty list there is nothing to delete
1.205 + if (deleteNode == iShaperCacheSentinel)
1.206 + return 0;
1.207 + // else navigating starting from the LRU entry
1.208 + while (deleteNode != iShaperCacheSentinel)
1.209 + {
1.210 + // cannot delete if the iHandleRefCount is greater than zero
1.211 + if (deleteNode->iHandleRefCount>0)
1.212 + {
1.213 + deleteNode = deleteNode->iPrevious;
1.214 + continue;
1.215 + }
1.216 +
1.217 + // otherwise we can delete the entry
1.218 + deleteNode->iPrevious->iNext = deleteNode->iNext;
1.219 + deleteNode->iNext->iPrevious = deleteNode->iPrevious;
1.220 +
1.221 + TInt heapSizeBeforeDel = 0;
1.222 + TInt heapSizeAfterDel = 0;
1.223 + aHeap->AllocSize(heapSizeBeforeDel);
1.224 + COpenFontShaperCacheEntry::Delete(aHeap, deleteNode);
1.225 + aHeap->AllocSize(heapSizeAfterDel);
1.226 + TInt deletedBytes = heapSizeBeforeDel - heapSizeAfterDel;
1.227 +
1.228 + iNumberOfShaperCacheEntries--;
1.229 + iShapingInfoCacheMemory -= deletedBytes;
1.230 +
1.231 + return deletedBytes;
1.232 + }
1.233 + // we have navigated through the whole list and cannot delete anything
1.234 + return 0;
1.235 + }
1.236 +
1.237 +TInt COpenFont::DecrementCachedRefCount(TInt aSessionHandle, TShapeHeader* aShapeHeader, TBool aResetAll)
1.238 + {
1.239 + COpenFontShaperCacheEntry* ptr=NULL;
1.240 + COpenFontGlyphCache* glyphCache=GetGlyphCache();
1.241 + if (glyphCache != NULL)
1.242 + ptr=glyphCache->iShaperCacheSentinel;
1.243 + if (ptr == NULL)
1.244 + return KErrNone;
1.245 +
1.246 + TInt ret = KErrNotFound;
1.247 + CFontStore* thisFontStore = File()->GetFontStore();
1.248 + TInt allocBefDec = 0;
1.249 + TInt allocAfterDec = 0;
1.250 + TInt deletedBytes = 0;
1.251 +
1.252 + // loop through the cache entry to decrement the ref count for a particular session
1.253 + while (ptr->iNext != NULL)
1.254 + {
1.255 + if (aResetAll)
1.256 + {
1.257 + // we want to reset any cache that has a matching the session handle
1.258 + // i.e. here we dont care about which TShapeHeader and hence we can
1.259 + // ignore the error code here if not found
1.260 +
1.261 + // Always update the memory usage of the cache as decreasing the ref count
1.262 + // releases memory
1.263 + iHeap->AllocSize(allocBefDec);
1.264 +
1.265 + ptr->DecRefCount(aSessionHandle, ETrue);
1.266 +
1.267 + iHeap->AllocSize(allocAfterDec);
1.268 + deletedBytes = allocBefDec - allocAfterDec;
1.269 + glyphCache->iShapingInfoCacheMemory -= deletedBytes;
1.270 + thisFontStore->SetShaperCacheMemUsage(thisFontStore->GetShaperCacheMemUsage() - deletedBytes);
1.271 +
1.272 + ret=KErrNone;
1.273 + }
1.274 + else if (ptr->iShapeHeader != NULL && ptr->iShapeHeader==aShapeHeader)
1.275 + {
1.276 + // Always update the memory usage of the cache as decreasing the ref count
1.277 + // releases memory
1.278 + iHeap->AllocSize(allocBefDec);
1.279 +
1.280 + ptr->DecRefCount(aSessionHandle);
1.281 +
1.282 + iHeap->AllocSize(allocAfterDec);
1.283 + deletedBytes = allocBefDec - allocAfterDec;
1.284 + glyphCache->iShapingInfoCacheMemory -= deletedBytes;
1.285 + thisFontStore->SetShaperCacheMemUsage(thisFontStore->GetShaperCacheMemUsage() - deletedBytes);
1.286 +
1.287 + return KErrNone;
1.288 + }
1.289 + ptr=ptr->iNext;
1.290 + if (ptr == glyphCache->iShaperCacheSentinel)
1.291 + {
1.292 + break;
1.293 + }
1.294 + }
1.295 + return ret;
1.296 + }
1.297 +
1.298 +TInt COpenFont::FreeShaperCacheMemory(TInt aBytesNeeded)
1.299 + {
1.300 + TInt totalDeletedBytes = 0;
1.301 + TInt tempDeletedBytes = 0;
1.302 + CFontStore* thisFontStore = File()->GetFontStore();
1.303 +
1.304 + if (aBytesNeeded <= KMaxShaperSesssionCacheMemory)
1.305 + {
1.306 + // delete LRU entries from all the caches except the one owned by this COpenFont
1.307 + // The 'if' condition here is to avoid looping through every font in the system
1.308 + // if only one of the them has a non-empty cache. In situations where only one
1.309 + // cache is left and it is full, this strategy makes freeing the memory faster.
1.310 + if (thisFontStore->GetNumShaperCaches() > 1)
1.311 + {
1.312 + CArrayPtrFlat<COpenFont>* fontList;
1.313 + CArrayPtrFlat<COpenFontFile>* fontFileList = thisFontStore->GetOpenFontFileList();
1.314 + TInt numberOfFontFiles = fontFileList->Count();
1.315 + TInt i = 0;
1.316 + while ((totalDeletedBytes < aBytesNeeded) && (i < numberOfFontFiles))
1.317 + {
1.318 + fontList = (*fontFileList)[i]->GetOpenFontList();
1.319 + TInt fontListCount=fontList->Count();
1.320 + TInt j = 0;
1.321 + while ((totalDeletedBytes < aBytesNeeded) && (j < fontListCount))
1.322 + {
1.323 + COpenFont* open_font = (*fontList)[j];
1.324 + COpenFontGlyphCache* glyphCache = open_font->GetGlyphCache();
1.325 + if ((open_font != this) && (glyphCache != NULL))
1.326 + {
1.327 + while ((totalDeletedBytes < aBytesNeeded) && (!glyphCache->ShaperCacheIsEmpty()))
1.328 + {
1.329 + totalDeletedBytes += glyphCache->DeleteLeastRecentlyUsedEntry(iHeap);
1.330 + if (glyphCache->ShaperCacheIsEmpty())
1.331 + {
1.332 + thisFontStore->DecNumShaperCaches();
1.333 + }
1.334 +
1.335 + // If totalDeletedBytes is zero mean we cannot delete from this font
1.336 + if (totalDeletedBytes == 0)
1.337 + {
1.338 + break;
1.339 + }
1.340 + }
1.341 + }
1.342 + j++;
1.343 + }
1.344 + i++;
1.345 + }
1.346 + }
1.347 +
1.348 + // If deleted bytes are still less than the required one delete from this font
1.349 + COpenFontGlyphCache* glyphCache = GetGlyphCache();
1.350 + if (glyphCache != NULL)
1.351 + {
1.352 + while (totalDeletedBytes < aBytesNeeded && !glyphCache->ShaperCacheIsEmpty())
1.353 + {
1.354 + tempDeletedBytes = glyphCache->DeleteLeastRecentlyUsedEntry(iHeap);
1.355 + if (tempDeletedBytes == 0)
1.356 + break;
1.357 + totalDeletedBytes += tempDeletedBytes;
1.358 + }
1.359 + } //if(glyphCache)
1.360 + } //if(aBytesNeeded <= KMaxShaperSesssionCacheMemory)
1.361 +
1.362 + // Update the global CFontStore cache memory count
1.363 + if (totalDeletedBytes > 0)
1.364 + {
1.365 + thisFontStore->SetShaperCacheMemUsage(thisFontStore->GetShaperCacheMemUsage() - totalDeletedBytes);
1.366 + }
1.367 +
1.368 + return totalDeletedBytes;
1.369 + }
1.370 +
1.371 +TShapeHeader* COpenFont::InsertShapedDataIntoCache(TInt aSessionHandle,TFontShapeFunctionParameters* aParams, TShapeHeader* aShapeHeader)
1.372 + {
1.373 + CShaper::TInput input;
1.374 + input.iEnd = aParams->iEnd;
1.375 + input.iStart = aParams->iStart;
1.376 + input.iScript = aParams->iScript;
1.377 + input.iLanguage = aParams->iLanguage;
1.378 + input.iText = aParams->iText;
1.379 + input.iMaximumAdvance = KMaxTInt;
1.380 + input.iFlags = 0;
1.381 + input.iSessionHandle = aSessionHandle;
1.382 + input.iReserved1 = 0;
1.383 +
1.384 + CFontStore* thisFontStore = File()->GetFontStore();
1.385 +
1.386 + // Create the glyph cache if it doesn't already exist.
1.387 + // This call can only come from FBSERV
1.388 + COpenFontGlyphCache* glyphCache = GetGlyphCache();
1.389 + if (glyphCache == NULL)
1.390 + {
1.391 + glyphCache = (COpenFontGlyphCache*) iHeap->Alloc(sizeof(COpenFontGlyphCache));
1.392 + if (glyphCache == NULL) // no memory
1.393 + {
1.394 + return NULL;
1.395 + }
1.396 + new (glyphCache) COpenFontGlyphCache(iHeap);
1.397 + SetGlyphCache(glyphCache);
1.398 + }
1.399 + // If there is no sentinel present, i.e. new cache
1.400 + if (glyphCache->iShaperCacheSentinel == NULL)
1.401 + {
1.402 + // Create a sentinel
1.403 + glyphCache->iShaperCacheSentinel = COpenFontShaperCacheEntry::New(iHeap);
1.404 + if (glyphCache->iShaperCacheSentinel == NULL)
1.405 + {
1.406 + // no memory
1.407 + return NULL;
1.408 + }
1.409 + glyphCache->iShaperCacheSentinel->iNext = glyphCache->iShaperCacheSentinel;
1.410 + glyphCache->iShaperCacheSentinel->iPrevious = glyphCache->iShaperCacheSentinel;
1.411 + glyphCache->iNumberOfShaperCacheEntries = 1;
1.412 + }
1.413 +
1.414 + // Before inserting into this cache, check if it was empty.
1.415 + // If empty, then increment the global cache count signifying one more cache is active
1.416 + if (glyphCache->ShaperCacheIsEmpty())
1.417 + {
1.418 + thisFontStore->IncNumShaperCaches();
1.419 + }
1.420 +
1.421 + TInt addedBytes = 0;
1.422 + TShapeHeader* cached_header = NULL;
1.423 +
1.424 + // Insert a new entry and return the newly inserted TShapeHeader entry
1.425 + cached_header = glyphCache->Insert(aSessionHandle, iHeap, input, aShapeHeader, addedBytes);
1.426 + if (cached_header == NULL)
1.427 + return NULL;
1.428 +
1.429 + // If the memory used by all the caches is greater than KMaxShaperSesssionCacheMemory, then
1.430 + // free some memory by releasing the same amount of memory that was just added
1.431 + if (thisFontStore->GetShaperCacheMemUsage() + addedBytes > KMaxShaperSesssionCacheMemory)
1.432 + {
1.433 + FreeShaperCacheMemory(addedBytes);
1.434 + }
1.435 +
1.436 + // Now update the memory count with the added memory for the new entry
1.437 + thisFontStore->SetShaperCacheMemUsage(thisFontStore->GetShaperCacheMemUsage() + addedBytes);
1.438 + return cached_header;
1.439 + }
1.440 +
1.441 +TShapeHeader* COpenFont::GetShapedData(TInt aSessionHandle, TFontShapeFunctionParameters* aParams)
1.442 + {
1.443 + COpenFontGlyphCache* glyphCache = GetGlyphCache();
1.444 + if (glyphCache == NULL)
1.445 + return NULL;
1.446 +
1.447 + TShapeHeader* cachedHeader = NULL;
1.448 + CFontStore* thisFontStore = File()->GetFontStore();
1.449 +
1.450 + // Always update the memory usage of the cache as increasing the reference count of a found header uses up memory
1.451 + TInt allocBefInc = 0;
1.452 + TInt allocAfterInc = 0;
1.453 + iHeap->AllocSize(allocBefInc);
1.454 +
1.455 + cachedHeader = glyphCache->SearchShaperCache(aSessionHandle,aParams);
1.456 +
1.457 + iHeap->AllocSize(allocAfterInc);
1.458 + TInt addedBytes = allocAfterInc - allocBefInc;
1.459 + glyphCache->iShapingInfoCacheMemory += addedBytes;
1.460 + thisFontStore->SetShaperCacheMemUsage(thisFontStore->GetShaperCacheMemUsage() + addedBytes);
1.461 +
1.462 + return cachedHeader;
1.463 + }
1.464 +
1.465 +TBool COpenFontGlyphCache::ShaperCacheIsEmpty()
1.466 + {
1.467 + if (iShaperCacheSentinel == NULL)
1.468 + return ETrue;
1.469 +
1.470 + if (iShaperCacheSentinel->iNext == iShaperCacheSentinel)
1.471 + return ETrue;
1.472 + else
1.473 + return EFalse;
1.474 + }
1.475 +
1.476 +/**
1.477 +C++ constructor taking shared heap, session cache list and font file as parameters.
1.478 +
1.479 +You must either use this, or the other constructor, when creating your derived
1.480 +object. This constructor might be used, in preference to the other, if there
1.481 +is only a single typeface in the font file.
1.482 +
1.483 +@param aHeap The shared heap.
1.484 +@param aSessionCacheList The session cache list.
1.485 +@param aFile A pointer to the COpenFontFile object creating this COpenFont.
1.486 +e.g. when creating a COpenFont the COpenFontFile derived object would pass
1.487 +it this.
1.488 +*/
1.489 +EXPORT_C COpenFont::COpenFont(RHeap* aHeap,COpenFontSessionCacheList* aSessionCacheList,
1.490 + COpenFontFile* aFile):
1.491 + iHeap(aHeap),
1.492 + iShaper(NULL),
1.493 + iFaceIndex(0)
1.494 + {
1.495 + SetFile(aFile);
1.496 + SetSessionCacheList(aSessionCacheList);
1.497 + }
1.498 +
1.499 +/**
1.500 +C++ constructor taking shared heap, session cache list, font file and face
1.501 +index as parameters.
1.502 +
1.503 +You must either use this, or the other constructor, when creating your derived
1.504 +object. This constructor would be used if the font file contains more than
1.505 +one typeface.
1.506 +
1.507 +@param aHeap The shared heap.
1.508 +@param aSessionCacheList The session cache list.
1.509 +@param aFile A pointer to the COpenFontFile object creating this COpenFont.
1.510 +e.g. when creating a COpenFont the COpenFontFile derived object would pass
1.511 +it this.
1.512 +@param aFaceIndex The index of the typeface within the font file aFile.
1.513 +*/
1.514 +EXPORT_C COpenFont::COpenFont(RHeap* aHeap,COpenFontSessionCacheList* aSessionCacheList, COpenFontFile* aFile,TInt aFaceIndex) :
1.515 + iHeap(aHeap),
1.516 + iShaper(NULL),
1.517 + iFaceIndex(aFaceIndex)
1.518 + {
1.519 + SetFile(aFile);
1.520 + SetSessionCacheList(aSessionCacheList);
1.521 + }
1.522 +
1.523 +/**
1.524 +Destructor
1.525 +
1.526 +This function frees all memory owned by the object, including the session
1.527 +cache list and the glyph list, prior to its destruction.
1.528 +*/
1.529 +EXPORT_C COpenFont::~COpenFont()
1.530 + {
1.531 + //Delete the shaper
1.532 + delete iShaper;
1.533 +
1.534 + File()->GetFontStore()->CleanupCacheOnOpenFontRemoval(this);
1.535 +
1.536 + COpenFontGlyphCache* glyphCache = GetGlyphCache();
1.537 + if (glyphCache != NULL)
1.538 + {
1.539 + glyphCache->iGlyphTreeById.ResetAndDestroy();
1.540 + glyphCache->iGlyphTreeByUnicode.ResetAndDestroy();
1.541 +
1.542 + // Delete the shaper cache as well
1.543 + if (glyphCache->iShaperCacheSentinel)
1.544 + {
1.545 + COpenFontShaperCacheEntry* previous = NULL;
1.546 + COpenFontShaperCacheEntry* si = glyphCache->iShaperCacheSentinel->iPrevious;
1.547 + TInt heapBefore = 0;
1.548 + TInt heapAfter = 0;
1.549 + iHeap->AllocSize(heapBefore);
1.550 + while (glyphCache->iNumberOfShaperCacheEntries > 0)
1.551 + {
1.552 + previous = si->iPrevious;
1.553 + COpenFontShaperCacheEntry::Delete(iHeap, si);
1.554 + si = previous;
1.555 + glyphCache->iNumberOfShaperCacheEntries--;
1.556 + }
1.557 + iHeap->AllocSize(heapAfter);
1.558 + File()->GetFontStore()->SetShaperCacheMemUsage(File()->GetFontStore()->GetShaperCacheMemUsage() - (heapBefore - heapAfter));
1.559 + File()->GetFontStore()->DecNumShaperCaches();
1.560 + }
1.561 +
1.562 + iHeap->Free(glyphCache);
1.563 + }
1.564 + COpenFontSessionCacheList* sessionCacheList = SessionCacheList();
1.565 + if (sessionCacheList != NULL)
1.566 + {
1.567 + sessionCacheList->DeleteFontGlyphs(iHeap, this);
1.568 + }
1.569 + COpenFontFile* file = File();
1.570 + if (file != NULL)
1.571 + {
1.572 + file->RemoveFontFromList(this);
1.573 + }
1.574 + }
1.575 +
1.576 +EXPORT_C void COpenFont::operator delete(TAny *aFont)
1.577 + {
1.578 + if(aFont != NULL)
1.579 + {
1.580 + COpenFont* f = (COpenFont*)aFont;
1.581 + if (f->iHeap)
1.582 + f->iHeap->Free(aFont);
1.583 + }
1.584 + }
1.585 +
1.586 +/**
1.587 +Rasterize a glyph
1.588 +
1.589 +This function may only be called via an FBSERV message.
1.590 +
1.591 +@param aSessionHandle Session handle of the calling session
1.592 +@param aCode Unicode value or glyph code if top bit is set
1.593 +@param aGlyphData
1.594 + Output data. May be null, in which case output may be
1.595 + obtained through a call to GetCharacterData.
1.596 +
1.597 +@return
1.598 + ETrue if aGlyphData contains valid data (that is, if aGlyphData->Bitmap()
1.599 + and aGlyphData->Metrics() are valid), EFalse otherwise.
1.600 +*/
1.601 +TBool COpenFont::Rasterize(TInt aSessionHandle, TInt aCode,
1.602 + TOpenFontGlyphData* aGlyphData)
1.603 + {
1.604 + // create the cache if it doesn't exisit. As this call can only come from
1.605 + // FBSERV if the chunk has to be resized then no panic will happen.
1.606 + COpenFontGlyphCache* glyphCache = GetGlyphCache();
1.607 + if (glyphCache == NULL)
1.608 + {
1.609 + glyphCache = (COpenFontGlyphCache*)iHeap->Alloc(sizeof(COpenFontGlyphCache));
1.610 + if (glyphCache == NULL) // no memory
1.611 + {
1.612 + return EFalse;
1.613 + }
1.614 + new(glyphCache) COpenFontGlyphCache(iHeap);
1.615 + SetGlyphCache(glyphCache);
1.616 + }
1.617 +
1.618 + // Look in the Font Cache
1.619 + const COpenFontGlyph* g = FontCacheGlyph(aCode);
1.620 +
1.621 + // If it has already been rasterized return it.
1.622 + if (g != NULL)
1.623 + {
1.624 + if (aGlyphData != NULL)
1.625 + {
1.626 + aGlyphData->SetMetricsPointer(&g->iMetrics);
1.627 + aGlyphData->SetBitmapPointer(g->Bitmap());
1.628 + }
1.629 +
1.630 + return ETrue;
1.631 + }
1.632 +
1.633 + // Rasterize the glyph.
1.634 + TOpenFontGlyphData* temp_glyph_data = NULL;
1.635 + TInt error = KErrNone;
1.636 + TRAP(error, RasterizeHelperL(aCode, aGlyphData, temp_glyph_data));
1.637 + if (error != KErrNone)
1.638 + {
1.639 + iHeap->Free(temp_glyph_data);
1.640 + return EFalse;
1.641 + }
1.642 +
1.643 + TBool glyph_data_valid = ETrue;
1.644 + const TOpenFontGlyphData* cur_glyph_data = temp_glyph_data ? temp_glyph_data : aGlyphData;
1.645 + COpenFontGlyph* new_glyph = NULL;
1.646 +
1.647 + // If the maximum per-font cache memory will not be exceeded, put the glyph into the font cache.
1.648 + TInt bytes = sizeof(COpenFontGlyph) + cur_glyph_data->BytesNeeded();
1.649 + if(glyphCache != NULL && bytes + glyphCache->iGlyphCacheMemory <= KMaxGlyphCacheMemory)
1.650 + {
1.651 + new_glyph = COpenFontGlyph::New(iHeap, aCode, cur_glyph_data->GlyphIndex(), *cur_glyph_data->Metrics(), cur_glyph_data->Bitmap());
1.652 + if (new_glyph != NULL)
1.653 + {
1.654 + if ((aCode & 0x80000000) != 0)
1.655 + {
1.656 + error = glyphCache->iGlyphTreeById.SetAt(aCode & 0x7FFFFFFF, new_glyph);
1.657 + }
1.658 + else
1.659 + {
1.660 + error = glyphCache->iGlyphTreeByUnicode.SetAt(aCode, new_glyph);
1.661 + }
1.662 + if (error == KErrNone)
1.663 + {
1.664 + glyphCache->iGlyphCacheMemory += bytes;
1.665 + }
1.666 + else
1.667 + {
1.668 + iHeap->Free(new_glyph);
1.669 + new_glyph = NULL;
1.670 + }
1.671 + }
1.672 + }
1.673 + // Otherwise put the glyph into the per-session cache.
1.674 + else
1.675 + {
1.676 + // Look in the session cache. Do not expect to find the glyph here
1.677 + // since the session cache has already been searched client-side.
1.678 + // However, SessionCacheGlyph() is called so that the session cache is
1.679 + // created if needed and an index is found where the new glyph will be
1.680 + // placed when added to the session cache.
1.681 + COpenFontSessionCache* cache = NULL;
1.682 + TInt index = 0;
1.683 + (void)SessionCacheGlyph(iHeap, aSessionHandle, aCode, cache, index, ETrue);
1.684 + if (cache == NULL)
1.685 + {
1.686 + iHeap->Free(temp_glyph_data);
1.687 + return EFalse;
1.688 + }
1.689 +
1.690 + COpenFontSessionCacheEntry* new_entry =
1.691 + COpenFontSessionCacheEntry::New(iHeap, this, aCode, cur_glyph_data->GlyphIndex(), *cur_glyph_data->Metrics(), cur_glyph_data->Bitmap());
1.692 + new_glyph = new_entry;
1.693 + if (new_entry != NULL)
1.694 + {
1.695 + cache->Insert(iHeap, new_entry, index);
1.696 + }
1.697 + }
1.698 +
1.699 + if (temp_glyph_data != NULL)
1.700 + {
1.701 + iHeap->Free(temp_glyph_data);
1.702 + }
1.703 +
1.704 + // Fix up the returned glyph data pointers to point to the actual data.
1.705 + if (new_glyph == NULL)
1.706 + glyph_data_valid = EFalse;
1.707 + else if (aGlyphData != NULL)
1.708 + {
1.709 + aGlyphData->SetMetricsPointer(&new_glyph->iMetrics);
1.710 + aGlyphData->SetBitmapPointer(new_glyph->Bitmap());
1.711 + }
1.712 +
1.713 + return glyph_data_valid;
1.714 + }
1.715 +
1.716 +void COpenFont::RasterizeHelperL(TInt aCode, TOpenFontGlyphData* aGlyphData, TOpenFontGlyphData*& aTempGlyphData)
1.717 + {
1.718 + aTempGlyphData = 0;
1.719 + MOpenFontShapingExtension* extensionInterface = 0;
1.720 +
1.721 + // if the MSB is set this is a request to rasterize a glyph code
1.722 + // rather than a unicode value. This can only be done if the rasterizer
1.723 + // supports the extended API.
1.724 + if ( aCode & 0x80000000 )
1.725 + {
1.726 + aCode = GLYPH_CODE(aCode);
1.727 + // get the extension API for RasterizeGlyphL() if available
1.728 + TAny* ext = NULL;
1.729 + ExtendedInterface(KUidOpenFontShapingExtension, ext);
1.730 + extensionInterface = reinterpret_cast<MOpenFontShapingExtension*>(ext);
1.731 +
1.732 + if (extensionInterface == NULL)
1.733 + // an attempt to rasterize a glyph when the rasterizer does not
1.734 + // support it; best to do nothing
1.735 + return;
1.736 + }
1.737 + TOpenFontGlyphData* currGlyphData = aGlyphData;
1.738 +
1.739 + if (currGlyphData == NULL)
1.740 + {
1.741 + aTempGlyphData = TOpenFontGlyphData::New(iHeap, 0);
1.742 + if (!aTempGlyphData)
1.743 + User::Leave(KErrNoMemory);
1.744 + currGlyphData = aTempGlyphData;
1.745 + }
1.746 +
1.747 + if (extensionInterface != NULL)
1.748 + extensionInterface->RasterizeGlyphL(aCode, currGlyphData);
1.749 + else
1.750 + RasterizeL(aCode, currGlyphData);
1.751 +
1.752 + // If the GlyphData object was not large enough, create a temporary one
1.753 + // that can then be deleted by the caller.
1.754 + if (currGlyphData->Overflow())
1.755 + {
1.756 + TInt bytesNeeded = currGlyphData->BytesNeeded();
1.757 + if (aTempGlyphData)
1.758 + iHeap->Free(aTempGlyphData);
1.759 + aTempGlyphData = TOpenFontGlyphData::New(iHeap, bytesNeeded);
1.760 + if (aTempGlyphData == NULL)
1.761 + User::Leave(KErrNoMemory);
1.762 +
1.763 + currGlyphData = aTempGlyphData;
1.764 +
1.765 + // If the extension interface was used above, then use again here
1.766 + if (extensionInterface != NULL)
1.767 + extensionInterface->RasterizeGlyphL(aCode, currGlyphData);
1.768 + else
1.769 + RasterizeL(aCode, currGlyphData);
1.770 + }
1.771 +
1.772 + if (currGlyphData->Metrics() == NULL)
1.773 + {
1.774 + User::Leave(KErrArgument);
1.775 + }
1.776 + }
1.777 +
1.778 +/** @internalComponent */
1.779 +void COpenFont::SetShaper(CShaper* aShaper)
1.780 + {
1.781 + iShaper = aShaper;
1.782 + }
1.783 +
1.784 +/** @internalComponent */
1.785 +CShaper* COpenFont::GetShaper()
1.786 + {
1.787 + return iShaper;
1.788 + }
1.789 +
1.790 +/** @internalComponent */
1.791 +TBool COpenFont::HasShaper() const
1.792 + {
1.793 + return iShaper != NULL;
1.794 + }
1.795 +
1.796 +void COpenFont::DeleteShaper() const
1.797 + {
1.798 + delete iShaper;
1.799 + }
1.800 +
1.801 +TInt COpenFont::GetFontTable(TUint32 aTag, TAny*& aTableContent, TInt& aLength)
1.802 + {
1.803 + // get the extension API for GetTrueTypeTable() if available
1.804 + TAny* ext = NULL;
1.805 + ExtendedInterface(KUidOpenFontTrueTypeExtension, ext);
1.806 + MOpenFontTrueTypeExtension* extensionInterface =
1.807 + reinterpret_cast<MOpenFontTrueTypeExtension*>(ext);
1.808 +
1.809 + TInt ret = KErrNone;
1.810 + if (extensionInterface == NULL)
1.811 + {
1.812 + ret = KErrNotSupported;
1.813 + }
1.814 + else
1.815 + {
1.816 + TUint32 tag = aTag;
1.817 + TInt len = 0;
1.818 + aTableContent = extensionInterface->GetTrueTypeTable(ret, tag, &len);
1.819 + if (KErrNone == ret)
1.820 + {
1.821 + aLength = len;
1.822 + }
1.823 + }
1.824 + return ret;
1.825 + }
1.826 +
1.827 +TInt COpenFont::GetGlyphOutline(TUint aCode,
1.828 + TBool aHinted, TAny*& aOutline, TInt &aLength)
1.829 + {
1.830 + // get the extension API for GetTrueTypeTable() if available
1.831 + TAny* ext = NULL;
1.832 + ExtendedInterface(KUidOpenFontGlyphOutlineExtension, ext);
1.833 + MOpenFontGlyphOutlineExtension *extensionInterface =
1.834 + reinterpret_cast<MOpenFontGlyphOutlineExtension*>(ext);
1.835 +
1.836 + TInt ret = KErrNone;
1.837 + if (extensionInterface == NULL)
1.838 + {
1.839 + ret = KErrNotSupported;
1.840 + }
1.841 + else
1.842 + {
1.843 + ret = extensionInterface->GetGlyphOutline(aCode, ETrue,
1.844 + aHinted, aOutline, aLength);
1.845 + }
1.846 + return ret;
1.847 + }
1.848 +
1.849 +
1.850 +/**
1.851 +A constructor initialised with a TCharacterMetrics object.
1.852 +
1.853 +This is the old-style character metrics object. As for other T classes, there
1.854 +is no need to explicitly cleanup TOpenFontCharMetrics objects.
1.855 +
1.856 +@param aMetrics The old-style metrics object.
1.857 +*/
1.858 +EXPORT_C TOpenFontCharMetrics::TOpenFontCharMetrics(const TCharacterMetrics& aMetrics)
1.859 + {
1.860 + iWidth = (TInt16)(aMetrics.iMoveInPixels - aMetrics.iLeftAdjustInPixels - aMetrics.iRightAdjustInPixels);
1.861 + iHeight = aMetrics.iHeightInPixels;
1.862 + iHorizBearingX = aMetrics.iLeftAdjustInPixels;
1.863 + iHorizBearingY = aMetrics.iAscentInPixels;
1.864 + iHorizAdvance = aMetrics.iMoveInPixels;
1.865 + iVertBearingX = 0;
1.866 + iVertBearingY = 0;
1.867 + iVertAdvance = aMetrics.iHeightInPixels;
1.868 + iGlyphBitmapType = 0;
1.869 + }
1.870 +
1.871 +/**
1.872 +Converts a TOpenFontCharacterMetrics object to a TCharacterMetrics.
1.873 +
1.874 +@param aMetrics On return, contains the character's old-style metrics.
1.875 +@return ETrue if it was possible to get the metrics, otherwise EFalse.
1.876 +*/
1.877 +EXPORT_C TBool TOpenFontCharMetrics::GetTCharacterMetrics(TCharacterMetrics& aMetrics) const
1.878 + {
1.879 + aMetrics.iAscentInPixels = iHorizBearingY;
1.880 + aMetrics.iHeightInPixels = iHeight;
1.881 + aMetrics.iLeftAdjustInPixels = iHorizBearingX;
1.882 + aMetrics.iMoveInPixels = iHorizAdvance;
1.883 + aMetrics.iRightAdjustInPixels = (TInt16)(iHorizAdvance - iHorizBearingX - iWidth);
1.884 + return ETrue;
1.885 + }
1.886 +
1.887 +TBool COpenFont::GetCharacterData(TInt aSessionHandle, TInt aCode, const TOpenFontCharMetrics*& aMetrics, const TUint8*& aBitmap) const
1.888 + {
1.889 + const COpenFontGlyph* g = Glyph(aSessionHandle, aCode);
1.890 + if (g != NULL)
1.891 + {
1.892 + aMetrics = &g->iMetrics;
1.893 + aBitmap = g->Bitmap();
1.894 + return ETrue;
1.895 + }
1.896 + else
1.897 + {
1.898 + aMetrics = NULL;
1.899 + aBitmap = NULL;
1.900 + return EFalse;
1.901 + }
1.902 + }
1.903 +
1.904 +
1.905 +
1.906 +void COpenFont::OnFileDeleted()
1.907 + {
1.908 + iFileOffset = 0;
1.909 + }
1.910 +
1.911 +COpenFontGlyphCache* COpenFont::GetGlyphCache() const
1.912 + {
1.913 + if (iGlyphCacheOffset == 0)
1.914 + {
1.915 + return NULL;
1.916 + }
1.917 + return reinterpret_cast<COpenFontGlyphCache*>(PtrAdd(const_cast<COpenFont*>(this), iGlyphCacheOffset));
1.918 + }
1.919 +
1.920 +const COpenFontGlyph* COpenFont::Glyph(TInt aSessionHandle, TInt aCode) const
1.921 + {
1.922 + const COpenFontGlyph* glyph = const_cast<COpenFont*>(this)->FontCacheGlyph(aCode);
1.923 + if (glyph == NULL)
1.924 + {
1.925 + COpenFontSessionCache* cache;
1.926 + TInt index;
1.927 + glyph = SessionCacheGlyph(iHeap, aSessionHandle, aCode, cache, index, EFalse);
1.928 + }
1.929 +
1.930 + return glyph;
1.931 + }
1.932 +
1.933 +/**
1.934 +Is the specified character present in the font?
1.935 +*/
1.936 +TBool COpenFont::HasCharacterL(TInt aCode) const
1.937 + {
1.938 + COpenFontFile* file = File();
1.939 + if (file != NULL)
1.940 + return file->HasUnicodeCharacterL(iFaceIndex, aCode);
1.941 + else
1.942 + return EFalse;
1.943 + }
1.944 +
1.945 +/**
1.946 +Retrieve glyph data from the per-font glyph cache.
1.947 +If it is not found return NULL.
1.948 +If the cache hasn't been created, then return NULL.
1.949 +Previous versions of this function created the cache, but as this function can potentially
1.950 +run in the context of threads other than FBSERV the alloc could panic if iHeap's chunk had to
1.951 +be resized - this is not allowed by the kernel.
1.952 +The cache is now created in COpenFont::Rasterize which can only be called within the context of FBSERV
1.953 +@param aCode The code for the glpyh to look for in the cache
1.954 +@return A pointer to the requested glyph if it was found in the glyph cache, NULL if it was not found.
1.955 +*/
1.956 +const COpenFontGlyph* COpenFont::FontCacheGlyph(TInt aCode) const
1.957 + {
1.958 + if (COpenFontGlyphCache* glyphCache = GetGlyphCache())
1.959 + {
1.960 + if ((aCode & 0x80000000) != 0)
1.961 + {
1.962 + return glyphCache->iGlyphTreeById.At(aCode & 0x7FFFFFFF);
1.963 + }
1.964 + else
1.965 + {
1.966 + return glyphCache->iGlyphTreeByUnicode.At(aCode);
1.967 + }
1.968 + }
1.969 +
1.970 + // No glyph found
1.971 + return NULL;
1.972 + }
1.973 +
1.974 +/** Retrieve glyph data from the session cache. If the glyph is not in the
1.975 +cache, return the cache and glyph index where the glyph data should be put. If
1.976 +there is no session cache, optionally create it.
1.977 +
1.978 +@param aHeap
1.979 + The heap on which to create the new cache, if appropriate. Not used if
1.980 + either the appropriate session cache already exists, or if aCreate is
1.981 + passed as false
1.982 +@param aSessionHandle The session handle
1.983 +@param aCode
1.984 + The code of the glyph to look up (Unicode or glyph code if the top bit is
1.985 + set)
1.986 +@param aCache
1.987 + Returns the appropriate session cache, or NULL if an attempt to create it
1.988 + has failed.
1.989 +@param aIndex
1.990 + Returns where the glyph is, or should be put
1.991 +@param aCreate
1.992 + If False, creation of a new cache is inhibited
1.993 +@return The glyph data, or null if the glyph is not in the cache
1.994 +@internalComponent
1.995 +*/
1.996 +const COpenFontGlyph* COpenFont::SessionCacheGlyph(RHeap* aHeap,
1.997 + TInt aSessionHandle, TInt aCode, COpenFontSessionCache*& aCache,
1.998 + TInt& aIndex, TBool aCreate) const
1.999 + {
1.1000 + aIndex = 0;
1.1001 + COpenFontSessionCacheList* cacheList = SessionCacheList();
1.1002 + aCache = cacheList->FindCache(aSessionHandle);
1.1003 + if (aCache != NULL)
1.1004 + {
1.1005 + return aCache->Glyph(this, aCode, aIndex);
1.1006 + }
1.1007 +
1.1008 + if (aCreate)
1.1009 + {
1.1010 + COpenFontSessionCache* new_cache = NULL;
1.1011 + TRAPD(error, new_cache = COpenFontSessionCache::NewL(aHeap, aSessionHandle, KSessionCacheEntries));
1.1012 +
1.1013 + if ((!error) && new_cache != NULL)
1.1014 + {
1.1015 + if (cacheList->AddCache(new_cache) != KErrNone)
1.1016 + {
1.1017 + new_cache->Delete(aHeap);
1.1018 + aHeap->Free(new_cache);
1.1019 + return NULL;
1.1020 + }
1.1021 +
1.1022 + aCache = new_cache;
1.1023 + aIndex = GLYPH_CODE(aCode) % KSessionCacheEntries;
1.1024 + }
1.1025 + }
1.1026 + return NULL;
1.1027 + }
1.1028 +
1.1029 +COpenFontSessionCacheList* COpenFont::SessionCacheList()const
1.1030 + {
1.1031 + if (iSessionCacheListOffset == 0)
1.1032 + {
1.1033 + return NULL;
1.1034 + }
1.1035 + return reinterpret_cast<COpenFontSessionCacheList*>(reinterpret_cast<TInt>(this) + iSessionCacheListOffset);
1.1036 + }
1.1037 +
1.1038 +void COpenFont::SetSessionCacheList(COpenFontSessionCacheList* aSessionCacheList)
1.1039 + {
1.1040 + iSessionCacheListOffset = aSessionCacheList ? reinterpret_cast<TInt>(aSessionCacheList) - reinterpret_cast<TInt>(this) : NULL;
1.1041 + }
1.1042 +
1.1043 +void COpenFont::SetFile(COpenFontFile* aFile)
1.1044 + {
1.1045 + iFileOffset = aFile ? reinterpret_cast<TInt>(aFile) - reinterpret_cast<TInt>(this) : NULL;
1.1046 + }
1.1047 +
1.1048 +void COpenFont::SetGlyphCache(COpenFontGlyphCache* aGlyphCache)
1.1049 + {
1.1050 + iGlyphCacheOffset = aGlyphCache ? reinterpret_cast<TInt>(aGlyphCache) - reinterpret_cast<TInt>(this) : NULL;
1.1051 + }
1.1052 +
1.1053 +
1.1054 +/**
1.1055 +Create a glyph data object on the shared heap, given the code, metrics and the data bytes.
1.1056 +The data is copied; ownership remains with the caller.
1.1057 +*/
1.1058 +COpenFontGlyph* COpenFontGlyph::New(RHeap* aHeap, TInt aCode, TInt aGlyphIndex, const TOpenFontCharMetrics& aMetrics, const TDesC8& aBitmap)
1.1059 + {
1.1060 + COpenFontGlyph* glyph = (COpenFontGlyph*)aHeap->Alloc(sizeof(COpenFontGlyph) + aBitmap.Size());
1.1061 + if (glyph == NULL)
1.1062 + {
1.1063 + return NULL;
1.1064 + }
1.1065 + new(glyph) COpenFontGlyph(aCode, aGlyphIndex, aMetrics);
1.1066 + glyph->SetBitmap(glyph + 1);
1.1067 + Mem::Copy(glyph + 1, aBitmap.Ptr(), aBitmap.Size());
1.1068 + return glyph;
1.1069 + }
1.1070 +
1.1071 +COpenFontSessionCacheEntry* COpenFontSessionCacheEntry::New(RHeap* aHeap, const COpenFont* aFont, TInt aCode, TInt aGlyphIndex, const TOpenFontCharMetrics& aMetrics, const TDesC8& aBitmap)
1.1072 + {
1.1073 + COpenFontSessionCacheEntry* entry = (COpenFontSessionCacheEntry*)aHeap->Alloc(sizeof(COpenFontSessionCacheEntry) + aBitmap.Size());
1.1074 + if (entry == NULL)
1.1075 + {
1.1076 + return NULL;
1.1077 + }
1.1078 + new(entry) COpenFontSessionCacheEntry(aFont, aCode, aGlyphIndex, aMetrics);
1.1079 + entry->SetBitmap(entry + 1);
1.1080 + Mem::Copy(entry + 1, aBitmap.Ptr(), aBitmap.Size());
1.1081 + return entry;
1.1082 + }
1.1083 +
1.1084 +void COpenFontGlyph::SetBitmap(const TAny* aBitmap)
1.1085 + {
1.1086 + iBitmapOffset = reinterpret_cast<TInt>(aBitmap) - reinterpret_cast<TInt>(this);
1.1087 + }
1.1088 +
1.1089 +COpenFontSessionCache* COpenFontSessionCache::NewL(RHeap* aHeap, TInt aSessionHandle, TInt aEntries)
1.1090 + {
1.1091 + COpenFontSessionCache* c = (COpenFontSessionCache*)aHeap->AllocL(sizeof(COpenFontSessionCache));
1.1092 + new(c) COpenFontSessionCache(aSessionHandle);
1.1093 + if (c->iEntryArray.Create(aHeap, aEntries) != KErrNone)
1.1094 + {
1.1095 + aHeap->Free(c);
1.1096 + User::Leave(KErrNoMemory);
1.1097 + }
1.1098 + return c;
1.1099 + }
1.1100 +
1.1101 +
1.1102 +void COpenFontSessionCache::Delete(RHeap* aHeap)
1.1103 + {
1.1104 + TInt numEntries = iEntryArray.Count();
1.1105 + for (TInt i = 0; i < numEntries; ++i)
1.1106 + {
1.1107 + COpenFontSessionCacheEntry* entry = iEntryArray[i];
1.1108 + if (entry != NULL)
1.1109 + {
1.1110 + COpenFont* font=const_cast<COpenFont*>(entry->Font());
1.1111 + if (font != NULL)
1.1112 + font->DecrementCachedRefCount(iSessionHandle,NULL,ETrue);
1.1113 + COpenFontSessionCacheEntry::Delete(aHeap, entry);
1.1114 + }
1.1115 + }
1.1116 + iEntryArray.Close(aHeap);
1.1117 + }
1.1118 +
1.1119 +const COpenFontGlyph* COpenFontSessionCache::Glyph(const COpenFont* aFont, TInt aCode, TInt& aIndex) const
1.1120 + {
1.1121 + aIndex = -1;
1.1122 + TInt numEntries = iEntryArray.Count();
1.1123 + TInt index = GLYPH_CODE(aCode) % numEntries; // simple hash function to shorten searches
1.1124 + for (TInt i = 0; i < numEntries; ++i, ++index)
1.1125 + {
1.1126 + if (index >= numEntries)
1.1127 + {
1.1128 + index = 0;
1.1129 + }
1.1130 + const COpenFontSessionCacheEntry* entry = iEntryArray[index];
1.1131 + if (entry == NULL)
1.1132 + {
1.1133 + if (aIndex < 0)
1.1134 + {
1.1135 + aIndex = index;
1.1136 + }
1.1137 + }
1.1138 + else if (entry->Font() == aFont && entry->iCode == aCode)
1.1139 + {
1.1140 + return entry;
1.1141 + }
1.1142 + }
1.1143 + return NULL;
1.1144 + }
1.1145 +
1.1146 +
1.1147 +void COpenFontSessionCache::Insert(RHeap* aHeap, COpenFontSessionCacheEntry* aEntry, TInt aIndex)
1.1148 + {
1.1149 + if (aIndex >= iEntryArray.Count())
1.1150 + {
1.1151 + Panic(EFntSessionCacheIndexOutOfRange);
1.1152 + }
1.1153 + if (aIndex < 0)
1.1154 + {
1.1155 + aIndex = Math::Rand(iRandomSeed) % iEntryArray.Count();
1.1156 + }
1.1157 + COpenFontSessionCacheEntry::Delete(aHeap, iEntryArray[aIndex]);
1.1158 + iEntryArray.SetAt(aIndex, aEntry);
1.1159 + }
1.1160 +
1.1161 +COpenFontSessionCache::COpenFontSessionCache(TInt aSessionHandle):
1.1162 + iSessionHandle(aSessionHandle),
1.1163 + iRandomSeed(0)
1.1164 + {
1.1165 + }
1.1166 +
1.1167 +TInt COpenFontSessionCacheList::AddCache(COpenFontSessionCache* aCache)
1.1168 + {
1.1169 + for (TInt index = 0; index < EMaxNumCaches; ++index)
1.1170 + {
1.1171 + if (iSessionHandleArray[index] == 0)
1.1172 + {
1.1173 + iSessionHandleArray[index] = aCache->SessionHandle();
1.1174 + iCacheOffsetArray[index] = reinterpret_cast<TInt>(aCache) - reinterpret_cast<TInt>(this);
1.1175 + return KErrNone;
1.1176 + }
1.1177 + }
1.1178 + return KErrNoMemory;
1.1179 + }
1.1180 +
1.1181 +COpenFontSessionCache* COpenFontSessionCacheList::FindCache(TInt aSessionHandle) const
1.1182 + {
1.1183 + if (aSessionHandle == 0)
1.1184 + {
1.1185 + return NULL;
1.1186 + }
1.1187 + for (TInt index = 0; index < EMaxNumCaches; ++index)
1.1188 + {
1.1189 + if (iSessionHandleArray[index] == aSessionHandle)
1.1190 + {
1.1191 + return reinterpret_cast<COpenFontSessionCache*>(reinterpret_cast<TInt>(this) + iCacheOffsetArray[index]);
1.1192 + }
1.1193 + }
1.1194 + return NULL;
1.1195 + }
1.1196 +
1.1197 +/** Delete all the items in the session cache if the current cache session handle
1.1198 +matches the passed session handle.
1.1199 +
1.1200 +@param aHeap The heap base of the current process.
1.1201 +@param aSessionHandle The session handle of the cache to be deleted.
1.1202 + */
1.1203 +void COpenFontSessionCacheList::DeleteCache(RHeap* aHeap, TInt aSessionHandle)
1.1204 + {
1.1205 + if (aSessionHandle == 0)
1.1206 + {
1.1207 + return;
1.1208 + }
1.1209 + for (TInt index = 0; index < EMaxNumCaches; ++index)
1.1210 + {
1.1211 + if (iSessionHandleArray[index] == aSessionHandle)
1.1212 + {
1.1213 + COpenFontSessionCache* cache = reinterpret_cast<COpenFontSessionCache*>(PtrAdd(this, iCacheOffsetArray[index]));
1.1214 + cache->Delete(aHeap);
1.1215 + aHeap->Free(cache);
1.1216 + iSessionHandleArray[index] = 0;
1.1217 + iCacheOffsetArray[index] = 0;
1.1218 + return;
1.1219 + }
1.1220 + }
1.1221 + }
1.1222 +
1.1223 +/** Delete all the items in the current session cache.
1.1224 +
1.1225 +@param aHeap The heap base of the current process.
1.1226 + */
1.1227 +void COpenFontSessionCacheList::Delete(RHeap* aHeap)
1.1228 + {
1.1229 + for (TInt index = 0; index < EMaxNumCaches; ++index)
1.1230 + {
1.1231 + if (iCacheOffsetArray[index] != 0)
1.1232 + {
1.1233 + COpenFontSessionCache* cache = reinterpret_cast<COpenFontSessionCache*>(PtrAdd(this, iCacheOffsetArray[index]));
1.1234 + cache->Delete(aHeap);
1.1235 + aHeap->Free(cache);
1.1236 + }
1.1237 + }
1.1238 + Mem::FillZ(this, sizeof(COpenFontSessionCacheList));
1.1239 + }
1.1240 +
1.1241 +/**
1.1242 +Delete all glyphs belonging to a particular font.
1.1243 +*/
1.1244 +void COpenFontSessionCacheList::DeleteFontGlyphs(RHeap* aHeap, const COpenFont* aFont)
1.1245 + {
1.1246 + for (TInt index = 0; index < EMaxNumCaches; ++index)
1.1247 + {
1.1248 + if (iCacheOffsetArray[index] != 0)
1.1249 + {
1.1250 + COpenFontSessionCache* cache = reinterpret_cast<COpenFontSessionCache*>(PtrAdd(this, iCacheOffsetArray[index]));
1.1251 + TInt numEntries = cache->iEntryArray.Count();
1.1252 + for (TInt i = 0; i < numEntries; ++i)
1.1253 + {
1.1254 + COpenFontSessionCacheEntry* entry = cache->iEntryArray[i];
1.1255 + if (entry != NULL && entry->Font() == aFont)
1.1256 + {
1.1257 + COpenFontSessionCacheEntry::Delete(aHeap, entry);
1.1258 + cache->iEntryArray.SetAt(i, NULL);
1.1259 + }
1.1260 + }
1.1261 + }
1.1262 + }
1.1263 + }
1.1264 +
1.1265 +/**
1.1266 +C++ constructor with a CFont parameter.
1.1267 +
1.1268 +This creates a TOpenFontMetrics and initialises it with size, ascent, maximum
1.1269 +height, descent, maximum depth and maximum character width information from
1.1270 +the CFont that was passed as a parameter.
1.1271 +
1.1272 +@param aFont The font from which to initialise the metrics object.
1.1273 +*/
1.1274 +EXPORT_C TOpenFontMetrics::TOpenFontMetrics(const CFont* aFont)
1.1275 + {
1.1276 + iDesignHeight = (TInt16) aFont->HeightInPixels();
1.1277 + iAscent = iMaxHeight = (TInt16) aFont->AscentInPixels();
1.1278 + iDescent = iMaxDepth = (TInt16)(iDesignHeight - iAscent);
1.1279 + iMaxWidth = (TInt16)aFont->MaxCharWidthInPixels();
1.1280 + iBaselineCorrection = 0;
1.1281 + }
1.1282 +
1.1283 +/**
1.1284 +@publishedPartner
1.1285 +@prototype
1.1286 +
1.1287 +@param aBaselineCorrection The baseline correction to be associated with this font
1.1288 +
1.1289 +Sets the baseline correction applied to this font; this value is used to offset
1.1290 +the underlinke and strikethrough positions and is used by linked fonts only.
1.1291 +*/
1.1292 +const TUint16 KBitsForUnderline = 10;
1.1293 +const TUint16 KMaskUnderline = (1<<KBitsForUnderline)-1; //bottom bits which are set
1.1294 +const TUint16 KMaskBitmapType = ~KMaskUnderline; //top bits which are set
1.1295 +const TUint16 KSignBit = 1<<(KBitsForUnderline-1); //sign bit for the lower number, which can be signed
1.1296 +const TUint32 KTop16Of32Bits = 0xffff0000;
1.1297 +
1.1298 +EXPORT_C void TOpenFontMetrics::SetBaselineCorrection(TInt aBaselineCorrection)
1.1299 + {
1.1300 + if (aBaselineCorrection >= (1<<(KBitsForUnderline-1)))
1.1301 + {
1.1302 + OstTrace1( TRACE_FATAL, TOPENFONTMETRICS_SETBASELINECORRECTION, "aBaselineCorrection=%d, Panic(EFntOverFlow)", aBaselineCorrection );
1.1303 + __ASSERT_DEBUG(0, Panic(EFntOverFlow));
1.1304 + }
1.1305 + if (aBaselineCorrection <= (0-(1<<(KBitsForUnderline-1))))
1.1306 + {
1.1307 + OstTrace1( TRACE_FATAL, DUP1_TOPENFONTMETRICS_SETBASELINECORRECTION, "aBaselineCorrection=%d, Panic(EFntOverFlow)", aBaselineCorrection );
1.1308 + __ASSERT_DEBUG(0, Panic(EFntOverFlow));
1.1309 + }
1.1310 +
1.1311 + TUint16 value = iBaselineCorrection;
1.1312 + value &=~KMaskUnderline; //zero all the underline position bits
1.1313 + if (aBaselineCorrection<0)
1.1314 + {
1.1315 + //need to mask out extra sign bits for negative value
1.1316 + iBaselineCorrection = value | (static_cast<TUint16>(aBaselineCorrection)&~KMaskBitmapType);
1.1317 + }
1.1318 + else
1.1319 + {
1.1320 + iBaselineCorrection = value | static_cast<TUint16>(aBaselineCorrection);
1.1321 + }
1.1322 + }
1.1323 +
1.1324 +/**
1.1325 +@publishedPartner
1.1326 +@prototype
1.1327 +
1.1328 +Gets the baseline correction applied to this font; this value is used to offset
1.1329 +the underlinke and strikethrough positions and is used by linked fonts only.
1.1330 +
1.1331 +@return The baseline correction associated with this font
1.1332 +*/
1.1333 +
1.1334 +EXPORT_C TInt TOpenFontMetrics::BaselineCorrection()
1.1335 + {
1.1336 + TUint16 value = iBaselineCorrection; //read once for improved multi threading
1.1337 + if (!(value & KSignBit))
1.1338 + {
1.1339 + //value is positive, no need to sign extend
1.1340 + return value & KMaskUnderline;
1.1341 + }
1.1342 + else
1.1343 + {
1.1344 + //value is negative, need to stuff ones into the high bits
1.1345 + //could shift up and shift down
1.1346 + return static_cast<TInt>(static_cast<TUint>(value) | KMaskBitmapType | KTop16Of32Bits);
1.1347 + }
1.1348 + }
1.1349 +
1.1350 +/**
1.1351 +C++ constructor with UID and filename.
1.1352 +
1.1353 +Call this constructor in the constructor for your derived object, passing
1.1354 +it aUid and aFileName arguments.
1.1355 +
1.1356 +Non Symbian-platform-native font files are allocated IDs by the font store.
1.1357 +These are passed in by the rasteriser class. UIDs are required by the
1.1358 +font framework. However you should not use the ID to access the file, since
1.1359 +a new UID will need to be allocated when the file is next loaded, e.g. after
1.1360 +a device reboot. Instead use the font file name.
1.1361 +
1.1362 +@param aUid The UID of the font file.
1.1363 +@param aFileName The full filename, including the path, of the font file.
1.1364 +*/
1.1365 +EXPORT_C COpenFontFile::COpenFontFile(TInt aUid, const TDesC& aFileName)
1.1366 + : iFaceAttrib(1),
1.1367 + iUid(TUid::Uid(aUid)),
1.1368 + iFileName(aFileName),
1.1369 + iFontList(8)
1.1370 + {
1.1371 + }
1.1372 +
1.1373 +/**
1.1374 +Destructor.
1.1375 +
1.1376 +It is not allowed that file is deleted before its fonts
1.1377 +and the logic is handled in CFontStore::RemoveFile().
1.1378 +*/
1.1379 +EXPORT_C COpenFontFile::~COpenFontFile()
1.1380 + {
1.1381 + CFontStore *fs = GetFontStore();
1.1382 + if (fs != NULL)
1.1383 + {
1.1384 + fs->CleanupCacheOnOpenFontFileRemoval(this);
1.1385 + }
1.1386 + delete iData;
1.1387 + }
1.1388 +
1.1389 +/**
1.1390 +Gets the nearest font in pixels.
1.1391 +
1.1392 +Implementations of this pure virtual function should create the COpenFont
1.1393 +derived object that most closely matches aFontSpec, and place a pointer to
1.1394 +it in aFont. If this cannot be done, e.g. if the font name doesn't match,
1.1395 +aFont should be set to NULL.
1.1396 +
1.1397 +The other two arguments, aHeap and aSessionCacheList, should be passed to
1.1398 +the COpenFont constructor.
1.1399 +
1.1400 +Implementations may use the utilitity function GetNearestFontHelper() to get
1.1401 +the attributes of the closest matching font.
1.1402 +
1.1403 +@param aHeap Shared heap. This value should be passed to the COpenFont derived
1.1404 +classes' constructor.
1.1405 +@param aSessionCacheList The session cache list. This value should be passed
1.1406 +to the COpenFont derived classes' constructor.
1.1407 +@param aDesiredFontSpec The desired font specification.
1.1408 +@param aPixelWidth The width of a pixel. Used with aPixelHeight for calculating
1.1409 +the algorithmic slant of the typeface.
1.1410 +@param aPixelHeight The height of a pixel. Used with aPixelWidth for calculating
1.1411 +the algorithmic slant of the typeface.
1.1412 +@param aFont On return, contains a pointer to the newly created COpenFont
1.1413 +derived object, or NULL if no font matching aDesiredFontSpec exists.
1.1414 +@param aActualFontSpec The actual font specification of the font retrieved
1.1415 +into aFont.
1.1416 +@see GetNearestFontHelper()
1.1417 +@deprecated Use GetNearestFontToDesignHeightInPixels
1.1418 +*/
1.1419 +TInt COpenFontFile::GetNearestFontInPixels(
1.1420 + RHeap* aHeap,
1.1421 + COpenFontSessionCacheList* aSessionCacheList,
1.1422 + const TOpenFontSpec& aDesiredFontSpec,
1.1423 + TInt aPixelWidth,
1.1424 + TInt aPixelHeight,
1.1425 + COpenFont*& aFont,
1.1426 + TOpenFontSpec& aActualFontSpec)
1.1427 + {
1.1428 + return GetNearestFontToDesignHeightInPixels(aHeap, aSessionCacheList, aDesiredFontSpec, aPixelWidth, aPixelHeight, aFont, aActualFontSpec);
1.1429 + }
1.1430 +
1.1431 +/**
1.1432 +Gets the nearest font in pixels.
1.1433 +
1.1434 +Implementations of this pure virtual function should create the COpenFont
1.1435 +derived object that most closely matches aFontSpec, and place a pointer to
1.1436 +it in aFont. If this cannot be done, e.g. if the font name doesn't match,
1.1437 +aFont should be set to NULL.
1.1438 +
1.1439 +The other two arguments, aHeap and aSessionCacheList, should be passed to
1.1440 +the COpenFont constructor.
1.1441 +
1.1442 +Implementations may use the utilitity function GetNearestFontHelper() to get
1.1443 +the attributes of the closest matching font.
1.1444 +
1.1445 +@param aHeap Shared heap. This value should be passed to the COpenFont derived
1.1446 +classes' constructor.
1.1447 +@param aSessionCacheList The session cache list. This value should be passed
1.1448 +to the COpenFont derived classes' constructor.
1.1449 +@param aDesiredFontSpec The desired font specification.
1.1450 +@param aPixelWidth The width of a pixel. Used with aPixelHeight for calculating
1.1451 +the algorithmic slant of the typeface.
1.1452 +@param aPixelHeight The height of a pixel. Used with aPixelWidth for calculating
1.1453 +the algorithmic slant of the typeface.
1.1454 +@param aFont On return, contains a pointer to the newly created COpenFont
1.1455 +derived object, or NULL if no font matching aDesiredFontSpec exists.
1.1456 +@param aActualFontSpec The actual font specification of the font retrieved
1.1457 +into aFont.
1.1458 +@see GetNearestFontHelper()
1.1459 +*/
1.1460 +TInt COpenFontFile::GetNearestFontToDesignHeightInPixels(
1.1461 + RHeap* aHeap,
1.1462 + COpenFontSessionCacheList* aSessionCacheList,
1.1463 + const TOpenFontSpec& aDesiredFontSpec,
1.1464 + TInt aPixelWidth,
1.1465 + TInt aPixelHeight,
1.1466 + COpenFont*& aFont,
1.1467 + TOpenFontSpec& aActualFontSpec)
1.1468 + {
1.1469 + aFont = NULL;
1.1470 + TRAPD(error, GetNearestFontToDesignHeightInPixelsAndAddToListL(aHeap, aSessionCacheList, aDesiredFontSpec, aPixelWidth, aPixelHeight, aFont, aActualFontSpec));
1.1471 + return error;
1.1472 + }
1.1473 +
1.1474 +
1.1475 +void COpenFontFile::GetNearestFontToDesignHeightInPixelsAndAddToListL(
1.1476 + RHeap* aHeap,
1.1477 + COpenFontSessionCacheList* aSessionCacheList,
1.1478 + const TOpenFontSpec& aDesiredFontSpec,
1.1479 + TInt aPixelWidth,
1.1480 + TInt aPixelHeight,
1.1481 + COpenFont*& aFont,
1.1482 + TOpenFontSpec& aActualFontSpec)
1.1483 + {
1.1484 + COpenFont* fontPtr = NULL;
1.1485 + GetNearestFontToDesignHeightInPixelsL(aHeap, aSessionCacheList, aDesiredFontSpec, aPixelWidth, aPixelHeight, fontPtr, aActualFontSpec);
1.1486 + if (fontPtr != NULL)
1.1487 + { // found a matching font
1.1488 + CleanupStack::PushL(fontPtr);
1.1489 + iFontList.AppendL(fontPtr);
1.1490 + // transfer ownership
1.1491 + aFont = fontPtr;
1.1492 + CleanupStack::Pop(fontPtr);
1.1493 + }
1.1494 + }
1.1495 +
1.1496 +
1.1497 +/**
1.1498 +Gets the nearest font in pixels that fits inside specified max height.
1.1499 +
1.1500 +Implementations of this pure virtual function should create the COpenFont
1.1501 +derived object that most closely matches aFontSpec, while fitting within
1.1502 +aMaxHeight, and place a pointer to it in aFont. If this cannot be done,
1.1503 +e.g. if the font name doesn't match, aFont should be set to NULL.
1.1504 +
1.1505 +The other two arguments, aHeap and aSessionCacheList, should be passed to
1.1506 +the COpenFont constructor.
1.1507 +
1.1508 +Implementations may use the utilitity function GetNearestFontHelper()
1.1509 +to get the attributes of the closest matching font.
1.1510 +
1.1511 +@param aHeap Shared heap. This value should be passed to the COpenFont derived
1.1512 +classes' constructor.
1.1513 +@param aSessionCacheList The session cache list. This value should be passed
1.1514 +to the COpenFont derived classes' constructor.
1.1515 +@param aDesiredFontSpec The desired font specification.
1.1516 +@param aPixelWidth The width of a pixel. Used with aPixelHeight for calculating
1.1517 +the algorithmic slant of the typeface.
1.1518 +@param aPixelHeight The height of a pixel. Used with aPixelWidth for calculating
1.1519 +the algorithmic slant of the typeface.
1.1520 +@param aFont On return, contains a pointer to the newly created COpenFont
1.1521 +derived object, or NULL if no font matching aDesiredFontSpec exists.
1.1522 +@param aActualFontSpec The actual font specification of the font retrieved
1.1523 +into aFont.
1.1524 +@param aMaxHeight The maximum height within which the font must fit.
1.1525 +@see GetNearestFontHelper()
1.1526 +*/
1.1527 +TInt COpenFontFile::GetNearestFontToMaxHeightInPixels(
1.1528 + RHeap* aHeap,
1.1529 + COpenFontSessionCacheList* aSessionCacheList,
1.1530 + const TOpenFontSpec& aDesiredFontSpec,
1.1531 + TInt aPixelWidth,
1.1532 + TInt aPixelHeight,
1.1533 + COpenFont*& aFont,
1.1534 + TOpenFontSpec& aActualFontSpec,
1.1535 + TInt aMaxHeight)
1.1536 + {
1.1537 + aFont = NULL;
1.1538 + TRAPD(error, GetNearestFontToMaxHeightInPixelsAndAddToListL(aHeap, aSessionCacheList, aDesiredFontSpec, aPixelWidth, aPixelHeight, aFont, aActualFontSpec, aMaxHeight));
1.1539 + return error;
1.1540 + }
1.1541 +
1.1542 +
1.1543 +void COpenFontFile::GetNearestFontToMaxHeightInPixelsAndAddToListL(
1.1544 + RHeap* aHeap,
1.1545 + COpenFontSessionCacheList* aSessionCacheList,
1.1546 + const TOpenFontSpec& aDesiredFontSpec,
1.1547 + TInt aPixelWidth,
1.1548 + TInt aPixelHeight,
1.1549 + COpenFont*& aFont,
1.1550 + TOpenFontSpec& aActualFontSpec,
1.1551 + TInt aMaxHeight)
1.1552 + {
1.1553 + COpenFont* fontPtr = NULL;
1.1554 + GetNearestFontToMaxHeightInPixelsL(aHeap, aSessionCacheList, aDesiredFontSpec, aPixelWidth, aPixelHeight, fontPtr, aActualFontSpec, aMaxHeight);
1.1555 + if (fontPtr != NULL)
1.1556 + { // found a matching font
1.1557 + CleanupStack::PushL(fontPtr);
1.1558 + iFontList.AppendL(fontPtr);
1.1559 + // transfer ownership
1.1560 + aFont = fontPtr;
1.1561 + CleanupStack::Pop(fontPtr);
1.1562 + }
1.1563 + }
1.1564 +
1.1565 +
1.1566 +/**
1.1567 +Gets the nearest font helper function.
1.1568 +
1.1569 +This function may be used by derived classes in their GetNearestFontInPixelsL()
1.1570 +implementations. It finds the nearest font in the typeface attribute array,
1.1571 +if any, to the provided font specification. If there is a possible match it
1.1572 +places the face index in aFaceIndex and the actual specification (including
1.1573 +algorithmic effects) in aActualFontSpec.
1.1574 +
1.1575 +@param aDesiredFontSpec The desired font specification.
1.1576 +@param aPixelWidth The width of a pixel. Used with aPixelHeight for calculating
1.1577 +the algorithmic slant of the typeface.
1.1578 +@param aPixelHeight The height of a pixel. Used with aPixelWidth for calculating
1.1579 +the algorithmic slant of the typeface.
1.1580 +@param aFaceIndex The index of the typeface which contains the closest match
1.1581 +to aDesiredFontSpec.
1.1582 +@param aActualFontSpec The actual font specification of the font with attributes
1.1583 +closest to aDesiredFontSpec.
1.1584 +@return ETrue if there is a possible font match, otherwise EFalse.
1.1585 +*/
1.1586 +EXPORT_C TBool COpenFontFile::GetNearestFontHelper(
1.1587 + const TOpenFontSpec& aDesiredFontSpec,
1.1588 + TInt aPixelWidth,
1.1589 + TInt aPixelHeight,
1.1590 + TInt& aFaceIndex,
1.1591 + TOpenFontSpec& aActualFontSpec) const
1.1592 + {
1.1593 + const TInt faces = FaceCount();
1.1594 + TInt best_points = 0;
1.1595 + TInt best_index = -1;
1.1596 +
1.1597 + for (TInt i = 0; i < faces; i++)
1.1598 + {
1.1599 + TInt cur_points = 0;
1.1600 +
1.1601 + if (0 < aDesiredFontSpec.Name().Length())
1.1602 + {
1.1603 + cur_points = ScoreByName(aDesiredFontSpec, iFaceAttrib[i]);
1.1604 + }
1.1605 + else
1.1606 + {
1.1607 + cur_points = ScoreByStyle(aDesiredFontSpec, iFaceAttrib[i]);
1.1608 + }
1.1609 +
1.1610 + if (cur_points)
1.1611 + {
1.1612 + if (aDesiredFontSpec.IsItalic() == iFaceAttrib[i].IsItalic())
1.1613 + cur_points++;
1.1614 + if (aDesiredFontSpec.IsBold() == iFaceAttrib[i].IsBold())
1.1615 + cur_points++;
1.1616 + }
1.1617 +
1.1618 + if (cur_points > best_points)
1.1619 + {
1.1620 + best_points = cur_points;
1.1621 + best_index = i;
1.1622 + }
1.1623 + }
1.1624 +
1.1625 + if (best_index != -1)
1.1626 + {
1.1627 + aActualFontSpec = aDesiredFontSpec;
1.1628 + // copy attributes & name
1.1629 + aActualFontSpec.SetAttrib(iFaceAttrib[best_index]);
1.1630 + aActualFontSpec.SetName(iFaceAttrib[best_index].FamilyName());
1.1631 + // Set an algorithmic slant and adjust it for the pixel aspect ratio.
1.1632 + if ((aDesiredFontSpec.IsItalic()) && (!iFaceAttrib[best_index].IsItalic()) && (0 == aDesiredFontSpec.SlantFactor()))
1.1633 + {
1.1634 + TInt factor = KDefaultSlantFactor;
1.1635 + if (TOpenFontSpec::IsCompensationForAspectRatioNeeded(aPixelWidth, aPixelHeight))
1.1636 + {
1.1637 + TOpenFontSpec::ApplyRatio(factor, aPixelWidth, aPixelHeight);
1.1638 + }
1.1639 + aActualFontSpec.SetSlantFactor(factor);
1.1640 + }
1.1641 + }
1.1642 +
1.1643 + aFaceIndex = best_index;
1.1644 + return best_index != -1;
1.1645 + }
1.1646 +
1.1647 +TInt COpenFontFile::ScoreByName(const TOpenFontSpec& aDesiredFontSpec, const TAttrib& aAttrib)
1.1648 + {
1.1649 + if (!aDesiredFontSpec.Name().CompareF(aAttrib.FullName()) || !aDesiredFontSpec.Name().CompareF(aAttrib.LocalFullName()))
1.1650 + {
1.1651 + return 4;
1.1652 + }
1.1653 + else if (!aDesiredFontSpec.Name().CompareF(aAttrib.ShortFullName()) || !aDesiredFontSpec.Name().CompareF(aAttrib.ShortLocalFullName()))
1.1654 + {
1.1655 + return 3;
1.1656 + }
1.1657 + else if (!aDesiredFontSpec.Name().CompareF(aAttrib.FamilyName()) || !aDesiredFontSpec.Name().CompareF(aAttrib.LocalFamilyName()))
1.1658 + {
1.1659 + return 2;
1.1660 + }
1.1661 + else if (!aDesiredFontSpec.Name().CompareF(aAttrib.ShortFamilyName()) || !aDesiredFontSpec.Name().CompareF(aAttrib.ShortLocalFamilyName()))
1.1662 + {
1.1663 + return 1;
1.1664 + }
1.1665 + return 0;
1.1666 + }
1.1667 +
1.1668 +TInt COpenFontFile::ScoreByStyle(const TOpenFontSpec& aDesiredFontSpec, const TAttrib& aAttrib)
1.1669 + {
1.1670 + if (aDesiredFontSpec.IsSymbol() == aAttrib.IsSymbol())
1.1671 + {
1.1672 + return 4;
1.1673 + }
1.1674 + else if(aDesiredFontSpec.IsMonoWidth() == aAttrib.IsMonoWidth())
1.1675 + {
1.1676 + return 3;
1.1677 + }
1.1678 + else if(aDesiredFontSpec.IsSerif() == aAttrib.IsSerif())
1.1679 + {
1.1680 + return 2;
1.1681 + }
1.1682 +
1.1683 + return 0;
1.1684 + }
1.1685 +
1.1686 +#ifdef _DEBUG
1.1687 +/** @internalComponent */
1.1688 +EXPORT_C TBool COpenFontFile::GetNearestFontHelperOld(const TOpenFontSpec& aDesiredFontSpec, TInt aPixelWidth,TInt aPixelHeight,TInt& aFaceIndex, TOpenFontSpec& aActualFontSpec) const
1.1689 + {
1.1690 + TInt faces = FaceCount();
1.1691 + TInt best_points = 0;
1.1692 + TInt best_index = -1;
1.1693 + TBool slant = FALSE;
1.1694 + for (TInt i = 0; i < faces; i++)
1.1695 + {
1.1696 + TPtrC family_name = iFaceAttrib[i].FamilyName();
1.1697 + TPtrC full_name = iFaceAttrib[i].FullName();
1.1698 + TPtrC local_family_name = iFaceAttrib[i].LocalFamilyName();
1.1699 + TPtrC local_full_name = iFaceAttrib[i].LocalFullName();
1.1700 + TPtrC desired_name = aDesiredFontSpec.Name();
1.1701 +
1.1702 + TInt cur_points = 0;
1.1703 + if (desired_name.Length() > 0)
1.1704 + {
1.1705 + if ((full_name.CompareF(desired_name) == 0) || (local_full_name.CompareF(desired_name) == 0))
1.1706 + cur_points = 4;
1.1707 + else if ((family_name.CompareF(desired_name) == 0) || (local_family_name.CompareF(desired_name) == 0))
1.1708 + cur_points = 2;
1.1709 + }
1.1710 + else
1.1711 + {
1.1712 + if ((aDesiredFontSpec.IsSerif() == iFaceAttrib[i].IsSerif()) && (aDesiredFontSpec.IsMonoWidth() == iFaceAttrib[i].IsMonoWidth()) && (aDesiredFontSpec.IsSymbol() == iFaceAttrib[i].IsSymbol()))
1.1713 + cur_points = 2;
1.1714 + }
1.1715 + if (cur_points)
1.1716 + {
1.1717 + if (aDesiredFontSpec.IsItalic() == iFaceAttrib[i].IsItalic())
1.1718 + cur_points++;
1.1719 + if (aDesiredFontSpec.IsBold() == iFaceAttrib[i].IsBold())
1.1720 + cur_points++;
1.1721 + if (cur_points > best_points)
1.1722 + {
1.1723 + best_points = cur_points;
1.1724 + best_index = i;
1.1725 + slant = (aDesiredFontSpec.IsItalic()) && (!iFaceAttrib[i].IsItalic());
1.1726 + }
1.1727 + }
1.1728 + }
1.1729 +
1.1730 + if (best_index != -1)
1.1731 + {
1.1732 + TInt32 slant_factor = aDesiredFontSpec.SlantFactor();
1.1733 +
1.1734 + // Set an algorithmic slant and adjust it for the pixel aspect ratio.
1.1735 + if (slant && slant_factor == 0)
1.1736 + {
1.1737 + slant_factor = KDefaultSlantFactor;
1.1738 + if (aPixelWidth>0 && aPixelHeight>0 && TOpenFontSpec::IsCompensationForAspectRatioNeeded(aPixelWidth,aPixelHeight))
1.1739 + {
1.1740 + TOpenFontSpec::ApplyRatio(slant_factor,aPixelWidth,aPixelHeight);
1.1741 + }
1.1742 + }
1.1743 +
1.1744 + aActualFontSpec = aDesiredFontSpec;
1.1745 + // copy attributes & name
1.1746 + aActualFontSpec.SetAttrib(iFaceAttrib[best_index]);
1.1747 + aActualFontSpec.SetName(iFaceAttrib[best_index].FamilyName());
1.1748 + aActualFontSpec.SetSlantFactor(slant_factor);
1.1749 + aActualFontSpec.SetEffects(0);
1.1750 + }
1.1751 +
1.1752 + aFaceIndex = best_index;
1.1753 + return best_index != -1;
1.1754 + }
1.1755 +#else //_DEBUG
1.1756 +/**
1.1757 +@internalComponent
1.1758 +*/
1.1759 +EXPORT_C TBool COpenFontFile::GetNearestFontHelperOld(const TOpenFontSpec&, TInt, TInt, TInt&, TOpenFontSpec&) const
1.1760 + {
1.1761 + return EFalse;
1.1762 + }
1.1763 +#endif //_DEBUG
1.1764 +
1.1765 +/** This function is called (via iFile) by a COpenFont when it is destroyed. */
1.1766 +void COpenFontFile::RemoveFontFromList(const COpenFont* aFont)
1.1767 + {
1.1768 + TInt fonts = iFontList.Count();
1.1769 + for (TInt i = 0; i < fonts; i++)
1.1770 + if (iFontList[i] == aFont)
1.1771 + {
1.1772 + iFontList.Delete(i);
1.1773 + break;
1.1774 + }
1.1775 + }
1.1776 +
1.1777 +/**
1.1778 +Adds a typeface to this object's typeface array.
1.1779 +
1.1780 +This function should be called during construction to add the attributes for
1.1781 +each typeface in the font file to the typeface attribute array.
1.1782 +
1.1783 +Note:
1.1784 +
1.1785 +The typeface array is what is searched for the closest match to a specified
1.1786 +font by GetNearestFontHelper().
1.1787 +
1.1788 +@param aAttrib The attributes for a typeface to be added to the typeface attribute
1.1789 +array.
1.1790 +@see FaceAttrib()
1.1791 +@see FaceCount()
1.1792 +*/
1.1793 +EXPORT_C void COpenFontFile::AddFaceL(const TOpenFontFaceAttrib& aAttrib)
1.1794 + {
1.1795 + TAttrib& a = iFaceAttrib.ExtendL();
1.1796 + (TOpenFontFaceAttrib&)a = aAttrib;
1.1797 + }
1.1798 +
1.1799 +void COpenFontFile::SetFontStoreL(CFontStore* aFontStore)
1.1800 + {
1.1801 + if (iData == NULL)
1.1802 + {
1.1803 + iData = new (ELeave) TOpenFontFileData;
1.1804 + }
1.1805 + iData->iFontStore = aFontStore;
1.1806 + }
1.1807 +
1.1808 +CFontStore* COpenFontFile::GetFontStore()
1.1809 + {
1.1810 + return iData ? iData->iFontStore : NULL;
1.1811 + }
1.1812 +
1.1813 +CArrayPtrFlat<COpenFont>* COpenFontFile::GetOpenFontList()
1.1814 + {
1.1815 + return &iFontList;
1.1816 + }
1.1817 +
1.1818 +
1.1819 +static const TInt KTOpenFontSpecBitsNumSymbol = 1;
1.1820 +static const TInt KTOpenFontSpecBitsNumScript = 4;
1.1821 +static const TInt KTOpenFontSpecMaskSymbol = (1 << KTOpenFontSpecBitsNumSymbol) - 1;
1.1822 +static const TInt KTOpenFontSpecMaskScript = ((1 << KTOpenFontSpecBitsNumScript) - 1) << KTOpenFontSpecBitsNumSymbol;
1.1823 +static const TInt KTOpenFontSpecSymbolFlag = 0x1;
1.1824 +
1.1825 +/**
1.1826 +Default C++ constructor setting
1.1827 +height to 16 pixels or twips,
1.1828 +width factor to 1 (65536 in 16.16 format),
1.1829 +slant factor to 0 (no slant),
1.1830 +effects to ENone,
1.1831 +symbol to 0 (assuming EScriptNone = 0),
1.1832 +print position to EPrintPosNormal.
1.1833 +*/
1.1834 +EXPORT_C TOpenFontSpec::TOpenFontSpec()
1.1835 + : iHeight(16),
1.1836 + iWidthFactor(KOneIn16Dot16FixedPointFormat),
1.1837 + iSlantFactor(0),
1.1838 + iBitmapType(0),
1.1839 + iEffects(FontEffect::ENone),
1.1840 + iSymbol(0),
1.1841 + iPrintPosition(EPrintPosNormal),
1.1842 + iReserved2(0)
1.1843 + {
1.1844 + }
1.1845 +
1.1846 +/**
1.1847 +C++ constructor taking a reference to a TFontSpec.
1.1848 +
1.1849 +This object's members are initialised from the values of the aFontSpec parameter.
1.1850 +
1.1851 +@param aFontSpec The font specification used to initialise this font specification.
1.1852 +*/
1.1853 +EXPORT_C TOpenFontSpec::TOpenFontSpec(const TFontSpec& aFontSpec)
1.1854 + {
1.1855 + *this = aFontSpec;
1.1856 + }
1.1857 +
1.1858 +/**
1.1859 +Assignment operator.
1.1860 +
1.1861 +@param aFontSpec The old-style font specification to copy into this font specification.
1.1862 +*/
1.1863 +EXPORT_C void TOpenFontSpec::operator=(const TFontSpec& aFontSpec)
1.1864 + {
1.1865 + iSlantFactor = 0;
1.1866 + iWidthFactor = KOneIn16Dot16FixedPointFormat;
1.1867 + iHeight = aFontSpec.iHeight; // in twips
1.1868 + iBitmapType = aFontSpec.iFontStyle.BitmapType();
1.1869 + iEffects = aFontSpec.iFontStyle.Effects();
1.1870 + iPrintPosition = aFontSpec.iFontStyle.PrintPosition();
1.1871 + iName = aFontSpec.iTypeface.iName;
1.1872 + SetScriptTypeForMetrics(aFontSpec.iTypeface.ScriptTypeForMetrics());
1.1873 + const TBool symbol = aFontSpec.iTypeface.IsSymbol();
1.1874 + SetSymbol(symbol);
1.1875 + if (symbol)
1.1876 + SetCoverage(0); // no appropriate coverage value for the symbol set
1.1877 + else
1.1878 + SetCoverage(3); // Latin and Latin-1 supplement
1.1879 + iStyle = 0;
1.1880 + if (!aFontSpec.iTypeface.IsProportional())
1.1881 + iStyle |= TOpenFontFaceAttrib::EMonoWidth;
1.1882 + if (aFontSpec.iTypeface.IsSerif())
1.1883 + iStyle |= TOpenFontFaceAttrib::ESerif;
1.1884 + if (aFontSpec.iFontStyle.Posture() == EPostureItalic)
1.1885 + iStyle |= TOpenFontFaceAttrib::EItalic;
1.1886 + if (aFontSpec.iFontStyle.StrokeWeight() == EStrokeWeightBold)
1.1887 + iStyle |= TOpenFontFaceAttrib::EBold;
1.1888 + }
1.1889 +
1.1890 +
1.1891 +/**
1.1892 +Adjust the width factor and slant factor to suit a pixel aspect ratio.
1.1893 +@publishedAll
1.1894 +@released
1.1895 +@param aPixelWidth The pixel width, in the same units as aPixelHeight.
1.1896 +@param aPixelHeight The pixel height, in the same units as aPixelWidth.
1.1897 +*/
1.1898 +EXPORT_C void TOpenFontSpec::CompensateForAspectRatio(TInt aPixelWidth, TInt aPixelHeight)
1.1899 + {
1.1900 + if (IsCompensationForAspectRatioNeeded(aPixelWidth, aPixelHeight))
1.1901 + {
1.1902 + ApplyRatio(iWidthFactor, aPixelHeight, aPixelWidth);
1.1903 + ApplyRatio(iSlantFactor, aPixelWidth, aPixelHeight);
1.1904 + }
1.1905 + }
1.1906 +
1.1907 +/**
1.1908 +Adjust the width factor and slant factor to suit a pixel aspect ratio stored
1.1909 +in a MGraphicsDeviceMap derived object.
1.1910 +@publishedAll
1.1911 +@released
1.1912 +@param aMap The MGraphicsDeviceMap defining the pixel aspect ratio.
1.1913 +*/
1.1914 +EXPORT_C void TOpenFontSpec::CompensateForAspectRatio(const MGraphicsDeviceMap& aMap)
1.1915 + {
1.1916 + CompensateForAspectRatio(aMap.HorizontalPixelsToTwips(1000), aMap.VerticalPixelsToTwips(1000));
1.1917 + }
1.1918 +
1.1919 +/**
1.1920 +The pixel width and height are used to derive a ratio, and so can be
1.1921 +in any units. Aspect ratios differing by less than 1/1000 are treated as 1:1.
1.1922 +@internalTechnology
1.1923 +*/
1.1924 +TBool TOpenFontSpec::IsCompensationForAspectRatioNeeded(TInt aPixelWidth,TInt aPixelHeight)
1.1925 + {
1.1926 + if ((aPixelWidth != aPixelHeight) && (0 < aPixelWidth) && (0 < aPixelHeight))
1.1927 + {
1.1928 + //If nearly square don't transform (0.999 < aPixelHeight/aPixelWidth < 1.001)
1.1929 + TInt64 width = aPixelWidth;
1.1930 + TInt64 height = aPixelHeight;
1.1931 + width *= 999; // Cannot do multiplication on declaration lines above as risk of TInt32 overflow
1.1932 + height *= 1000;
1.1933 + if (width <= height) // 999 * aPixelWidth <= 1000 * aPixelHeight
1.1934 + return ETrue;
1.1935 + width += aPixelWidth;
1.1936 + width += aPixelWidth; // Cannot do with previous line as small risk of TInt32 overflow
1.1937 + if (width >= height) // 1001 * aPixelWidth >= 1000 * aPixelHeight
1.1938 + return ETrue;
1.1939 + }
1.1940 + return EFalse;
1.1941 + }
1.1942 +
1.1943 +/**
1.1944 +Multiplies aValue by aNumerator/aDenominator but using TInt64's to avoid any overflows.
1.1945 +Returns ETrue if the final result has an overflow.
1.1946 +@internalTechnology
1.1947 +*/
1.1948 +TBool TOpenFontSpec::ApplyRatio(TInt& aValue, TInt aNumerator, TInt aDenominator)
1.1949 + {
1.1950 + TInt64 value(aValue);
1.1951 + value = (value * aNumerator) / aDenominator;
1.1952 + aValue = I64LOW(value);
1.1953 + if (I64HIGH(value) != 0)
1.1954 + {
1.1955 + OstTrace1( TRACE_FATAL, TOPENFONTSPEC_APPLYRATIO, "value=%ld, Panic(EFntOverFlow)", value );
1.1956 + __ASSERT_DEBUG(0, Panic(EFntOverFlow));
1.1957 + }
1.1958 + return I64HIGH(value) != 0;
1.1959 + }
1.1960 +
1.1961 +/**
1.1962 +Same as above function but this takes a TInt32 not a TInt
1.1963 +*/
1.1964 +TBool TOpenFontSpec::ApplyRatio(TInt32& aValue, TInt aNumerator, TInt aDenominator)
1.1965 + {
1.1966 + TInt value = aValue;
1.1967 + TBool ret = ApplyRatio(value, aNumerator, aDenominator);
1.1968 + aValue = value;
1.1969 + return ret;
1.1970 + }
1.1971 +
1.1972 +EXPORT_C void TOpenFontSpec::SetAttrib(const TOpenFontFaceAttribBase& aAttrib)
1.1973 +/**
1.1974 +Sets the font attributes.
1.1975 +
1.1976 +@param aAttrib The font attributes.
1.1977 +*/
1.1978 + {
1.1979 + TOpenFontFaceAttribBase* self = this;
1.1980 + *self = aAttrib;
1.1981 + }
1.1982 +
1.1983 +/**
1.1984 +Gets the TFontSpec corresponding to this Open Font System font specification.
1.1985 +@publishedAll
1.1986 +@released
1.1987 +@param aFontSpec On return, contains the TFontSpec corresponding to this font
1.1988 +specification.
1.1989 +*/
1.1990 +EXPORT_C void TOpenFontSpec::GetTFontSpec(TFontSpec& aFontSpec) const
1.1991 + {
1.1992 + aFontSpec = TFontSpec();
1.1993 + TPtrC short_name(iName.Ptr(), Min(iName.Length(), KMaxTypefaceNameLength));
1.1994 + aFontSpec.iTypeface.iName = short_name;
1.1995 + aFontSpec.iTypeface.SetIsProportional(!IsMonoWidth());
1.1996 + aFontSpec.iTypeface.SetIsSerif(IsSerif());
1.1997 + aFontSpec.iTypeface.SetIsSymbol(Symbol());
1.1998 + aFontSpec.iTypeface.SetScriptTypeForMetrics(ScriptTypeForMetrics());
1.1999 + aFontSpec.iHeight = iHeight; // as twips
1.2000 + if (IsItalic() || (iSlantFactor > 0))
1.2001 + aFontSpec.iFontStyle.SetPosture(EPostureItalic);
1.2002 + if (IsBold() || IsEffectOn(FontEffect::EAlgorithmicBold))
1.2003 + aFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
1.2004 + aFontSpec.iFontStyle.SetPrintPosition(iPrintPosition);
1.2005 + aFontSpec.iFontStyle.SetBitmapType(BitmapType());
1.2006 + aFontSpec.iFontStyle.SetEffects(iEffects);
1.2007 + }
1.2008 +
1.2009 +/**
1.2010 +Sets a font effect to the given state.
1.2011 +@publishedAll
1.2012 +@released
1.2013 +@param aEffect The font effect to be set.
1.2014 +@param aOn True represents on, otherwise off.
1.2015 +@see TOpenFontSpec::IsEffectOn()
1.2016 +*/
1.2017 +EXPORT_C void TOpenFontSpec::SetEffects(FontEffect::TEffect aEffect, TBool aOn)
1.2018 + {
1.2019 + FontEffect::SetEffect(aEffect, aOn, iEffects);
1.2020 + }
1.2021 +
1.2022 +/** Checks if a font effect is on.
1.2023 +@publishedAll
1.2024 +@released
1.2025 +@return True represents the specified font effect is on, otherwise off.
1.2026 +@param aEffect The font effect to be checked.
1.2027 +@see TOpenFontSpec::SetEffects()
1.2028 +*/
1.2029 +EXPORT_C TBool TOpenFontSpec::IsEffectOn(FontEffect::TEffect aEffect) const
1.2030 + {
1.2031 + return FontEffect::IsEffectOn(aEffect, iEffects);
1.2032 + }
1.2033 +
1.2034 +/**
1.2035 +@deprecated This needs to be maintained to just call the inline methods.
1.2036 +*/
1.2037 +EXPORT_C void TOpenFontSpec::DoSetEffects(TUint32 aEffects)
1.2038 + {
1.2039 + SetEffects(aEffects);
1.2040 + }
1.2041 +
1.2042 +/**
1.2043 +@deprecated This needs to be maintained to just call the inline methods.
1.2044 +*/
1.2045 +EXPORT_C TUint32 TOpenFontSpec::DoEffects() const
1.2046 + {
1.2047 + return Effects();
1.2048 + }
1.2049 +
1.2050 +/**
1.2051 +Specifies the script which font metrics calculation will be based on.
1.2052 +@publishedAll
1.2053 +@released
1.2054 +@param aLanguage The language used to derive the required script.
1.2055 +*/
1.2056 +EXPORT_C void TOpenFontSpec::SetScriptTypeForMetrics(TLanguage aLanguage)
1.2057 + {
1.2058 + SetScriptTypeForMetrics(GlyphSample::TLanguage2TScript(aLanguage));
1.2059 + }
1.2060 +
1.2061 +/**
1.2062 +@internalTechnology
1.2063 +*/
1.2064 +void TOpenFontSpec::SetScriptTypeForMetrics(TInt aScript)
1.2065 + {
1.2066 + iSymbol &= ~KTOpenFontSpecMaskScript;
1.2067 + iSymbol |= (KTOpenFontSpecMaskScript & (aScript << KTOpenFontSpecBitsNumSymbol));
1.2068 + }
1.2069 +
1.2070 +/**
1.2071 +Gets the script which the font metrics calculation will be based on.
1.2072 +@internalTechnology
1.2073 +@return The script.
1.2074 +*/
1.2075 +EXPORT_C TInt TOpenFontSpec::ScriptTypeForMetrics() const
1.2076 + {
1.2077 + return (KTOpenFontSpecMaskScript & iSymbol) >> KTOpenFontSpecBitsNumSymbol;
1.2078 + }
1.2079 +
1.2080 +/**
1.2081 +@internalTechnology
1.2082 +*/
1.2083 +void TOpenFontSpec::SetSymbol(TBool aSymbol)
1.2084 + {
1.2085 + iSymbol &= ~KTOpenFontSpecMaskSymbol;
1.2086 + iSymbol |= (aSymbol ? KTOpenFontSpecSymbolFlag : 0);
1.2087 + }
1.2088 +
1.2089 +/**
1.2090 +@internalTechnology
1.2091 +*/
1.2092 +TBool TOpenFontSpec::Symbol() const
1.2093 + {
1.2094 + return (KTOpenFontSpecSymbolFlag & iSymbol) > 0;
1.2095 + }
1.2096 +
1.2097 +/**
1.2098 +@deprecated This needs to be maintained to just call the inline methods.
1.2099 +*/
1.2100 +EXPORT_C TBool TOpenFontSpec::OperatorEquality(const TOpenFontSpec& aOpenFontSpec) const
1.2101 + {
1.2102 + return this->operator == (aOpenFontSpec);
1.2103 + }
1.2104 +
1.2105 +/**
1.2106 +@internalTechnology
1.2107 +*/
1.2108 +TBool TOpenFontSpec::operator!=(const TOpenFontSpec& aOpenFontSpec) const
1.2109 + {
1.2110 + return !(this->operator == (aOpenFontSpec));
1.2111 + }
1.2112 +
1.2113 +/**
1.2114 +Static constructor for a TOpenFontGlyphData.
1.2115 +
1.2116 +This constructor creates the object on a specified heap. It must be deleted
1.2117 +using RHeap::Free().
1.2118 +
1.2119 +@param aHeap The shared heap on which the object is constructed.
1.2120 +@param aBufferSize The amount of memory allocated for the glyph data.
1.2121 +@return A pointer to the newly created object.
1.2122 +*/
1.2123 +EXPORT_C TOpenFontGlyphData* TOpenFontGlyphData::New(RHeap* aHeap, TInt aBufferSize)
1.2124 + {
1.2125 + if (aBufferSize < 1)
1.2126 + aBufferSize = 1;
1.2127 + TInt bytes = sizeof(TOpenFontGlyphData) + aBufferSize - 1;
1.2128 + TOpenFontGlyphData* g = (TOpenFontGlyphData*)aHeap->Alloc(bytes);
1.2129 + if (g != NULL)
1.2130 + {
1.2131 + Mem::FillZ(g, bytes);
1.2132 + g->iBitmapBufferSize = aBufferSize;
1.2133 + }
1.2134 + return g;
1.2135 + }
1.2136 +
1.2137 +// Virtual functions reserved for future expansion.
1.2138 +/**
1.2139 +@publishedPartner
1.2140 +@prototype
1.2141 +*/
1.2142 +EXPORT_C void COpenFontRasterizer::ExtendedInterface(TUid, TAny*&)
1.2143 + {
1.2144 + }
1.2145 +
1.2146 +/** @internalComponent */
1.2147 +EXPORT_C void COpenFontFile::ExtendedInterface(TUid, TAny*&)
1.2148 + {
1.2149 + }
1.2150 +
1.2151 +EXPORT_C void COpenFont::ExtendedInterface(TUid, TAny*&)
1.2152 + {
1.2153 + }
1.2154 +
1.2155 +EXPORT_C CShaper::CShaper()
1.2156 + {
1.2157 +
1.2158 + }
1.2159 +
1.2160 +EXPORT_C CShaper::~CShaper()
1.2161 + {
1.2162 +
1.2163 + }
1.2164 +/** @internalComponent */
1.2165 +EXPORT_C void* CShaper::ExtendedInterface(TUid)
1.2166 + {
1.2167 + return 0;
1.2168 + }
1.2169 +
1.2170 +/**
1.2171 +Sets the glyph bitmap type.
1.2172 +
1.2173 +Normally the bitmap type belongs to the font, but for linked fonts this can
1.2174 +be different between different font elements making up the linked font.
1.2175 +
1.2176 +Note: This is only of use in conjunction with rasterizer based linked fonts.
1.2177 +
1.2178 +@publishedPartner
1.2179 +@prototype
1.2180 +*/
1.2181 +EXPORT_C void TOpenFontCharMetrics::SetGlyphType(TGlyphBitmapType aGlyphBitmapType)
1.2182 + {
1.2183 + iGlyphBitmapType = aGlyphBitmapType;
1.2184 + }
1.2185 +
1.2186 +/**
1.2187 +Gets the glyph bitmap type.
1.2188 +
1.2189 +@publishedPartner
1.2190 +@prototype
1.2191 +*/
1.2192 +EXPORT_C TGlyphBitmapType TOpenFontCharMetrics::GlyphType() const
1.2193 + {
1.2194 + if (iGlyphBitmapType == 0)
1.2195 + return EGlyphBitmapTypeNotDefined;
1.2196 + else
1.2197 + return static_cast<TGlyphBitmapType>(iGlyphBitmapType);
1.2198 + }