os/textandloc/fontservices/textshaperplugin/source/SymbianFontInstance.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
* Symbian implementation of LEFontInstance
sl@0
    16
*
sl@0
    17
*/
sl@0
    18
sl@0
    19
// Symbian includes
sl@0
    20
#include <stdio.h>
sl@0
    21
#include <gdi.h>
sl@0
    22
#include <openfont.h>
sl@0
    23
#include <fntstore.h>
sl@0
    24
#include <string.h>
sl@0
    25
sl@0
    26
// Icu includes
sl@0
    27
#include "layout/LETypes.h"
sl@0
    28
#include "layout/LEFontInstance.h"
sl@0
    29
#include "layout/LESwaps.h"
sl@0
    30
sl@0
    31
#include "SymbianFontInstance.h"
sl@0
    32
sl@0
    33
//
sl@0
    34
// Finds the high bit by binary searching
sl@0
    35
// through the bits in n.
sl@0
    36
//
sl@0
    37
le_int8 SymbianFontInstance::highBit(le_int32 value)
sl@0
    38
	{
sl@0
    39
    if (value <= 0) 
sl@0
    40
    	{
sl@0
    41
        return -32;
sl@0
    42
    	}
sl@0
    43
sl@0
    44
    le_uint8 bit = 0;
sl@0
    45
sl@0
    46
    if (value >= 1 << 16) 
sl@0
    47
    	{
sl@0
    48
        value >>= 16;
sl@0
    49
        bit += 16;
sl@0
    50
    	}
sl@0
    51
sl@0
    52
    if (value >= 1 << 8) 
sl@0
    53
    	{
sl@0
    54
        value >>= 8;
sl@0
    55
        bit += 8;
sl@0
    56
    	}
sl@0
    57
sl@0
    58
    if (value >= 1 << 4) 
sl@0
    59
    	{
sl@0
    60
        value >>= 4;
sl@0
    61
        bit += 4;
sl@0
    62
    	}
sl@0
    63
sl@0
    64
    if (value >= 1 << 2) 
sl@0
    65
    	{
sl@0
    66
        value >>= 2;
sl@0
    67
        bit += 2;
sl@0
    68
    	}
sl@0
    69
sl@0
    70
    if (value >= 1 << 1) 
sl@0
    71
    	{
sl@0
    72
        value >>= 1;
sl@0
    73
        bit += 1;
sl@0
    74
    	}
sl@0
    75
sl@0
    76
    return bit;
sl@0
    77
	}
sl@0
    78
sl@0
    79
// This is used to build a shaper which does not require the rasteriser
sl@0
    80
// to support table access.  This is required for interworking testing.
sl@0
    81
// #define TRUETYPE_EXTENSION_NOT_SUPPORTED
sl@0
    82
#ifndef TRUETYPE_EXTENSION_NOT_SUPPORTED
sl@0
    83
sl@0
    84
	
sl@0
    85
SymbianFontInstance::SymbianFontInstance(CBitmapFont *aBitmapFont,
sl@0
    86
	LEErrorCode &status, le_bool aKeepGlyphOfZWJ)
sl@0
    87
	: fFile(NULL), fUnitsPerEM(0), fAscent(0), fDescent(0), fLeading(0),
sl@0
    88
      fDirectory(NULL), fCMAPMapper(NULL), fHMTXTable(0), fNumGlyphs(0),
sl@0
    89
      fNumLongHorMetrics(0), iFont(aBitmapFont), iKeepGlyphOfZWJ(aKeepGlyphOfZWJ)
sl@0
    90
