os/graphics/graphicsdeviceinterface/gdi/sgdi/TFSTORE.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <gdi.h>
sl@0
    17
#include "GDIPANIC.h"
sl@0
    18
sl@0
    19
_LIT(KCTypefaceStore, "CTypefaceStore");
sl@0
    20
static const TInt KDefaultNumOfFontAccess = 4;
sl@0
    21
sl@0
    22
//
sl@0
    23
// CTypefaceStore
sl@0
    24
//
sl@0
    25
sl@0
    26
EXPORT_C CTypefaceStore::CTypefaceStore()
sl@0
    27
	{
sl@0
    28
	}
sl@0
    29
sl@0
    30
sl@0
    31
EXPORT_C CTypefaceStore::~CTypefaceStore()
sl@0
    32
/** Destroys the typeface store and reclaims the memory allocated to it. */
sl@0
    33
	{
sl@0
    34
	if (iFontAccess)
sl@0
    35
		{
sl@0
    36
		const TInt count = iFontAccess->Count();
sl@0
    37
		for (TInt i = 0; i < count; i++)
sl@0
    38
			{
sl@0
    39
			GDI_ASSERT_DEBUG_GENERAL((*iFontAccess)[0].iAccessCount > 0, User::Panic(KCTypefaceStore, KErrCorrupt));
sl@0
    40
			GDI_ASSERT_DEBUG_GENERAL((*iFontAccess)[0].iAccessCount == 1, User::Panic(KCTypefaceStore, KErrInUse));
sl@0
    41
			delete (*iFontAccess)[0].iFont;
sl@0
    42
			iFontAccess->Delete(0);
sl@0
    43
			}
sl@0
    44
		delete iFontAccess;
sl@0
    45
		}
sl@0
    46
	}
sl@0
    47
sl@0
    48
EXPORT_C void CTypefaceStore::ConstructL()
sl@0
    49
/** Second phase constructor. */
sl@0
    50
	{
sl@0
    51
	iFontAccess = new(ELeave) CArrayFixFlat<TFontAccess>(KDefaultNumOfFontAccess);
sl@0
    52
	}
sl@0
    53
sl@0
    54
EXPORT_C void CTypefaceStore::AddFontL(CFont* aFont)
sl@0
    55
/** Adds a hold, by a client of the typeface store, on the specified font.
sl@0
    56
sl@0
    57
If the specified font is not currently accessed by any clients of the typeface store
sl@0
    58
then the font is added to the font list and the access count set to 1.
sl@0
    59
If it is currently accessed then the access count for the font is incremented by 1.
sl@0
    60
sl@0
    61
@param aFont Pointer to the device specific font accessed. */
sl@0
    62
	{
sl@0
    63
	GDI_ASSERT_DEBUG_GENERAL(NULL != iFontAccess, User::Panic(KCTypefaceStore, KErrNoMemory));
sl@0
    64
	if (IncrementFontCount(aFont))
sl@0
    65
		return;
sl@0
    66
	TFontAccess fontAccess;
sl@0
    67
	fontAccess.iAccessCount = 1;
sl@0
    68
	fontAccess.iFont = aFont;
sl@0
    69
	iFontAccess->AppendL(fontAccess);
sl@0
    70
	}
sl@0
    71
sl@0
    72
EXPORT_C void CTypefaceStore::ReleaseFont(CFont* aFont)
sl@0
    73
