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