sl@0
    91
	{
sl@0
    92
	// get the OpenFont details
sl@0
    93
	if (!aBitmapFont->IsOpenFont())
sl@0
    94
		{
sl@0
    95
		// the font supplied was not a Openfont so ..
sl@0
    96
		status = LE_ILLEGAL_ARGUMENT_ERROR;
sl@0
    97
		return;
sl@0
    98
		}
sl@0
    99
sl@0
   100
	COpenFont* font = aBitmapFont->OpenFont();
sl@0
   101
sl@0
   102
	// get the extended interface
sl@0
   103
	TAny* ext = 0;
sl@0
   104
	font->ExtendedInterface(KUidOpenFontShapingExtension, ext);
sl@0
   105
	MOpenFontShapingExtension* extensionInterface
sl@0
   106
		= reinterpret_cast<MOpenFontShapingExtension*>(ext);
sl@0
   107
sl@0
   108
	font->ExtendedInterface(KUidOpenFontTrueTypeExtension, ext);
sl@0
   109
	MOpenFontTrueTypeExtension* trueTypeExtensionInterface
sl@0
   110
		= reinterpret_cast<MOpenFontTrueTypeExtension*>(ext);
sl@0
   111
sl@0
   112
	/* Currently if the trueTypeExtensionInterface is not available the 
sl@0
   113
	truetype tables are accessed directly rather than via the rasteriser */
sl@0
   114
	if (!extensionInterface /* || !trueTypeExtensionInterface*/)
sl@0
   115
		{
sl@0
   116
		// this rasterizer does not support the required interface
sl@0
   117
		// so do not bother to shape
sl@0
   118
		status = LE_ILLEGAL_ARGUMENT_ERROR;
sl@0
   119
		return ;
sl@0
   120
		}
sl@0
   121
sl@0
   122
	iTrueTypeExtensionInterface = trueTypeExtensionInterface;
sl@0
   123
	iExtensionInterface = extensionInterface;
sl@0
   124
	
sl@0
   125
	// get the font file name from the COpenFontFile in the COpenFont
sl@0
   126
	TBuf8<KMaxFileName> fontFileName;
sl@0
   127
	fontFileName.Copy(font->File()->FileName());
sl@0
   128
	fontFileName.ZeroTerminate();
sl@0
   129
sl@0
   130
	/* get the font metrics via the rasterizer */
sl@0
   131
	MOpenFontShapingExtension::TExtensionFontMetrics fontMetrics;
sl@0
   132
	extensionInterface->GetExtensionFontMetrics(fontMetrics);
sl@0
   133
sl@0
   134
 	/* The number of font design units per em. */
sl@0
   135
	fUnitsPerEM	= fontMetrics.iUnitsPerEm;
sl@0
   136
sl@0
   137
	/* The size of the font's em square in pixels. */
sl@0
   138
	fXPixelsPerEm	= fontMetrics.iXPixelsPerEm;
sl@0
   139
	fYPixelsPerEm	= fontMetrics.iYPixelsPerEm;
sl@0
   140
sl@0
   141
	/* Scaling factors, pixels per font unit. */
sl@0
   142
	fDeviceScaleY = fontMetrics.iYScaleFactor;
sl@0
   143
	fDeviceScaleX = fontMetrics.iXScaleFactor;
sl@0
   144
sl@0
   145
	// open the font file
sl@0
   146
	fFile = fopen( (char *)fontFileName.Ptr(), "rb");
sl@0
   147
	if (fFile == 0)
sl@0
   148
		{
sl@0
   149
		status = LE_FONT_FILE_NOT_FOUND_ERROR;
sl@0
   150
		return;
sl@0
   151
		}
sl@0
   152
sl@0
   153
    // read in the directory
sl@0
   154
    SFNTDirectory tempDir;
sl@0
   155
sl@0
   156
    fread(&tempDir, sizeof tempDir, 1, fFile);
sl@0
   157
sl@0
   158
    le_int32 dirSize = sizeof tempDir + ((SWAPW(tempDir.numTables) - ANY_NUMBER) * sizeof(DirectoryEntry));
sl@0
   159
    const LETag headTag = LE_HEAD_TABLE_TAG;
sl@0
   160
    const LETag hheaTag = LE_HHEA_TABLE_TAG;
sl@0
   161
    const HEADTable *headTable = NULL;
sl@0
   162
    const HHEATable *hheaTable = NULL;
sl@0
   163
    le_uint16 numTables = 0;
sl@0
   164
    
sl@0
   165
    //coverity[incorrect_multiplication]
sl@0
   166
    //coverity[buffer_alloc]
sl@0
   167
    // dirSize is The actually sizoe of fDirectory which indeed contains more data thant SFNTDirectory defined.
sl@0
   168
    fDirectory = (const SFNTDirectory *) LE_NEW_ARRAY(char, dirSize);
sl@0
   169
   
sl@0
   170
    if (fDirectory == NULL) 
sl@0
   171
    	{
sl@0
   172
        status = LE_MEMORY_ALLOCATION_ERROR;
sl@0
   173
        goto error_exit;
sl@0
   174
    	}
sl@0
   175
sl@0
   176
    fseek(fFile, 0L, SEEK_SET);
sl@0
   177
    fread((void *) fDirectory, sizeof(char), dirSize, fFile);
sl@0
   178
sl@0
   179
    //
sl@0
   180
    // We calculate these numbers 'cause some fonts
sl@0
   181
    // have bogus values for them in the directory header.
sl@0
   182
    //
sl@0
   183
    numTables = SWAPW(fDirectory->numTables);
sl@0
   184
    fDirPower = 1 << highBit(numTables);
sl@0
   185
    fDirExtra = numTables - fDirPower;
sl@0
   186
sl@0
   187
    // read unitsPerEm from 'head' table
sl@0
   188
    headTable = (const HEADTable *) readFontTable(headTag);
sl@0
   189
sl@0
   190
    if (headTable == NULL) 
sl@0
   191
    	{
sl@0
   192
        status = LE_MISSING_FONT_TABLE_ERROR;
sl@0
   193
        goto error_exit;
sl@0
   194
    	}
sl@0
   195
sl@0
   196
    fUnitsPerEM = SWAPW(headTable->unitsPerEm);
sl@0
   197
    deleteTable(headTable);
sl@0
   198
sl@0
   199
    hheaTable = (HHEATable *) readFontTable(hheaTag);
sl@0
   200
sl@0
   201
    if (hheaTable == NULL) 
sl@0
   202
    	{
sl@0
   203
        status = LE_MISSING_FONT_TABLE_ERROR;
sl@0
   204
        goto error_exit;
sl@0
   205
    	}
sl@0
   206
sl@0
   207
    fAscent  = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent));
