os/textandloc/fontservices/textbase/sgdi/FONT.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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     }