--- a/graphicsdeviceinterface/gdi/sgdi/FontThai.cpp Thu Sep 02 21:50:40 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,968 +0,0 @@
-// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
-// All rights reserved.
-// This component and the accompanying materials are made available
-// under the terms of "Eclipse Public License v1.0"
-// which accompanies this distribution, and is available
-// at the URL "http://www.eclipse.org/legal/epl-v10.html".
-//
-// Initial Contributors:
-// Nokia Corporation - initial contribution.
-//
-// Contributors:
-//
-// Description:
-//
-
-/**
- @file
- @internalComponent
-*/
-
-
-#include <gdi.h>
-#include "FontThai.h"
-
-
-//
-// ThaiGlyph Namespace definition
-//
-
-
-/**
- This namespace holds functions used to evaluate a glyph character code
- against a given Thai related prediciate. The 'code' argument is a glyph
- from the current output cluster and so may be a Thai glyph, Thai PUA glyph,
- the dotted circle glyph or 0xffff. Therefore it was decided not to implement
- these routines using a data driven table approach as it would be inefficient.
-@internalComponent.
-*/
-namespace ThaiGlyph
- {
- const TText16 KYoYing = 0x0E0D;
- const TText16 KYoYingPua = 0xF70F;
- const TText16 KThoThan = 0x0E10;
- const TText16 KThoThanPua = 0xF700;
- const TText16 KNikhahit = 0x0E4D;
- const TText16 KNikhahitPua = 0xF711;
- const TText16 KSaraAa = 0x0E32;
- const TText16 KSaraAm = 0x0E33;
-
-
- TBool IsThaiGlyph(TUint code)
- {
- return ((code > 0x0E00 && code < 0x0E3B) ||
- (code > 0x0E3E && code < 0x0E5C) ||
- (code >= 0xF700 && code <= 0xF71A));
- }
-
- TBool IsThaiConsonant(TUint code)
- {
- return (code >= 0x0E01 && code <= 0x0E2E);
- }
-
- TBool IsThaiTallConsonant(TUint code)
- {
- return (//code == 0x0E0A || // CHO CHANG not tall at all
- //code == 0x0E0B || // SO SO not tall at all
- code == 0x0E1B || // PO PLA
- code == 0x0E1D || // FO FA
- code == 0x0E1F || // FO FAN
- code == 0x0E2C); // LO CHULA in some fonts, Unicode tables show it as tall
- }
-
- TBool IsThaiShortConsonant(TUint code)
- {
- return (((code >= 0x0E01 && code <= 0x0E2E) || (code == KUnicodeDottedCircle)) &&
- code != 0x0E1B && // PO PLA
- code != 0x0E1D && // FO FA
- code != 0x0E1F && // FO FAN
- code != 0x0E2C); // LO CHULA in some fonts, Unicode tables show it as tall
- }
-
- TBool IsThaiConsonantWithDisjointDescender(TUint code)
- {
- return (code == ThaiGlyph::KYoYing || code == ThaiGlyph::KThoThan);
- }
-
- TBool IsThaiConsonantWithJointDescender(TUint code)
- {
- return (code == 0x0E0E || // DO CHADA
- code == 0x0E0F || // PO PATAK
- code == 0x0E24 || // RU
- code == 0x0E26); // LU
- }
-
- TBool IsThaiVowel(TUint code)
- {
- return ((code >= 0x0E30 && code <= 0x0E3A) ||
- (code >= 0x0E40 && code <= 0x0E44) ||
- code == 0x0E47); // MAITAIKHU
- }
-
- TBool IsThaiDepVowel(TUint code)
- {
- return (code == 0x0E31 || // MAI HAN-AKAT
- (code >= 0x0E34 && code <= 0x0E3A) ||
- code == 0x0E47); // MAITAIKHU
- }
-
- TBool IsThaiDepVowelAbove(TUint code)
- {
- return (code == 0x0E31 || // MAI HAN-AKAT
- (code >= 0x0E34 && code <= 0x0E37) ||
- code == 0x0E47); // MAITAIKHU
- }
-
- TBool IsThaiDepVowelAbovePUA(TUint code)
- {
- return (code == 0xF710 || // MAI HAN-AKAT
- (code >= 0xF701 && code <= 0xF704) ||
- code == 0xF712); // MAITAIKHU
- }
-
- TBool IsThaiDepVowelBelow(TUint code)
- {
- return (code >= 0x0E38 && code <= 0x0E3A);
- }
-
- TBool IsThaiIndepVowel(TUint code)
- {
- return (code == 0x0E30 || // SARA A
- code == 0x0E32 || // SARA AA
- code == 0x0E33 || // SARA AM
- (code >= 0x0E40 && code <= 0x0E44));
- }
-
- TBool IsThaiToneMark(TUint code)
- {
- return (code >= 0x0E48 && code <= 0x0E4B);
- }
- }
-
-
-//
-//
-// ThaiCharRules Namespace definition
-//
-//
-
-
-/**
- ThaiCharRules namespace holds the data and lookup methods
- implementing the WTT 2.0 input/output validation matrix.
-@internalComponent
-*/
-namespace ThaiCharRules
- {
- const TUint KThaiCodePageStart = 0x0E00;
- const TUint KThaiCodePageEnd = 0x0E5C;
- const TUint KNumThaiCharacters = KThaiCodePageEnd-KThaiCodePageStart;
-
- enum Wtt2Rule
- {
- EUndefined,
- EAccept,
- EComposite,
- EReject,
- ERejectStrict,
- };
-
- /**
- This enumeration holds the set of classification values a Thai
- character can be categorised as in the WTT2.0 specification.
- */
- enum CharClassification
- {
- ENull,
- EControl,
- ENonPrintable,
- EConsonant,
- ELeadingVowel,
- EOrdinaryFollowingVowel,
- EDependentFollowingVowel,
- ESpecialFollowingVowel,
- EShortBelowVowel,
- ELongBelowVowel,
- EBelowDiacritic,
- EToneMark,
- EAboveDiacritic0,
- EAboveDiacritic1,
- EAboveDiacritic2,
- EAboveDiacritic3,
- EAboveVowel1,
- EAboveVowel2,
- EAboveVowel3,
- // marker for end
- EMaxClassification
- };
-
-
- /**
- Data table holding the classification of each character.
- */
- static const TUint8 iCharClassifications[KNumThaiCharacters] =
- {
- ENull, // No entry in code page
- EConsonant, // 0x0E01
- EConsonant, // 0x0E02
- EConsonant, // 0x0E03
- EConsonant, // 0x0E04
- EConsonant, // 0x0E05
- EConsonant, // 0x0E06
- EConsonant, // 0x0E07
- EConsonant, // 0x0E08
- EConsonant, // 0x0E09
- EConsonant, // 0x0E0A
- EConsonant, // 0x0E0B
- EConsonant, // 0x0E0C
- EConsonant, // 0x0E0D
- EConsonant, // 0x0E0E
- EConsonant, // 0x0E0F
-
- EConsonant, // 0x0E10
- EConsonant, // 0x0E11
- EConsonant, // 0x0E12
- EConsonant, // 0x0E13
- EConsonant, // 0x0E14
- EConsonant, // 0x0E15
- EConsonant, // 0x0E16
- EConsonant, // 0x0E17
- EConsonant, // 0x0E18
- EConsonant, // 0x0E19
- EConsonant, // 0x0E1A
- EConsonant, // 0x0E1B
- EConsonant, // 0x0E1C
- EConsonant, // 0x0E1D
- EConsonant, // 0x0E1E
- EConsonant, // 0x0E1F
-
- EConsonant, // 0x0E20
- EConsonant, // 0x0E21
- EConsonant, // 0x0E22
- EConsonant, // 0x0E23
- EConsonant, // 0x0E24
- EConsonant, // 0x0E25
- EConsonant, // 0x0E26
- EConsonant, // 0x0E27
- EConsonant, // 0x0E28
- EConsonant, // 0x0E29
- EConsonant, // 0x0E2A
- EConsonant, // 0x0E2B
- EConsonant, // 0x0E2C
- EConsonant, // 0x0E2D
- EConsonant, // 0x0E2E
- ENonPrintable, // 0x0E2F
-
- EOrdinaryFollowingVowel,// 0x0E30
- EAboveVowel2, // 0x0E31
- EOrdinaryFollowingVowel,// 0x0E32
- EOrdinaryFollowingVowel,// 0x0E33
- EAboveVowel1, // 0x0E34
- EAboveVowel3, // 0x0E35
- EAboveVowel2, // 0x0E36
- EAboveVowel3, // 0x0E37
- EShortBelowVowel, // 0x0E38
- ELongBelowVowel, // 0x0E39
- EBelowDiacritic, // 0x0E3A
- ENull, // 0x0E3B
- ENull, // 0x0E3C
- ENull, // 0x0E3D
- ENull, // 0x0E3E
- ENonPrintable, // 0x0E3F
-
- ELeadingVowel, // 0x0E40
- ELeadingVowel, // 0x0E41
- ELeadingVowel, // 0x0E42
- ELeadingVowel, // 0x0E43
- ELeadingVowel, // 0x0E44
- EDependentFollowingVowel,//0x0E45
- ENonPrintable, // 0x0E46
- EAboveDiacritic2, // 0x0E47
- EToneMark, // 0x0E48
- EToneMark, // 0x0E49
- EToneMark, // 0x0E4A
- EToneMark, // 0x0E4B
- EAboveDiacritic1, // 0x0E4C
- EAboveDiacritic0, // 0x0E4D
- EAboveDiacritic3, // 0x0E4E
- ENonPrintable, // 0x0E4F
-
- ENonPrintable, // 0x0E50
- ENonPrintable, // 0x0E51
- ENonPrintable, // 0x0E52
- ENonPrintable, // 0x0E53
- ENonPrintable, // 0x0E54
- ENonPrintable, // 0x0E55
- ENonPrintable, // 0x0E56
- ENonPrintable, // 0x0E57
- ENonPrintable, // 0x0E58
- ENonPrintable, // 0x0E59
- ENonPrintable, // 0x0E5A
- ENonPrintable, // 0x0E5B
-
- // Value at last measurement was 92 bytes. 27/6/2003
- };
-
-
- /**
- WTT 2.0 Rules data table of prev to next character
- */
- static const TUint8 iInputRules[EMaxClassification][EMaxClassification] =
- {
- /* Previous character ENull */
- {
- EUndefined, EUndefined, EUndefined, EUndefined, EUndefined,
- EUndefined, EUndefined, EUndefined, EUndefined, EUndefined,
- EUndefined, EUndefined, EUndefined, EUndefined, EUndefined,
- EUndefined, EUndefined, EUndefined, EUndefined
- },
-
- /* Previous character EControl */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- EAccept, EAccept, EAccept, EReject, EReject,
- EReject, EReject, EReject, EReject, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character ENonPrintable */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- ERejectStrict, ERejectStrict, EAccept, EReject, EReject,
- EReject, EReject, EReject, EReject, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character EConsonant */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- EAccept, ERejectStrict, EAccept, EComposite, EComposite,
- EComposite, EComposite, EComposite, EComposite, EComposite, EComposite,
- EComposite, EComposite, EComposite,
- },
-
- /* Previous character ELeadingVowel */
- {
- EUndefined, EUndefined, ERejectStrict, EAccept, ERejectStrict,
- ERejectStrict, ERejectStrict, ERejectStrict, EReject, EReject,
- EReject, EReject, EReject, EReject, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character EOrdinaryFollowingVowel */
- {
- EUndefined, EUndefined, ERejectStrict, EAccept, ERejectStrict,
- EAccept, ERejectStrict, EAccept, EReject, EReject,
- EReject, EReject, EReject, EReject, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character EDependentFollowingVowel */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- EAccept, ERejectStrict, EAccept, EReject, EReject,
- EReject, EReject, EReject, EReject, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character ESpecialFollowingVowel */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- ERejectStrict, EAccept, ERejectStrict, EReject, EReject,
- EReject, EReject, EReject, EReject, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character EShortBelowVowel */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- EAccept, ERejectStrict, EAccept, EReject, EReject,
- EReject, EComposite, EComposite, EComposite, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character ELongBelowVowel */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- ERejectStrict, ERejectStrict, EAccept, EReject, EReject,
- EReject, EComposite, EReject, EReject, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character EBelowDiacritic */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- ERejectStrict, ERejectStrict, EAccept, EReject, EReject,
- EReject, EReject, EReject, EReject, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character EToneMark */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- EAccept, EAccept, EAccept, EReject, EReject,
- EReject, EReject, EReject, EReject, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character EAboveDiacritic0 */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- ERejectStrict, ERejectStrict, EAccept, EReject, EReject,
- EReject, EReject, EReject, EReject, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character EAboveDiacritic1 */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- ERejectStrict, ERejectStrict, EAccept, EReject, EReject,
- EReject, EReject, EReject, EReject, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character EAboveDiacritic2 */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- ERejectStrict, ERejectStrict, EAccept, EReject, EReject,
- EReject, EReject, EReject, EReject, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character EAboveDiacritic3 */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- ERejectStrict, ERejectStrict, EAccept, EReject, EReject,
- EReject, EReject, EReject, EReject, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character EAboveVowel1 */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- ERejectStrict, ERejectStrict, EAccept, EReject, EReject,
- EReject, EComposite, EReject, EComposite, EReject, EReject,
-// EReject, EComposite, EComposite, EComposite, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character EAboveVowel2 */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- ERejectStrict, ERejectStrict, EAccept, EReject, EReject,
- EReject, EComposite, EReject, EReject, EReject, EReject,
- EReject, EReject, EReject,
- },
-
- /* Previous character EAboveVowel3 */
- {
- EUndefined, EUndefined, EAccept, EAccept, EAccept,
- ERejectStrict, ERejectStrict, EAccept, EReject, EReject,
- EReject, EComposite, EReject, EReject, EReject, EReject,
-// EReject, EComposite, EReject, EComposite, EReject,
- EReject, EReject, EReject,
- },
-
- // Value at last measurement was 324 bytes. 27/6/2003
- };
-
-
- /**
- This routine looks up the WTT 2.0 rule for the given
- Thai character codes provided in the WTT 2.0 data table.
- @param aPrevChar
- Unicode character code preceding the assumed position.
- @param aChar
- Unicode character code proceeding the assumed position.
- @return Wtt2Rule
- The rule value found in data table.
- */
- Wtt2Rule LookupWtt2Rule(TUint aPrevChar, TUint aChar)
- {
- const CharClassification prevCharClassification =
- static_cast<CharClassification>(
- (aPrevChar > KThaiCodePageStart && aPrevChar < KThaiCodePageEnd) ?
- iCharClassifications[aPrevChar - KThaiCodePageStart] :
- ENonPrintable);
- const CharClassification charClassification =
- static_cast<CharClassification>(
- (aChar > KThaiCodePageStart && aChar < KThaiCodePageEnd) ?
- iCharClassifications[aChar - KThaiCodePageStart] :
- ENonPrintable);
-
- return static_cast<Wtt2Rule>
- (iInputRules[prevCharClassification][charClassification]);
- }
-
- }
-
-using namespace ThaiCharRules;
-
-
-//
-//
-// ThaiGlyphPUASubstitution Namespace definition
-//
-//
-
-
-/**
- This utility namespace holds the data and lookup mechanisms to support
- the GlyphSelector_Thai glyph selection class in choosing Private User
- Area (PUA) Thai character positional variant glyphs. Use of the PUA glyphs
- results in a satisfactory rendition of Thai writing in Symbian OS.
-@internalComponent
-*/
-namespace ThaiGlyphPUASubstitution
- {
-
- typedef TBool (*UnicodeCharValidator)(const TGlyphSelectionState& aGss);
-
- struct PUASubstTableEntry
- {
- TUint iOrigGlyph;
- TUint iPUAGlyph;
- UnicodeCharValidator iRuleFunc;
- };
-
-
- /**
- ThaiGlyphPUASubstitution rule method which checks the context for
- short consonant preceding char OR
- short consonant & dependent vowel below preceding char.
- @param aGss
- Container object holds the glyph selection context for the method.
- @return TBool
- ETrue when the rule context is satisfied, EFalse if not.
- */
- TBool RuleShortConsonant(const TGlyphSelectionState& aGss)
- {
- if (aGss.iParam.iOutputGlyphs == 1) {
- //check the context for short consonant preceding char
- TUint consonantGss = aGss.iParam.iOutput[0].iCode;
- if (ThaiGlyph::IsThaiShortConsonant(consonantGss) ||
- consonantGss == ThaiGlyph::KYoYingPua ||
- consonantGss == ThaiGlyph::KThoThanPua)
- return ETrue;
- else
- return EFalse;
- }
- if (aGss.iParam.iOutputGlyphs == 2) {
- //check the context for short consonant & dependent vowel below preceding char
- TUint consonantGss = aGss.iParam.iOutput[0].iCode;
- TUint depVowelGss = aGss.iParam.iOutput[1].iCode;
- if ((ThaiGlyph::IsThaiShortConsonant(consonantGss) ||
- consonantGss == ThaiGlyph::KYoYingPua ||
- consonantGss == ThaiGlyph::KThoThanPua) &&
- (ThaiGlyph::IsThaiDepVowelBelow(depVowelGss) ||
- (depVowelGss >= 0xF718 &&
- depVowelGss <= 0xF71A)))
- return ETrue;
- else
- return EFalse;
- }
- return EFalse;
- }
-
- /**
- ThaiGlyphPUASubstitution rule method which checks the context for
- tall consonant preceding char.
- @param aGss
- Container object holds the glyph selection context for the method.
- @return TBool
- ETrue when the rule context is satisfied, EFalse if not.
- */
- TBool RuleTallConsonant(const TGlyphSelectionState& aGss)
- {
- if ((aGss.iParam.iOutputGlyphs == 1) &&
- ThaiGlyph::IsThaiTallConsonant(aGss.iParam.iOutput[0].iCode))
- return ETrue;
- else
- return EFalse;
- }
-
- /**
- ThaiGlyphPUASubstitution rule method which checks the context for a tall
- consonant which does not have a dependent vowel above or a nikhahit or a
- following sara am.
- @param aGss
- Container object holds the glyph selection context for the method.
- @return TBool
- ETrue when the rule context is satisfied, EFalse if not.
- */
- TBool RuleTallConsonantNoVowelAbove(const TGlyphSelectionState& aGss)
- {
- if (aGss.iParam.iOutputGlyphs == 0)
- return EFalse;
- if (!ThaiGlyph::IsThaiTallConsonant(aGss.iParam.iOutput[0].iCode))
- return EFalse;
- if (aGss.iParam.iOutputGlyphs == 1)
- return ETrue;
- if (aGss.iParam.iOutputGlyphs != 2)
- return EFalse;
- TUint wantDepVowel = aGss.iParam.iOutput[1].iCode;
- if (ThaiGlyph::IsThaiDepVowelAbove(wantDepVowel)
- || ThaiGlyph::IsThaiDepVowelAbovePUA(wantDepVowel)
- || wantDepVowel == ThaiGlyph::KNikhahit
- || wantDepVowel == ThaiGlyph::KNikhahitPua)
- return EFalse;
- return ETrue;
- }
-
- /**
- ThaiGlyphPUASubstitution rule method which checks the context for tall
- consonant with either a dependent vowel above or nikhahit.
- @param aGss
- Container object holds the glyph selection context for the method.
- @return TBool
- ETrue when the rule context is satisfied, EFalse if not.
- */
- TBool RuleTallConsonantVowelAbove(const TGlyphSelectionState& aGss)
- {
- if ((aGss.iParam.iOutputGlyphs == 2) &&
- ThaiGlyph::IsThaiTallConsonant(aGss.iParam.iOutput[0].iCode) &&
- (ThaiGlyph::IsThaiDepVowelAbovePUA(aGss.iParam.iOutput[1].iCode))
- || aGss.iParam.iOutput[1].iCode == ThaiGlyph::KNikhahitPua)
- return ETrue;
- else
- return EFalse;
- }
-
- /**
- ThaiGlyphPUASubstitution rule method which checks the context for
- consonant with joined descender preceding char.
- @param aGss
- Container object holds the glyph selection context for the method.
- @return TBool
- ETrue when the rule context is satisfied, EFalse if not.
- */
- TBool RuleConsonantWithJointDescender(const TGlyphSelectionState& aGss)
- {
- if ((aGss.iParam.iOutputGlyphs == 1) &&
- ThaiGlyph::IsThaiConsonantWithJointDescender(aGss.iParam.iOutput[0].iCode))
- return ETrue;
- else
- return EFalse;
- }
-
-
- const PUASubstTableEntry RuleTable[] = {
- /**
- This data member of the ThaiGlyphPUASubstitution class holds rules
- on when a given PUA glyph should be substituted for the original
- 0x0Exx glyph. Table lookup returns the first match found from the
- start of the table, therefore duplicate match situations must be
- avoided in the rule set logic.
- */
- /* iOrigGlyph, iPUAGlyph, iRuleFunc */
-
- // Substitutions for a tone or sign mark above a short consonant
- { 0x0E48, 0xF70A, RuleShortConsonant },
- { 0x0E49, 0xF70B, RuleShortConsonant },
- { 0x0E4A, 0xF70C, RuleShortConsonant },
- { 0x0E4B, 0xF70D, RuleShortConsonant },
- { 0x0E4C, 0xF70E, RuleShortConsonant },
-
- // Substitutions for a vowel or sign mark above a tall consonant
- { 0x0E34, 0xF701, RuleTallConsonant },
- { 0x0E35, 0xF702, RuleTallConsonant },
- { 0x0E36, 0xF703, RuleTallConsonant },
- { 0x0E37, 0xF704, RuleTallConsonant },
- { 0x0E31, 0xF710, RuleTallConsonant },
- { 0x0E4D, 0xF711, RuleTallConsonant },
- { 0x0E47, 0xF712, RuleTallConsonant },
-
- // Substitutions for a tone or sign mark above a tall consonant
- { 0x0E48, 0xF705, RuleTallConsonantNoVowelAbove },
- { 0x0E49, 0xF706, RuleTallConsonantNoVowelAbove },
- { 0x0E4A, 0xF707, RuleTallConsonantNoVowelAbove },
- { 0x0E4B, 0xF708, RuleTallConsonantNoVowelAbove },
- { 0x0E4C, 0xF709, RuleTallConsonantNoVowelAbove },
-
- // Substitutions for a tone or sign mark above a vowel which is
- // above a tall consonant
- { 0x0E48, 0xF713, RuleTallConsonantVowelAbove },
- { 0x0E49, 0xF714, RuleTallConsonantVowelAbove },
- { 0x0E4A, 0xF715, RuleTallConsonantVowelAbove },
- { 0x0E4B, 0xF716, RuleTallConsonantVowelAbove },
- { 0x0E4C, 0xF717, RuleTallConsonantVowelAbove },
-
- // Substitutions for a vowel or sign mark below a consonant with a
- // joined descender
- { 0x0E38, 0xF718, RuleConsonantWithJointDescender },
- { 0x0E39, 0xF719, RuleConsonantWithJointDescender },
- { 0x0E3A, 0xF71A, RuleConsonantWithJointDescender },
-
- { 0, 0, 0}
-
- // Size of table at last measurement was 312 bytes. 27/6/2003
- };
-
-
- /**
- This is the lookup method to determine if the current character being
- processed needs to be substituted for a glyph in the PUA area given the
- supplied context. It scans the rule table and returns when it finds it's
- first match. Therefore duplicate match situations must be avoided in
- the rule set logic.
- @param aCode
- On input it is the character to lookup, on exit it is either unchanged
- or a code in the PUA 0xF700..0xF71A.
- @param aGss
- Container object holds the glyph selection context for the method.
- @return TBool
- ETrue when a match is found and aCode has changed, EFalse otherwise.
- */
- TBool Lookup(TUint& aCode, const TGlyphSelectionState& aGss)
- {
- const PUASubstTableEntry* tablePtr = RuleTable;
- while (tablePtr->iOrigGlyph)
- {
- if ((aCode == tablePtr->iOrigGlyph) && tablePtr->iRuleFunc(aGss))
- {
- aCode = tablePtr->iPUAGlyph;
- return ETrue; // Rule match, substitute glyph code
- }
- tablePtr++;
- }
- return EFalse; // No match in table
- }
- }
-
-
-//
-//
-// GlyphSelector_Thai Class definition
-//
-//
-
-
-/**
- This is the default glyph processing method for the Thai characters in the
- range 0x0E00..0x0E7F and is invoked from the Glyph selection algorithm in
- CFont::GetCharacterPosition() method. It is capable of processing base
- Thai characters as well as Thai combining vowels, signs a tone marks.
-@param aGss
- Container object holds the input/output parameters of the method.
-@return TBool
- ETrue when glyph cluster updated successfully, EFalse on error condition.
-@see
- The method GlyphSelector_Thai::Process() also handles it for other cases.
-*/
-TBool GlyphSelector_Thai::Process(TGlyphSelectionState& aGss, RShapeInfo&)
- {
- // Get the Unicode character codes we need to process the current
- // glyph and increment the iterator onto th next character.
- TUint prevCode = (aGss.iText.LengthToStart() > 0) ? aGss.iText.Get(-1) : 0xFFFF;
- TUint code = aGss.iText.GetThenNext(); // Inc to next char
- TUint nextCode = !aGss.iText.AtEnd() ? aGss.iText.Get(0) : 0xFFFF;
-
- // Is it a Thai base char or a mark (combining) char?
- if ((aGss.iCats & 0xF0) == TChar::EMarkGroup)
- {
-
- // Thai character is combining mark but first check to see if it
- // follows a Thai base character before processing it.
- if ((aGss.iParam.iOutputGlyphs > 0) &&
- !ThaiGlyph::IsThaiGlyph(prevCode))
- {
- (void) aGss.iText.Prev();
- aGss.iClusterState = TGlyphSelectionState::EGClusterComplete;
- return ETrue;
- }
-
- // Missing base glyph? Insert a dotted circle glyph if true.
- if (aGss.iParam.iOutputGlyphs == 0)
- {
- if (!aGss.AppendGlyphToCluster(KUnicodeDottedCircle))
- return EFalse;
- aGss.iParam.iPen += aGss.iAdvance;
- }
-
- // Test if SARA AM follows this current Thai mark, since it is
- // a SPECIAL CASE. If present we need NIKHAHIT glyph before this
- // current Thai mark char.
- if (nextCode == ThaiGlyph::KSaraAm &&
- (aGss.iParam.iOutputGlyphs == 1) && ThaiGlyph::IsThaiToneMark(code))
- {
- TUint nikhahit = ThaiGlyph::KNikhahit;
- // Check and do PUA glyph substitution on Nikhahit
- ThaiGlyphPUASubstitution::Lookup(nikhahit, aGss);
-
- if (!aGss.AppendGlyphToCluster(nikhahit))
- return EFalse;
-
- // Check and do PUA glyph substitution on combining mark
- ThaiGlyphPUASubstitution::Lookup(code, aGss);
-
- // Append the curernt Thai Mark to the output stack of glyphs.
- if (!aGss.AppendGlyphToCluster(code))
- return EFalse;
-
- // We now need to add SARA AA glyph after the current Thai mark char.
- aGss.iAdvance.iWidth = aGss.iAdvance.iHeight = 0;
- if (!aGss.AppendGlyphToCluster(ThaiGlyph::KSaraAa))
- return EFalse;
-
- // Skip the following SARA AM character since we've added
- // its glyphs to it's previous character's glyph cluster.
- // As we've added a base char to the end of the glyph cluster
- // make sure the pen is moved on by the caller.
- (void) aGss.iText.Next();
- aGss.iPen = TGlyphSelectionState::EPenAdvance_Yes;
- }
- else
- {
- // Check and do PUA glyph substitution on combining mark
- ThaiGlyphPUASubstitution::Lookup(code, aGss);
-
- // Append the curernt Thai Mark to the output stack of glyphs.
- if (!aGss.AppendGlyphToCluster(code))
- return EFalse;
-
- aGss.iPen = TGlyphSelectionState::EPenAdvance_No;
- }
- }
- else
-
- {
- // Thai character is an independent consonant, digit or sign
-
- // Handle disjoint descender consonants followed by below vowel.
- // In these two cases we substitute consonant with PUA
- // consonant that the descender removed. Check code not last one.
- if (code == ThaiGlyph::KYoYing && nextCode != 0xffff &&
- ThaiGlyph::IsThaiDepVowelBelow(nextCode))
- code = ThaiGlyph::KYoYingPua;
- else if (code == ThaiGlyph::KThoThan && nextCode != 0xffff &&
- ThaiGlyph::IsThaiDepVowelBelow(nextCode))
- code = ThaiGlyph::KThoThanPua;
-
- // Append the glyph details for the Thai character onto the output
- // stack of glyphs.
- if (!aGss.AppendGlyphToCluster(code))
- return EFalse;
-
- // Make sure the caller advances the pen for a base char!
- aGss.iPen = TGlyphSelectionState::EPenAdvance_Yes;
- }
-
- // Lookup in rule table to determine if the current glyph and cluster is
- // now complete?
- if (ThaiCharRules::LookupWtt2Rule(aGss.iCodePt, nextCode) == ThaiCharRules::EComposite)
- aGss.iClusterState = TGlyphSelectionState::EGClusterNotComplete;
- else
- aGss.iClusterState = TGlyphSelectionState::EGClusterComplete;
-
- return ETrue;
- }
-
-
-//
-//
-// GlyphSelector_ThaiSaraAm Class definition
-//
-//
-
-
-/**
- This is the glyph processing method for the Thai SARA AM (U+0E33) character
- which is handled as a special case since it is decomposed into two glyphs
- - the combining NIKHAHIT mark & SARA AA following vowel in some cases.
- It is invoked from the Glyph selection algorithm in
- CFont::GetCharacterPosition() method for all cases where SARA AM is not
- following a tone mark and thus be a glyph cluster of its own.
-@param aGss
- Container object holds the input/output parameters of the method.
-@return TBool
- ETrue when glyph cluster updated successfully, EFalse on error condition.
-@see
- The method GlyphSelector_Thai::Process() also handles it for other cases.
-*/
-TBool GlyphSelector_ThaiSaraAm::Process(TGlyphSelectionState& aGss, RShapeInfo&)
- {
- if (aGss.iCodePt != ThaiGlyph::KSaraAm) //could have got here via
- { //FindLocalisedProcessFunc in font.cpp
- RShapeInfo dummy;
- return GlyphSelector_Thai::Process(aGss, dummy);
- }
-
- // Pen advance accumulator local variable
- TSize compoundAdvance;
-
- if (aGss.iText.LengthToStart() == 0)
- {
- // If at the start of a line then render it with a preceding
- // dotted circle as this is invalid positioning for SARA AM.
-
- if (!aGss.AppendGlyphToCluster(KUnicodeDottedCircle))
- return EFalse;
- aGss.iParam.iPen += aGss.iAdvance;
-
- aGss.iAdvance.iWidth = aGss.iAdvance.iHeight = 0;
- if (!aGss.AppendGlyphToCluster(ThaiGlyph::KSaraAm))
- return EFalse;
- compoundAdvance += aGss.iAdvance;
- }
- else
- {
- // Normal condition - text iterator now some way into the text line
- // being processed.
-
- TUint prevChar = aGss.iText.Get(-1);
- if (ThaiGlyph::IsThaiShortConsonant(prevChar))
- {
- // SARA AM is following normal height consonant so we can output
- // non-decomposed SARA AM glyph.
-
- if (!aGss.AppendGlyphToCluster(ThaiGlyph::KSaraAm))
- return EFalse;
- compoundAdvance = aGss.iAdvance;
- }
- else if (ThaiGlyph::IsThaiTallConsonant(prevChar))
- {
- // SARA AM is following tall consonant so we output decomposed
- // version of SARA AM but with NIKHAHIT taken from the PUA.
-
- if (!aGss.AppendGlyphToCluster(ThaiGlyph::KNikhahitPua))
- return EFalse;
- compoundAdvance = aGss.iAdvance;
- aGss.iAdvance.iWidth = aGss.iAdvance.iHeight = 0;
- if (!aGss.AppendGlyphToCluster(ThaiGlyph::KSaraAa))
- return EFalse;
- compoundAdvance += aGss.iAdvance;
- }
- else
- {
- // SARA AM is a following vowel but is not following a valid
- // consonant char and so default is to render with dotted circle.
- if (!aGss.AppendGlyphToCluster(KUnicodeDottedCircle))
- return EFalse;
- aGss.iParam.iPen += aGss.iAdvance;
-
- aGss.iAdvance.iWidth = aGss.iAdvance.iHeight = 0;
- if (!aGss.AppendGlyphToCluster(ThaiGlyph::KSaraAm))
- return EFalse;
- compoundAdvance += aGss.iAdvance;
- }
-
- }
-
- // Update output parameters resulting from above processing.
- // Move text iterator onto next character to process.
- aGss.iText.Next();
-
- // Advance pen just for the SARA AA char as advance for dotted
- // circle is done above.
- aGss.iAdvance = compoundAdvance;
- aGss.iPen = TGlyphSelectionState::EPenAdvance_Yes;
-
- if (!aGss.iText.AtEnd() &&
- (ThaiCharRules::LookupWtt2Rule(aGss.iCodePt, aGss.iText.Get()) ==
- ThaiCharRules::EComposite))
- aGss.iClusterState = TGlyphSelectionState::EGClusterNotComplete;
- else
- aGss.iClusterState = TGlyphSelectionState::EGClusterComplete;
-
- return ETrue;
- }