/** Releases the hold of a typeface store client on a specified font.
sl@0
    74
sl@0
    75
Decrements the access-count for the specified font by one. If this reduces the access-count 
sl@0
    76
to zero then the font is no longer needed by any client, and is deleted from 
sl@0
    77
the typeface store list.
sl@0
    78
sl@0
    79
@param aFont The font to be released by the client. */
sl@0
    80
	{
sl@0
    81
	
sl@0
    82
	GDI_ASSERT_DEBUG_GENERAL(NULL != iFontAccess, User::Panic(KCTypefaceStore, KErrNoMemory));
sl@0
    83
	if (!aFont)
sl@0
    84
		return;
sl@0
    85
	TInt idx = 0;
sl@0
    86
	GDI_ASSERT_ALWAYS_GENERAL(FindFont(aFont, idx), User::Panic(KCTypefaceStore, KErrNotFound));
sl@0
    87
	GDI_ASSERT_DEBUG_GENERAL(0 < iFontAccess->At(idx).iAccessCount, User::Panic(KCTypefaceStore, KErrCorrupt));
sl@0
    88
	iFontAccess->At(idx).iAccessCount--;
sl@0
    89
	if (0 == iFontAccess->At(idx).iAccessCount)
sl@0
    90
		{
sl@0
    91
		CFont *font=iFontAccess->At(idx).iFont;
sl@0
    92
		iFontAccess->Delete(idx);
sl@0
    93
		delete font;
sl@0
    94
		}
sl@0
    95
	}
sl@0
    96
sl@0
    97
EXPORT_C TBool CTypefaceStore::IncrementFontCount(const CFont* aFont)
sl@0
    98
/**
sl@0
    99
Search for the font in iFontAccess and increment its count.
sl@0
   100
@param aFont Font to search for.
sl@0
   101
@return ETrue if the specified font is found, EFalse otherwise.
sl@0
   102
*/
sl@0
   103
	{
sl@0
   104
	TInt idx = 0;
sl@0
   105
	if (FindFont(aFont, idx))
sl@0
   106
		{
sl@0
   107
		iFontAccess->At(idx).iAccessCount++;
sl@0
   108
		return ETrue;
sl@0
   109
		}
sl@0
   110
	return EFalse;
sl@0
   111
	}
sl@0
   112
sl@0
   113
TBool CTypefaceStore::FindFont(const CFont* aFont, TInt& aIdx) const
sl@0
   114
/**
sl@0
   115
Search for the font in iFontAccess.
sl@0
   116
@param aFont Font to search for.
sl@0
   117
@param aIdx Index of the font found.
sl@0
   118
@return ETrue if the specified font is found, EFalse with aIdx = -1 otherwise.
sl@0
   119
*/
sl@0
   120
	{
sl@0
   121
	aIdx = -1;
sl@0
   122
	if (!iFontAccess)
sl@0
   123
		return EFalse;
sl@0
   124
	const TInt count = iFontAccess->Count();
sl@0
   125
	for (TInt i = 0; i < count; i++)
sl@0
   126
		{
sl@0
   127
		if ((*iFontAccess)[i].iFont == aFont)
sl@0
   128
			{
sl@0
   129
			aIdx = i;
sl@0
   130
			return ETrue;
sl@0
   131
			}
sl@0
   132
		}
sl@0
   133
	return EFalse;
sl@0
   134
	}
sl@0
   135
sl@0
   136
EXPORT_C TInt CTypefaceStore::BaselineOffset(TInt aHeight,TFontPrintPosition aPos)
sl@0
   137
/** Gets the baseline offset, in twips, for any font in subscript or superscript 
sl@0
   138
form.
sl@0
   139
sl@0
   140
If the print position is normal then zero is returned. If it is superscript 
sl@0
   141
then the baseline offset returned is a percentage, KSuperscriptOffsetPercentage, 
sl@0
   142
of aHeight. If it is subscript then the baseline offset returned is a percentage, 
sl@0
   143
KSubscriptOffsetPercentage, of aHeight.
sl@0
   144
sl@0
   145
@param aHeight The height of a font. 
sl@0
   146
@param aPos The print position of the required font: superscript, subscript 
sl@0
   147
or normal. 
sl@0
   148
@return The baseline offset for the font. */
sl@0
   149
	{
sl@0
   150
	TInt offset=0;
sl@0
   151
	if (aPos==EPrintPosSuperscript)
sl@0
   152
		offset=KSuperscriptOffsetPercentage*aHeight/100;
sl@0
   153
	else if (aPos==EPrintPosSubscript)
sl@0
   154
		offset=KSubscriptOffsetPercentage*aHeight/100;
sl@0
   155
	return offset;
sl@0
   156
	}
