os/graphics/graphicsdeviceinterface/gdi/sgdi/FONT.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.
     1 // Copyright (c) 1998-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include <gdi.h>
    17 #include <openfont.h>
    18 #include "GlyphSel.h"
    19 #include "FontThai.h"
    20 #include "FontArabic.h"
    21 #include "FontIndic.h"
    22 #include "GDIPANIC.h"
    23 #include "glyphsample.h"
    24 #include "gdiinline.inl"
    25 #include "gdistructs.h"
    26 #include "gdiconsts.h"
    27 #include "gdiplatapi.h"
    28 
    29 /**
    30  Names holds the types & data associated with the glyph selection
    31  algorithm in CFont::GetCharacterPosition().
    32 @internalComponent
    33 */
    34 namespace GlyphSelection
    35     {
    36 
    37     typedef TBool (*ProcessFunc)(TGlyphSelectionState& aGss, RShapeInfo&);
    38 
    39     /**
    40      This structure defines the fields present in each row of the GlyphTable
    41      datat table below. 
    42     @internalComponent
    43     */
    44     struct TTableEntry 
    45     	{
    46     	TUint            iLow;
    47     	TUint            iHigh;
    48     	ProcessFunc	 iProcessFunc;
    49     	};
    50 
    51     /**
    52      This table encodes the Unicode character ranges and the glyph selector
    53      classes to be used for each character range when processing characters
    54      into glyph clusters in CFont::GetCharacterPosition().
    55      New glyph selection classes must make sure they are listed in this 
    56      table to ensure they are invoked as required.
    57      A '0' iProcessFunc entry tells the algorithm to skip the character.
    58     @internalComponent
    59     */
    60     static const TTableEntry Table[] =
    61     	{
    62     	//    iLow,     iHigh,    iProcessFunc
    63     		{ 0x0000,   0x00AC,   GlyphSelector_Default::Process},
    64     		{ 0x00AD,   0x00AD,   GlyphSelector_SoftHyphen::Process},
    65     		{ 0x00AE,   0x05FF,   GlyphSelector_Default::Process},
    66     		{ 0x0600,   0x06FF,   GlyphSelector_Arabic::Process},
    67     		{ 0x0700,   0x08FF,   GlyphSelector_Default::Process},
    68     		{ 0x0900,   0x0970,   GlyphSelector_Devanagari::Process},
    69     		{ 0x0980,   0x09FF,   GlyphSelector_Bengali::Process},
    70     		{ 0x0A00,   0x0A7F,   GlyphSelector_Gurmukhi::Process},
    71     		{ 0x0A80,   0x0AFF,   GlyphSelector_Gujarati::Process},
    72     		{ 0x0B80,   0x0BFF,   GlyphSelector_Tamil::Process},
    73     		{ 0x0C00,	0x0C7F,   GlyphSelector_Telugu::Process},
    74     		{ 0x0C80,	0x0CFF,   GlyphSelector_Kannada::Process},
    75     		{ 0x0D00,   0x0D7F,   GlyphSelector_Malayalam::Process},    		
    76     		{ 0x0D80,   0x0DFF,   GlyphSelector_Default::Process},
    77     		{ 0x0E00,   0x0E32,   GlyphSelector_Thai::Process},
    78     		{ 0x0E33,   0x0E33,   GlyphSelector_ThaiSaraAm::Process},
    79     		{ 0x0E34,   0x0E7F,   GlyphSelector_Thai::Process},
    80     		{ 0x0E80,   0x200B,   GlyphSelector_Default::Process},
    81     		{ 0x200C,   0x200F,   0},
    82     		{ 0x2010,   0x2029,   GlyphSelector_Default::Process},
    83     		{ 0x202A,   0x202E,   0},
    84     		{ 0x202F,   0xFFFD,   GlyphSelector_Default::Process},
    85     		{ 0xFFFE,   0xFFFF,   0},
    86     		{ 0x10000,	0x10FFFF, GlyphSelector_Default::Process},
    87     		{0xFFFFFFFF,0xFFFFFFFF, 0}
    88     	};
    89     }
    90 
    91 /** Find appropriate processor function for the given character.
    92 @param aChar Character for processing.
    93 @return processor function or 0 if the character is to be skipped.
    94 @internalComponent */
    95 GlyphSelection::ProcessFunc CharacterToProcessFunction(TInt aChar)
    96 	{
    97 	for (const GlyphSelection::TTableEntry* glyphSel = GlyphSelection::Table;
    98 		glyphSel->iLow != 0xFFFFFFFF; glyphSel++)
    99 		{
   100 		if ((glyphSel->iLow <= aChar) && (aChar <= glyphSel->iHigh))
   101 			return glyphSel->iProcessFunc;
   102 		}
   103 	return 0;
   104 	}
   105 
   106 /**
   107 @internalTechnology For use by TFontStyle/TOpenFontSpec.
   108 */
   109 EXPORT_C TBool FontEffect::IsEffectOn(TEffect aEffect, TUint32 aFontEffect)
   110 	{
   111 	return aEffect & aFontEffect;
   112 	}
   113 
   114 /**
   115 @internalTechnology For use by TFontStyle/TOpenFontSpec.
   116 */
   117 EXPORT_C void FontEffect::SetEffect(TEffect aEffect, TBool aOn, TUint32& aFontEffect)
   118 	{
   119 	if (aOn)
   120 		aFontEffect |= aEffect;
   121 	else
   122 		aFontEffect &= ~aEffect;
   123 	}
   124 
   125 
   126 //
   127 // TFontStyle
   128 //
   129 
   130 /** Default C++ constructor. */
   131 EXPORT_C TFontStyle::TFontStyle():
   132 	iFlags(0), iReserved1(0), iReserved2(0)
   133 	{}
   134 
   135 
   136 /** Constructs a TFontStyle object with the specified attributes.
   137 @param aPost The posture attribute. 
   138 @param aStrWgt The stroke weight attribute. 
   139 @param aPrintPos The print position attribute. */
   140 EXPORT_C TFontStyle::TFontStyle(TFontPosture aPostr,TFontStrokeWeight aWgt,TFontPrintPosition aPos):
   141 	iFlags(0), iReserved1(0), iReserved2(0)
   142 	{
   143 	if (aPostr == EPostureItalic)
   144 		{
   145 		iFlags |= EItalic;
   146 		}
   147 	if (aWgt == EStrokeWeightBold)
   148 		{
   149 		iFlags |= EBold;
   150 		}
   151 	if (aPos == EPrintPosSuperscript)
   152 		{
   153 		iFlags |= ESuper;
   154 		}
   155 	else if (aPos == EPrintPosSubscript)
   156 		{
   157 		iFlags |= ESub;
   158 		}
   159 	}
   160 
   161 
   162 EXPORT_C void TFontStyle::InternalizeL(RReadStream& aStream)
   163 /** Internalises a font style from a read stream.
   164 
   165 The presence of this function means that the standard templated operator>>() 
   166 (defined in s32strm.h) is available to internalise objects of this class.
   167 
   168 @param aStream The stream from which the font style is to be internalised 
   169 @leave KErrNoMemory If there is a problem reading from the stream.
   170 If internalisation causes an out of memory error. */
   171 	{
   172 	iFlags = aStream.ReadUint32L();
   173 	}
   174 
   175 
   176 EXPORT_C void TFontStyle::ExternalizeL(RWriteStream& aStream) const
   177 /** Externalises the font style to a write stream.
   178 
   179 The presence of this function means that the standard templated operator<<() 
   180 (defined in s32strm.h) is available to externalise objects of this class.
   181 
   182 @param aStream The stream to which the font style is to be externalised.
   183 @leave KErrNoMemory This function may leave, if the write action causes the 
   184 stream's resources to be exhausted. */
   185 	{
   186 	aStream.WriteUint32L(iFlags);
   187 	}
   188 
   189 
   190 EXPORT_C TFontPosture TFontStyle::Posture() const
   191 /** Gets the posture attribute.
   192 
   193 @return The font style's posture. */
   194 	{
   195 	if(iFlags&EItalic) return(EPostureItalic);
   196 	return(EPostureUpright);
   197 	}
   198 
   199 
   200 EXPORT_C TFontStrokeWeight TFontStyle::StrokeWeight() const
   201 /** Gets the stroke weight attribute.
   202 
   203 @return The font style's stroke weight. */
   204 	{
   205 	if(iFlags&EBold) return(EStrokeWeightBold);
   206 	return(EStrokeWeightNormal);
   207 	}
   208 
   209 
   210 EXPORT_C TFontPrintPosition TFontStyle::PrintPosition() const
   211 /** Gets the print position attribute.
   212 
   213 @return The font style's print position. */
   214 	{
   215 	if((iFlags&ESuper) && !(iFlags&ESub)) return(EPrintPosSuperscript);
   216 	else if((iFlags&ESub) && !(iFlags&ESuper)) return(EPrintPosSubscript);
   217 	return(EPrintPosNormal);
   218 	}
   219 
   220 
   221 EXPORT_C void TFontStyle::SetPosture(TFontPosture aPosture)
   222 /** Sets the posture attribute.
   223 
   224 @param aPosture The posture to be set. */
   225 	{
   226 	if(aPosture==EPostureItalic) iFlags|=EItalic;
   227 	else iFlags&=~EItalic;
   228 	}
   229 
   230 
   231 EXPORT_C void TFontStyle::SetStrokeWeight(TFontStrokeWeight aStrokeWeight)
   232 /** Sets the stroke weight attribute.
   233 
   234 @param aStrokeWeight The stroke weight to be set. */
   235 	{
   236 	if(aStrokeWeight==EStrokeWeightBold) iFlags|=EBold;
   237 	else iFlags&=~EBold;
   238 	}
   239 
   240 
   241 EXPORT_C void TFontStyle::SetPrintPosition(TFontPrintPosition aPrintPosition)
   242 /** Sets the print position attribute.
   243 
   244 @param aPrintPosition The print position to be set. */
   245 	{
   246 	switch(aPrintPosition)
   247 		{
   248 		case EPrintPosSuperscript:
   249 			{
   250 			iFlags|=ESuper;
   251 			iFlags&=~ESub;
   252 			break;
   253 			}
   254 		case EPrintPosSubscript:
   255 			{
   256 			iFlags&=~ESuper;
   257 			iFlags|=ESub;
   258 			break;
   259 			}
   260 		default:
   261 			{
   262 			iFlags&=~ESuper;
   263 			iFlags&=~ESub;
   264 			}
   265 	 	}
   266 	}
   267 
   268 /** Gets the font effects flags.
   269 @publishedAll
   270 @released
   271 @return The font effects flags.
   272 @see TFontStyle::SetEffects()
   273 */
   274 EXPORT_C TUint32 TFontStyle::Effects() const
   275 	{
   276 	return 0xFFF0 & iFlags;
   277 	}
   278 
   279 /** Checks if a font effect is on.
   280 @publishedAll
   281 @released
   282 @return True represents the specified font effect is on, otherwise off.
   283 @param aEffect The font effect to be checked.
   284 @see TFontStyle::SetEffects()
   285 */
   286 EXPORT_C TBool TFontStyle::IsEffectOn(FontEffect::TEffect aEffect) const
   287 	{
   288 	return FontEffect::IsEffectOn(aEffect, iFlags);
   289 	}
   290 
   291 /** Sets the font effects flags.
   292 @publishedAll
   293 @released
   294 @param aEffect The font effects flags to be set.
   295 @see TFontStyle::Effects()
   296 */
   297 EXPORT_C void TFontStyle::SetEffects(TUint32 aEffects)
   298 	{
   299 	iFlags &= 0xFFFF000F;
   300 	iFlags |= 0xFFF0 & aEffects;
   301 	}
   302 
   303 /** Sets a font effect to the given state.
   304 @publishedAll
   305 @released
   306 @param aEffect The font effect to be set.
   307 @param aOn True represents on, otherwise off.
   308 @see TFontStyle::IsEffectOn()
   309 */
   310 EXPORT_C void TFontStyle::SetEffects(FontEffect::TEffect aEffect, TBool aOn)
   311 	{
   312 	FontEffect::SetEffect(aEffect, aOn, iFlags);
   313 	}
   314 
   315 /** Compares a font style for equality.
   316 @publishedAll
   317 @released
   318 @param aFontStyle The font style to be compared with this font style.
   319 @return ETrue, if this TFontStyle is equal to aFontStyle, EFalse, otherwise.
   320 */
   321 EXPORT_C TBool TFontStyle::operator==(const TFontStyle& aFontStyle) const
   322 	{
   323 	return iFlags == aFontStyle.iFlags;
   324 	}
   325 
   326 //
   327 // TFontSpec
   328 //
   329 EXPORT_C TFontSpec::TFontSpec():
   330 	iTypeface(),
   331 	iHeight(0),
   332 	iFontStyle()
   333 /** Default constructor.
   334 
   335 The object's font style is set to the default: EPostureUpright, EStrokeWeightNormal, 
   336 and EPrintPosNormal. */
   337 	{}
   338 
   339 
   340 EXPORT_C TFontSpec::TFontSpec(const TDesC& aTypefaceName,TInt aHeight):
   341 	iTypeface(),
   342 	iHeight(aHeight),
   343 	iFontStyle(EPostureUpright,EStrokeWeightNormal,EPrintPosNormal)
   344 /** Constructs a TFontSpec object with the specified typeface and height. 
   345 
   346 The object's font style is set to the default: EPostureUpright, EStrokeWeightNormal, 
   347 and EPrintPosNormal.
   348 
   349 @param aTypefaceName The name of the typeface (e.g. "Roman"). It should be no
   350 	longer than KMaxTypefaceNameLength characters in length.
   351 @param aHeight The height of the typeface, in twips. 
   352 @panic GDI 6, if aTypefaceName is more than KMaxTypefaceNameLength characters long.
   353 */
   354 	{
   355 	iTypeface.SetName(aTypefaceName);
   356 	}
   357 
   358 
   359 EXPORT_C TBool TFontSpec::operator==(const TFontSpec& aFontSpec) const
   360 /** Compares this font specification with another.
   361 @param aFontSpec The font specification to be compared with this one. 
   362 @return ETrue, if the TFontSpecs are identical, EFalse otherwise.
   363 */
   364 	{
   365 	return
   366 		iHeight		== aFontSpec.iHeight &&
   367 		iFontStyle	== aFontSpec.iFontStyle &&
   368 		iTypeface	== aFontSpec.iTypeface;
   369 	}
   370 
   371 
   372 EXPORT_C void TFontSpec::InternalizeL(RReadStream& aStream)
   373 /** Internalises a font specification from a read stream.
   374 
   375 The presence of this function means that the standard templated operator>>() 
   376 (defined in s32strm.h) is available to internalise objects of this class.
   377 
   378 @param aStream The stream from which the font specification is to be internalised.
   379 @leave KErrNoMemory If internalisation causes an out of memory error. */
   380 	{
   381 	iTypeface.InternalizeL(aStream);
   382 	iHeight=aStream.ReadUint16L();
   383 	iFontStyle.InternalizeL(aStream);
   384 	}
   385 
   386 
   387 EXPORT_C void TFontSpec::ExternalizeL(RWriteStream& aStream) const
   388 /** Externalises the font specification to a write stream.
   389 
   390 The presence of this function means that the standard templated operator<<() 
   391 (defined in s32strm.h) is available to externalise objects of this class.
   392 
   393 @param aStream The stream to which the font specification is to be externalised 
   394 
   395 @leave KErrNoMemory If the write action causes the stream's resources to be 
   396 exhausted. */
   397 	{
   398 	iTypeface.ExternalizeL(aStream);
   399 	aStream.WriteUint16L(iHeight);
   400 	iFontStyle.ExternalizeL(aStream);
   401 	}
   402 
   403 EXPORT_C void TFontSpec::SetScriptTypeForMetrics(TLanguage aLanguage)
   404 /** Specifies the script with which font metrics calculation will be based on.
   405 @param aLanguage The language used to derive the required script.
   406 @publishedAll
   407 @released
   408 */
   409 	{
   410 	iTypeface.SetScriptTypeForMetrics(aLanguage);
   411 	}
   412 
   413 EXPORT_C TInt TFontSpec::ScriptTypeForMetrics() const
   414 /** Returns the script with which font metrics calculation will be based on.
   415 @internalTechnology
   416 */
   417 	{
   418 	return iTypeface.ScriptTypeForMetrics();
   419 	}
   420 
   421 //
   422 // TTypeface
   423 //
   424 static const TInt KTTypefaceBitsNumAttrib = 3;
   425 static const TInt KTTypefaceBitsNumScript = 4;
   426 static const TInt KTTypefaceMaskAttrib = (1 << KTTypefaceBitsNumAttrib) - 1;
   427 static const TInt KTTypefaceMaskScript = ((1 << KTTypefaceBitsNumScript) - 1) << KTTypefaceBitsNumAttrib;
   428 EXPORT_C TTypeface::TTypeface():
   429 	iName(),
   430 	iFlags(0)
   431 /** Default C++ constructor. */
   432 	{}
   433 
   434 /**
   435 @internalComponent
   436 */
   437 void TTypeface::ResetAttributes()
   438 	{
   439 	iFlags &= KTTypefaceMaskScript;
   440 	}
   441 
   442 /**
   443 @internalComponent
   444 */
   445 void TTypeface::ResetScriptType()
   446 	{
   447 	iFlags &= KTTypefaceMaskAttrib;
   448 	}
   449 
   450 EXPORT_C void TTypeface::InternalizeL(RReadStream& aStream)
   451 /** Internalises a typeface from a read stream. 
   452 
   453 The presence of this function means that the standard templated operator>>() 
   454 (defined in s32strm.h) is available to internalise objects of this class.
   455 
   456 @param aStream Stream from which the typeface is to be internalised. */
   457 	{
   458 	TBuf<KMaxTypefaceNameLength> tempname;
   459 	aStream >> tempname;
   460 	new(&iName) TBufC<KMaxTypefaceNameLength>(tempname);
   461 	iFlags = aStream.ReadInt8L();
   462 	}
   463 
   464 
   465 EXPORT_C void TTypeface::ExternalizeL(RWriteStream& aStream) const
   466 /** Externalises a typeface to a write stream. 
   467 
   468 The presence of this function means that the standard templated operator<<() 
   469 (defined in s32strm.h) is available to externalise objects of this class.
   470 
   471 @param aStream The stream to which the typeface is to be externalised. */
   472 	{
   473 	aStream << iName;
   474 	aStream.WriteInt8L(static_cast<TInt8>(iFlags));
   475 	}
   476 
   477 
   478 EXPORT_C TBool TTypeface::operator==(const TTypeface& aTypeface) const
   479 /** Compares two typefaces for equality.
   480 
   481 @param aTypeface The typeface to be compared with. 
   482 @return ETrue, if this TTypeface is equal to aTypeface, otherwise EFalse. */
   483 	{
   484 	return
   485 		iFlags == aTypeface.iFlags &&
   486 		iName == aTypeface.iName;
   487 	}
   488 
   489 EXPORT_C void TTypeface::SetAttributes(TInt aAttributes)
   490 /** Set the combination of attributes for this typeface.
   491 
   492 @param aAttributes A bitmap defining the combination of attributes. */
   493 	{
   494 	ResetAttributes();
   495 	iFlags |= KTTypefaceMaskAttrib & aAttributes & (EProportional | ESerif | ESymbol);
   496 	}
   497 
   498 
   499 EXPORT_C void TTypeface::SetIsProportional(TBool aIsProportional)
   500 /** Sets the typeface's proportional attribute.
   501 
   502 @param aIsProportional ETrue if the typeface is a proportional typeface, otherwise 
   503 EFalse. */
   504 	{
   505 	if (aIsProportional)
   506 		{
   507 		iFlags |= EProportional;
   508 		}
   509 	else
   510 		{
   511 		iFlags &= ~EProportional;
   512 		}
   513 	}
   514 
   515 
   516 EXPORT_C void TTypeface::SetIsSerif(TBool aIsSerif)
   517 /** Sets the typeface's serif attribute.
   518 
   519 @param aIsSerif ETrue if the typeface is a serif typeface, otherwise EFalse. */
   520 	{
   521 	if (aIsSerif)
   522 		{
   523 		iFlags |= ESerif;
   524 		}
   525 	else
   526 		{
   527 		iFlags &= ~ESerif;
   528 		}
   529 	}
   530 
   531 
   532 EXPORT_C void TTypeface::SetIsSymbol(TBool aIsSymbol)
   533 /** Sets the typeface's symbol attribute.
   534 
   535 @param aIsSymbol ETrue if the typeface is a symbol typeface, otherwise EFalse. */
   536 	{
   537 	if (aIsSymbol)
   538 		{
   539 		iFlags |= ESymbol;
   540 		}
   541 	else
   542 		{
   543 		iFlags &= ~ESymbol;
   544 		}
   545 	}
   546 
   547 
   548 EXPORT_C TInt TTypeface::Attributes() const
   549 /** Gets the combination of attributes of the typeface.
   550 
   551 @return The combination of attributes of the typeface. */
   552 	{
   553 	return KTTypefaceMaskAttrib & iFlags;
   554 	}
   555 
   556 
   557 EXPORT_C TBool TTypeface::IsProportional() const
   558 /** Gets the typeface's proportional attribute.
   559 
   560 @return ETrue if the typeface is proportional, EFalse otherwise. */
   561 	{
   562 	return KTTypefaceMaskAttrib & iFlags & EProportional;
   563 	}
   564 
   565 
   566 EXPORT_C TBool TTypeface::IsSerif() const
   567 /** Gets the typeface's serif attribute.
   568 
   569 @return ETrue if the typeface is a serif typeface, EFalse otherwise */
   570 	{
   571 	return KTTypefaceMaskAttrib & iFlags & ESerif;
   572 	}
   573 
   574 
   575 EXPORT_C TBool TTypeface::IsSymbol() const
   576 /** Gets the typeface's symbol attribute.
   577 
   578 @return ETrue if the typeface is a symbol typeface, EFalse otherwise */
   579 	{
   580 	return KTTypefaceMaskAttrib & iFlags & ESymbol;
   581 	}
   582 
   583 
   584 /** Specifies the script with which font metrics calculation will be based on.
   585 @param aLanguage The language used to derive the required script.
   586 @internalTechnology
   587 */
   588 EXPORT_C void TTypeface::SetScriptTypeForMetrics(TLanguage aLanguage)
   589 	{
   590 	SetScriptTypeForMetrics(GlyphSample::TLanguage2TScript(aLanguage));
   591 	}
   592 
   593 /** Specifies the script with which font metrics calculation will be based on.
   594 @param aScript The script.
   595 @internalTechnology
   596 */
   597 EXPORT_C void TTypeface::SetScriptTypeForMetrics(TInt aScript)
   598 	{
   599 	ResetScriptType();
   600 	iFlags |= KTTypefaceMaskScript & (aScript << KTTypefaceBitsNumAttrib);
   601 	}
   602 
   603 /** Gets the script with which font metrics calculation will be based on.
   604 @return The script.
   605 @internalTechnology
   606 */
   607 EXPORT_C TInt TTypeface::ScriptTypeForMetrics() const
   608 	{
   609 	return (KTTypefaceMaskScript & iFlags) >> KTTypefaceBitsNumAttrib;
   610 	}
   611 
   612 /**
   613 Sets the name of the typeface. This method should be used rather than
   614 directly accessing the iName public member.
   615 @param aName The name of the typeface (e.g. "Roman"). It should be no 
   616 	longer than KMaxTypefaceNameLength characters in length.
   617 @panic GDI 6, if aName is more than KMaxTypefaceNameLength characters
   618 	long.
   619 */
   620 EXPORT_C void TTypeface::SetName(const TDesC& aName)
   621 	{
   622 	GDI_ASSERT_ALWAYS(aName.Length() <= KMaxTypefaceNameLength, EGdiPanic_TypefaceNameOverflow);
   623 	iName=aName;
   624 	}
   625 
   626 /**
   627 Returns the name of the typeface.
   628 @return The name of the typeface.
   629 */
   630 EXPORT_C const TDesC& TTypeface::Name() const
   631 	{
   632 	return iName;
   633 	}
   634 
   635 
   636 //
   637 // CFont
   638 //
   639 
   640 /** Default destructor. */
   641 EXPORT_C CFont::~CFont()
   642 	{}
   643 
   644 _LIT(KGdiZeroCharacter,"0");
   645 
   646 /** Gets the width of the zero character of this font in pixels. 
   647 
   648 This function is provided as the "0" character is roughly the average width 
   649 of the characters of any font.
   650 
   651 @return The width of the "0" character, in pixels. */
   652 EXPORT_C TInt CFont::WidthZeroInPixels() const
   653 	{
   654 	return(TextWidthInPixels(KGdiZeroCharacter));
   655 	}
   656 
   657 
   658 /** Gets the font descent in pixels.
   659 It is defined to be HeightInPixels() minus AscentInPixels().
   660 Note that this deprecated function is replaced by the new @c FontMaxDescent()
   661 or in some cases @c FontStandardDescent().
   662 
   663 @return The font descent in pixels.
   664 @see FontStandardDescent() 
   665 @see FontMaxDescent()
   666 @deprecated */
   667 EXPORT_C TInt CFont::DoDescentInPixels() const
   668 	{
   669 	return HeightInPixels() - AscentInPixels();
   670 	}
   671 
   672 
   673 /** Checks to see if the pen position needs to be included in the bounds
   674 calculation for purposes of considering side-bearings in the line break point
   675 
   676 @param aInput The input block. Contains the check flag and maxbounds.
   677 @param aPenPos The current value of the pen position.
   678 @param aBoundsBR Bottom-right bounds value.
   679 @param aBoundsTL Top-left bounds value.
   680 @return Whether or not MaxBounds has been exceeded
   681 */
   682 LOCAL_C TBool BoundsExceeded(const CFont::TMeasureTextInput& aInput,
   683 	const TInt& aPenPos, TInt& aBoundsBR, TInt& aBoundsTL)
   684 	{
   685 	if (aInput.iFlags & CFont::TMeasureTextInput::EFIncludePenPositionInBoundsCheck)
   686 		{
   687 		if (aInput.iFlags & CFont::TMeasureTextInput::EFVisualOrderRightToLeft)
   688 			{
   689 			aBoundsTL = Min(aBoundsTL, aPenPos);
   690 			}
   691 		else
   692 			{
   693 		 	aBoundsBR = Max(aBoundsBR, aPenPos);
   694 			}
   695 		}
   696  	return (aBoundsBR - aBoundsTL > aInput.iMaxBounds);
   697 	}
   698 
   699 
   700 /** Text measurement function.
   701 
   702 This is a powerful text measurement function underlying all the
   703 other text measurement functions. It takes optional input and output
   704 parameter blocks, which may be null, and returns the advance 
   705 width (change in pen position when drawn horizontally) of the text, or the advance
   706 height, if the text is drawn vertically.
   707 
   708 Some of the functions that can be performed using this
   709 function are listed below. Many of them are used by the Text Views
   710 API to do its typographic layout.
   711 - Get the advance width or advance height (return value).
   712 The advance width is the amount by which the pen advances when drawing
   713 the text horizontally, while the advance height is the amount by which 
   714 the pen advances when drawing the text vertically.
   715 - Measure some text in context, so that shaping behaviour
   716 (e.g. in Arabic) can be affected by what comes before and after the
   717 text. Do this using TMeasureTextInput::iStartInputChar and 
   718 TMeasureTextInput::iEndInputChar to tell the function where to start and end 
   719 in the supplied descriptor.
   720 - Determine how much text fits a given size by setting 
   721 TMeasureTextInput::iMaxAdvance or TMeasureTextInput::iMaxBounds. 
   722 - Specify letter spacing and word spacing using TMeasureTextInput::iCharJustNum,
   723 TMeasureTextInput::iCharJustExcess, 
   724 TMeasureTextInput::iWordJustNum and 
   725 TMeasureTextInput::iWordJustExcess. 
   726 - Get the number of characters drawn in TMeasureTextOutput::iChars 
   727 when applying the various constraints in TMeasureTextInput. 
   728 - Get the number of glyphs drawn in TMeasureTextOutput::iGlyphs. 
   729 - Get the number of groups (formed by ligation or diacritic placement) in 
   730 TMeasureTextOutput::iGroups. Groups are units of cursor
   731 movement: the cursor hops over a character-plus-accent group or an
   732 Arabic or other ligature in one go.
   733 - Get the number of word spaces in TMeasureTextOutput::iSpaces. 
   734 - Get the bounds of the inked-in pixels in TMeasureTextOutput::iBounds. 
   735 - Get the size of the biggest glyph that would be drawn in TMeasureTextOutput::iMaxGlyphSize.
   736 
   737 @param aText The text to be measured.
   738 @param aInput The input block. This may be NULL.
   739 @param aOutput The output block. This may be NULL.
   740 @return The advance width if the text is drawn horizontally or the advance 
   741 height if the text is drawn vertically. 
   742 
   743 @panic GDI 1 In debug builds only, if TMeasureTextInput::iStartInputChar is negative.
   744 */
   745 EXPORT_C TInt CFont::MeasureText(const TDesC& aText,const TMeasureTextInput* aInput,TMeasureTextOutput* aOutput) const
   746 	{
   747 	TMeasureTextInput input;
   748 	if (aInput)
   749 		input = *aInput;
   750 	if (aOutput)
   751 		{
   752 		Mem::FillZ(aOutput,sizeof(*aOutput));
   753 		aOutput->iChars = input.iStartInputChar;
   754 		}
   755 	TPositionParam param;
   756 	param.iDirection = input.iDirection;
   757  
   758  	TBool vertical = param.iDirection == EVertical;
   759  	TBool penMovesLeft = EFalse;
   760  	if (input.iFlags & TMeasureTextInput::EFVisualOrderRightToLeft)
   761  		{
   762  		if (!vertical)
   763  			penMovesLeft = ETrue;
   764  		param.iFlags |= TPositionParam::EFLogicalOrder;
   765  		}
   766  	else if (!(input.iFlags & TMeasureTextInput::EFVisualOrder))
   767    		param.iFlags |= TPositionParam::EFLogicalOrder;
   768 
   769 
   770 	param.iText.Set(aText);
   771 
   772 	int advance = 0;
   773 	int groups = 0;
   774 	int spaces = 0;
   775 	param.iPosInText = input.iStartInputChar;
   776 	int end_char = Min(aText.Length(),input.iEndInputChar);
   777 	TRect bounds;
   778 	// Total advance if pen is moving left. Positive.
   779  	TInt rightToLeftAdvance = 0;
   780 	// Shaping information of the text
   781 	RShapeInfo shapeInfo;
   782 	while (param.iPosInText < end_char)
   783 		{
   784 		if (!GetCharacterPosition2(param, shapeInfo))
   785 			{
   786 			if (aOutput)
   787 				aOutput->iChars = param.iPosInText;
   788 			continue;
   789 			}
   790 
   791 		int new_advance = vertical ? param.iPen.iY : param.iPen.iX;
   792 		if (input.iCharJustExcess != 0)
   793 			new_advance += CGraphicsContext::JustificationInPixels(input.iCharJustExcess,input.iCharJustNum,groups,1);
   794 		groups++;
   795 		// Allow justification to occur at spaces
   796 		if (param.iOutput[0].iCode == 0x0020)
   797 			{
   798 			if (input.iWordJustExcess != 0)
   799 				new_advance += CGraphicsContext::JustificationInPixels(input.iWordJustExcess,input.iWordJustNum,spaces,1);
   800 			spaces++;
   801 			}
   802 		if (vertical)
   803 			param.iPen.iY = new_advance;
   804 		else
   805 			param.iPen.iX = new_advance;
   806 		
   807 		if (penMovesLeft)
   808  			{
   809  			// If the pen is moving left, we will begin each cluster at (0,0)
   810  			// and shift the bounds to the right to compensate.
   811  			bounds.iTl.iX += param.iPen.iX;
   812  			bounds.iBr.iX += param.iPen.iX;
   813  			bounds.iTl.iY += param.iPen.iY;
   814  			bounds.iBr.iY += param.iPen.iY;
   815  			rightToLeftAdvance += param.iPen.iX;
   816  			new_advance = rightToLeftAdvance;
   817  			param.iPen.iX = 0;
   818  			param.iPen.iY = 0;
   819  			}
   820 
   821 		if (aInput || aOutput)
   822 			{
   823 			const TPositionParam::TOutput* output = param.iOutput;
   824 			for (int i = 0; i < param.iOutputGlyphs; i++, output++)
   825 				{
   826 				//if (!output->iBounds.IsEmpty()) -- optimized to:
   827 				if (output->iBounds.iTl.iX != output->iBounds.iBr.iX
   828 					|| output->iBounds.iTl.iY != output->iBounds.iBr.iY)
   829 					{
   830 					if (aOutput)
   831 						{
   832 						// increase iMaxGlyphSize if either dimension smaller than
   833 						// current glyph
   834 						TInt boundsDim = output->iBounds.iBr.iX - output->iBounds.iTl.iX;
   835 						aOutput->iMaxGlyphSize.iWidth = aOutput->iMaxGlyphSize.iWidth < boundsDim?
   836 							boundsDim : aOutput->iMaxGlyphSize.iWidth;
   837 						boundsDim = output->iBounds.iBr.iY - output->iBounds.iTl.iY;
   838 						aOutput->iMaxGlyphSize.iHeight = aOutput->iMaxGlyphSize.iHeight < boundsDim?
   839 							boundsDim : aOutput->iMaxGlyphSize.iHeight;
   840 						}
   841 					//bounds.BoundingRect(output->iBounds); -- optimized to:
   842 					if (output->iBounds.iTl.iX < bounds.iTl.iX)
   843 						bounds.iTl.iX = output->iBounds.iTl.iX;
   844 					if (bounds.iBr.iX < output->iBounds.iBr.iX)
   845 						bounds.iBr.iX = output->iBounds.iBr.iX;
   846 					if (output->iBounds.iTl.iY < bounds.iTl.iY)
   847 						bounds.iTl.iY = output->iBounds.iTl.iY;
   848 					if (bounds.iBr.iY < output->iBounds.iBr.iY)
   849 						bounds.iBr.iY = output->iBounds.iBr.iY;
   850 					}
   851 				}
   852 
   853 			// Would any limits be exceeded by adding this group?
   854 			if (param.iPosInText > end_char)
   855 				break;
   856 			if (new_advance > input.iMaxAdvance)
   857 				break;
   858 			if (vertical)
   859 				{
   860 				if (BoundsExceeded(input, param.iPen.iY, bounds.iBr.iY, bounds.iTl.iY))
   861 					break;
   862 				}
   863 			else
   864 				{
   865 				if (BoundsExceeded(input, param.iPen.iX, bounds.iBr.iX, bounds.iTl.iX))
   866 					break;
   867 				}
   868 
   869 			if (aOutput)
   870 				{
   871 				aOutput->iChars = param.iPosInText;		// should this not be aOutput->iChars = param.iPosInText - input.iShartInputChar;?
   872 				aOutput->iGlyphs += param.iOutputGlyphs;
   873 				aOutput->iGroups = groups;
   874 				aOutput->iSpaces = spaces;
   875 				aOutput->iBounds = bounds;
   876 				}
   877 			}
   878 
   879 		advance = new_advance;
   880 		}
   881 	if(shapeInfo.IsOpen())
   882 		shapeInfo.Close();
   883 	return advance;
   884 	}
   885 
   886 // These 3 functions should probably be moved to E32/Euser as part of TChar or
   887 // similar as there seem to be several local copies of similar functions in
   888 // various OS modules so we should remove duplication
   889 
   890 TUint16 HighSurrogate(TUint aCode)
   891 	{
   892 	GDI_ASSERT_DEBUG(aCode  > 0xFFFF, EGdiPanic_InvalidInputParam);
   893 	return STATIC_CAST(TUint16, 0xD7C0 + (aCode >> 10));
   894 	}
   895 	
   896 TUint16 LowSurrogate(TUint aCode)
   897 	{
   898 	GDI_ASSERT_DEBUG(aCode  > 0xFFFF, EGdiPanic_InvalidInputParam);
   899 	return STATIC_CAST(TUint16, 0xDC00 | (aCode & 0x3FF));
   900 	}
   901 	
   902 TUint CombineSurrogates(TUint aHighSurrogate, TUint aLowSurrogate)
   903 	{
   904 	GDI_ASSERT_DEBUG((0xD800 == (aHighSurrogate & 0xF800)), EGdiPanic_InvalidInputParam);
   905 	GDI_ASSERT_DEBUG((0xD800 == (aHighSurrogate & 0xFC00)), EGdiPanic_InvalidInputParam);
   906 	GDI_ASSERT_DEBUG((0xDC00 == (aLowSurrogate & 0xFC00)), EGdiPanic_InvalidInputParam);
   907 	return ((aHighSurrogate - 0xD7F7) << 10) + aLowSurrogate;
   908 	}
   909 
   910 
   911 /** Overridable function innards of GetCharacterPosition and
   912 GetCharacterPosition2. It is generally not useful to override this function.
   913 @publishedAll
   914 @see GetCharacterPosition
   915 @see GetCharacterPosition2
   916 */
   917 EXPORT_C TBool CFont::DoGetCharacterPosition(TPositionParam& aParam) const
   918 	{
   919 	RShapeInfo shapeInfo;
   920 	TBool r = GetCharacterPosition2(aParam, shapeInfo);
   921 	if (shapeInfo.IsOpen())
   922 		shapeInfo.Close();
   923 	return r;
   924 	}
   925 
   926 // Find the script (and hence the correct process function) that any punctuation or digit may belong to
   927 LOCAL_C GlyphSelection::ProcessFunc FindContextualProcessFunc(RShapeInfo& aShapeInfo, const TGlyphSelectionState aGss)
   928 	{
   929 	GlyphSelection::ProcessFunc processFunc = CharacterToProcessFunction(aGss.iCodeChar);
   930 	GlyphSelection::ProcessFunc contextProcessFunc = (GlyphSelection::ProcessFunc)aShapeInfo.GetContext();
   931 	
   932 	// If context or prevCode is NULL, use processFunc,
   933 	// else use function of context or prevCode
   934 	if ((aGss.iCodeChar.IsDigit() || aGss.iCodeChar.IsPunctuation()) && !QuoteOrBracketPair(aGss.iCodeChar) && processFunc!=GlyphSelector_SoftHyphen::Process)
   935 		{
   936 		// If context is not set, check the previous char for context.
   937 		if (contextProcessFunc == NULL)
   938 			{
   939 			if (aGss.iParam.iPosInText > 0)
   940 				{
   941 				TChar prevCode = aGss.iText.Get(-1);
   942 				GlyphSelection::ProcessFunc prevProcessFunc = CharacterToProcessFunction(prevCode);
   943 				if (prevProcessFunc != NULL && (prevCode.IsAlpha() || prevProcessFunc != GlyphSelector_Default::Process))
   944 					{
   945 					aShapeInfo.SetContext((TAny *)prevProcessFunc);
   946 					return prevProcessFunc;
   947 					}
   948 				}
   949 			} 
   950 		else 
   951 			return contextProcessFunc;
   952 		
   953 		return processFunc;
   954 		}
   955 	
   956 	// set the context with current processFunc only if current char is not ignored for context.
   957  	if (processFunc != NULL && (aGss.iCodeChar.IsAlpha() || processFunc != GlyphSelector_Default::Process))
   958  			aShapeInfo.SetContext((TAny *)processFunc);
   959  	return processFunc;
   960 	}
   961 
   962 /** Takes Unicode text and produces the glyph cluster for the first character
   963 in that text plus any combining mark characters, or for the first indic
   964 syllable. It is responsible for contextual glyph selection, ligature creation
   965 and diacritic placement.
   966 
   967 @param aParam
   968 	The input/output parameter of the text/glyph data for the algorithm.
   969 @param aShapeInfo
   970 	The function will cache "shaped" text (e.g. complex scripts such as
   971 	Devanagari) here. aShapeInfo must be freshly-constructed or closed for each
   972 	new piece of text in aParam.iText. If aParam.iText is unchanged between
   973 	calls, aShapeInfo should be passed back in unchanged as well.
   974 @return
   975 	ETrue if glyphs for supplied text have been produced, EFalse in failure.
   976 @see CFont::TPositionParam
   977 @publishedAll
   978 @released */
   979 EXPORT_C TBool CFont::GetCharacterPosition2(TPositionParam& aParam, RShapeInfo& aShapeInfo) const
   980 	{
   981 	GDI_ASSERT_DEBUG(aParam.iPosInText>=0, EGdiPanic_InvalidInputParam);
   982 	GDI_ASSERT_DEBUG(aParam.iText.Ptr(), EGdiPanic_InvalidInputParam);
   983 
   984 	aParam.iOutputGlyphs = 0;
   985 	TInt textLen = aParam.iText.Length();
   986 	TBool outputOk = ETrue;
   987 	TPoint penCopy = aParam.iPen;
   988 
   989 	// Verify input parameters are sane
   990 	if (aParam.iPosInText >= textLen)
   991 		return EFalse;
   992 
   993 	// Setup glyph selection algorithm data
   994 	TUtf32Iterator textIter(aParam.iText.Ptr(), aParam.iText.Ptr()+textLen, aParam.iPosInText);
   995 	if (textIter.AtEnd())
   996 		{
   997 		aParam.iPosInText = textIter.LengthToStart();
   998 		return outputOk;
   999 		}
  1000 
  1001 	// Process each character in the text in turn until we reach the end of
  1002 	// the iterator, the next base (non-mark/combining) character or reach
  1003 	// the limit in a glyph cluster.
  1004 	GlyphSelection::ProcessFunc firstProcessFn = 0;
  1005 	TGlyphSelectionState gss(textIter, this, aParam);
  1006 	do
  1007 		{
  1008 		// Retrieve character info for processing.
  1009 		gss.iCodePt = gss.iCodeChar = textIter.Get();
  1010 		gss.iCombCls = gss.iCodeChar.GetCombiningClass();
  1011 		gss.iCats = gss.iCodeChar.GetCategory();
  1012 		gss.iClusterState = TGlyphSelectionState::EGClusterNotComplete;
  1013 		gss.iPen = TGlyphSelectionState::EPenAdvance_No;
  1014 
  1015 		// Find the correct processesing function for the script being used.
  1016 		// If gss.iCodePt is a strongly directional character, then simply map it in TTableEntry Table[]
  1017 		// and use the returned process function pointer.
  1018 		// If gss.iCodePt is a punctuation or a digit, then use a context character in the text (if
  1019 		// available) to find the contextual script being rendered and use its process function pointer.
  1020 		GlyphSelection::ProcessFunc processFn = FindContextualProcessFunc(aShapeInfo, gss);
  1021 
  1022 		if (!firstProcessFn)
  1023 			firstProcessFn = processFn;
  1024 
  1025 		if (processFn)
  1026 			{
  1027 			if (firstProcessFn == processFn)
  1028 				outputOk = processFn(gss, aShapeInfo);
  1029 			else
  1030 				break;
  1031 			}
  1032 		else
  1033 			{
  1034 			// Table entry blank, unicode char to be skipped
  1035 			outputOk = ETrue;
  1036 			textIter.Next();
  1037 			gss.iClusterState = 
  1038 				(!textIter.AtEnd() &&
  1039 				((textIter.Get().GetCategory() & 0xF0) 
  1040 				== TChar::EMarkGroup)) ?
  1041 					TGlyphSelectionState::EGClusterNotComplete : TGlyphSelectionState::EGClusterComplete;
  1042 			}
  1043 
  1044 		// Abort if no class was available to process the character or if
  1045 		// processing failed.
  1046 		if (!outputOk)
  1047 			{
  1048 			aParam.iPosInText = textIter.LengthToStart();
  1049 			return outputOk;
  1050 			}
  1051 
  1052 		// Did the glyph selector that processed the character want the 
  1053 		// pen to advance?
  1054 		if (gss.iPen == TGlyphSelectionState::EPenAdvance_Yes)
  1055 			{
  1056 			aParam.iPen.iX += gss.iAdvance.iWidth;
  1057 			aParam.iPen.iY += gss.iAdvance.iHeight;
  1058 			gss.iPen = TGlyphSelectionState::EPenAdvance_No;
  1059 			}
  1060 
  1061 		// Here we assume the Process() methods have advanced the iterator as
  1062 		// they consume characters they handle so that it now points to the
  1063 		// character to process next time around the loop.
  1064 		}
  1065 	while (!textIter.AtEnd()	// We still have more text to process
  1066 		&& (gss.iClusterState == TGlyphSelectionState::EGClusterNotComplete) // Glyph cluster !complete
  1067 		&& (aParam.iOutputGlyphs < TPositionParam::EMaxOutputGlyphs)); // Room for another glyph entry
  1068 
  1069 	// If a complete glyph cluster has been identified then we should try to
  1070 	// compose it as fully as possible. Obviously, if it only contains one
  1071 	// character then it is already fully composed so we can ignore it.
  1072 	// Skip this if any language-specific processing has taken place.
  1073 	if (gss.iGlyphPostCombine == TGlyphSelectionState::EGPostCombine_Yes
  1074 		&& gss.iClusterState == TGlyphSelectionState::EGClusterComplete)
  1075 		{
  1076 		// Leave room to handle surrogates - Decompose() outputs UTF-16
  1077 		// The max that can come out of the previous stage is TPositionParam::EMaxOutputGlyphs
  1078 		// long with only one base char at the start. Even if that base char decomposed to the
  1079 		// max it could only be MaxOutputGlyphs long, giving a total of (2 * MaxOutputGlyphs)-1
  1080 		// Conceivably the use of surrogates throughout could double that when converting to UTF-16
  1081 		TBuf<TPositionParam::EMaxOutputGlyphs * 4> decomposeArray;
  1082 		TBool success = ETrue;
  1083 		// Go through the glyph cluster one char at a time
  1084 		for (TInt i = 0; i < aParam.iOutputGlyphs; i++)
  1085 			{
  1086 			TChar singleChar(aParam.iOutput[i].iCode);
  1087 			// If first character try to decompose it otherwise just take the character
  1088 			TBool decomposed = EFalse;
  1089 			TPtrC16 decomposition;
  1090 			if (i == 0)
  1091 				decomposed = singleChar.Decompose(decomposition);
  1092 			if (decomposed)
  1093 				{ // Pick up the sequence of characters
  1094 				decomposeArray.Append(decomposition);
  1095 				}
  1096 			else
  1097 				{ // Keep the original character
  1098 				if (singleChar > 0xFFFF)
  1099 					{ // Above the BMP so we need a surrogate pair for UTF-16
  1100 					// This calculation really ought to go into a separate routine - probably part of TChar
  1101 					decomposeArray.Append(HighSurrogate(singleChar));
  1102 					decomposeArray.Append(LowSurrogate(singleChar));
  1103 					}
  1104 				else
  1105 					{ // It's not a surrogate so we just need to cast it down (since it's safe)
  1106 					decomposeArray.Append(singleChar);
  1107 					}
  1108 				}
  1109 			// Guard against bad input overflowing the array and causing a panic
  1110 			if (decomposeArray.Length() > (TPositionParam::EMaxOutputGlyphs * 4) - 2)
  1111 				{ // too long to be a viable composition so don't try
  1112 				success = EFalse;
  1113 				break;
  1114 				}
  1115 			}
  1116 		TUint composedChar = 0;
  1117 		TOpenFontCharMetrics metrics;
  1118 		TPositionParam::TOutput output;
  1119 		TSize advance; // gets initialized to 0,0
  1120 		if (success)
  1121 			{
  1122 			//Now try and compose the string to a single character
  1123 			success = TChar::Compose(composedChar, decomposeArray);
  1124 			}
  1125 		if (success)
  1126 			{
  1127 			// if single char is not in font or can't get char metrics for it
  1128 			// N.B. This will probably always return metrics because if the
  1129 			// char is not in the font this will usually return the substitute
  1130 			// "missing" glyph (and its metrics). There should be a function to
  1131 			// really tell you if a glyph is in the font - but there isn't.
  1132 			if (GetCharacterData(composedChar, metrics, output.iBitmap, output.iBitmapSize) == CFont::ENoCharacterData)
  1133 				success = EFalse;
  1134 			}
  1135 		if (success)
  1136 			{
  1137 			// We should replace the glyph cluster made from multiple chars
  1138 			// with the correct single char and fix up the rest of the output
  1139 			// parameters as well
  1140 			output.iCode = composedChar;
  1141 			// Set the glyph's bounds and record pen advancement.
  1142 			if (aParam.iDirection == CFont::EVertical)
  1143 				{
  1144 				metrics.GetVertBounds(output.iBounds);
  1145 				advance.iHeight = metrics.VertAdvance();
  1146 				}
  1147 			else
  1148 				{
  1149 				metrics.GetHorizBounds(output.iBounds);
  1150 				advance.iWidth = metrics.HorizAdvance();
  1151 				}
  1152 			// Adjust the glyph's bounding box to offset it from the pen
  1153 			// position (origin of drawing). For speed increment directly.
  1154 			output.iBounds.iTl.iX += penCopy.iX;
  1155 			output.iBounds.iBr.iX += penCopy.iX;
  1156 			output.iBounds.iTl.iY += penCopy.iY;
  1157 			output.iBounds.iBr.iY += penCopy.iY;
  1158 			// Set penCopy, the copy of aParam.iPen that we made
  1159 			penCopy.iX += advance.iWidth;
  1160 			penCopy.iY += advance.iHeight;
  1161 			// Overwrite the original output parameters for the glyph cluster
  1162 			// with the values for the single composed character
  1163 			aParam.iOutput[0] = output;
  1164 			aParam.iOutputGlyphs = 1;
  1165 			aParam.iPen = penCopy;	
  1166 			}
  1167 		}
  1168 
  1169 	// Exit routine with result and increment position in text to 
  1170 	// where we reached during processing to avoid any caller loops from 
  1171 	// infinite execution.
  1172 	aParam.iPosInText = textIter.LengthToStart();
  1173 	return outputOk;
  1174 	}
  1175 
  1176 /** Gets the character metrics for a character.
  1177 	
  1178 @param aCode The character code.
  1179 @param aMetrics On return, contains the character bitmap.
  1180 @param aBitmap On return, this points to NULL.
  1181 @param aBitmapSize On return, this has a size of (0,0).
  1182 @return ECharacterWidthOnly 
  1183 */
  1184 EXPORT_C CFont::TCharacterDataAvailability CFont::DoGetCharacterData(TUint aCode,TOpenFontCharMetrics& aMetrics,
  1185 		const TUint8*& aBinaryData,TSize& aBitmapSize) const
  1186 	{
  1187 	int width = CharWidthInPixels(aCode);
  1188 	aMetrics.SetHorizAdvance(width);
  1189 	aBinaryData = NULL;
  1190 	// For speed set to 0 directly rather than call SetSize()
  1191 	aBitmapSize.iWidth = 0;
  1192 	aBitmapSize.iHeight = 0;
  1193 
  1194 	/*
  1195 	Set the other metrics using the width and font metrics.
  1196 	This allows derived classes that don't override this function, like CInfoFont,
  1197 	to give usable results for TextWidthInPixels and MeasureText.
  1198 	*/
  1199 	aMetrics.SetWidth(width);
  1200 	int height = HeightInPixels();
  1201 	aMetrics.SetHeight(height);
  1202 	aMetrics.SetVertAdvance(height);
  1203 	aMetrics.SetHorizBearingX(0);
  1204 	aMetrics.SetHorizBearingY(AscentInPixels());
  1205 	aMetrics.SetVertBearingX(0);
  1206 	aMetrics.SetVertBearingY(0);
  1207 
  1208 	return CFont::ECharacterWidthOnly;
  1209 	}
  1210 
  1211 
  1212 /** Determines if aLeftCharacter and aRightCharacter affect each other's
  1213 contextual glyph form if placed next to each other. If either character
  1214 is a combining character, EFalse will be returned, which is not generally
  1215 useful information. Pass in base characters ignoring intervening combining
  1216 characters.
  1217 @param aLeftCharacter Unicode code for the character that stands on the left.
  1218 @param aRightCharacter Unicode code for the character that stands on the right.
  1219 @return EFalse if the characters do not affect the contextual glyphs that are
  1220 be chosen when the two are rendered together, compared to being separated 
  1221 (for example by a space). */	
  1222 EXPORT_C TBool CFont::CharactersJoin(TInt aLeftCharacter, TInt aRightCharacter)
  1223 	{
  1224 	return GlyphSelector_Arabic::CharactersJoin(aLeftCharacter, aRightCharacter);
  1225 	}
  1226 
  1227 /** API extension system that enables the caller to access a particular API
  1228 extension function. N.B. Any overload of this function in a derived class
  1229 should call its immediate parent implementation for any extension function Uid
  1230 that it does not recognize and handle.
  1231 @param aInterfaceId UID of the required extension function
  1232 @param aParam Pointer to an arbitrary parameter block that can be used to
  1233 provide and/or return information to/from the particular extension function,
  1234 defaults to NULL.
  1235 @return Integer return value from extension function
  1236 @internalTechnology
  1237 @released
  1238 */
  1239 EXPORT_C TInt CFont::DoExtendedFunction(TUid aFunctionId, TAny* /* aParam */) const
  1240 	{
  1241 	if (KFontCapitalAscent	== aFunctionId ||
  1242 		KFontMaxAscent		== aFunctionId)
  1243 		{
  1244 		return AscentInPixels();
  1245 		}
  1246 	else if (KFontStandardDescent	== aFunctionId ||
  1247 			 KFontMaxDescent		== aFunctionId)
  1248 		{
  1249 		return DescentInPixels();
  1250 		}
  1251 	else if (KFontLineGap == aFunctionId)
  1252 		{ // 1.2 of em height (rounded) is reasonable approximation of interline gap
  1253 		return (HeightInPixels() * 12 + 5) / 10;
  1254 		}
  1255 	return KErrNotFound;
  1256 	}
  1257 
  1258 EXPORT_C TUid CFont::TypeUid() const
  1259 	{
  1260 	return DoTypeUid();
  1261 	}
  1262 
  1263 EXPORT_C TInt CFont::HeightInPixels() const
  1264 	{
  1265 	return DoHeightInPixels();
  1266 	}
  1267 
  1268 EXPORT_C TInt CFont::AscentInPixels() const
  1269 	{
  1270 	return DoAscentInPixels();
  1271 	}
  1272 
  1273 EXPORT_C TInt CFont::DescentInPixels() const
  1274 	{
  1275 	return DoDescentInPixels();
  1276 	}
  1277 
  1278 EXPORT_C TInt CFont::CharWidthInPixels(TChar aChar) const
  1279 	{
  1280 	return DoCharWidthInPixels(aChar);
  1281 	}
  1282 
  1283 EXPORT_C TInt CFont::TextWidthInPixels(const TDesC& aText) const
  1284 	{
  1285 	return DoTextWidthInPixels(aText);
  1286 	}
  1287 
  1288 EXPORT_C TInt CFont::BaselineOffsetInPixels() const
  1289 	{
  1290 	return DoBaselineOffsetInPixels();
  1291 	}
  1292 
  1293 EXPORT_C TInt CFont::TextCount(const TDesC& aText,TInt aWidthInPixels) const
  1294 	{
  1295 	return DoTextCount(aText, aWidthInPixels);
  1296 	}
  1297 
  1298 EXPORT_C TInt CFont::TextCount(const TDesC& aText, TInt aWidthInPixels, TInt& aExcessWidthInPixels) const
  1299 	{
  1300 	return DoTextCount(aText, aWidthInPixels, aExcessWidthInPixels);
  1301 	}
  1302 
  1303 EXPORT_C TInt CFont::MaxCharWidthInPixels() const
  1304 	{
  1305 	return DoMaxCharWidthInPixels();
  1306 	}
  1307 
  1308 EXPORT_C TInt CFont::MaxNormalCharWidthInPixels() const
  1309 	{
  1310 	return DoMaxNormalCharWidthInPixels();
  1311 	}
  1312 
  1313 EXPORT_C TFontSpec CFont::FontSpecInTwips() const
  1314 	{
  1315 	return DoFontSpecInTwips();
  1316 	}
  1317 	
  1318 /** Gets the character metrics for a character.
  1319 	
  1320 @param aCode The character code.
  1321 @param aMetrics On return, contains the character bitmap.
  1322 @param aBitmap On return, this points to NULL.
  1323 @param aBitmapSize On return, this has a size of (0,0).
  1324 @return ECharacterWidthOnly 
  1325 */
  1326 EXPORT_C CFont::TCharacterDataAvailability CFont::GetCharacterData(TUint aCode, TOpenFontCharMetrics& aMetrics, const TUint8*& aBitmap, TSize& aBitmapSize) const
  1327 	{
  1328 	return DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
  1329 	}
  1330 
  1331 /** Transforms one cluster of characters (base character plus combining marks,
  1332 ligature or indic syllable) into one cluster of glyphs together with their
  1333 positions. Repeated calls of this function (for the same input text) are
  1334 considerably slower than repeated calls of GetCharacterPosition2 for Indic text
  1335 (such as Hindi), as GetCharacterPosition2 can cache information between calls.
  1336 @param aParam Input and output parameters
  1337 @return True for success
  1338 @see GetCharacterPosition2
  1339 @publishedAll */
  1340 EXPORT_C TBool CFont::GetCharacterPosition(TPositionParam& aParam) const
  1341 	{
  1342 	return DoGetCharacterPosition(aParam);
  1343 	}
  1344 
  1345 /** Enables the caller to access a particular API
  1346 extension function. N.B. Any overload of this function in a derived class
  1347 should call its immediate parent implementation for any extension function UID
  1348 that it does not recognize and handle.
  1349 @param aFunctionId UID of the required extension function
  1350 @param aParam Pointer to an arbitrary parameter block that can be used to
  1351 provide and/or return information to/from the particular extension function,
  1352 defaults to NULL.
  1353 @return Integer return value from extension function 
  1354 */
  1355 EXPORT_C TInt CFont::ExtendedFunction(TUid aFunctionId, TAny* aParam) const
  1356 	{
  1357 	return DoExtendedFunction(aFunctionId, aParam);
  1358 	}
  1359 	
  1360 EXPORT_C TInt CFont::TextWidthInPixels(const TDesC& aText,const TMeasureTextInput* aParam) const
  1361 	{
  1362 	TTextWidthInternal context;
  1363 	TTextWidthInternal* contextPtr = &context;
  1364 	contextPtr->iText.Set(aText);
  1365 	contextPtr->iParam.iStartInputChar = aParam->iStartInputChar;
  1366 	contextPtr->iParam.iEndInputChar = aParam->iEndInputChar;
  1367 	return DoExtendedFunction(KTextInContextWidthInPixelsUid, (TAny*)contextPtr);
  1368 	}
  1369 
  1370 /**
  1371 Maps TLanguage to TScript.
  1372 
  1373 EScriptOther represents languages not yet supported in KTScript2GlyphSample.
  1374 This array does not handle ELangNone and ELangMaximum to save storage space.
  1375 */
  1376 const TInt GlyphSample::KTLanguage2TScript[] = 
  1377 	{
  1378 	EScriptNone,			// 00 ELangTest
  1379 	EScriptLatin,			// 01 ELangEnglish
  1380 	EScriptLatin,			// 02 ELangFrench
  1381 	EScriptLatin,			// 03 ELangGerman
  1382 	EScriptLatin,			// 04 ELangSpanish
  1383 	EScriptLatin,			// 05 ELangItalian
  1384 	EScriptLatin,			// 06 ELangSwedish
  1385 	EScriptLatin,			// 07 ELangDanish
  1386 	EScriptLatin,			// 08 ELangNorwegian
  1387 	EScriptLatin,			// 09 ELangFinnish
  1388 	EScriptLatin,			// 10 ELangAmerican
  1389 	EScriptLatin,			// 11 ELangSwissFrench
  1390 	EScriptLatin,			// 12 ELangSwissGerman
  1391 	EScriptLatin,			// 13 ELangPortuguese
  1392 	EScriptLatin,			// 14 ELangTurkish
  1393 	EScriptLatin,			// 15 ELangIcelandic
  1394 	EScriptCyrillic,		// 16 ELangRussian
  1395 	EScriptLatin,			// 17 ELangHungarian
  1396 	EScriptLatin,			// 18 ELangDutch
  1397 	EScriptLatin,			// 19 ELangBelgianFlemish
  1398 	EScriptLatin,			// 20 ELangAustralian
  1399 	EScriptLatin,			// 21 ELangBelgianFrench
  1400 	EScriptLatin,			// 22 ELangAustrian
  1401 	EScriptLatin,			// 23 ELangNewZealand
  1402 	EScriptLatin,			// 24 ELangInternationalFrench
  1403 	EScriptLatin,			// 25 ELangCzech
  1404 	EScriptLatin,			// 26 ELangSlovak
  1405 	EScriptLatin,			// 27 ELangPolish
  1406 	EScriptLatin,			// 28 ELangSlovenian
  1407 	EScriptHanIdeographs,	// 29 ELangTaiwanChinese
  1408 	EScriptHanIdeographs,	// 30 ELangHongKongChinese
  1409 	EScriptHanIdeographs,	// 31 ELangPrcChinese
  1410 	EScriptHanIdeographs,	// 32 ELangJapanese
  1411 	EScriptThai,			// 33 ELangThai
  1412 	EScriptLatin,			// 34 ELangAfrikaans
  1413 	EScriptLatin,			// 35 ELangAlbanian
  1414 	EScriptOther,			// 36 ELangAmharic
  1415 	EScriptArabic,			// 37 ELangArabic
  1416 	EScriptOther,			// 38 ELangArmenian
  1417 	EScriptOther,			// 39 ELangTagalog
  1418 	EScriptCyrillic,		// 40 ELangBelarussian
  1419 	EScriptOther,			// 41 ELangBengali
  1420 	EScriptCyrillic,		// 42 ELangBulgarian
  1421 	EScriptOther,			// 43 ELangBurmese
  1422 	EScriptLatin,			// 44 ELangCatalan
  1423 	EScriptLatin,			// 45 ELangCroatian
  1424 	EScriptLatin,			// 46 ELangCanadianEnglish
  1425 	EScriptLatin,			// 47 ELangInternationalEnglish
  1426 	EScriptLatin,			// 48 ELangSouthAfricanEnglish
  1427 	EScriptLatin,			// 49 ELangEstonian
  1428 	EScriptArabic,			// 50 ELangFarsi
  1429 	EScriptLatin,			// 51 ELangCanadianFrench
  1430 	EScriptLatin,			// 52 ELangScotsGaelic
  1431 	EScriptOther,			// 53 ELangGeorgian
  1432 	EScriptGreek,			// 54 ELangGreek
  1433 	EScriptGreek,			// 55 ELangCyprusGreek
  1434 	EScriptOther,			// 56 ELangGujarati
  1435 	EScriptHebrew,			// 57 ELangHebrew
  1436 	EScriptDevanagari,		// 58 ELangHindi
  1437 	EScriptLatin,			// 59 ELangIndonesian
  1438 	EScriptLatin,			// 60 ELangIrish
  1439 	EScriptLatin,			// 61 ELangSwissItalian
  1440 	EScriptOther,			// 62 ELangKannada
  1441 	EScriptCyrillic,		// 63 ELangKazakh
  1442 	EScriptOther,			// 64 ELangKhmer
  1443 	EScriptHanIdeographs,	// 65 ELangKorean
  1444 	EScriptOther,			// 66 ELangLao
  1445 	EScriptLatin,			// 67 ELangLatvian
  1446 	EScriptLatin,			// 68 ELangLithuanian
  1447 	EScriptCyrillic,		// 69 ELangMacedonian
  1448 	EScriptLatin,			// 70 ELangMalay
  1449 	EScriptOther,			// 71 ELangMalayalam
  1450 	EScriptDevanagari,		// 72 ELangMarathi
  1451 	EScriptLatin,			// 73 ELangMoldavian
  1452 	EScriptOther,			// 74 ELangMongolian
  1453 	EScriptLatin,			// 75 ELangNorwegianNynorsk
  1454 	EScriptLatin,			// 76 ELangBrazilianPortuguese
  1455 	EScriptOther,			// 77 ELangPunjabi
  1456 	EScriptLatin,			// 78 ELangRomanian
  1457 	EScriptCyrillic,		// 79 ELangSerbian
  1458 	EScriptOther,			// 80 ELangSinhalese
  1459 	EScriptLatin,			// 81 ELangSomali
  1460 	EScriptLatin,			// 82 ELangInternationalSpanish
  1461 	EScriptLatin,			// 83 ELangLatinAmericanSpanish
  1462 	EScriptLatin,			// 84 ELangSwahili
  1463 	EScriptLatin,			// 85 ELangFinlandSwedish
  1464 	EScriptNone,			// 86 ELangReserved1
  1465 	EScriptOther,			// 87 ELangTamil
  1466 	EScriptOther,			// 88 ELangTelugu
  1467 	EScriptOther,			// 89 ELangTibetan
  1468 	EScriptOther,			// 90 ELangTigrinya
  1469 	EScriptLatin,			// 91 ELangCyprusTurkish
  1470 	EScriptCyrillic,		// 92 ELangTurkmen
  1471 	EScriptCyrillic,		// 93 ELangUkrainian
  1472 	EScriptArabic,			// 94 ELangUrdu
  1473 	EScriptNone,			// 95 ELangReserved2
  1474 	EScriptLatin,			// 96 ELangVietnamese
  1475 	EScriptLatin,			// 97 ELangWelsh
  1476 	EScriptLatin,			// 98 ELangZulu
  1477 	};
  1478 
  1479 /**
  1480 Maps TScript to glyph samples.
  1481 
  1482 The order of samples definition has to follow the script order in TScript.
  1483 
  1484 Supported scripts	Fonts used to experiment/determine glyph samples
  1485 
  1486 Latin				Arial, Times, Century
  1487 Greek				Ditto
  1488 Cyrillic			Ditto
  1489 Hebrew				Aharoni, David, FrankRuehl, Levenim MT, Miriam, Narkisim, Rod
  1490 Arabic				Andalus, Arabic Transparent, Simplified Arabic, Traditional Arabic
  1491 Devanagari			Mangal
  1492 Thai				Angsana New, Browallia, Cordia New, DilleniaUPC, EucrosiaUPC,
  1493 					FreesiaUPC, IrisUPC, JasmineUPC, KodchiangUPC, LilyUPC
  1494 HanIdeographs		Chinese	: SimSun, SimHei (Simplified) / MingLiU (Traditional)
  1495 					Japanese: MS Mincho, MS Gothic
  1496 					Korean	: Batang, Gulim
  1497 */
  1498 const TText* const GlyphSample::KTScript2GlyphSample[] = 
  1499 	{
  1500 	//
  1501 	// 02 EScriptLatin
  1502 	//
  1503 	//	0x00C0 - Ascent : Capital letter A with grave (Latin-1 Supplement)
  1504 	//	0x013A - Ascent : Small letter l with acute (Latin Extended A)
  1505 	//	0x1EA2 - Ascent : Capital letter A with hook above (Latin Extended Additional)
  1506 	//	0x00C7 - Descent: Capital letter C with cedilla (Latin-1 Supplement)
  1507 	//	0x0163 - Descent: Small letter t with cedilla (Latin Extended A)
  1508 	//
  1509 	_S("\x00C0\x013A\x1EA2\x00C7\x0163"),
  1510 	//
  1511 	// 03 EScriptGreek
  1512 	//
  1513 	//	0x03AA - Ascent : Capital letter iota with dialytika
  1514 	//	0x03AB - Ascent : Capital letter upsilon with dialytika
  1515 	//	0x03AE - Descent: Small letter eta with tonos
  1516 	//	0x03B2 - Descent: Small letter beta
  1517 	//	0x03C8 - Descent: Small letter psi
  1518 	//
  1519 	_S("\x03AA\x03AB\x03AE\x03B2\x03C8"),
  1520 	//
  1521 	// 04 EScriptCyrillic
  1522 	//
  1523 	//	0x0403 - Ascent : Capital letter gje
  1524 	//	0x0419 - Ascent : Capital letter short i
  1525 	//	0x0440 - Descent: Small letter er
  1526 	//	0x0452 - Descent: Small letter dje
  1527 	//	0x0458 - Descent: Small letter je
  1528 	//
  1529 	_S("\x0403\x0419\x0440\x0452\x0458"),
  1530 	//
  1531 	// 05 EScriptHebrew
  1532 	//
  1533 	//	0x05BE - Ascent : Punctuation maqaf
  1534 	//	0x05DC - Ascent : Letter lamed
  1535 	//	0x05B0 - Descent: Point sheva
  1536 	//	0x05BD - Descent: Point meteg
  1537 	//	0x05E7 - Descent: Letter qof
  1538 	//
  1539 	_S("\x05BE\x05DC\x05B0\x05BD\x05E7"),
  1540 	//
  1541 	// 06 EScriptArabic
  1542 	//
  1543 	// 	0x0670 - Ascent : Alef above (Arabic)
  1544 	// 	0x0671 - Ascent : Hamzat Wasl on Alef  isolated form
  1545 	// 	0x064D - Descent: Kasratan (Arabic)
  1546 	// 	0xFB7B - Descent: Final form of 0686
  1547 	// 	0xFBF2 - Descent: Final form of 064A
  1548 	//
  1549 	//PDEF120737: EScriptArabic value has been changed for this defect & tested using the font file provided by client (i.e. kamelion arabic font).
  1550 	//The client's font file can't be used for IPR reasons. Thus the test code to demonstrate this defect
  1551 	//is not added. Also, there was no other font file available that reproduces this defect. 
  1552 	//
  1553 	_S("\x0670\x0671\x064D\xFB7B\xFBF2"),
  1554 	//
  1555 	// 07 EScriptDevanagari
  1556 	//
  1557 	//	0x0914 - Ascent : Letter au
  1558 	//	0x0951 - Ascent : Stress sign udatta
  1559 	//	0x0941 - Descent: Vowel sign u
  1560 	//	0x0944 - Descent: Vowel sign rr
  1561 	//	0x0963 - Descent: Vowel sign vocalic ll
  1562 	//
  1563 	_S("\x0914\x0951\x0941\x0944\x0963"),
  1564 	//
  1565 	// 08 EScriptThai
  1566 	//
  1567 	//	0x0E49 - Ascent : Character mai tho
  1568 	//	0x0E4B - Ascent : Character mai chattawa
  1569 	//	0x0E0E - Descent: Character do chada
  1570 	//	0x0E24 - Descent: Character ru
  1571 	//	0x0E39 - Descent: Character sara uu
  1572 	//
  1573 	_S("\x0E49\x0E4B\x0E0E\x0E24\x0E39"),
  1574 	//
  1575 	// 09 EScriptHanIdeographs
  1576 	//
  1577 	//	0x1100 - Ascent/Descent: Korean
  1578 	//	0x4E1C - Ascent/Descent: Chinese Simplified
  1579 	//	0x5283 - Ascent/Descent: Japanese
  1580 	//	0x758A - Ascent : Chinese Traditional
  1581 	//	0x7BEA - Descent: Chinese Traditional
  1582 	//
  1583 	_S("\x1100\x4E1C\x5283\x758A\x7BEA"),
  1584 	};
  1585 
  1586 /**
  1587 Maps a TLanguage type to the TScript type.
  1588 @internalTechnology
  1589 @param aLanguage The language.
  1590 @return A TInt representing the script, or 
  1591 EScriptNone if its not defined for aLanguage.
  1592 */
  1593 EXPORT_C TInt GlyphSample::TLanguage2TScript(TLanguage aLanguage)
  1594 	{
  1595 	if (ELangNone == aLanguage || ELangMaximum == aLanguage || aLanguage >= (sizeof(KTLanguage2TScript)/sizeof(KTLanguage2TScript[0])))
  1596 		{
  1597 		return EScriptNone;
  1598 		}
  1599 	return KTLanguage2TScript[aLanguage];
  1600 	}
  1601 
  1602 /**
  1603 Maps a TScript type to some glyph samples which are stored as Unicode.
  1604 @internalTechnology
  1605 @param aScript The script.
  1606 @return A TPtrC pointing to the first glyph sample,
  1607 or empty if no samples is defined for aScript.
  1608 */
  1609 EXPORT_C const TPtrC GlyphSample::TScript2GlyphSample(TInt aScript)
  1610 	{
  1611 	if (EScriptOther >= aScript)
  1612 		{
  1613 		return TPtrC();
  1614 		}
  1615 	// -3 to offset EScriptDefault, EScriptNone and EScriptOther
  1616 	// being the first three elements in TScript.
  1617 	return TPtrC(KTScript2GlyphSample[aScript - 3]);
  1618 	}
  1619 
  1620 
  1621 EXPORT_C RFontTable::RFontTable():iTableContent(0), iLength(0),
  1622         iFont(NULL), iTag(0)
  1623     {
  1624     // a null constructor.
  1625     }
  1626 
  1627 EXPORT_C TInt
  1628 RFontTable::Open(CFont& aFont, TUint32 aTag) 
  1629     {
  1630     TGetFontTableParam param;
  1631     param.iTag = aTag;
  1632     
  1633     // remember the parameters, to be used when releasing the font table.
  1634     iFont = &aFont;
  1635     iTag = aTag;
  1636     
  1637     TInt ret = aFont.ExtendedFunction(KFontGetFontTable, (TAny *)&param);
  1638     if (KErrNone == ret)
  1639         {
  1640         iTableContent = (TAny *)param.iContent;
  1641         iLength = param.iLength;
  1642         }
  1643     return ret;
  1644     }
  1645 
  1646 EXPORT_C TInt 
  1647 RFontTable::TableLength() const
  1648     {
  1649     return iLength;
  1650     }
  1651 
  1652 EXPORT_C const TUint8*
  1653 RFontTable::TableContent() const 
  1654     {
  1655     return (TUint8*)iTableContent;
  1656     }
  1657 
  1658 EXPORT_C void
  1659 RFontTable::Close()
  1660     {
  1661     if (NULL != iFont)
  1662         {
  1663         (void)iFont->ExtendedFunction(KFontReleaseFontTable, (TAny *)&iTag);
  1664         }
  1665     iTableContent = 0;
  1666     iLength = 0;
  1667     iFont = NULL;
  1668     iTag = 0;
  1669     }
  1670 
  1671 EXPORT_C 
  1672 RGlyphOutlineIterator::RGlyphOutlineIterator():iOutlines(0), iLengths(0), 
  1673     iCursor(-1), iCount(0), iFont(NULL), iCodes(NULL), iHinted(EFalse)
  1674     {
  1675     // a null constructor.
  1676     }
  1677 
  1678 EXPORT_C TInt
  1679 RGlyphOutlineIterator::Open(CFont& aFont, const TUint* aCodes, TInt aCount, TBool aHinted) 
  1680     {
  1681     if (NULL == aCodes || 0 == aCount)
  1682         {
  1683         return KErrArgument;
  1684         }
  1685     TGetGlyphOutlineParam param;
  1686     iLengths = (TInt *)User::Alloc(sizeof(TInt) * aCount);
  1687     if (NULL == iLengths) 
  1688         {
  1689         return KErrNoMemory;
  1690         }
  1691     iOutlines = (TAny **)User::Alloc(sizeof(TAny *) * aCount);
  1692     if (NULL == iOutlines)
  1693         {
  1694         User::Free(iLengths);
  1695         iLengths = NULL;
  1696         return KErrNoMemory;
  1697         }
  1698     
  1699     param.iLengths = iLengths; 
  1700     param.iCount = aCount;
  1701     param.iCodes = aCodes; 
  1702     param.iHinted = aHinted;
  1703     param.iOutlines = iOutlines; 
  1704         
  1705     /* information needed in Close() */
  1706     iCodes = (TUint *)User::Alloc(sizeof(TUint) * aCount);
  1707     if (NULL == iCodes) 
  1708         {
  1709         User::Free(iLengths);
  1710         User::Free(iOutlines);
  1711         iLengths = NULL;
  1712         iOutlines = NULL;
  1713         return KErrNoMemory;
  1714         }
  1715     Mem::Copy(iCodes, aCodes, aCount*sizeof(TUint));
  1716     iFont = &aFont;
  1717     iHinted = aHinted;
  1718     iCount = aCount;
  1719     
  1720     TInt ret = aFont.ExtendedFunction(KFontGetGlyphOutline, (TAny *)&param);
  1721     if (KErrNone != ret)
  1722         {
  1723         User::Free(iLengths);
  1724         User::Free(iOutlines);
  1725         User::Free(iCodes);
  1726         iLengths = NULL;
  1727         iOutlines = NULL;
  1728         iCodes = NULL;
  1729         iFont = NULL;
  1730         }
  1731     else 
  1732         {
  1733         iCursor = 0;
  1734         }
  1735 
  1736     return ret;
  1737     }
  1738 
  1739 EXPORT_C const TUint8*
  1740 RGlyphOutlineIterator::Outline() const
  1741     {
  1742     GDI_ASSERT_ALWAYS(iCursor >= 0, EGdiPanic_Unknown);
  1743     
  1744     if (iLengths[iCursor] < 0) 
  1745         {
  1746         return NULL;
  1747         }
  1748     else 
  1749         {
  1750         return (const TUint8*)iOutlines[iCursor];
  1751         }
  1752     }
  1753 
  1754 EXPORT_C TInt 
  1755 RGlyphOutlineIterator::OutlineLength() const 
  1756     {
  1757     GDI_ASSERT_ALWAYS(iCursor >= 0, EGdiPanic_Unknown);
  1758     
  1759     if (iLengths[iCursor] < 0) 
  1760         {
  1761         return KErrGeneral;
  1762         }
  1763     else 
  1764         {
  1765         return iLengths[iCursor];
  1766         }
  1767     }
  1768 
  1769 EXPORT_C TInt
  1770 RGlyphOutlineIterator::Next()
  1771     {
  1772     if (iCursor >= 0 && iCursor < iCount-1) 
  1773         {
  1774         ++iCursor;
  1775         return KErrNone;
  1776         }
  1777     else
  1778         {
  1779         iCursor = -1; 
  1780         // if the iterator goes beyond the last element [when
  1781         // Next() returns KErrNotFound], the next call
  1782         // to Outline() or OutlineLength() will panic.
  1783         
  1784         return KErrNotFound;
  1785         }
  1786     }
  1787 
  1788 EXPORT_C void
  1789 RGlyphOutlineIterator::Close()
  1790     {
  1791     TReleaseGlyphOutlineParam param;
  1792     param.iCount = iCount;
  1793     param.iHinted = iHinted;
  1794     param.iCodes = iCodes;
  1795     
  1796     if (NULL != iFont)
  1797         {
  1798         iFont->ExtendedFunction(KFontReleaseGlyphOutline, (TAny *)&param);
  1799         }
  1800     
  1801     iFont = NULL;
  1802     iCount = 0;
  1803     User::Free(iLengths);
  1804     iLengths = NULL;
  1805     iCursor = -1;
  1806     User::Free(iCodes);
  1807     iCodes = NULL;
  1808     User::Free(iOutlines);
  1809     iOutlines = NULL;
  1810     }