First public contribution.
1 // Copyright (c) 1998-2010 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
20 #include "FontArabic.h"
21 #include "FontIndic.h"
23 #include "glyphsample.h"
24 #include "gdiinline.inl"
25 #include "gdistructs.h"
26 #include "gdiconsts.h"
27 #include "gdiplatapi.h"
30 Names holds the types & data associated with the glyph selection
31 algorithm in CFont::GetCharacterPosition().
34 namespace GlyphSelection
37 typedef TBool (*ProcessFunc)(TGlyphSelectionState& aGss, RShapeInfo&);
40 This structure defines the fields present in each row of the GlyphTable
48 ProcessFunc iProcessFunc;
52 This table encodes the Unicode character ranges and the glyph selector
53 classes to be used for each character range when processing characters
54 into glyph clusters in CFont::GetCharacterPosition().
55 New glyph selection classes must make sure they are listed in this
56 table to ensure they are invoked as required.
57 A '0' iProcessFunc entry tells the algorithm to skip the character.
60 static const TTableEntry Table[] =
62 // iLow, iHigh, iProcessFunc
63 { 0x0000, 0x00AC, GlyphSelector_Default::Process},
64 { 0x00AD, 0x00AD, GlyphSelector_SoftHyphen::Process},
65 { 0x00AE, 0x05FF, GlyphSelector_Default::Process},
66 { 0x0600, 0x06FF, GlyphSelector_Arabic::Process},
67 { 0x0700, 0x08FF, GlyphSelector_Default::Process},
68 { 0x0900, 0x0970, GlyphSelector_Devanagari::Process},
69 { 0x0980, 0x09FF, GlyphSelector_Bengali::Process},
70 { 0x0A00, 0x0A7F, GlyphSelector_Gurmukhi::Process},
71 { 0x0A80, 0x0AFF, GlyphSelector_Gujarati::Process},
72 { 0x0B80, 0x0BFF, GlyphSelector_Tamil::Process},
73 { 0x0C00, 0x0C7F, GlyphSelector_Telugu::Process},
74 { 0x0C80, 0x0CFF, GlyphSelector_Kannada::Process},
75 { 0x0D00, 0x0D7F, GlyphSelector_Malayalam::Process},
76 { 0x0D80, 0x0DFF, GlyphSelector_Default::Process},
77 { 0x0E00, 0x0E32, GlyphSelector_Thai::Process},
78 { 0x0E33, 0x0E33, GlyphSelector_ThaiSaraAm::Process},
79 { 0x0E34, 0x0E7F, GlyphSelector_Thai::Process},
80 { 0x0E80, 0x200B, GlyphSelector_Default::Process},
82 { 0x2010, 0x2029, GlyphSelector_Default::Process},
84 { 0x202F, 0xFFFD, GlyphSelector_Default::Process},
86 { 0x10000, 0x10FFFF, GlyphSelector_Default::Process},
87 {0xFFFFFFFF,0xFFFFFFFF, 0}
91 /** Find appropriate processor function for the given character.
92 @param aChar Character for processing.
93 @return processor function or 0 if the character is to be skipped.
95 GlyphSelection::ProcessFunc CharacterToProcessFunction(TInt aChar)
97 for (const GlyphSelection::TTableEntry* glyphSel = GlyphSelection::Table;
98 glyphSel->iLow != 0xFFFFFFFF; glyphSel++)
100 if ((glyphSel->iLow <= aChar) && (aChar <= glyphSel->iHigh))
101 return glyphSel->iProcessFunc;
107 @internalTechnology For use by TFontStyle/TOpenFontSpec.
109 EXPORT_C TBool FontEffect::IsEffectOn(TEffect aEffect, TUint32 aFontEffect)
111 return aEffect & aFontEffect;
115 @internalTechnology For use by TFontStyle/TOpenFontSpec.
117 EXPORT_C void FontEffect::SetEffect(TEffect aEffect, TBool aOn, TUint32& aFontEffect)
120 aFontEffect |= aEffect;
122 aFontEffect &= ~aEffect;
130 /** Default C++ constructor. */
131 EXPORT_C TFontStyle::TFontStyle():
132 iFlags(0), iReserved1(0), iReserved2(0)
136 /** Constructs a TFontStyle object with the specified attributes.
137 @param aPost The posture attribute.
138 @param aStrWgt The stroke weight attribute.
139 @param aPrintPos The print position attribute. */
140 EXPORT_C TFontStyle::TFontStyle(TFontPosture aPostr,TFontStrokeWeight aWgt,TFontPrintPosition aPos):
141 iFlags(0), iReserved1(0), iReserved2(0)
143 if (aPostr == EPostureItalic)
147 if (aWgt == EStrokeWeightBold)
151 if (aPos == EPrintPosSuperscript)
155 else if (aPos == EPrintPosSubscript)
162 EXPORT_C void TFontStyle::InternalizeL(RReadStream& aStream)
163 /** Internalises a font style from a read stream.
165 The presence of this function means that the standard templated operator>>()
166 (defined in s32strm.h) is available to internalise objects of this class.
168 @param aStream The stream from which the font style is to be internalised
169 @leave KErrNoMemory If there is a problem reading from the stream.
170 If internalisation causes an out of memory error. */
172 iFlags = aStream.ReadUint32L();
176 EXPORT_C void TFontStyle::ExternalizeL(RWriteStream& aStream) const
177 /** Externalises the font style to a write stream.
179 The presence of this function means that the standard templated operator<<()
180 (defined in s32strm.h) is available to externalise objects of this class.
182 @param aStream The stream to which the font style is to be externalised.
183 @leave KErrNoMemory This function may leave, if the write action causes the
184 stream's resources to be exhausted. */
186 aStream.WriteUint32L(iFlags);
190 EXPORT_C TFontPosture TFontStyle::Posture() const
191 /** Gets the posture attribute.
193 @return The font style's posture. */
195 if(iFlags&EItalic) return(EPostureItalic);
196 return(EPostureUpright);
200 EXPORT_C TFontStrokeWeight TFontStyle::StrokeWeight() const
201 /** Gets the stroke weight attribute.
203 @return The font style's stroke weight. */
205 if(iFlags&EBold) return(EStrokeWeightBold);
206 return(EStrokeWeightNormal);
210 EXPORT_C TFontPrintPosition TFontStyle::PrintPosition() const
211 /** Gets the print position attribute.
213 @return The font style's print position. */
215 if((iFlags&ESuper) && !(iFlags&ESub)) return(EPrintPosSuperscript);
216 else if((iFlags&ESub) && !(iFlags&ESuper)) return(EPrintPosSubscript);
217 return(EPrintPosNormal);
221 EXPORT_C void TFontStyle::SetPosture(TFontPosture aPosture)
222 /** Sets the posture attribute.
224 @param aPosture The posture to be set. */
226 if(aPosture==EPostureItalic) iFlags|=EItalic;
227 else iFlags&=~EItalic;
231 EXPORT_C void TFontStyle::SetStrokeWeight(TFontStrokeWeight aStrokeWeight)
232 /** Sets the stroke weight attribute.
234 @param aStrokeWeight The stroke weight to be set. */
236 if(aStrokeWeight==EStrokeWeightBold) iFlags|=EBold;
241 EXPORT_C void TFontStyle::SetPrintPosition(TFontPrintPosition aPrintPosition)
242 /** Sets the print position attribute.
244 @param aPrintPosition The print position to be set. */
246 switch(aPrintPosition)
248 case EPrintPosSuperscript:
254 case EPrintPosSubscript:
268 /** Gets the font effects flags.
271 @return The font effects flags.
272 @see TFontStyle::SetEffects()
274 EXPORT_C TUint32 TFontStyle::Effects() const
276 return 0xFFF0 & iFlags;
279 /** Checks if a font effect is on.
282 @return True represents the specified font effect is on, otherwise off.
283 @param aEffect The font effect to be checked.
284 @see TFontStyle::SetEffects()
286 EXPORT_C TBool TFontStyle::IsEffectOn(FontEffect::TEffect aEffect) const
288 return FontEffect::IsEffectOn(aEffect, iFlags);
291 /** Sets the font effects flags.
294 @param aEffect The font effects flags to be set.
295 @see TFontStyle::Effects()
297 EXPORT_C void TFontStyle::SetEffects(TUint32 aEffects)
299 iFlags &= 0xFFFF000F;
300 iFlags |= 0xFFF0 & aEffects;
303 /** Sets a font effect to the given state.
306 @param aEffect The font effect to be set.
307 @param aOn True represents on, otherwise off.
308 @see TFontStyle::IsEffectOn()
310 EXPORT_C void TFontStyle::SetEffects(FontEffect::TEffect aEffect, TBool aOn)
312 FontEffect::SetEffect(aEffect, aOn, iFlags);
315 /** Compares a font style for equality.
318 @param aFontStyle The font style to be compared with this font style.
319 @return ETrue, if this TFontStyle is equal to aFontStyle, EFalse, otherwise.
321 EXPORT_C TBool TFontStyle::operator==(const TFontStyle& aFontStyle) const
323 return iFlags == aFontStyle.iFlags;
329 EXPORT_C TFontSpec::TFontSpec():
333 /** Default constructor.
335 The object's font style is set to the default: EPostureUpright, EStrokeWeightNormal,
336 and EPrintPosNormal. */
340 EXPORT_C TFontSpec::TFontSpec(const TDesC& aTypefaceName,TInt aHeight):
343 iFontStyle(EPostureUpright,EStrokeWeightNormal,EPrintPosNormal)
344 /** Constructs a TFontSpec object with the specified typeface and height.
346 The object's font style is set to the default: EPostureUpright, EStrokeWeightNormal,
349 @param aTypefaceName The name of the typeface (e.g. "Roman"). It should be no
350 longer than KMaxTypefaceNameLength characters in length.
351 @param aHeight The height of the typeface, in twips.
352 @panic GDI 6, if aTypefaceName is more than KMaxTypefaceNameLength characters long.
355 iTypeface.SetName(aTypefaceName);
359 EXPORT_C TBool TFontSpec::operator==(const TFontSpec& aFontSpec) const
360 /** Compares this font specification with another.
361 @param aFontSpec The font specification to be compared with this one.
362 @return ETrue, if the TFontSpecs are identical, EFalse otherwise.
366 iHeight == aFontSpec.iHeight &&
367 iFontStyle == aFontSpec.iFontStyle &&
368 iTypeface == aFontSpec.iTypeface;
372 EXPORT_C void TFontSpec::InternalizeL(RReadStream& aStream)
373 /** Internalises a font specification from a read stream.
375 The presence of this function means that the standard templated operator>>()
376 (defined in s32strm.h) is available to internalise objects of this class.
378 @param aStream The stream from which the font specification is to be internalised.
379 @leave KErrNoMemory If internalisation causes an out of memory error. */
381 iTypeface.InternalizeL(aStream);
382 iHeight=aStream.ReadUint16L();
383 iFontStyle.InternalizeL(aStream);
387 EXPORT_C void TFontSpec::ExternalizeL(RWriteStream& aStream) const
388 /** Externalises the font specification to a write stream.
390 The presence of this function means that the standard templated operator<<()
391 (defined in s32strm.h) is available to externalise objects of this class.
393 @param aStream The stream to which the font specification is to be externalised
395 @leave KErrNoMemory If the write action causes the stream's resources to be
398 iTypeface.ExternalizeL(aStream);
399 aStream.WriteUint16L(iHeight);
400 iFontStyle.ExternalizeL(aStream);
403 EXPORT_C void TFontSpec::SetScriptTypeForMetrics(TLanguage aLanguage)
404 /** Specifies the script with which font metrics calculation will be based on.
405 @param aLanguage The language used to derive the required script.
410 iTypeface.SetScriptTypeForMetrics(aLanguage);
413 EXPORT_C TInt TFontSpec::ScriptTypeForMetrics() const
414 /** Returns the script with which font metrics calculation will be based on.
418 return iTypeface.ScriptTypeForMetrics();
424 static const TInt KTTypefaceBitsNumAttrib = 3;
425 static const TInt KTTypefaceBitsNumScript = 4;
426 static const TInt KTTypefaceMaskAttrib = (1 << KTTypefaceBitsNumAttrib) - 1;
427 static const TInt KTTypefaceMaskScript = ((1 << KTTypefaceBitsNumScript) - 1) << KTTypefaceBitsNumAttrib;
428 EXPORT_C TTypeface::TTypeface():
431 /** Default C++ constructor. */
437 void TTypeface::ResetAttributes()
439 iFlags &= KTTypefaceMaskScript;
445 void TTypeface::ResetScriptType()
447 iFlags &= KTTypefaceMaskAttrib;
450 EXPORT_C void TTypeface::InternalizeL(RReadStream& aStream)
451 /** Internalises a typeface from a read stream.
453 The presence of this function means that the standard templated operator>>()
454 (defined in s32strm.h) is available to internalise objects of this class.
456 @param aStream Stream from which the typeface is to be internalised. */
458 TBuf<KMaxTypefaceNameLength> tempname;
460 new(&iName) TBufC<KMaxTypefaceNameLength>(tempname);
461 iFlags = aStream.ReadInt8L();
465 EXPORT_C void TTypeface::ExternalizeL(RWriteStream& aStream) const
466 /** Externalises a typeface to a write stream.
468 The presence of this function means that the standard templated operator<<()
469 (defined in s32strm.h) is available to externalise objects of this class.
471 @param aStream The stream to which the typeface is to be externalised. */
474 aStream.WriteInt8L(static_cast<TInt8>(iFlags));
478 EXPORT_C TBool TTypeface::operator==(const TTypeface& aTypeface) const
479 /** Compares two typefaces for equality.
481 @param aTypeface The typeface to be compared with.
482 @return ETrue, if this TTypeface is equal to aTypeface, otherwise EFalse. */
485 iFlags == aTypeface.iFlags &&
486 iName == aTypeface.iName;
489 EXPORT_C void TTypeface::SetAttributes(TInt aAttributes)
490 /** Set the combination of attributes for this typeface.
492 @param aAttributes A bitmap defining the combination of attributes. */
495 iFlags |= KTTypefaceMaskAttrib & aAttributes & (EProportional | ESerif | ESymbol);
499 EXPORT_C void TTypeface::SetIsProportional(TBool aIsProportional)
500 /** Sets the typeface's proportional attribute.
502 @param aIsProportional ETrue if the typeface is a proportional typeface, otherwise
507 iFlags |= EProportional;
511 iFlags &= ~EProportional;
516 EXPORT_C void TTypeface::SetIsSerif(TBool aIsSerif)
517 /** Sets the typeface's serif attribute.
519 @param aIsSerif ETrue if the typeface is a serif typeface, otherwise EFalse. */
532 EXPORT_C void TTypeface::SetIsSymbol(TBool aIsSymbol)
533 /** Sets the typeface's symbol attribute.
535 @param aIsSymbol ETrue if the typeface is a symbol typeface, otherwise EFalse. */
548 EXPORT_C TInt TTypeface::Attributes() const
549 /** Gets the combination of attributes of the typeface.
551 @return The combination of attributes of the typeface. */
553 return KTTypefaceMaskAttrib & iFlags;
557 EXPORT_C TBool TTypeface::IsProportional() const
558 /** Gets the typeface's proportional attribute.
560 @return ETrue if the typeface is proportional, EFalse otherwise. */
562 return KTTypefaceMaskAttrib & iFlags & EProportional;
566 EXPORT_C TBool TTypeface::IsSerif() const
567 /** Gets the typeface's serif attribute.
569 @return ETrue if the typeface is a serif typeface, EFalse otherwise */
571 return KTTypefaceMaskAttrib & iFlags & ESerif;
575 EXPORT_C TBool TTypeface::IsSymbol() const
576 /** Gets the typeface's symbol attribute.
578 @return ETrue if the typeface is a symbol typeface, EFalse otherwise */
580 return KTTypefaceMaskAttrib & iFlags & ESymbol;
584 /** Specifies the script with which font metrics calculation will be based on.
585 @param aLanguage The language used to derive the required script.
588 EXPORT_C void TTypeface::SetScriptTypeForMetrics(TLanguage aLanguage)
590 SetScriptTypeForMetrics(GlyphSample::TLanguage2TScript(aLanguage));
593 /** Specifies the script with which font metrics calculation will be based on.
594 @param aScript The script.
597 EXPORT_C void TTypeface::SetScriptTypeForMetrics(TInt aScript)
600 iFlags |= KTTypefaceMaskScript & (aScript << KTTypefaceBitsNumAttrib);
603 /** Gets the script with which font metrics calculation will be based on.
607 EXPORT_C TInt TTypeface::ScriptTypeForMetrics() const
609 return (KTTypefaceMaskScript & iFlags) >> KTTypefaceBitsNumAttrib;
613 Sets the name of the typeface. This method should be used rather than
614 directly accessing the iName public member.
615 @param aName The name of the typeface (e.g. "Roman"). It should be no
616 longer than KMaxTypefaceNameLength characters in length.
617 @panic GDI 6, if aName is more than KMaxTypefaceNameLength characters
620 EXPORT_C void TTypeface::SetName(const TDesC& aName)
622 GDI_ASSERT_ALWAYS(aName.Length() <= KMaxTypefaceNameLength, EGdiPanic_TypefaceNameOverflow);
627 Returns the name of the typeface.
628 @return The name of the typeface.
630 EXPORT_C const TDesC& TTypeface::Name() const
640 /** Default destructor. */
641 EXPORT_C CFont::~CFont()
644 _LIT(KGdiZeroCharacter,"0");
646 /** Gets the width of the zero character of this font in pixels.
648 This function is provided as the "0" character is roughly the average width
649 of the characters of any font.
651 @return The width of the "0" character, in pixels. */
652 EXPORT_C TInt CFont::WidthZeroInPixels() const
654 return(TextWidthInPixels(KGdiZeroCharacter));
658 /** Gets the font descent in pixels.
659 It is defined to be HeightInPixels() minus AscentInPixels().
660 Note that this deprecated function is replaced by the new @c FontMaxDescent()
661 or in some cases @c FontStandardDescent().
663 @return The font descent in pixels.
664 @see FontStandardDescent()
665 @see FontMaxDescent()
667 EXPORT_C TInt CFont::DoDescentInPixels() const
669 return HeightInPixels() - AscentInPixels();
673 /** Checks to see if the pen position needs to be included in the bounds
674 calculation for purposes of considering side-bearings in the line break point
676 @param aInput The input block. Contains the check flag and maxbounds.
677 @param aPenPos The current value of the pen position.
678 @param aBoundsBR Bottom-right bounds value.
679 @param aBoundsTL Top-left bounds value.
680 @return Whether or not MaxBounds has been exceeded
682 LOCAL_C TBool BoundsExceeded(const CFont::TMeasureTextInput& aInput,
683 const TInt& aPenPos, TInt& aBoundsBR, TInt& aBoundsTL)
685 if (aInput.iFlags & CFont::TMeasureTextInput::EFIncludePenPositionInBoundsCheck)
687 if (aInput.iFlags & CFont::TMeasureTextInput::EFVisualOrderRightToLeft)
689 aBoundsTL = Min(aBoundsTL, aPenPos);
693 aBoundsBR = Max(aBoundsBR, aPenPos);
696 return (aBoundsBR - aBoundsTL > aInput.iMaxBounds);
700 /** Text measurement function.
702 This is a powerful text measurement function underlying all the
703 other text measurement functions. It takes optional input and output
704 parameter blocks, which may be null, and returns the advance
705 width (change in pen position when drawn horizontally) of the text, or the advance
706 height, if the text is drawn vertically.
708 Some of the functions that can be performed using this
709 function are listed below. Many of them are used by the Text Views
710 API to do its typographic layout.
711 - Get the advance width or advance height (return value).
712 The advance width is the amount by which the pen advances when drawing
713 the text horizontally, while the advance height is the amount by which
714 the pen advances when drawing the text vertically.
715 - Measure some text in context, so that shaping behaviour
716 (e.g. in Arabic) can be affected by what comes before and after the
717 text. Do this using TMeasureTextInput::iStartInputChar and
718 TMeasureTextInput::iEndInputChar to tell the function where to start and end
719 in the supplied descriptor.
720 - Determine how much text fits a given size by setting
721 TMeasureTextInput::iMaxAdvance or TMeasureTextInput::iMaxBounds.
722 - Specify letter spacing and word spacing using TMeasureTextInput::iCharJustNum,
723 TMeasureTextInput::iCharJustExcess,
724 TMeasureTextInput::iWordJustNum and
725 TMeasureTextInput::iWordJustExcess.
726 - Get the number of characters drawn in TMeasureTextOutput::iChars
727 when applying the various constraints in TMeasureTextInput.
728 - Get the number of glyphs drawn in TMeasureTextOutput::iGlyphs.
729 - Get the number of groups (formed by ligation or diacritic placement) in
730 TMeasureTextOutput::iGroups. Groups are units of cursor
731 movement: the cursor hops over a character-plus-accent group or an
732 Arabic or other ligature in one go.
733 - Get the number of word spaces in TMeasureTextOutput::iSpaces.
734 - Get the bounds of the inked-in pixels in TMeasureTextOutput::iBounds.
735 - Get the size of the biggest glyph that would be drawn in TMeasureTextOutput::iMaxGlyphSize.
737 @param aText The text to be measured.
738 @param aInput The input block. This may be NULL.
739 @param aOutput The output block. This may be NULL.
740 @return The advance width if the text is drawn horizontally or the advance
741 height if the text is drawn vertically.
743 @panic GDI 1 In debug builds only, if TMeasureTextInput::iStartInputChar is negative.
745 EXPORT_C TInt CFont::MeasureText(const TDesC& aText,const TMeasureTextInput* aInput,TMeasureTextOutput* aOutput) const
747 TMeasureTextInput input;
752 Mem::FillZ(aOutput,sizeof(*aOutput));
753 aOutput->iChars = input.iStartInputChar;
755 TPositionParam param;
756 param.iDirection = input.iDirection;
758 TBool vertical = param.iDirection == EVertical;
759 TBool penMovesLeft = EFalse;
760 if (input.iFlags & TMeasureTextInput::EFVisualOrderRightToLeft)
763 penMovesLeft = ETrue;
764 param.iFlags |= TPositionParam::EFLogicalOrder;
766 else if (!(input.iFlags & TMeasureTextInput::EFVisualOrder))
767 param.iFlags |= TPositionParam::EFLogicalOrder;
770 param.iText.Set(aText);
775 param.iPosInText = input.iStartInputChar;
776 int end_char = Min(aText.Length(),input.iEndInputChar);
778 // Total advance if pen is moving left. Positive.
779 TInt rightToLeftAdvance = 0;
780 // Shaping information of the text
781 RShapeInfo shapeInfo;
782 while (param.iPosInText < end_char)
784 if (!GetCharacterPosition2(param, shapeInfo))
787 aOutput->iChars = param.iPosInText;
791 int new_advance = vertical ? param.iPen.iY : param.iPen.iX;
792 if (input.iCharJustExcess != 0)
793 new_advance += CGraphicsContext::JustificationInPixels(input.iCharJustExcess,input.iCharJustNum,groups,1);
795 // Allow justification to occur at spaces
796 if (param.iOutput[0].iCode == 0x0020)
798 if (input.iWordJustExcess != 0)
799 new_advance += CGraphicsContext::JustificationInPixels(input.iWordJustExcess,input.iWordJustNum,spaces,1);
803 param.iPen.iY = new_advance;
805 param.iPen.iX = new_advance;
809 // If the pen is moving left, we will begin each cluster at (0,0)
810 // and shift the bounds to the right to compensate.
811 bounds.iTl.iX += param.iPen.iX;
812 bounds.iBr.iX += param.iPen.iX;
813 bounds.iTl.iY += param.iPen.iY;
814 bounds.iBr.iY += param.iPen.iY;
815 rightToLeftAdvance += param.iPen.iX;
816 new_advance = rightToLeftAdvance;
821 if (aInput || aOutput)
823 const TPositionParam::TOutput* output = param.iOutput;
824 for (int i = 0; i < param.iOutputGlyphs; i++, output++)
826 //if (!output->iBounds.IsEmpty()) -- optimized to:
827 if (output->iBounds.iTl.iX != output->iBounds.iBr.iX
828 || output->iBounds.iTl.iY != output->iBounds.iBr.iY)
832 // increase iMaxGlyphSize if either dimension smaller than
834 TInt boundsDim = output->iBounds.iBr.iX - output->iBounds.iTl.iX;
835 aOutput->iMaxGlyphSize.iWidth = aOutput->iMaxGlyphSize.iWidth < boundsDim?
836 boundsDim : aOutput->iMaxGlyphSize.iWidth;
837 boundsDim = output->iBounds.iBr.iY - output->iBounds.iTl.iY;
838 aOutput->iMaxGlyphSize.iHeight = aOutput->iMaxGlyphSize.iHeight < boundsDim?
839 boundsDim : aOutput->iMaxGlyphSize.iHeight;
841 //bounds.BoundingRect(output->iBounds); -- optimized to:
842 if (output->iBounds.iTl.iX < bounds.iTl.iX)
843 bounds.iTl.iX = output->iBounds.iTl.iX;
844 if (bounds.iBr.iX < output->iBounds.iBr.iX)
845 bounds.iBr.iX = output->iBounds.iBr.iX;
846 if (output->iBounds.iTl.iY < bounds.iTl.iY)
847 bounds.iTl.iY = output->iBounds.iTl.iY;
848 if (bounds.iBr.iY < output->iBounds.iBr.iY)
849 bounds.iBr.iY = output->iBounds.iBr.iY;
853 // Would any limits be exceeded by adding this group?
854 if (param.iPosInText > end_char)
856 if (new_advance > input.iMaxAdvance)
860 if (BoundsExceeded(input, param.iPen.iY, bounds.iBr.iY, bounds.iTl.iY))
865 if (BoundsExceeded(input, param.iPen.iX, bounds.iBr.iX, bounds.iTl.iX))
871 aOutput->iChars = param.iPosInText; // should this not be aOutput->iChars = param.iPosInText - input.iShartInputChar;?
872 aOutput->iGlyphs += param.iOutputGlyphs;
873 aOutput->iGroups = groups;
874 aOutput->iSpaces = spaces;
875 aOutput->iBounds = bounds;
879 advance = new_advance;
881 if(shapeInfo.IsOpen())
886 // These 3 functions should probably be moved to E32/Euser as part of TChar or
887 // similar as there seem to be several local copies of similar functions in
888 // various OS modules so we should remove duplication
890 TUint16 HighSurrogate(TUint aCode)
892 GDI_ASSERT_DEBUG(aCode > 0xFFFF, EGdiPanic_InvalidInputParam);
893 return STATIC_CAST(TUint16, 0xD7C0 + (aCode >> 10));
896 TUint16 LowSurrogate(TUint aCode)
898 GDI_ASSERT_DEBUG(aCode > 0xFFFF, EGdiPanic_InvalidInputParam);
899 return STATIC_CAST(TUint16, 0xDC00 | (aCode & 0x3FF));
902 TUint CombineSurrogates(TUint aHighSurrogate, TUint aLowSurrogate)
904 GDI_ASSERT_DEBUG((0xD800 == (aHighSurrogate & 0xF800)), EGdiPanic_InvalidInputParam);
905 GDI_ASSERT_DEBUG((0xD800 == (aHighSurrogate & 0xFC00)), EGdiPanic_InvalidInputParam);
906 GDI_ASSERT_DEBUG((0xDC00 == (aLowSurrogate & 0xFC00)), EGdiPanic_InvalidInputParam);
907 return ((aHighSurrogate - 0xD7F7) << 10) + aLowSurrogate;
911 /** Overridable function innards of GetCharacterPosition and
912 GetCharacterPosition2. It is generally not useful to override this function.
914 @see GetCharacterPosition
915 @see GetCharacterPosition2
917 EXPORT_C TBool CFont::DoGetCharacterPosition(TPositionParam& aParam) const
919 RShapeInfo shapeInfo;
920 TBool r = GetCharacterPosition2(aParam, shapeInfo);
921 if (shapeInfo.IsOpen())
926 // Find the script (and hence the correct process function) that any punctuation or digit may belong to
927 LOCAL_C GlyphSelection::ProcessFunc FindContextualProcessFunc(RShapeInfo& aShapeInfo, const TGlyphSelectionState aGss)
929 GlyphSelection::ProcessFunc processFunc = CharacterToProcessFunction(aGss.iCodeChar);
930 GlyphSelection::ProcessFunc contextProcessFunc = (GlyphSelection::ProcessFunc)aShapeInfo.GetContext();
932 // If context or prevCode is NULL, use processFunc,
933 // else use function of context or prevCode
934 if ((aGss.iCodeChar.IsDigit() || aGss.iCodeChar.IsPunctuation()) && !QuoteOrBracketPair(aGss.iCodeChar) && processFunc!=GlyphSelector_SoftHyphen::Process)
936 // If context is not set, check the previous char for context.
937 if (contextProcessFunc == NULL)
939 if (aGss.iParam.iPosInText > 0)
941 TChar prevCode = aGss.iText.Get(-1);
942 GlyphSelection::ProcessFunc prevProcessFunc = CharacterToProcessFunction(prevCode);
943 if (prevProcessFunc != NULL && (prevCode.IsAlpha() || prevProcessFunc != GlyphSelector_Default::Process))
945 aShapeInfo.SetContext((TAny *)prevProcessFunc);
946 return prevProcessFunc;
951 return contextProcessFunc;
956 // set the context with current processFunc only if current char is not ignored for context.
957 if (processFunc != NULL && (aGss.iCodeChar.IsAlpha() || processFunc != GlyphSelector_Default::Process))
958 aShapeInfo.SetContext((TAny *)processFunc);
962 /** Takes Unicode text and produces the glyph cluster for the first character
963 in that text plus any combining mark characters, or for the first indic
964 syllable. It is responsible for contextual glyph selection, ligature creation
965 and diacritic placement.
968 The input/output parameter of the text/glyph data for the algorithm.
970 The function will cache "shaped" text (e.g. complex scripts such as
971 Devanagari) here. aShapeInfo must be freshly-constructed or closed for each
972 new piece of text in aParam.iText. If aParam.iText is unchanged between
973 calls, aShapeInfo should be passed back in unchanged as well.
975 ETrue if glyphs for supplied text have been produced, EFalse in failure.
976 @see CFont::TPositionParam
979 EXPORT_C TBool CFont::GetCharacterPosition2(TPositionParam& aParam, RShapeInfo& aShapeInfo) const
981 GDI_ASSERT_DEBUG(aParam.iPosInText>=0, EGdiPanic_InvalidInputParam);
982 GDI_ASSERT_DEBUG(aParam.iText.Ptr(), EGdiPanic_InvalidInputParam);
984 aParam.iOutputGlyphs = 0;
985 TInt textLen = aParam.iText.Length();
986 TBool outputOk = ETrue;
987 TPoint penCopy = aParam.iPen;
989 // Verify input parameters are sane
990 if (aParam.iPosInText >= textLen)
993 // Setup glyph selection algorithm data
994 TUtf32Iterator textIter(aParam.iText.Ptr(), aParam.iText.Ptr()+textLen, aParam.iPosInText);
995 if (textIter.AtEnd())
997 aParam.iPosInText = textIter.LengthToStart();
1001 // Process each character in the text in turn until we reach the end of
1002 // the iterator, the next base (non-mark/combining) character or reach
1003 // the limit in a glyph cluster.
1004 GlyphSelection::ProcessFunc firstProcessFn = 0;
1005 TGlyphSelectionState gss(textIter, this, aParam);
1008 // Retrieve character info for processing.
1009 gss.iCodePt = gss.iCodeChar = textIter.Get();
1010 gss.iCombCls = gss.iCodeChar.GetCombiningClass();
1011 gss.iCats = gss.iCodeChar.GetCategory();
1012 gss.iClusterState = TGlyphSelectionState::EGClusterNotComplete;
1013 gss.iPen = TGlyphSelectionState::EPenAdvance_No;
1015 // Find the correct processesing function for the script being used.
1016 // If gss.iCodePt is a strongly directional character, then simply map it in TTableEntry Table[]
1017 // and use the returned process function pointer.
1018 // If gss.iCodePt is a punctuation or a digit, then use a context character in the text (if
1019 // available) to find the contextual script being rendered and use its process function pointer.
1020 GlyphSelection::ProcessFunc processFn = FindContextualProcessFunc(aShapeInfo, gss);
1022 if (!firstProcessFn)
1023 firstProcessFn = processFn;
1027 if (firstProcessFn == processFn)
1028 outputOk = processFn(gss, aShapeInfo);
1034 // Table entry blank, unicode char to be skipped
1038 (!textIter.AtEnd() &&
1039 ((textIter.Get().GetCategory() & 0xF0)
1040 == TChar::EMarkGroup)) ?
1041 TGlyphSelectionState::EGClusterNotComplete : TGlyphSelectionState::EGClusterComplete;
1044 // Abort if no class was available to process the character or if
1045 // processing failed.
1048 aParam.iPosInText = textIter.LengthToStart();
1052 // Did the glyph selector that processed the character want the
1054 if (gss.iPen == TGlyphSelectionState::EPenAdvance_Yes)
1056 aParam.iPen.iX += gss.iAdvance.iWidth;
1057 aParam.iPen.iY += gss.iAdvance.iHeight;
1058 gss.iPen = TGlyphSelectionState::EPenAdvance_No;
1061 // Here we assume the Process() methods have advanced the iterator as
1062 // they consume characters they handle so that it now points to the
1063 // character to process next time around the loop.
1065 while (!textIter.AtEnd() // We still have more text to process
1066 && (gss.iClusterState == TGlyphSelectionState::EGClusterNotComplete) // Glyph cluster !complete
1067 && (aParam.iOutputGlyphs < TPositionParam::EMaxOutputGlyphs)); // Room for another glyph entry
1069 // If a complete glyph cluster has been identified then we should try to
1070 // compose it as fully as possible. Obviously, if it only contains one
1071 // character then it is already fully composed so we can ignore it.
1072 // Skip this if any language-specific processing has taken place.
1073 if (gss.iGlyphPostCombine == TGlyphSelectionState::EGPostCombine_Yes
1074 && gss.iClusterState == TGlyphSelectionState::EGClusterComplete)
1076 // Leave room to handle surrogates - Decompose() outputs UTF-16
1077 // The max that can come out of the previous stage is TPositionParam::EMaxOutputGlyphs
1078 // long with only one base char at the start. Even if that base char decomposed to the
1079 // max it could only be MaxOutputGlyphs long, giving a total of (2 * MaxOutputGlyphs)-1
1080 // Conceivably the use of surrogates throughout could double that when converting to UTF-16
1081 TBuf<TPositionParam::EMaxOutputGlyphs * 4> decomposeArray;
1082 TBool success = ETrue;
1083 // Go through the glyph cluster one char at a time
1084 for (TInt i = 0; i < aParam.iOutputGlyphs; i++)
1086 TChar singleChar(aParam.iOutput[i].iCode);
1087 // If first character try to decompose it otherwise just take the character
1088 TBool decomposed = EFalse;
1089 TPtrC16 decomposition;
1091 decomposed = singleChar.Decompose(decomposition);
1093 { // Pick up the sequence of characters
1094 decomposeArray.Append(decomposition);
1097 { // Keep the original character
1098 if (singleChar > 0xFFFF)
1099 { // Above the BMP so we need a surrogate pair for UTF-16
1100 // This calculation really ought to go into a separate routine - probably part of TChar
1101 decomposeArray.Append(HighSurrogate(singleChar));
1102 decomposeArray.Append(LowSurrogate(singleChar));
1105 { // It's not a surrogate so we just need to cast it down (since it's safe)
1106 decomposeArray.Append(singleChar);
1109 // Guard against bad input overflowing the array and causing a panic
1110 if (decomposeArray.Length() > (TPositionParam::EMaxOutputGlyphs * 4) - 2)
1111 { // too long to be a viable composition so don't try
1116 TUint composedChar = 0;
1117 TOpenFontCharMetrics metrics;
1118 TPositionParam::TOutput output;
1119 TSize advance; // gets initialized to 0,0
1122 //Now try and compose the string to a single character
1123 success = TChar::Compose(composedChar, decomposeArray);
1127 // if single char is not in font or can't get char metrics for it
1128 // N.B. This will probably always return metrics because if the
1129 // char is not in the font this will usually return the substitute
1130 // "missing" glyph (and its metrics). There should be a function to
1131 // really tell you if a glyph is in the font - but there isn't.
1132 if (GetCharacterData(composedChar, metrics, output.iBitmap, output.iBitmapSize) == CFont::ENoCharacterData)
1137 // We should replace the glyph cluster made from multiple chars
1138 // with the correct single char and fix up the rest of the output
1139 // parameters as well
1140 output.iCode = composedChar;
1141 // Set the glyph's bounds and record pen advancement.
1142 if (aParam.iDirection == CFont::EVertical)
1144 metrics.GetVertBounds(output.iBounds);
1145 advance.iHeight = metrics.VertAdvance();
1149 metrics.GetHorizBounds(output.iBounds);
1150 advance.iWidth = metrics.HorizAdvance();
1152 // Adjust the glyph's bounding box to offset it from the pen
1153 // position (origin of drawing). For speed increment directly.
1154 output.iBounds.iTl.iX += penCopy.iX;
1155 output.iBounds.iBr.iX += penCopy.iX;
1156 output.iBounds.iTl.iY += penCopy.iY;
1157 output.iBounds.iBr.iY += penCopy.iY;
1158 // Set penCopy, the copy of aParam.iPen that we made
1159 penCopy.iX += advance.iWidth;
1160 penCopy.iY += advance.iHeight;
1161 // Overwrite the original output parameters for the glyph cluster
1162 // with the values for the single composed character
1163 aParam.iOutput[0] = output;
1164 aParam.iOutputGlyphs = 1;
1165 aParam.iPen = penCopy;
1169 // Exit routine with result and increment position in text to
1170 // where we reached during processing to avoid any caller loops from
1171 // infinite execution.
1172 aParam.iPosInText = textIter.LengthToStart();
1176 /** Gets the character metrics for a character.
1178 @param aCode The character code.
1179 @param aMetrics On return, contains the character bitmap.
1180 @param aBitmap On return, this points to NULL.
1181 @param aBitmapSize On return, this has a size of (0,0).
1182 @return ECharacterWidthOnly
1184 EXPORT_C CFont::TCharacterDataAvailability CFont::DoGetCharacterData(TUint aCode,TOpenFontCharMetrics& aMetrics,
1185 const TUint8*& aBinaryData,TSize& aBitmapSize) const
1187 int width = CharWidthInPixels(aCode);
1188 aMetrics.SetHorizAdvance(width);
1190 // For speed set to 0 directly rather than call SetSize()
1191 aBitmapSize.iWidth = 0;
1192 aBitmapSize.iHeight = 0;
1195 Set the other metrics using the width and font metrics.
1196 This allows derived classes that don't override this function, like CInfoFont,
1197 to give usable results for TextWidthInPixels and MeasureText.
1199 aMetrics.SetWidth(width);
1200 int height = HeightInPixels();
1201 aMetrics.SetHeight(height);
1202 aMetrics.SetVertAdvance(height);
1203 aMetrics.SetHorizBearingX(0);
1204 aMetrics.SetHorizBearingY(AscentInPixels());
1205 aMetrics.SetVertBearingX(0);
1206 aMetrics.SetVertBearingY(0);
1208 return CFont::ECharacterWidthOnly;
1212 /** Determines if aLeftCharacter and aRightCharacter affect each other's
1213 contextual glyph form if placed next to each other. If either character
1214 is a combining character, EFalse will be returned, which is not generally
1215 useful information. Pass in base characters ignoring intervening combining
1217 @param aLeftCharacter Unicode code for the character that stands on the left.
1218 @param aRightCharacter Unicode code for the character that stands on the right.
1219 @return EFalse if the characters do not affect the contextual glyphs that are
1220 be chosen when the two are rendered together, compared to being separated
1221 (for example by a space). */
1222 EXPORT_C TBool CFont::CharactersJoin(TInt aLeftCharacter, TInt aRightCharacter)
1224 return GlyphSelector_Arabic::CharactersJoin(aLeftCharacter, aRightCharacter);
1227 /** API extension system that enables the caller to access a particular API
1228 extension function. N.B. Any overload of this function in a derived class
1229 should call its immediate parent implementation for any extension function Uid
1230 that it does not recognize and handle.
1231 @param aInterfaceId UID of the required extension function
1232 @param aParam Pointer to an arbitrary parameter block that can be used to
1233 provide and/or return information to/from the particular extension function,
1235 @return Integer return value from extension function
1239 EXPORT_C TInt CFont::DoExtendedFunction(TUid aFunctionId, TAny* /* aParam */) const
1241 if (KFontCapitalAscent == aFunctionId ||
1242 KFontMaxAscent == aFunctionId)
1244 return AscentInPixels();
1246 else if (KFontStandardDescent == aFunctionId ||
1247 KFontMaxDescent == aFunctionId)
1249 return DescentInPixels();
1251 else if (KFontLineGap == aFunctionId)
1252 { // 1.2 of em height (rounded) is reasonable approximation of interline gap
1253 return (HeightInPixels() * 12 + 5) / 10;
1255 return KErrNotFound;
1258 EXPORT_C TUid CFont::TypeUid() const
1263 EXPORT_C TInt CFont::HeightInPixels() const
1265 return DoHeightInPixels();
1268 EXPORT_C TInt CFont::AscentInPixels() const
1270 return DoAscentInPixels();
1273 EXPORT_C TInt CFont::DescentInPixels() const
1275 return DoDescentInPixels();
1278 EXPORT_C TInt CFont::CharWidthInPixels(TChar aChar) const
1280 return DoCharWidthInPixels(aChar);
1283 EXPORT_C TInt CFont::TextWidthInPixels(const TDesC& aText) const
1285 return DoTextWidthInPixels(aText);
1288 EXPORT_C TInt CFont::BaselineOffsetInPixels() const
1290 return DoBaselineOffsetInPixels();
1293 EXPORT_C TInt CFont::TextCount(const TDesC& aText,TInt aWidthInPixels) const
1295 return DoTextCount(aText, aWidthInPixels);
1298 EXPORT_C TInt CFont::TextCount(const TDesC& aText, TInt aWidthInPixels, TInt& aExcessWidthInPixels) const
1300 return DoTextCount(aText, aWidthInPixels, aExcessWidthInPixels);
1303 EXPORT_C TInt CFont::MaxCharWidthInPixels() const
1305 return DoMaxCharWidthInPixels();
1308 EXPORT_C TInt CFont::MaxNormalCharWidthInPixels() const
1310 return DoMaxNormalCharWidthInPixels();
1313 EXPORT_C TFontSpec CFont::FontSpecInTwips() const
1315 return DoFontSpecInTwips();
1318 /** Gets the character metrics for a character.
1320 @param aCode The character code.
1321 @param aMetrics On return, contains the character bitmap.
1322 @param aBitmap On return, this points to NULL.
1323 @param aBitmapSize On return, this has a size of (0,0).
1324 @return ECharacterWidthOnly
1326 EXPORT_C CFont::TCharacterDataAvailability CFont::GetCharacterData(TUint aCode, TOpenFontCharMetrics& aMetrics, const TUint8*& aBitmap, TSize& aBitmapSize) const
1328 return DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
1331 /** Transforms one cluster of characters (base character plus combining marks,
1332 ligature or indic syllable) into one cluster of glyphs together with their
1333 positions. Repeated calls of this function (for the same input text) are
1334 considerably slower than repeated calls of GetCharacterPosition2 for Indic text
1335 (such as Hindi), as GetCharacterPosition2 can cache information between calls.
1336 @param aParam Input and output parameters
1337 @return True for success
1338 @see GetCharacterPosition2
1340 EXPORT_C TBool CFont::GetCharacterPosition(TPositionParam& aParam) const
1342 return DoGetCharacterPosition(aParam);
1345 /** Enables the caller to access a particular API
1346 extension function. N.B. Any overload of this function in a derived class
1347 should call its immediate parent implementation for any extension function UID
1348 that it does not recognize and handle.
1349 @param aFunctionId UID of the required extension function
1350 @param aParam Pointer to an arbitrary parameter block that can be used to
1351 provide and/or return information to/from the particular extension function,
1353 @return Integer return value from extension function
1355 EXPORT_C TInt CFont::ExtendedFunction(TUid aFunctionId, TAny* aParam) const
1357 return DoExtendedFunction(aFunctionId, aParam);
1360 EXPORT_C TInt CFont::TextWidthInPixels(const TDesC& aText,const TMeasureTextInput* aParam) const
1362 TTextWidthInternal context;
1363 TTextWidthInternal* contextPtr = &context;
1364 contextPtr->iText.Set(aText);
1365 contextPtr->iParam.iStartInputChar = aParam->iStartInputChar;
1366 contextPtr->iParam.iEndInputChar = aParam->iEndInputChar;
1367 return DoExtendedFunction(KTextInContextWidthInPixelsUid, (TAny*)contextPtr);
1371 Maps TLanguage to TScript.
1373 EScriptOther represents languages not yet supported in KTScript2GlyphSample.
1374 This array does not handle ELangNone and ELangMaximum to save storage space.
1376 const TInt GlyphSample::KTLanguage2TScript[] =
1378 EScriptNone, // 00 ELangTest
1379 EScriptLatin, // 01 ELangEnglish
1380 EScriptLatin, // 02 ELangFrench
1381 EScriptLatin, // 03 ELangGerman
1382 EScriptLatin, // 04 ELangSpanish
1383 EScriptLatin, // 05 ELangItalian
1384 EScriptLatin, // 06 ELangSwedish
1385 EScriptLatin, // 07 ELangDanish
1386 EScriptLatin, // 08 ELangNorwegian
1387 EScriptLatin, // 09 ELangFinnish
1388 EScriptLatin, // 10 ELangAmerican
1389 EScriptLatin, // 11 ELangSwissFrench
1390 EScriptLatin, // 12 ELangSwissGerman
1391 EScriptLatin, // 13 ELangPortuguese
1392 EScriptLatin, // 14 ELangTurkish
1393 EScriptLatin, // 15 ELangIcelandic
1394 EScriptCyrillic, // 16 ELangRussian
1395 EScriptLatin, // 17 ELangHungarian
1396 EScriptLatin, // 18 ELangDutch
1397 EScriptLatin, // 19 ELangBelgianFlemish
1398 EScriptLatin, // 20 ELangAustralian
1399 EScriptLatin, // 21 ELangBelgianFrench
1400 EScriptLatin, // 22 ELangAustrian
1401 EScriptLatin, // 23 ELangNewZealand
1402 EScriptLatin, // 24 ELangInternationalFrench
1403 EScriptLatin, // 25 ELangCzech
1404 EScriptLatin, // 26 ELangSlovak
1405 EScriptLatin, // 27 ELangPolish
1406 EScriptLatin, // 28 ELangSlovenian
1407 EScriptHanIdeographs, // 29 ELangTaiwanChinese
1408 EScriptHanIdeographs, // 30 ELangHongKongChinese
1409 EScriptHanIdeographs, // 31 ELangPrcChinese
1410 EScriptHanIdeographs, // 32 ELangJapanese
1411 EScriptThai, // 33 ELangThai
1412 EScriptLatin, // 34 ELangAfrikaans
1413 EScriptLatin, // 35 ELangAlbanian
1414 EScriptOther, // 36 ELangAmharic
1415 EScriptArabic, // 37 ELangArabic
1416 EScriptOther, // 38 ELangArmenian
1417 EScriptOther, // 39 ELangTagalog
1418 EScriptCyrillic, // 40 ELangBelarussian
1419 EScriptOther, // 41 ELangBengali
1420 EScriptCyrillic, // 42 ELangBulgarian
1421 EScriptOther, // 43 ELangBurmese
1422 EScriptLatin, // 44 ELangCatalan
1423 EScriptLatin, // 45 ELangCroatian
1424 EScriptLatin, // 46 ELangCanadianEnglish
1425 EScriptLatin, // 47 ELangInternationalEnglish
1426 EScriptLatin, // 48 ELangSouthAfricanEnglish
1427 EScriptLatin, // 49 ELangEstonian
1428 EScriptArabic, // 50 ELangFarsi
1429 EScriptLatin, // 51 ELangCanadianFrench
1430 EScriptLatin, // 52 ELangScotsGaelic
1431 EScriptOther, // 53 ELangGeorgian
1432 EScriptGreek, // 54 ELangGreek
1433 EScriptGreek, // 55 ELangCyprusGreek
1434 EScriptOther, // 56 ELangGujarati
1435 EScriptHebrew, // 57 ELangHebrew
1436 EScriptDevanagari, // 58 ELangHindi
1437 EScriptLatin, // 59 ELangIndonesian
1438 EScriptLatin, // 60 ELangIrish
1439 EScriptLatin, // 61 ELangSwissItalian
1440 EScriptOther, // 62 ELangKannada
1441 EScriptCyrillic, // 63 ELangKazakh
1442 EScriptOther, // 64 ELangKhmer
1443 EScriptHanIdeographs, // 65 ELangKorean
1444 EScriptOther, // 66 ELangLao
1445 EScriptLatin, // 67 ELangLatvian
1446 EScriptLatin, // 68 ELangLithuanian
1447 EScriptCyrillic, // 69 ELangMacedonian
1448 EScriptLatin, // 70 ELangMalay
1449 EScriptOther, // 71 ELangMalayalam
1450 EScriptDevanagari, // 72 ELangMarathi
1451 EScriptLatin, // 73 ELangMoldavian
1452 EScriptOther, // 74 ELangMongolian
1453 EScriptLatin, // 75 ELangNorwegianNynorsk
1454 EScriptLatin, // 76 ELangBrazilianPortuguese
1455 EScriptOther, // 77 ELangPunjabi
1456 EScriptLatin, // 78 ELangRomanian
1457 EScriptCyrillic, // 79 ELangSerbian
1458 EScriptOther, // 80 ELangSinhalese
1459 EScriptLatin, // 81 ELangSomali
1460 EScriptLatin, // 82 ELangInternationalSpanish
1461 EScriptLatin, // 83 ELangLatinAmericanSpanish
1462 EScriptLatin, // 84 ELangSwahili
1463 EScriptLatin, // 85 ELangFinlandSwedish
1464 EScriptNone, // 86 ELangReserved1
1465 EScriptOther, // 87 ELangTamil
1466 EScriptOther, // 88 ELangTelugu
1467 EScriptOther, // 89 ELangTibetan
1468 EScriptOther, // 90 ELangTigrinya
1469 EScriptLatin, // 91 ELangCyprusTurkish
1470 EScriptCyrillic, // 92 ELangTurkmen
1471 EScriptCyrillic, // 93 ELangUkrainian
1472 EScriptArabic, // 94 ELangUrdu
1473 EScriptNone, // 95 ELangReserved2
1474 EScriptLatin, // 96 ELangVietnamese
1475 EScriptLatin, // 97 ELangWelsh
1476 EScriptLatin, // 98 ELangZulu
1480 Maps TScript to glyph samples.
1482 The order of samples definition has to follow the script order in TScript.
1484 Supported scripts Fonts used to experiment/determine glyph samples
1486 Latin Arial, Times, Century
1489 Hebrew Aharoni, David, FrankRuehl, Levenim MT, Miriam, Narkisim, Rod
1490 Arabic Andalus, Arabic Transparent, Simplified Arabic, Traditional Arabic
1492 Thai Angsana New, Browallia, Cordia New, DilleniaUPC, EucrosiaUPC,
1493 FreesiaUPC, IrisUPC, JasmineUPC, KodchiangUPC, LilyUPC
1494 HanIdeographs Chinese : SimSun, SimHei (Simplified) / MingLiU (Traditional)
1495 Japanese: MS Mincho, MS Gothic
1496 Korean : Batang, Gulim
1498 const TText* const GlyphSample::KTScript2GlyphSample[] =
1503 // 0x00C0 - Ascent : Capital letter A with grave (Latin-1 Supplement)
1504 // 0x013A - Ascent : Small letter l with acute (Latin Extended A)
1505 // 0x1EA2 - Ascent : Capital letter A with hook above (Latin Extended Additional)
1506 // 0x00C7 - Descent: Capital letter C with cedilla (Latin-1 Supplement)
1507 // 0x0163 - Descent: Small letter t with cedilla (Latin Extended A)
1509 _S("\x00C0\x013A\x1EA2\x00C7\x0163"),
1513 // 0x03AA - Ascent : Capital letter iota with dialytika
1514 // 0x03AB - Ascent : Capital letter upsilon with dialytika
1515 // 0x03AE - Descent: Small letter eta with tonos
1516 // 0x03B2 - Descent: Small letter beta
1517 // 0x03C8 - Descent: Small letter psi
1519 _S("\x03AA\x03AB\x03AE\x03B2\x03C8"),
1521 // 04 EScriptCyrillic
1523 // 0x0403 - Ascent : Capital letter gje
1524 // 0x0419 - Ascent : Capital letter short i
1525 // 0x0440 - Descent: Small letter er
1526 // 0x0452 - Descent: Small letter dje
1527 // 0x0458 - Descent: Small letter je
1529 _S("\x0403\x0419\x0440\x0452\x0458"),
1533 // 0x05BE - Ascent : Punctuation maqaf
1534 // 0x05DC - Ascent : Letter lamed
1535 // 0x05B0 - Descent: Point sheva
1536 // 0x05BD - Descent: Point meteg
1537 // 0x05E7 - Descent: Letter qof
1539 _S("\x05BE\x05DC\x05B0\x05BD\x05E7"),
1543 // 0x0670 - Ascent : Alef above (Arabic)
1544 // 0x0671 - Ascent : Hamzat Wasl on Alef isolated form
1545 // 0x064D - Descent: Kasratan (Arabic)
1546 // 0xFB7B - Descent: Final form of 0686
1547 // 0xFBF2 - Descent: Final form of 064A
1549 //PDEF120737: EScriptArabic value has been changed for this defect & tested using the font file provided by client (i.e. kamelion arabic font).
1550 //The client's font file can't be used for IPR reasons. Thus the test code to demonstrate this defect
1551 //is not added. Also, there was no other font file available that reproduces this defect.
1553 _S("\x0670\x0671\x064D\xFB7B\xFBF2"),
1555 // 07 EScriptDevanagari
1557 // 0x0914 - Ascent : Letter au
1558 // 0x0951 - Ascent : Stress sign udatta
1559 // 0x0941 - Descent: Vowel sign u
1560 // 0x0944 - Descent: Vowel sign rr
1561 // 0x0963 - Descent: Vowel sign vocalic ll
1563 _S("\x0914\x0951\x0941\x0944\x0963"),
1567 // 0x0E49 - Ascent : Character mai tho
1568 // 0x0E4B - Ascent : Character mai chattawa
1569 // 0x0E0E - Descent: Character do chada
1570 // 0x0E24 - Descent: Character ru
1571 // 0x0E39 - Descent: Character sara uu
1573 _S("\x0E49\x0E4B\x0E0E\x0E24\x0E39"),
1575 // 09 EScriptHanIdeographs
1577 // 0x1100 - Ascent/Descent: Korean
1578 // 0x4E1C - Ascent/Descent: Chinese Simplified
1579 // 0x5283 - Ascent/Descent: Japanese
1580 // 0x758A - Ascent : Chinese Traditional
1581 // 0x7BEA - Descent: Chinese Traditional
1583 _S("\x1100\x4E1C\x5283\x758A\x7BEA"),
1587 Maps a TLanguage type to the TScript type.
1589 @param aLanguage The language.
1590 @return A TInt representing the script, or
1591 EScriptNone if its not defined for aLanguage.
1593 EXPORT_C TInt GlyphSample::TLanguage2TScript(TLanguage aLanguage)
1595 if (ELangNone == aLanguage || ELangMaximum == aLanguage || aLanguage >= (sizeof(KTLanguage2TScript)/sizeof(KTLanguage2TScript[0])))
1599 return KTLanguage2TScript[aLanguage];
1603 Maps a TScript type to some glyph samples which are stored as Unicode.
1605 @param aScript The script.
1606 @return A TPtrC pointing to the first glyph sample,
1607 or empty if no samples is defined for aScript.
1609 EXPORT_C const TPtrC GlyphSample::TScript2GlyphSample(TInt aScript)
1611 if (EScriptOther >= aScript)
1615 // -3 to offset EScriptDefault, EScriptNone and EScriptOther
1616 // being the first three elements in TScript.
1617 return TPtrC(KTScript2GlyphSample[aScript - 3]);
1621 EXPORT_C RFontTable::RFontTable():iTableContent(0), iLength(0),
1622 iFont(NULL), iTag(0)
1624 // a null constructor.
1628 RFontTable::Open(CFont& aFont, TUint32 aTag)
1630 TGetFontTableParam param;
1633 // remember the parameters, to be used when releasing the font table.
1637 TInt ret = aFont.ExtendedFunction(KFontGetFontTable, (TAny *)¶m);
1638 if (KErrNone == ret)
1640 iTableContent = (TAny *)param.iContent;
1641 iLength = param.iLength;
1647 RFontTable::TableLength() const
1652 EXPORT_C const TUint8*
1653 RFontTable::TableContent() const
1655 return (TUint8*)iTableContent;
1663 (void)iFont->ExtendedFunction(KFontReleaseFontTable, (TAny *)&iTag);
1672 RGlyphOutlineIterator::RGlyphOutlineIterator():iOutlines(0), iLengths(0),
1673 iCursor(-1), iCount(0), iFont(NULL), iCodes(NULL), iHinted(EFalse)
1675 // a null constructor.
1679 RGlyphOutlineIterator::Open(CFont& aFont, const TUint* aCodes, TInt aCount, TBool aHinted)
1681 if (NULL == aCodes || 0 == aCount)
1683 return KErrArgument;
1685 TGetGlyphOutlineParam param;
1686 iLengths = (TInt *)User::Alloc(sizeof(TInt) * aCount);
1687 if (NULL == iLengths)
1689 return KErrNoMemory;
1691 iOutlines = (TAny **)User::Alloc(sizeof(TAny *) * aCount);
1692 if (NULL == iOutlines)
1694 User::Free(iLengths);
1696 return KErrNoMemory;
1699 param.iLengths = iLengths;
1700 param.iCount = aCount;
1701 param.iCodes = aCodes;
1702 param.iHinted = aHinted;
1703 param.iOutlines = iOutlines;
1705 /* information needed in Close() */
1706 iCodes = (TUint *)User::Alloc(sizeof(TUint) * aCount);
1709 User::Free(iLengths);
1710 User::Free(iOutlines);
1713 return KErrNoMemory;
1715 Mem::Copy(iCodes, aCodes, aCount*sizeof(TUint));
1720 TInt ret = aFont.ExtendedFunction(KFontGetGlyphOutline, (TAny *)¶m);
1721 if (KErrNone != ret)
1723 User::Free(iLengths);
1724 User::Free(iOutlines);
1739 EXPORT_C const TUint8*
1740 RGlyphOutlineIterator::Outline() const
1742 GDI_ASSERT_ALWAYS(iCursor >= 0, EGdiPanic_Unknown);
1744 if (iLengths[iCursor] < 0)
1750 return (const TUint8*)iOutlines[iCursor];
1755 RGlyphOutlineIterator::OutlineLength() const
1757 GDI_ASSERT_ALWAYS(iCursor >= 0, EGdiPanic_Unknown);
1759 if (iLengths[iCursor] < 0)
1765 return iLengths[iCursor];
1770 RGlyphOutlineIterator::Next()
1772 if (iCursor >= 0 && iCursor < iCount-1)
1780 // if the iterator goes beyond the last element [when
1781 // Next() returns KErrNotFound], the next call
1782 // to Outline() or OutlineLength() will panic.
1784 return KErrNotFound;
1789 RGlyphOutlineIterator::Close()
1791 TReleaseGlyphOutlineParam param;
1792 param.iCount = iCount;
1793 param.iHinted = iHinted;
1794 param.iCodes = iCodes;
1798 iFont->ExtendedFunction(KFontReleaseGlyphOutline, (TAny *)¶m);
1803 User::Free(iLengths);
1808 User::Free(iOutlines);