sl@0
   208
    fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent));
sl@0
   209
    fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap));
sl@0
   210
sl@0
   211
    fNumLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
sl@0
   212
sl@0
   213
    deleteTable((void *) hheaTable);
sl@0
   214
sl@0
   215
    fCMAPMapper = findUnicodeMapper();
sl@0
   216
sl@0
   217
    if (fCMAPMapper == NULL) 
sl@0
   218
    	{
sl@0
   219
        status = LE_MISSING_FONT_TABLE_ERROR;
sl@0
   220
        goto error_exit;
sl@0
   221
    	}
sl@0
   222
sl@0
   223
	return;
sl@0
   224
	
sl@0
   225
error_exit:
sl@0
   226
    fclose(fFile);
sl@0
   227
    fFile = NULL;
sl@0
   228
    return;
sl@0
   229
	}
sl@0
   230
sl@0
   231
SymbianFontInstance::~SymbianFontInstance()
sl@0
   232
	{
sl@0
   233
	if (fFile != NULL) 
sl@0
   234
		{
sl@0
   235
		fclose(fFile);
sl@0
   236
		deleteTable(fHMTXTable);
sl@0
   237
		delete fCMAPMapper;
sl@0
   238
		LE_DELETE_ARRAY(fDirectory);
sl@0
   239
		}
sl@0
   240
	};
sl@0
   241
sl@0
   242
#else
sl@0
   243
 	/* read the font directly.  This is used if rasterizers do not support
sl@0
   244
 	   the trueTypeExtensionInterface */
sl@0
   245
 
sl@0
   246
SymbianFontInstance::SymbianFontInstance(CBitmapFont *aBitmapFont,
sl@0
   247
 	LEErrorCode &status)
sl@0
   248
 	: fFile(NULL), fUnitsPerEM(0), fAscent(0), fDescent(0), fLeading(0),
sl@0
   249
       fDirectory(NULL), fCMAPMapper(NULL), fHMTXTable(0), fNumGlyphs(0),
sl@0
   250
       fNumLongHorMetrics(0), iFont(aBitmapFont)
sl@0
   251
 
