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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 //#include <textbase.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"
32 Names holds the types & data associated with the glyph selection
33 algorithm in CFont::GetCharacterPosition().
36 namespace GlyphSelection
39 typedef TBool (*ProcessFunc)(TGlyphSelectionState& aGss, RShapeInfo&);
42 This structure defines the fields present in each row of the GlyphTable
50 ProcessFunc iProcessFunc;
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.
62 static const TTableEntry Table[] =
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},
84 { 0x2010, 0x2029, GlyphSelector_Default::Process},
86 { 0x202F, 0xFFFD, GlyphSelector_Default::Process},
88 { 0x10000, 0x10FFFF, GlyphSelector_Default::Process},
89 {0xFFFFFFFF,0xFFFFFFFF, 0}
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.
97 GlyphSelection::ProcessFunc CharacterToProcessFunction(TInt aChar)
99 for (const GlyphSelection::TTableEntry* glyphSel = GlyphSelection::Table;
100 glyphSel->iLow != 0xFFFFFFFF; glyphSel++)
102 if ((glyphSel->iLow <= aChar) && (aChar <= glyphSel->iHigh))
103 return glyphSel->iProcessFunc;
109 @internalTechnology For use by TFontStyle/TOpenFontSpec.
111 EXPORT_C TBool FontEffect::IsEffectOn(TEffect aEffect, TUint32 aFontEffect)
113 return aEffect & aFontEffect;
117 @internalTechnology For use by TFontStyle/TOpenFontSpec.
119 EXPORT_C void FontEffect::SetEffect(TEffect aEffect, TBool aOn, TUint32& aFontEffect)
122 aFontEffect |= aEffect;
124 aFontEffect &= ~aEffect;
132 /** Default C++ constructor. */
133 EXPORT_C TFontStyle::TFontStyle():
134 iFlags(0), iReserved1(0), iReserved2(0)
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)
145 if (aPostr == EPostureItalic)
149 if (aWgt == EStrokeWeightBold)
153 if (aPos == EPrintPosSuperscript)
157 else if (aPos == EPrintPosSubscript)
164 EXPORT_C void TFontStyle::InternalizeL(RReadStream& aStream)
165 /** Internalises a font style from a read stream.
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.
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. */
174 iFlags = aStream.ReadUint32L();
178 EXPORT_C void TFontStyle::ExternalizeL(RWriteStream& aStream) const
179 /** Externalises the font style to a write stream.
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.
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. */
188 aStream.WriteUint32L(iFlags);
192 EXPORT_C TFontPosture TFontStyle::Posture() const
193 /** Gets the posture attribute.
195 @return The font style's posture. */
197 if(iFlags&EItalic) return(EPostureItalic);
198 return(EPostureUpright);
202 EXPORT_C TFontStrokeWeight TFontStyle::StrokeWeight() const
203 /** Gets the stroke weight attribute.
205 @return The font style's stroke weight. */
207 if(iFlags&EBold) return(EStrokeWeightBold);
208 return(EStrokeWeightNormal);
212 EXPORT_C TFontPrintPosition TFontStyle::PrintPosition() const
213 /** Gets the print position attribute.
215 @return The font style's print position. */
217 if((iFlags&ESuper) && !(iFlags&ESub)) return(EPrintPosSuperscript);
218 else if((iFlags&ESub) && !(iFlags&ESuper)) return(EPrintPosSubscript);
219 return(EPrintPosNormal);
223 EXPORT_C void TFontStyle::SetPosture(TFontPosture aPosture)
224 /** Sets the posture attribute.
226 @param aPosture The posture to be set. */
228 if(aPosture==EPostureItalic) iFlags|=EItalic;
229 else iFlags&=~EItalic;
233 EXPORT_C void TFontStyle::SetStrokeWeight(TFontStrokeWeight aStrokeWeight)
234 /** Sets the stroke weight attribute.
236 @param aStrokeWeight The stroke weight to be set. */
238 if(aStrokeWeight==EStrokeWeightBold) iFlags|=EBold;
243 EXPORT_C void TFontStyle::SetPrintPosition(TFontPrintPosition aPrintPosition)
244 /** Sets the print position attribute.
246 @param aPrintPosition The print position to be set. */
248 switch(aPrintPosition)
250 case EPrintPosSuperscript:
256 case EPrintPosSubscript:
270 /** Gets the font effects flags.
273 @return The font effects flags.
274 @see TFontStyle::SetEffects()
276 EXPORT_C TUint32 TFontStyle::Effects() const
278 return 0xFFF0 & iFlags;
281 /** Checks if a font effect is on.
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()
288 EXPORT_C TBool TFontStyle::IsEffectOn(FontEffect::TEffect aEffect) const
290 return FontEffect::IsEffectOn(aEffect, iFlags);
293 /** Sets the font effects flags.
296 @param aEffect The font effects flags to be set.
297 @see TFontStyle::Effects()
299 EXPORT_C void TFontStyle::SetEffects(TUint32 aEffects)
301 iFlags &= 0xFFFF000F;
302 iFlags |= 0xFFF0 & aEffects;
305 /** Sets a font effect to the given state.
308 @param aEffect The font effect to be set.
309 @param aOn True represents on, otherwise off.
310 @see TFontStyle::IsEffectOn()
312 EXPORT_C void TFontStyle::SetEffects(FontEffect::TEffect aEffect, TBool aOn)
314 FontEffect::SetEffect(aEffect, aOn, iFlags);
317 /** Compares a font style for equality.
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.
323 EXPORT_C TBool TFontStyle::operator==(const TFontStyle& aFontStyle) const
325 return iFlags == aFontStyle.iFlags;
331 EXPORT_C TFontSpec::TFontSpec():
335 /** Default constructor.
337 The object's font style is set to the default: EPostureUpright, EStrokeWeightNormal,
338 and EPrintPosNormal. */
342 EXPORT_C TFontSpec::TFontSpec(const TDesC& aTypefaceName,TInt aHeight):
345 iFontStyle(EPostureUpright,EStrokeWeightNormal,EPrintPosNormal)
346 /** Constructs a TFontSpec object with the specified typeface and height.
348 The object's font style is set to the default: EPostureUpright, EStrokeWeightNormal,
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.
357 iTypeface.SetName(aTypefaceName);
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.
368 iHeight == aFontSpec.iHeight &&
369 iFontStyle == aFontSpec.iFontStyle &&
370 iTypeface == aFontSpec.iTypeface;
374 EXPORT_C void TFontSpec::InternalizeL(RReadStream& aStream)
375 /** Internalises a font specification from a read stream.
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.
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. */
383 iTypeface.InternalizeL(aStream);
384 iHeight=aStream.ReadUint16L();
385 iFontStyle.InternalizeL(aStream);
389 EXPORT_C void TFontSpec::ExternalizeL(RWriteStream& aStream) const
390 /** Externalises the font specification to a write stream.
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.
395 @param aStream The stream to which the font specification is to be externalised
397 @leave KErrNoMemory If the write action causes the stream's resources to be
400 iTypeface.ExternalizeL(aStream);
401 aStream.WriteUint16L(iHeight);
402 iFontStyle.ExternalizeL(aStream);
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.
412 iTypeface.SetScriptTypeForMetrics(aLanguage);
415 EXPORT_C TInt TFontSpec::ScriptTypeForMetrics() const
416 /** Returns the script with which font metrics calculation will be based on.
420 return iTypeface.ScriptTypeForMetrics();
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():
433 /** Default C++ constructor. */
439 void TTypeface::ResetAttributes()
441 iFlags &= KTTypefaceMaskScript;
447 void TTypeface::ResetScriptType()
449 iFlags &= KTTypefaceMaskAttrib;
452 EXPORT_C void TTypeface::InternalizeL(RReadStream& aStream)
453 /** Internalises a typeface from a read stream.
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.
458 @param aStream Stream from which the typeface is to be internalised. */
460 TBuf<KMaxTypefaceNameLength> tempname;
462 new(&iName) TBufC<KMaxTypefaceNameLength>(tempname);
463 iFlags = aStream.ReadInt8L();
467 EXPORT_C void TTypeface::ExternalizeL(RWriteStream& aStream) const
468 /** Externalises a typeface to a write stream.
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.
473 @param aStream The stream to which the typeface is to be externalised. */
476 aStream.WriteInt8L(static_cast<TInt8>(iFlags));
480 EXPORT_C TBool TTypeface::operator==(const TTypeface& aTypeface) const
481 /** Compares two typefaces for equality.
483 @param aTypeface The typeface to be compared with.
484 @return ETrue, if this TTypeface is equal to aTypeface, otherwise EFalse. */
487 iFlags == aTypeface.iFlags &&
488 iName == aTypeface.iName;
491 EXPORT_C void TTypeface::SetAttributes(TInt aAttributes)
492 /** Set the combination of attributes for this typeface.
494 @param aAttributes A bitmap defining the combination of attributes. */
497 iFlags |= KTTypefaceMaskAttrib & aAttributes & (EProportional | ESerif | ESymbol);
501 EXPORT_C void TTypeface::SetIsProportional(TBool aIsProportional)
502 /** Sets the typeface's proportional attribute.
504 @param aIsProportional ETrue if the typeface is a proportional typeface, otherwise
509 iFlags |= EProportional;
513 iFlags &= ~EProportional;
518 EXPORT_C void TTypeface::SetIsSerif(TBool aIsSerif)
519 /** Sets the typeface's serif attribute.
521 @param aIsSerif ETrue if the typeface is a serif typeface, otherwise EFalse. */
534 EXPORT_C void TTypeface::SetIsSymbol(TBool aIsSymbol)
535 /** Sets the typeface's symbol attribute.
537 @param aIsSymbol ETrue if the typeface is a symbol typeface, otherwise EFalse. */
550 EXPORT_C TInt TTypeface::Attributes() const
551 /** Gets the combination of attributes of the typeface.
553 @return The combination of attributes of the typeface. */
555 return KTTypefaceMaskAttrib & iFlags;
559 EXPORT_C TBool TTypeface::IsProportional() const
560 /** Gets the typeface's proportional attribute.
562 @return ETrue if the typeface is proportional, EFalse otherwise. */
564 return KTTypefaceMaskAttrib & iFlags & EProportional;
568 EXPORT_C TBool TTypeface::IsSerif() const
569 /** Gets the typeface's serif attribute.
571 @return ETrue if the typeface is a serif typeface, EFalse otherwise */
573 return KTTypefaceMaskAttrib & iFlags & ESerif;
577 EXPORT_C TBool TTypeface::IsSymbol() const
578 /** Gets the typeface's symbol attribute.
580 @return ETrue if the typeface is a symbol typeface, EFalse otherwise */
582 return KTTypefaceMaskAttrib & iFlags & ESymbol;
586 /** Specifies the script with which font metrics calculation will be based on.
587 @param aLanguage The language used to derive the required script.
590 EXPORT_C void TTypeface::SetScriptTypeForMetrics(TLanguage aLanguage)
592 SetScriptTypeForMetrics(GlyphSample::TLanguage2TScript(aLanguage));
595 /** Specifies the script with which font metrics calculation will be based on.
596 @param aScript The script.
599 EXPORT_C void TTypeface::SetScriptTypeForMetrics(TInt aScript)
602 iFlags |= KTTypefaceMaskScript & (aScript << KTTypefaceBitsNumAttrib);
605 /** Gets the script with which font metrics calculation will be based on.
609 EXPORT_C TInt TTypeface::ScriptTypeForMetrics() const
611 return (KTTypefaceMaskScript & iFlags) >> KTTypefaceBitsNumAttrib;
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
622 EXPORT_C void TTypeface::SetName(const TDesC& aName)
624 TEXTBASE_ASSERT_ALWAYS(aName.Length() <= KMaxTypefaceNameLength, ETextBasePanic_TypefaceNameOverflow);
629 Returns the name of the typeface.
630 @return The name of the typeface.
632 EXPORT_C const TDesC& TTypeface::Name() const
642 /** Default destructor. */
643 EXPORT_C CFont::~CFont()
646 _LIT(KGdiZeroCharacter,"0");
648 /** Gets the width of the zero character of this font in pixels.
650 This function is provided as the "0" character is roughly the average width
651 of the characters of any font.
653 @return The width of the "0" character, in pixels. */
654 EXPORT_C TInt CFont::WidthZeroInPixels() const
656 return(TextWidthInPixels(KGdiZeroCharacter));
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().
665 @return The font descent in pixels.
666 @see FontStandardDescent()
667 @see FontMaxDescent()
669 EXPORT_C TInt CFont::DoDescentInPixels() const
671 return HeightInPixels() - AscentInPixels();
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
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
684 LOCAL_C TBool BoundsExceeded(const CFont::TMeasureTextInput& aInput,
685 const TInt& aPenPos, TInt& aBoundsBR, TInt& aBoundsTL)
687 if (aInput.iFlags & CFont::TMeasureTextInput::EFIncludePenPositionInBoundsCheck)
689 if (aInput.iFlags & CFont::TMeasureTextInput::EFVisualOrderRightToLeft)
691 aBoundsTL = Min(aBoundsTL, aPenPos);
695 aBoundsBR = Max(aBoundsBR, aPenPos);
698 return (aBoundsBR - aBoundsTL > aInput.iMaxBounds);
702 /** Text measurement function.
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.
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.
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.
745 @panic GDI 1 In debug builds only, if TMeasureTextInput::iStartInputChar is negative.
747 EXPORT_C TInt CFont::MeasureText(const TDesC& aText,const TMeasureTextInput* aInput,TMeasureTextOutput* aOutput) const
749 TMeasureTextInput input;
754 Mem::FillZ(aOutput,sizeof(*aOutput));
755 aOutput->iChars = input.iStartInputChar;
757 TPositionParam param;
758 param.iDirection = input.iDirection;
760 TBool vertical = param.iDirection == EVertical;
761 TBool penMovesLeft = EFalse;
762 if (input.iFlags & TMeasureTextInput::EFVisualOrderRightToLeft)
765 penMovesLeft = ETrue;
766 param.iFlags |= TPositionParam::EFLogicalOrder;
768 else if (!(input.iFlags & TMeasureTextInput::EFVisualOrder))
769 param.iFlags |= TPositionParam::EFLogicalOrder;
772 param.iText.Set(aText);
777 param.iPosInText = input.iStartInputChar;
778 int end_char = Min(aText.Length(),input.iEndInputChar);
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)
786 if (!GetCharacterPosition2(param, shapeInfo))
789 aOutput->iChars = param.iPosInText;
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);
797 // Allow justification to occur at spaces
798 if (param.iOutput[0].iCode == 0x0020)
800 if (input.iWordJustExcess != 0)
801 new_advance += CGraphicsContext::JustificationInPixels(input.iWordJustExcess,input.iWordJustNum,spaces,1);
805 param.iPen.iY = new_advance;
807 param.iPen.iX = new_advance;
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;
823 if (aInput || aOutput)
825 const TPositionParam::TOutput* output = param.iOutput;
826 for (int i = 0; i < param.iOutputGlyphs; i++, output++)
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)
834 // increase iMaxGlyphSize if either dimension smaller than
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;
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;
855 // Would any limits be exceeded by adding this group?
856 if (param.iPosInText > end_char)
858 if (new_advance > input.iMaxAdvance)
862 if (BoundsExceeded(input, param.iPen.iY, bounds.iBr.iY, bounds.iTl.iY))
867 if (BoundsExceeded(input, param.iPen.iX, bounds.iBr.iX, bounds.iTl.iX))
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;
881 advance = new_advance;
883 if(shapeInfo.IsOpen())
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
892 TUint16 HighSurrogate(TUint aCode)
894 TEXTBASE_ASSERT_DEBUG(aCode > 0xFFFF, ETextBasePanic_InvalidInputParam);
895 return STATIC_CAST(TUint16, 0xD7C0 + (aCode >> 10));
898 TUint16 LowSurrogate(TUint aCode)
900 TEXTBASE_ASSERT_DEBUG(aCode > 0xFFFF, ETextBasePanic_InvalidInputParam);
901 return STATIC_CAST(TUint16, 0xDC00 | (aCode & 0x3FF));
904 TUint CombineSurrogates(TUint aHighSurrogate, TUint aLowSurrogate)
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;
913 /** Overridable function innards of GetCharacterPosition and
914 GetCharacterPosition2. It is generally not useful to override this function.
916 @see GetCharacterPosition
917 @see GetCharacterPosition2
919 EXPORT_C TBool CFont::DoGetCharacterPosition(TPositionParam& aParam) const
921 RShapeInfo shapeInfo;
922 TBool r = GetCharacterPosition2(aParam, shapeInfo);
923 if (shapeInfo.IsOpen())
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)
931 GlyphSelection::ProcessFunc processFunc = CharacterToProcessFunction(aGss.iCodeChar);
932 GlyphSelection::ProcessFunc contextProcessFunc = (GlyphSelection::ProcessFunc)aShapeInfo.GetContext();
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)
938 // If context is not set, check the previous char for context.
939 if (contextProcessFunc == NULL)
941 if (aGss.iParam.iPosInText > 0)
943 TChar prevCode = aGss.iText.Get(-1);
944 GlyphSelection::ProcessFunc prevProcessFunc = CharacterToProcessFunction(prevCode);
945 if (prevProcessFunc != NULL && (prevCode.IsAlpha() || prevProcessFunc != GlyphSelector_Default::Process))
947 aShapeInfo.SetContext((TAny *)prevProcessFunc);
948 return prevProcessFunc;
953 return contextProcessFunc;
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);
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.
970 The input/output parameter of the text/glyph data for the algorithm.
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.
977 ETrue if glyphs for supplied text have been produced, EFalse in failure.
978 @see CFont::TPositionParam
981 EXPORT_C TBool CFont::GetCharacterPosition2(TPositionParam& aParam, RShapeInfo& aShapeInfo) const
983 TEXTBASE_ASSERT_DEBUG(aParam.iPosInText>=0, ETextBasePanic_InvalidInputParam);
984 TEXTBASE_ASSERT_DEBUG(aParam.iText.Ptr(), ETextBasePanic_InvalidInputParam);
986 aParam.iOutputGlyphs = 0;
987 TInt textLen = aParam.iText.Length();
988 TBool outputOk = ETrue;
989 TPoint penCopy = aParam.iPen;
991 // Verify input parameters are sane
992 if (aParam.iPosInText >= textLen)
995 // Setup glyph selection algorithm data
996 TUtf32Iterator textIter(aParam.iText.Ptr(), aParam.iText.Ptr()+textLen, aParam.iPosInText);
997 if (textIter.AtEnd())
999 aParam.iPosInText = textIter.LengthToStart();
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);
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;
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);
1024 if (!firstProcessFn)
1025 firstProcessFn = processFn;
1029 if (firstProcessFn == processFn)
1030 outputOk = processFn(gss, aShapeInfo);
1036 // Table entry blank, unicode char to be skipped
1040 (!textIter.AtEnd() &&
1041 ((textIter.Get().GetCategory() & 0xF0)
1042 == TChar::EMarkGroup)) ?
1043 TGlyphSelectionState::EGClusterNotComplete : TGlyphSelectionState::EGClusterComplete;
1046 // Abort if no class was available to process the character or if
1047 // processing failed.
1050 aParam.iPosInText = textIter.LengthToStart();
1054 // Did the glyph selector that processed the character want the
1056 if (gss.iPen == TGlyphSelectionState::EPenAdvance_Yes)
1058 aParam.iPen.iX += gss.iAdvance.iWidth;
1059 aParam.iPen.iY += gss.iAdvance.iHeight;
1060 gss.iPen = TGlyphSelectionState::EPenAdvance_No;
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.
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
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)
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++)
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;
1093 decomposed = singleChar.Decompose(decomposition);
1095 { // Pick up the sequence of characters
1096 decomposeArray.Append(decomposition);
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));
1107 { // It's not a surrogate so we just need to cast it down (since it's safe)
1108 decomposeArray.Append(singleChar);
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
1118 TUint composedChar = 0;
1119 TOpenFontCharMetrics metrics;
1120 TPositionParam::TOutput output;
1121 TSize advance; // gets initialized to 0,0
1124 //Now try and compose the string to a single character
1125 success = TChar::Compose(composedChar, decomposeArray);
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)
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)
1146 metrics.GetVertBounds(output.iBounds);
1147 advance.iHeight = metrics.VertAdvance();
1151 metrics.GetHorizBounds(output.iBounds);
1152 advance.iWidth = metrics.HorizAdvance();
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;
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();
1178 /** Gets the character metrics for a character.
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
1186 EXPORT_C CFont::TCharacterDataAvailability CFont::DoGetCharacterData(TUint aCode,TOpenFontCharMetrics& aMetrics,
1187 const TUint8*& aBinaryData,TSize& aBitmapSize) const
1189 int width = CharWidthInPixels(aCode);
1190 aMetrics.SetHorizAdvance(width);
1192 // For speed set to 0 directly rather than call SetSize()
1193 aBitmapSize.iWidth = 0;
1194 aBitmapSize.iHeight = 0;
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.
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);
1210 return CFont::ECharacterWidthOnly;
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
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)
1226 return GlyphSelector_Arabic::CharactersJoin(aLeftCharacter, aRightCharacter);
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,
1237 @return Integer return value from extension function
1241 EXPORT_C TInt CFont::DoExtendedFunction(TUid aFunctionId, TAny* /* aParam */) const
1243 if (KFontCapitalAscent == aFunctionId ||
1244 KFontMaxAscent == aFunctionId)
1246 return AscentInPixels();
1248 else if (KFontStandardDescent == aFunctionId ||
1249 KFontMaxDescent == aFunctionId)
1251 return DescentInPixels();
1253 else if (KFontLineGap == aFunctionId)
1254 { // 1.2 of em height (rounded) is reasonable approximation of interline gap
1255 return (HeightInPixels() * 12 + 5) / 10;
1257 return KErrNotFound;
1260 EXPORT_C TUid CFont::TypeUid() const
1265 EXPORT_C TInt CFont::HeightInPixels() const
1267 return DoHeightInPixels();
1270 EXPORT_C TInt CFont::AscentInPixels() const
1272 return DoAscentInPixels();
1275 EXPORT_C TInt CFont::DescentInPixels() const
1277 return DoDescentInPixels();
1280 EXPORT_C TInt CFont::CharWidthInPixels(TChar aChar) const
1282 return DoCharWidthInPixels(aChar);
1285 EXPORT_C TInt CFont::TextWidthInPixels(const TDesC& aText) const
1287 return DoTextWidthInPixels(aText);
1290 EXPORT_C TInt CFont::BaselineOffsetInPixels() const
1292 return DoBaselineOffsetInPixels();
1295 EXPORT_C TInt CFont::TextCount(const TDesC& aText,TInt aWidthInPixels) const
1297 return DoTextCount(aText, aWidthInPixels);
1300 EXPORT_C TInt CFont::TextCount(const TDesC& aText, TInt aWidthInPixels, TInt& aExcessWidthInPixels) const
1302 return DoTextCount(aText, aWidthInPixels, aExcessWidthInPixels);
1305 EXPORT_C TInt CFont::MaxCharWidthInPixels() const
1307 return DoMaxCharWidthInPixels();
1310 EXPORT_C TInt CFont::MaxNormalCharWidthInPixels() const
1312 return DoMaxNormalCharWidthInPixels();
1315 EXPORT_C TFontSpec CFont::FontSpecInTwips() const
1317 return DoFontSpecInTwips();
1320 /** Gets the character metrics for a character.
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
1328 EXPORT_C CFont::TCharacterDataAvailability CFont::GetCharacterData(TUint aCode, TOpenFontCharMetrics& aMetrics, const TUint8*& aBitmap, TSize& aBitmapSize) const
1330 return DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
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
1342 EXPORT_C TBool CFont::GetCharacterPosition(TPositionParam& aParam) const
1344 return DoGetCharacterPosition(aParam);
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,
1355 @return Integer return value from extension function
1357 EXPORT_C TInt CFont::ExtendedFunction(TUid aFunctionId, TAny* aParam) const
1359 return DoExtendedFunction(aFunctionId, aParam);
1362 EXPORT_C TInt CFont::TextWidthInPixels(const TDesC& aText,const TMeasureTextInput* aParam) const
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);
1373 Maps TLanguage to TScript.
1375 EScriptOther represents languages not yet supported in KTScript2GlyphSample.
1376 This array does not handle ELangNone and ELangMaximum to save storage space.
1378 const TInt GlyphSample::KTLanguage2TScript[] =
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
1482 Maps TScript to glyph samples.
1484 The order of samples definition has to follow the script order in TScript.
1486 Supported scripts Fonts used to experiment/determine glyph samples
1488 Latin Arial, Times, Century
1491 Hebrew Aharoni, David, FrankRuehl, Levenim MT, Miriam, Narkisim, Rod
1492 Arabic Andalus, Arabic Transparent, Simplified Arabic, Traditional Arabic
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
1500 const TText* const GlyphSample::KTScript2GlyphSample[] =
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)
1511 _S("\x00C0\x013A\x1EA2\x00C7\x0163"),
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
1521 _S("\x03AA\x03AB\x03AE\x03B2\x03C8"),
1523 // 04 EScriptCyrillic
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
1531 _S("\x0403\x0419\x0440\x0452\x0458"),
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
1541 _S("\x05BE\x05DC\x05B0\x05BD\x05E7"),
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
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.
1555 _S("\x0670\x0671\x064D\xFB7B\xFBF2"),
1557 // 07 EScriptDevanagari
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
1565 _S("\x0914\x0951\x0941\x0944\x0963"),
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
1575 _S("\x0E49\x0E4B\x0E0E\x0E24\x0E39"),
1577 // 09 EScriptHanIdeographs
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
1585 _S("\x1100\x4E1C\x5283\x758A\x7BEA"),
1589 Maps a TLanguage type to the TScript type.
1591 @param aLanguage The language.
1592 @return A TInt representing the script, or
1593 EScriptNone if its not defined for aLanguage.
1595 EXPORT_C TInt GlyphSample::TLanguage2TScript(TLanguage aLanguage)
1597 if (ELangNone == aLanguage || ELangMaximum == aLanguage || aLanguage >= (sizeof(KTLanguage2TScript)/sizeof(KTLanguage2TScript[0])))
1601 return KTLanguage2TScript[aLanguage];
1605 Maps a TScript type to some glyph samples which are stored as Unicode.
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.
1611 EXPORT_C const TPtrC GlyphSample::TScript2GlyphSample(TInt aScript)
1613 if (EScriptOther >= aScript)
1617 // -3 to offset EScriptDefault, EScriptNone and EScriptOther
1618 // being the first three elements in TScript.
1619 return TPtrC(KTScript2GlyphSample[aScript - 3]);
1623 EXPORT_C RFontTable::RFontTable():iTableContent(0), iLength(0),
1624 iFont(NULL), iTag(0)
1626 // a null constructor.
1630 RFontTable::Open(CFont& aFont, TUint32 aTag)
1632 TGetFontTableParam param;
1635 // remember the parameters, to be used when releasing the font table.
1639 TInt ret = aFont.ExtendedFunction(KFontGetFontTable, (TAny *)¶m);
1640 if (KErrNone == ret)
1642 iTableContent = (TAny *)param.iContent;
1643 iLength = param.iLength;
1649 RFontTable::TableLength() const
1654 EXPORT_C const TUint8*
1655 RFontTable::TableContent() const
1657 return (TUint8*)iTableContent;
1665 (void)iFont->ExtendedFunction(KFontReleaseFontTable, (TAny *)&iTag);
1674 RGlyphOutlineIterator::RGlyphOutlineIterator():iOutlines(0), iLengths(0),
1675 iCursor(-1), iCount(0), iFont(NULL), iCodes(NULL), iHinted(EFalse)
1677 // a null constructor.
1681 RGlyphOutlineIterator::Open(CFont& aFont, const TUint* aCodes, TInt aCount, TBool aHinted)
1683 if (NULL == aCodes || 0 == aCount)
1685 return KErrArgument;
1687 TGetGlyphOutlineParam param;
1688 iLengths = (TInt *)User::Alloc(sizeof(TInt) * aCount);
1689 if (NULL == iLengths)
1691 return KErrNoMemory;
1693 iOutlines = (TAny **)User::Alloc(sizeof(TAny *) * aCount);
1694 if (NULL == iOutlines)
1696 User::Free(iLengths);
1698 return KErrNoMemory;
1701 param.iLengths = iLengths;
1702 param.iCount = aCount;
1703 param.iCodes = aCodes;
1704 param.iHinted = aHinted;
1705 param.iOutlines = iOutlines;
1707 /* information needed in Close() */
1708 iCodes = (TUint *)User::Alloc(sizeof(TUint) * aCount);
1711 User::Free(iLengths);
1712 User::Free(iOutlines);
1715 return KErrNoMemory;
1717 Mem::Copy(iCodes, aCodes, aCount*sizeof(TUint));
1722 TInt ret = aFont.ExtendedFunction(KFontGetGlyphOutline, (TAny *)¶m);
1723 if (KErrNone != ret)
1725 User::Free(iLengths);
1726 User::Free(iOutlines);
1741 EXPORT_C const TUint8*
1742 RGlyphOutlineIterator::Outline() const
1744 TEXTBASE_ASSERT_ALWAYS(iCursor >= 0, ETextBasePanic_Unknown);
1746 if (iLengths[iCursor] < 0)
1752 return (const TUint8*)iOutlines[iCursor];
1757 RGlyphOutlineIterator::OutlineLength() const
1759 TEXTBASE_ASSERT_ALWAYS(iCursor >= 0, ETextBasePanic_Unknown);
1761 if (iLengths[iCursor] < 0)
1767 return iLengths[iCursor];
1772 RGlyphOutlineIterator::Next()
1774 if (iCursor >= 0 && iCursor < iCount-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.
1786 return KErrNotFound;
1791 RGlyphOutlineIterator::Close()
1793 TReleaseGlyphOutlineParam param;
1794 param.iCount = iCount;
1795 param.iHinted = iHinted;
1796 param.iCodes = iCodes;
1800 iFont->ExtendedFunction(KFontReleaseGlyphOutline, (TAny *)¶m);
1805 User::Free(iLengths);
1810 User::Free(iOutlines);