graphicsdeviceinterface/gdi/sgdi/FONT.CPP
changeset 183 6a1564a2f3e6
parent 168 2bd88482bfe5
child 194 18f84489a694
equal deleted inserted replaced
168:2bd88482bfe5 183:6a1564a2f3e6
     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     }