sl@0
   252
 	{
sl@0
   253
 	// get the OpenFont details
sl@0
   254
 	if (!aBitmapFont->IsOpenFont())
sl@0
   255
 		{
sl@0
   256
 		// the font supplied was not a Openfont so ..
sl@0
   257
 		status = LE_ILLEGAL_ARGUMENT_ERROR;
sl@0
   258
 		return;
sl@0
   259
 		}
sl@0
   260
 
sl@0
   261
 	COpenFont* font = aBitmapFont->OpenFont();
sl@0
   262
 
sl@0
   263
 	// get the extended interface
sl@0
   264
 	TAny* ext = 0;
sl@0
   265
 	font->ExtendedInterface(KUidOpenFontShapingExtension, ext);
sl@0
   266
 	iExtensionInterface = reinterpret_cast<MOpenFontShapingExtension*>(ext);
sl@0
   267
 
sl@0
   268
 	// do not use the true type interface
sl@0
   269
 	iTrueTypeExtensionInterface = 0;
sl@0
   270
 
sl@0
   271
 	if (!iExtensionInterface  )
sl@0
   272
 		{
sl@0
   273
 		// this rasterizer does not support the required interface
sl@0
   274
 		// so do not bother to shape
sl@0
   275
 		status = LE_ILLEGAL_ARGUMENT_ERROR;
sl@0
   276
 		return ;
sl@0
   277
 		}
sl@0
   278
 
sl@0
   279
 	// get the font file name from the COpenFontFile in the COpenFont
sl@0
   280
 	TBuf8<KMaxFileName> fontFileName;
sl@0
   281
 	fontFileName.Copy(font->File()->FileName());
sl@0
   282
 	fontFileName.ZeroTerminate();
sl@0
   283
 
sl@0
   284
 	/* get the font metrics via the rasterizer */
sl@0
   285
 	MOpenFontShapingExtension::TExtensionFontMetrics fontMetrics;
sl@0
   286
 	iExtensionInterface->GetExtensionFontMetrics(fontMetrics);
sl@0
   287
   
sl@0
   288
    /* The number of font design units per em. */
sl@0
   289
   	fUnitsPerEM	= fontMetrics.iUnitsPerEm;
sl@0
   290
   
sl@0
   291
   	/* The size of the font's em square in pixels. */
sl@0
   292
   	fXPixelsPerEm	= fontMetrics.iXPixelsPerEm;
sl@0
   293
   	fYPixelsPerEm	= fontMetrics.iYPixelsPerEm;
sl@0
   294
   
sl@0
   295
   	/* Scaling factors, pixels per font unit. */
sl@0
   296
   	fDeviceScaleY = fontMetrics.iYScaleFactor;
sl@0
   297
   	fDeviceScaleX = fontMetrics.iXScaleFactor;
sl@0
   298
   
sl@0
   299
   	// open the font file
sl@0
   300
   	fFile = fopen( (char *)fontFileName.Ptr(), "rb");
sl@0
   301
   	if (fFile == 0)
sl@0
   302
   		{
sl@0
   303
   		status = LE_FONT_FILE_NOT_FOUND_ERROR;
sl@0
   304
   		return;
sl@0
   305
   		}
sl@0
   306
   
sl@0
   307
    // read in the directory
sl@0
   308
    SFNTDirectory tempDir;
sl@0
   309
   
sl@0
   310
    fread(&tempDir, sizeof tempDir, 1, fFile);
sl@0
   311
   
sl@0
   312
    le_int32 dirSize = sizeof tempDir + ((SWAPW(tempDir.numTables) - ANY_NUMBER) * sizeof(DirectoryEntry));
sl@0
   313
    const LETag headTag = LE_HEAD_TABLE_TAG;
sl@0
   314
    const LETag hheaTag = LE_HHEA_TABLE_TAG;
sl@0
   315
    const HEADTable *headTable = NULL;
sl@0
   316
    const HHEATable *hheaTable = NULL;
sl@0
   317
    le_uint16 numTables = 0;
sl@0
   318
    
sl@0
   319
    fDirectory = (const SFNTDirectory *) LE_NEW_ARRAY(char, dirSize);
sl@0
   320
    
sl@0
   321
    if (fDirectory == NULL) 
sl@0
   322
    	{
sl@0
   323
        status = LE_MEMORY_ALLOCATION_ERROR;
sl@0
   324
        goto error_exit;
sl@0
   325
    	}
sl@0
   326
   
sl@0
   327
    fseek(fFile, 0L, SEEK_SET);
sl@0
   328
    fread((void *) fDirectory, sizeof(char), dirSize, fFile);
sl@0
   329
   
sl@0
   330
    //
sl@0
   331
    // We calculate these numbers 'cause some fonts
sl@0
   332
    // have bogus values for them in the directory header.
sl@0
   333
    //
sl@0
   334
    numTables = SWAPW(fDirectory->numTables);
sl@0
   335
    fDirPower = 1 << highBit(numTables);
sl@0
   336
    fDirExtra = numTables - fDirPower;
sl@0
   337
   
sl@0
   338
    // read unitsPerEm from 'head' table
sl@0
   339
    headTable = (const HEADTable *) readFontTable(headTag);
sl@0
   340
   
sl@0
   341
    if (headTable == NULL) 
sl@0
   342
    	{
sl@0
   343
        status = LE_MISSING_FONT_TABLE_ERROR;
sl@0
   344
        goto error_exit;
sl@0
   345
    	}
sl@0
   346
   
sl@0
   347
    fUnitsPerEM = SWAPW(headTable->unitsPerEm);
sl@0
   348
    deleteTable(headTable);
sl@0
   349
   
sl@0
   350
    hheaTable = (HHEATable *) readFontTable(hheaTag);
sl@0
   351
   
sl@0
   352
    if (hheaTable == NULL) 
sl@0
   353
    	{
sl@0
   354
        status = LE_MISSING_FONT_TABLE_ERROR;
sl@0
   355
        goto error_exit;
sl@0
   356
    	}
sl@0
   357
   
sl@0
   358
    fAscent  = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent));