sl@0
   157
	 
sl@0
   158
 
sl@0
   159
EXPORT_C TInt CTypefaceStore::SuperSubHeight(TInt aHeight,TFontPrintPosition aPos)
sl@0
   160
/** Gets the height for a font in subscript or superscript form. 
sl@0
   161
sl@0
   162
If the print position is normal then aHeight is returned unchanged. If it 
sl@0
   163
is superscript or subscript then the height returned is a percentage, KSuperSubScalingPercentage, 
sl@0
   164
of aHeight.
sl@0
   165
sl@0
   166
@param aHeight The height of a font. 
sl@0
   167
@param aPos The print position of the font: superscript, subscript or normal.
sl@0
   168
@return The required height of the font. */
sl@0
   169
	{
sl@0
   170
	if(aPos!=EPrintPosNormal)
sl@0
   171
		aHeight=(KSuperSubScalingPercentage*aHeight)/100;
sl@0
   172
	return aHeight;
sl@0
   173
	}
sl@0
   174
sl@0
   175
//
sl@0
   176
// CFontCache
sl@0
   177
//
sl@0
   178
 
sl@0
   179
EXPORT_C CFontCache::CFontCache():
sl@0
   180
	CBase(),
sl@0
   181
	iMaxEntries(KMaxFontCacheEntries)
sl@0
   182
/** Default constructor.
sl@0
   183
sl@0
   184
This constructs a CFontCache of size KMaxFontCacheEntries. */
sl@0
   185
	{
sl@0
   186
	__DECLARE_NAME(_S("CFontCache"));
sl@0
   187
	}
sl@0
   188
 
sl@0
   189
EXPORT_C CFontCache::CFontCache(TInt aMaxEntries):
sl@0
   190
	CBase(),
sl@0
   191
	iMaxEntries(aMaxEntries)
sl@0
   192
/** Constructor specifying the number of cache entries.
sl@0
   193
sl@0
   194
@param aMaxEntries Number of entries for this cache. You must ensure this 
sl@0
   195
is less than or equal to KMaxFontCacheEntries. */
sl@0
   196
	{
sl@0
   197
	__DECLARE_NAME(_S("CFontCache"));
sl@0
   198
	}
sl@0
   199
sl@0
   200
 
sl@0
   201
EXPORT_C CFontCache::~CFontCache()
sl@0
   202
/** Destructor. 
sl@0
   203
sl@0
   204
This destroys the cashe and releases its allocated memory. */
sl@0
   205
	{
sl@0
   206
	CFontCacheEntry* entry=iFirst;
sl@0
   207
	while(entry)
sl@0
   208
		{
sl@0
   209
		iFirst=entry->iNext;
sl@0
   210
		delete entry;
sl@0
   211
		entry=iFirst;
sl@0
   212
		}
sl@0
   213
	}
sl@0
   214
sl@0
   215
 
sl@0
   216
EXPORT_C CFont* CFontCache::Search(const TFontSpec& aFontSpec)
sl@0
   217