sl@0
   359
    fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent));
sl@0
   360
    fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap));
sl@0
   361
   
sl@0
   362
    fNumLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
sl@0
   363
   
sl@0
   364
    deleteTable((void *) hheaTable);
sl@0
   365
   
sl@0
   366
    fCMAPMapper = findUnicodeMapper();
sl@0
   367
   
sl@0
   368
    if (fCMAPMapper == NULL) 
sl@0
   369
    	{
sl@0
   370
        status = LE_MISSING_FONT_TABLE_ERROR;
sl@0
   371
        goto error_exit;
sl@0
   372
    	}
sl@0
   373
   
sl@0
   374
	return;
sl@0
   375
   	
sl@0
   376
   	error_exit:
sl@0
   377
       fclose(fFile);
sl@0
   378
       fFile = NULL;
sl@0
   379
       return;
sl@0
   380
   	}
sl@0
   381
   
sl@0
   382
SymbianFontInstance::~SymbianFontInstance()
sl@0
   383
   	{
sl@0
   384
       if (fFile != NULL) 
sl@0
   385
       	{
sl@0
   386
           fclose(fFile);
sl@0
   387
       
sl@0
   388
           deleteTable(fHMTXTable);
sl@0
   389
   
sl@0
   390
           delete fCMAPMapper;
sl@0
   391
   
sl@0
   392
           LE_DELETE_ARRAY(fDirectory);
sl@0
   393
       	}
sl@0
   394
   	};
sl@0
   395
   
sl@0
   396
#endif
sl@0
   397
   
sl@0
   398
sl@0
   399
void SymbianFontInstance::deleteTable(const void *table) const
sl@0
   400
	{
sl@0
   401
	LE_DELETE_ARRAY(table);
sl@0
   402
	}
sl@0
   403
sl@0
   404
const DirectoryEntry *SymbianFontInstance::findTable(LETag tag) const
sl@0
   405
	{
sl@0
   406
    if (fDirectory != NULL) 
sl@0
   407
    	{
sl@0
   408
        le_uint16 table = 0;
sl@0
   409
        le_uint16 probe = fDirPower;
sl@0
   410
sl@0
   411
        if (SWAPL(fDirectory->tableDirectory[fDirExtra].tag) <= tag) 
sl@0
   412
        	{
sl@0
   413
            table = fDirExtra;
sl@0
   414
        	}
sl@0
   415
sl@0
   416
        while (probe > (1 << 0)) 
sl@0
   417
        	{
sl@0
   418
            probe >>= 1;
sl@0
   419
sl@0
   420
            if (SWAPL(fDirectory->tableDirectory[table + probe].tag) <= tag) 
sl@0
   421
            	{
sl@0
   422
                table += probe;
sl@0
   423
            	}
sl@0
   424
        	}
sl@0
   425
sl@0
   426
        if (SWAPL(fDirectory->tableDirectory[table].tag) == tag) 
sl@0
   427
        	{
sl@0
   428
            return &fDirectory->tableDirectory[table];
sl@0
   429
        	}
sl@0
   430
    	}
sl@0
   431
sl@0
   432
    return NULL;
sl@0
   433
	}
sl@0
   434
sl@0
   435
const void *SymbianFontInstance::readTable(LETag aTag, le_uint32 *aLength) const
sl@0
   436
	{
sl@0
   437
	void *table = NULL;
sl@0
   438
sl@0
   439
	/* If the current rasteriser supports the TrueTypeExtensionInterface 
sl@0
   440
	   use it to access the true Type tables */
sl@0
   441
	if (iTrueTypeExtensionInterface)
sl@0
   442
		{
sl@0
   443
		TInt error;
sl@0
   444
		TInt length;
sl@0
   445
		TAny * trueTypeTable = iTrueTypeExtensionInterface->
sl@0
   446
			GetTrueTypeTable(error, aTag, &length);
sl@0
   447
sl@0
   448
	 	if (!trueTypeTable) 
sl@0
   449
			{
sl@0
   450
			*aLength = 0;
sl@0
   451
			return 0;
sl@0
   452
			}
sl@0
   453
sl@0
   454
		if (aLength)
sl@0
   455
			*aLength = length;
sl@0
   456
sl@0
   457
		// allocate some memory for the table & copy table into it
sl@0
   458
		table = LE_NEW_ARRAY(char, length);
sl@0
   459
		if (table) 
sl@0
   460
			{
sl@0
   461
			// copy the table from the rasteriser
sl@0
   462
			Mem::Copy(table, (char *) trueTypeTable, length);
sl@0
   463
			}
sl@0
   464
	  
sl@0
   465
	  	iTrueTypeExtensionInterface->ReleaseTrueTypeTable(trueTypeTable);
sl@0
   466
  	  	}
sl@0
   467
  	else
sl@0
   468
  	  	{
sl@0
   469
		// old method, read the table directly
sl@0
   470
		const DirectoryEntry *entry = findTable(aTag);
sl@0
   471
sl@0
   472
		if (entry == NULL) 
sl@0
   473
			{
sl@0
   474
			if (aLength)
sl@0
   475
				*aLength = 0;
sl@0
   476
			return NULL;
sl@0
   477
			}
sl@0
   478
sl@0
   479
		TInt length = SWAPL(entry->length);
sl@0
   480
		if (aLength)
sl@0
   481
			*aLength = length;
sl@0
   482
sl@0
   483
		table = LE_NEW_ARRAY(char, length);
sl@0
   484
sl@0
   485
		if (table != NULL) 
sl@0
   486
			{
sl@0
   487
			fseek(fFile, SWAPL(entry->offset), SEEK_SET);
sl@0
   488
			fread(table, sizeof(char), length, fFile);
sl@0
   489
			}
sl@0
   490
		}
sl@0
   491
	    
sl@0
   492
    return table;
sl@0
   493
    }
sl@0
   494
    
sl@0
   495
const void *SymbianFontInstance::getFontTable(LETag tableTag) const
sl@0
   496
	{
sl@0
   497
	if (iTrueTypeExtensionInterface)
sl@0
   498
		{
sl@0
   499
		TInt error;
sl@0
   500
		return iTrueTypeExtensionInterface->GetTrueTypeTable(error, tableTag, 0);
sl@0
   501
		}
sl@0
   502
	return FontTableCache::find(tableTag);
sl@0
   503
	}
sl@0
   504
sl@0
   505
const void *SymbianFontInstance::readFontTable(LETag tableTag) const
sl@0
   506
	{
sl@0
   507
	return readTable(tableTag, 0);
sl@0
   508
	}
sl@0
   509
sl@0
   510
CMAPMapper *SymbianFontInstance::findUnicodeMapper()
sl@0
   511
	{
sl@0
   512
	LETag cmapTag = LE_CMAP_TABLE_TAG;
sl@0
   513
	const CMAPTable *cmap = (CMAPTable *) readFontTable(cmapTag);
sl@0
   514
sl@0
   515
	return cmap ? CMAPMapper::createUnicodeMapper(cmap) : NULL;
sl@0
   516
	}
sl@0
   517