/** Searches the cache for a specified font. 
sl@0
   218
sl@0
   219
The CFont returned is that which corresponds to the font specification aFontSpec.
sl@0
   220
sl@0
   221
@param aFontSpec The specification of the font to be searched for. 
sl@0
   222
@return If an entry for the font specification is found in the cache, the pointer 
sl@0
   223
to the font corresponding to the font specification is returned. Otherwise 
sl@0
   224
NULL is returned. */
sl@0
   225
	{
sl@0
   226
	CFontCacheEntry* entry=iFirst;
sl@0
   227
	CFontCacheEntry* previous=NULL;
sl@0
   228
	while(entry)
sl@0
   229
		{
sl@0
   230
		if(entry->iSpec==aFontSpec)
sl@0
   231
			{
sl@0
   232
			iNumHits++;
sl@0
   233
			if(previous)
sl@0
   234
				{
sl@0
   235
				previous->iNext=entry->iNext;
sl@0
   236
				entry->iNext=iFirst;
sl@0
   237
				iFirst=entry;
sl@0
   238
				}
sl@0
   239
			return(entry->iFont);
sl@0
   240
			}
sl@0
   241
		previous=entry;
sl@0
   242
		entry=entry->iNext;
sl@0
   243
		}
sl@0
   244
	iNumMisses++;
sl@0
   245
	return(NULL);
sl@0
   246
	}
sl@0
   247
sl@0
   248
 
sl@0
   249
EXPORT_C CFont* CFontCache::AddEntryL(CFont* aFont,const TFontSpec& aFontSpec)
sl@0
   250
/** Adds a font entry to the cache. 
sl@0
   251
sl@0
   252
The font, and the font specification required to extract it from the cache, 
sl@0
   253
are both specified. If the cache is already full, the font replaces the oldest 
sl@0
   254
entry already in the cache, which is returned.
sl@0
   255
sl@0
   256
@param aFont The font to be stored in the cache. 
sl@0
   257
@param aFontSpec The font's corresponding font specification. 
sl@0
   258
@return If the cache isn't full, NULL is returned. If the cache is full, the 
sl@0
   259
displaced cache entry is returned. */
sl@0
   260
	{
sl@0
   261
	CFontCacheEntry* entry=new(ELeave) CFontCacheEntry(aFont,aFontSpec,iFirst);
sl@0
   262
	iFirst=entry;
sl@0
   263
	iNumEntries++;
sl@0
   264
	if(iNumEntries<=iMaxEntries)
sl@0
   265
		return(NULL);
sl@0
   266
	CFontCacheEntry* previous=NULL;
sl@0
   267
	while(entry->iNext)
sl@0
   268
		{
sl@0
   269
		previous=entry;
sl@0
   270
		entry=entry->iNext;
sl@0
   271
		}
sl@0
   272
	CFont* discardfont=entry->iFont;
sl@0
   273
	delete entry;
sl@0
   274
	iNumEntries--;
sl@0
   275
	if(previous)
sl@0
   276
		previous->iNext=NULL;
sl@0
   277
	else
sl@0
   278
		iFirst=NULL;
sl@0
   279
	return(discardfont);
sl@0
   280
	}
sl@0
   281
sl@0
   282
 
sl@0
   283
EXPORT_C CFont* CFontCache::RemoveFirstEntry()
sl@0
   284
/** Removes the first entry from the font cache and returns it.
sl@0
   285
sl@0
   286
@return The entry removed from the font cache. If the cache is empty, NULL 
sl@0
   287
is returned. */
sl@0
   288
	{
sl@0
   289
	if(iFirst==NULL) return(NULL);
sl@0
   290
	CFontCacheEntry* entry=iFirst;
sl@0
   291
	iFirst=entry->iNext;
sl@0
   292
	CFont* font=entry->iFont;
sl@0
   293
	delete entry;
sl@0
   294
	iNumEntries--;
sl@0
   295
	return(font);
sl@0
   296
	}
sl@0
   297
sl@0
   298
// CFontCacheEntry
sl@0
   299
sl@0
   300
CFontCache::CFontCacheEntry::CFontCacheEntry(CFont* aFont,const TFontSpec& aFontSpec,CFontCacheEntry* aNext):
sl@0
   301
	CBase(),
sl@0
   302
	iFont(aFont),
sl@0
   303
	iSpec(aFontSpec),
sl@0
   304
	iNext(aNext)
sl@0
   305
	{
sl@0
   306
	__DECLARE_NAME(_S("CFontCacheEntry"));
sl@0
   307
	}