sl@0
   518
void SymbianFontInstance::getGlyphAdvance(
sl@0
   519
	LEGlyphID aGlyph, LEPoint &aAdvance) const
sl@0
   520
	{
sl@0
   521
	TInt glyph = LE_GET_GLYPH(aGlyph) | 0x80000000;
sl@0
   522
	TOpenFontCharMetrics metrics;
sl@0
   523
	const TUint8* bitmap = 0;
sl@0
   524
	
sl@0
   525
	// If an FFFF glyph code is received, avoid trying to rasterize it as there
sl@0
   526
	// is no character data associated with FFFF.
sl@0
   527
	// This will avoid the overhead of trying to rasterize it.
sl@0
   528
	if (glyph == 0x8000FFFF)
sl@0
   529
		{
sl@0
   530
		aAdvance.fX = 0;
sl@0
   531
		aAdvance.fY = 0;
sl@0
   532
		return;
sl@0
   533
		}
sl@0
   534
		
sl@0
   535
	if (!iFont->GetCharacterData(iSessionHandle, glyph, metrics, bitmap))
sl@0
   536
		{
sl@0
   537
		// Glyph not yet rasterized; rasterize it ourselves
sl@0
   538
		iFont->Rasterize(iSessionHandle, glyph, 0);
sl@0
   539
		if (!iFont->GetCharacterData(iSessionHandle, glyph, metrics, bitmap))
sl@0
   540
			{
sl@0
   541
			aAdvance.fX = 0;
sl@0
   542
			aAdvance.fY = 0;
sl@0
   543
			return;
sl@0
   544
			}
sl@0
   545
		}
sl@0
   546
	aAdvance.fX = metrics.HorizAdvance();
sl@0
   547
	aAdvance.fY = 0;
sl@0
   548
	return;
sl@0
   549
	}
sl@0
   550
sl@0
   551
le_bool SymbianFontInstance::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const
sl@0
   552
	{
sl@0
   553
	TReal x;
sl@0
   554
	TReal y;
sl@0
   555
	if (!iExtensionInterface->GlyphPointInHintedPixels(
sl@0
   556
		glyph, pointNumber, x, y ))
sl@0
   557
		return FALSE;
sl@0
   558
	point.fX = x;
sl@0
   559
	point.fY = y;
sl@0
   560
	return TRUE;
sl@0
   561
	}
sl@0
   562
sl@0
   563
void SymbianFontInstance::transformFunits(float xFunits, float yFunits, LEPoint &pixels) const
sl@0
   564
	{
sl@0
   565
	pixels.fX = xFunits / fUnitsPerEM * fXPixelsPerEm;
sl@0
   566
	pixels.fY = yFunits / fUnitsPerEM * fYPixelsPerEm;
sl@0
   567
	}
sl@0
   568
sl@0
   569
float SymbianFontInstance::xUnitsToPoints(float xUnits) const
sl@0
   570
	{
sl@0
   571
	// Seems like this function should have been called xUnitsToPixels?!
sl@0
   572
	return xUnits / fUnitsPerEM * fXPixelsPerEm;
sl@0
   573
	}
sl@0
   574
sl@0
   575
float SymbianFontInstance::yUnitsToPoints(float yUnits) const
sl@0
   576
	{
sl@0
   577
	// Seems like this function should have been called yUnitsToPixels?!
sl@0
   578
	return yUnits / fUnitsPerEM * fYPixelsPerEm;
sl@0
   579
	}
sl@0
   580
sl@0
   581
float SymbianFontInstance::getXPixelsPerEm() const
sl@0
   582
	{
sl@0
   583
	return fXPixelsPerEm;
sl@0
   584
	}
sl@0
   585
sl@0
   586
float SymbianFontInstance::getYPixelsPerEm() const
sl@0
   587
	{
sl@0
   588
	return fYPixelsPerEm;
sl@0
   589
	}
sl@0
   590
sl@0
   591
float SymbianFontInstance::getScaleFactorX() const
sl@0
   592
	{
sl@0
   593
	return fDeviceScaleX;
sl@0
   594
	}
sl@0
   595
sl@0
   596
float SymbianFontInstance::getScaleFactorY() const
sl@0
   597
	{
sl@0
   598
	return fDeviceScaleY;
sl@0
   599
	}