Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / MS / Internal / Shaping / IndicFontClient.cs / 1 / IndicFontClient.cs
//---------------------------------------------------------------------- // // Microsoft Windows Client Platform // Copyright (C) Microsoft Corporation, 2003 // // File: IndicCharClassifier.cs // // Contents: Implementation of Indic shaping engine and its factory // // Created: 03-04-2007 Nick Beal (nbeal) // //----------------------------------------------------------------------- // #define VALIDATE_CLUSTER_PARAMETERS using System; using System.Security; using System.Security.Permissions; using System.Diagnostics; using System.Collections; using System.Globalization; using System.Windows; using System.Windows.Media; using System.Windows.Media.TextFormatting; using MS.Internal.FontCache; using MS.Internal.FontFace; using MS.Internal.PresentationCore; namespace MS.Internal.Shaping { ////// IndicFontClient - /// internal class IndicFontClient : ShaperFontClient { private bool _useV2ScriptTag; private bool _isFormsDiscoveryDone; // private bool _areConsonantFormsCached; // private byte[] _charFormsInfo; private ushort _halantGlyph; private IndicCharClassifier _indicCharConverter; public IndicFontClient( GlyphTypeface fontFace, IndicCharClassifier indicCharConverter ) : base(fontFace, indicCharConverter) { _halantGlyph = 0; _useV2ScriptTag = true; _isFormsDiscoveryDone = false; // _areConsonantFormsCached = false; _indicCharConverter = indicCharConverter; } ////// IndicFontClient.Initialize - initializer /// ////// Critical - The method reads raw font table bits (i.e. FindLangSys()). /// [SecurityCritical] public override bool Initialize( OpenTypeLayoutWorkspace layoutWorkspace, OpenTypeTags featureType, ScriptID scriptID, LanguageTags langSysTag ) { bool success = base.Initialize(layoutWorkspace,featureType,scriptID,langSysTag); if (success && !_isFormsDiscoveryDone) { IndicCharConverter.GetFontCharacterFormsInfo(this); } return success; } ////// OpenType script tag supported by this shaping engine /// public bool IsIndicV2Font { get{ return _useV2ScriptTag; } } internal IndicCharClassifier IndicCharConverter { get { return _indicCharConverter; } } public uint[] ScriptGsubFeaturesList { get { return GetGsubFeaturesList(); } } // public uint[] ScriptSubstitutionFeaturesList // { // get { return _indicSubstitutionFeatures; } // } ////// Critical - calls critical code, passes pointer parameters /// public ushort HalantGlyph { [SecurityCritical] get { if (_halantGlyph == 0) { _halantGlyph = IndicCharConverter.ToGlyph(IndicCharConverter.HalantCharacter); } return _halantGlyph; } } ////// Returns the font's script tag /// public override ScriptTags ToScriptTag (ScriptID scriptID) { if (_useV2ScriptTag) { switch (scriptID) { case ScriptID.Devanagari: return ScriptTags.Devanagari_v2; case ScriptID.Bengali: return ScriptTags.Bengali_v2; case ScriptID.Gurmukhi: return ScriptTags.Gurmukhi_v2; case ScriptID.Gujarati: return ScriptTags.Gujarati_v2; case ScriptID.Oriya: return ScriptTags.Oriya_v2; case ScriptID.Tamil: return ScriptTags.Tamil_v2; case ScriptID.Telugu: return ScriptTags.Telugu_v2; case ScriptID.Kannada: return ScriptTags.Kannada_v2; case ScriptID.Malayalam: return ScriptTags.Malayalam_v2; default: break; } } return Script.ToTag(scriptID); } ////// Critical - The method reads raw font table bits (i.e. FindLangSys()). /// [SecurityCritical] public bool ValidateScriptTag (ScriptTags scriptTag) { bool isScriptTagValid = false; if (_useV2ScriptTag) { ScriptTags v2Tag = 0; // convert script tags to version 2... switch (scriptTag) { case ScriptTags.Devanagari: v2Tag = ScriptTags.Devanagari_v2; break; case ScriptTags.Bengali: v2Tag = ScriptTags.Bengali_v2; break; case ScriptTags.Gurmukhi: v2Tag = ScriptTags.Gurmukhi_v2; break; case ScriptTags.Gujarati: v2Tag = ScriptTags.Gujarati_v2; break; case ScriptTags.Oriya: v2Tag = ScriptTags.Oriya_v2; break; case ScriptTags.Tamil: v2Tag = ScriptTags.Tamil_v2; break; case ScriptTags.Telugu: v2Tag = ScriptTags.Telugu_v2; break; case ScriptTags.Kannada: v2Tag = ScriptTags.Kannada_v2; break; case ScriptTags.Malayalam: v2Tag = ScriptTags.Malayalam_v2; break; default: Debug.Assert(false, "Script tag is not Indic tag."); return false; } if (OpenTypeLayout.FindScript(this,(uint)v2Tag) != TagInfoFlags.None) { isScriptTagValid = true; // v2 script tag exists in this font } else { _useV2ScriptTag = false; } } if (OpenTypeLayout.FindScript(this,(uint)scriptTag) != TagInfoFlags.None) { isScriptTagValid = true; // v1 script tag exists in this font } return isScriptTagValid; } private uint[] GetGsubFeaturesList () { switch (IndicCharConverter.ScriptIx) { case IndicScriptIndices.Devanagari: return _hindiGsubFeatures; case IndicScriptIndices.Bengali: return _bengaliGsubFeatures; case IndicScriptIndices.Gurmukhi: return _gurmukhiGsubFeatures; case IndicScriptIndices.Gujarati: return _gujaratiGsubFeatures; case IndicScriptIndices.Oriya: return _oriyaGsubFeatures; case IndicScriptIndices.Tamil: return _tamilGsubFeatures; case IndicScriptIndices.Telugu: return _teluguGsubFeatures; case IndicScriptIndices.Kannada: return _kannadaGsubFeatures; case IndicScriptIndices.Malayalam: return _malayalamGsubFeatures; default: throw new NotSupportedException(); } } ////// Critical - calls critical code /// [SecurityCritical] public bool GetCachedCharacterFormsInfo ( byte[] charFormsInfo ) { return false; } private const CharShapeInfo IndicCharClassMask = (CharShapeInfo)IndicCharClass.CharClassMask; //////IndicCharClassifier.GetFontFormsInfo - gets the consonant forms features that this font supports /// ////// Critical - calls critical code /// [SecurityCritical] public bool GetCharacterFormsInfo ( byte[] formsInfo ) { if ( !_useV2ScriptTag && IndicCharConverter.ScriptIx == IndicScriptIndices.Tamil ) { return false; } bool isFontFormInfoValidated = GetCachedCharacterFormsInfo(formsInfo); if ( !isFontFormInfoValidated ) { // forms info isn't cached for this font, so do the work now... ushort halantGlyph = HalantGlyph; CharShapeInfo halantShape = IndicCharConverter.ToShapeInfo(IndicCharConverter.HalantCharacter); GlyphInfoList glyphs = new GlyphInfoList(2,1,false); UshortList charMap = new UshortList(2,1); glyphs.SetRange(0,2); charMap.SetRange(0,2); uint[] featureTags = GetGsubFeaturesList(); bool isOldStyleKartikaFont = !_useV2ScriptTag && IndicCharConverter.ScriptIx == IndicScriptIndices.Malayalam; Feature[] fontFeatures = new Feature[1]; fontFeatures[0] = new Feature(0,2,(uint)FeatureTags.RephForm,1); // test font for various consonant forms for (int i = 0; i < IndicCharClassifier.CharsPerIndicScript; ++i) { char consonantChar = (char)(IndicCharConverter.FirstCharacterInScriptRange + i); CharShapeInfo charShape = IndicCharConverter.ToShapeInfo(consonantChar); IndicCharClass charClass = (IndicCharClass)(charShape & IndicCharClassMask); // copy over non-consonant form info without modifying it // (assume this is a non-consonant) formsInfo[i] = (byte)IndicCharConverter.ToFormInfo(consonantChar); // now check if this is an interesting consonant if (charClass == IndicCharClass.Consonant || charClass == IndicCharClass.Ra || charClass == IndicCharClass.NuktaConsonant) { // clear any unverified consonant form info except bengali init form // (keep that flag because we're not going to try to validate 'init') formsInfo[i] = (byte)(formsInfo[i] & (byte)(IndicFormFlags.InitForm | (isOldStyleKartikaFont ? (IndicFormFlags.SubForm | IndicFormFlags.PostForm | IndicFormFlags.DravidianBase | IndicFormFlags.PostbaseReph ) : 0))); // apply features for (ushort tagIx = 0; tagIx < featureTags.Length; ++tagIx) { IndicFormFlags consonantFormFlags; bool isPostMainForm = true; bool useVCOrder = _useV2ScriptTag; // if v2 fonts, expect features to work with h+C, not C+h switch ( featureTags[tagIx] ) { case (uint)FeatureTags.PrebaseForms: if (isOldStyleKartikaFont) { continue; } consonantFormFlags = IndicFormFlags.PostbaseReph; break; case (uint)FeatureTags.BelowBaseForms: consonantFormFlags = IndicFormFlags.SubForm; if (isOldStyleKartikaFont) { if (((byte)consonantFormFlags & formsInfo[i]) != 0) { isFontFormInfoValidated = true; } continue; } break; case (uint)FeatureTags.PostbaseForms: consonantFormFlags = IndicFormFlags.PostForm; if (isOldStyleKartikaFont) { if (((byte)consonantFormFlags & formsInfo[i]) != 0) { isFontFormInfoValidated = true; } continue; } break; case (uint)FeatureTags.VattuVariants: consonantFormFlags = IndicFormFlags.VattuForm; if (!_useV2ScriptTag && i == IndicCharClassifier.RaOffset && (IndicCharConverter.ToFormInfo(consonantChar) & IndicFormFlags.VattuForm) != 0) { // for XP-style fonts, if the static table says the ra has a // vattu form, then assume that its so. formsInfo[i] |= (byte)consonantFormFlags; continue; } break; case (uint)FeatureTags.HalfForms: consonantFormFlags = IndicFormFlags.HalfForm; isPostMainForm = useVCOrder = false; break; case (uint)FeatureTags.RephForm: consonantFormFlags = IndicFormFlags.RephForm; isPostMainForm = useVCOrder = false; break; default: continue; } fontFeatures[0].Tag = featureTags[tagIx]; // initialize glyphs, charMap for (ushort ix = 0; ix < 2; ++ix) { glyphs.LigatureCounts[ix] = 1; glyphs.GlyphFlags[ix] = (ushort)GlyphFlags.Unresolved; glyphs.FirstChars[ix] = ix; glyphs.Glyphs[ix] = HalantGlyph; charMap[ix] = ix; } glyphs.Glyphs[useVCOrder ? 1 : 0] = IndicCharConverter.ToGlyph(consonantChar); // Apply the Indic Text Features from currentRun SubstituteGlyphs( fontFeatures, 1, charMap, glyphs); if (glyphs.Length == 1) // if the 2 characters became one glyph... { formsInfo[i] |= (byte)consonantFormFlags; if (isPostMainForm) { // we found a virama+consonant lookup! // (must be a good font!) isFontFormInfoValidated = true; } glyphs.SetLength(2); } } } } } // now would be a great time to cache the font's character form information _isFormsDiscoveryDone = true; return isFontFormInfoValidated; } // Indic (all scripts) required substitution presentation forms // private static readonly uint[] _indicSubstitutionFeatures = // { // (uint)FeatureTags.PrebaseSubstitutions, // (uint)FeatureTags.AboveBaseSubstitutions, // (uint)FeatureTags.BelowBaseSubstitutions, // (uint)FeatureTags.PostbaseSubstitutions, // (uint)FeatureTags.HalantForms, // (uint)FeatureTags.ContextualAlternates, // }; // Bengali Script required substitution form features // private static readonly uint[] _bengaliGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.HalfForms, (uint)FeatureTags.PostbaseForms, (uint)FeatureTags.VattuVariants, (uint)FeatureTags.Conjuncts, (uint)FeatureTags.InitialForms, }; // Gujarati Script required substitution form features // private static readonly uint[] _gujaratiGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.RakarForms, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.HalfForms, (uint)FeatureTags.VattuVariants, (uint)FeatureTags.Conjuncts, }; // Gurmukhi Script required substitution form features // private static readonly uint[] _gurmukhiGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.Akhands, (uint)FeatureTags.RephForm, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.HalfForms, (uint)FeatureTags.PostbaseForms, (uint)FeatureTags.VattuVariants, (uint)FeatureTags.Conjuncts, }; // Hindi (Devanagari) Script required substitution form features // private static readonly uint[] _hindiGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.RakarForms, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.HalfForms, (uint)FeatureTags.VattuVariants, (uint)FeatureTags.Conjuncts, }; // Kannada Script required substitution form features // private static readonly uint[] _kannadaGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.PrebaseForms, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.HalfForms, (uint)FeatureTags.PostbaseForms, (uint)FeatureTags.Conjuncts, }; // Malayalam Script required substitution form features // private static readonly uint[] _malayalamGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.PrebaseForms, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.HalfForms, (uint)FeatureTags.PostbaseForms, (uint)FeatureTags.Conjuncts, }; // Oriya Script required substitution form features // private static readonly uint[] _oriyaGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.PostbaseForms, (uint)FeatureTags.Conjuncts, }; // Tamil Script required substitution form features // private static readonly uint[] _tamilGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.PrebaseForms, (uint)FeatureTags.HalfForms, }; // Telugu Script required substitution form features // private static readonly uint[] _teluguGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.PrebaseForms, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.HalfForms, (uint)FeatureTags.PostbaseForms, (uint)FeatureTags.Conjuncts, }; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------- // // Microsoft Windows Client Platform // Copyright (C) Microsoft Corporation, 2003 // // File: IndicCharClassifier.cs // // Contents: Implementation of Indic shaping engine and its factory // // Created: 03-04-2007 Nick Beal (nbeal) // //----------------------------------------------------------------------- // #define VALIDATE_CLUSTER_PARAMETERS using System; using System.Security; using System.Security.Permissions; using System.Diagnostics; using System.Collections; using System.Globalization; using System.Windows; using System.Windows.Media; using System.Windows.Media.TextFormatting; using MS.Internal.FontCache; using MS.Internal.FontFace; using MS.Internal.PresentationCore; namespace MS.Internal.Shaping { ////// IndicFontClient - /// internal class IndicFontClient : ShaperFontClient { private bool _useV2ScriptTag; private bool _isFormsDiscoveryDone; // private bool _areConsonantFormsCached; // private byte[] _charFormsInfo; private ushort _halantGlyph; private IndicCharClassifier _indicCharConverter; public IndicFontClient( GlyphTypeface fontFace, IndicCharClassifier indicCharConverter ) : base(fontFace, indicCharConverter) { _halantGlyph = 0; _useV2ScriptTag = true; _isFormsDiscoveryDone = false; // _areConsonantFormsCached = false; _indicCharConverter = indicCharConverter; } ////// IndicFontClient.Initialize - initializer /// ////// Critical - The method reads raw font table bits (i.e. FindLangSys()). /// [SecurityCritical] public override bool Initialize( OpenTypeLayoutWorkspace layoutWorkspace, OpenTypeTags featureType, ScriptID scriptID, LanguageTags langSysTag ) { bool success = base.Initialize(layoutWorkspace,featureType,scriptID,langSysTag); if (success && !_isFormsDiscoveryDone) { IndicCharConverter.GetFontCharacterFormsInfo(this); } return success; } ////// OpenType script tag supported by this shaping engine /// public bool IsIndicV2Font { get{ return _useV2ScriptTag; } } internal IndicCharClassifier IndicCharConverter { get { return _indicCharConverter; } } public uint[] ScriptGsubFeaturesList { get { return GetGsubFeaturesList(); } } // public uint[] ScriptSubstitutionFeaturesList // { // get { return _indicSubstitutionFeatures; } // } ////// Critical - calls critical code, passes pointer parameters /// public ushort HalantGlyph { [SecurityCritical] get { if (_halantGlyph == 0) { _halantGlyph = IndicCharConverter.ToGlyph(IndicCharConverter.HalantCharacter); } return _halantGlyph; } } ////// Returns the font's script tag /// public override ScriptTags ToScriptTag (ScriptID scriptID) { if (_useV2ScriptTag) { switch (scriptID) { case ScriptID.Devanagari: return ScriptTags.Devanagari_v2; case ScriptID.Bengali: return ScriptTags.Bengali_v2; case ScriptID.Gurmukhi: return ScriptTags.Gurmukhi_v2; case ScriptID.Gujarati: return ScriptTags.Gujarati_v2; case ScriptID.Oriya: return ScriptTags.Oriya_v2; case ScriptID.Tamil: return ScriptTags.Tamil_v2; case ScriptID.Telugu: return ScriptTags.Telugu_v2; case ScriptID.Kannada: return ScriptTags.Kannada_v2; case ScriptID.Malayalam: return ScriptTags.Malayalam_v2; default: break; } } return Script.ToTag(scriptID); } ////// Critical - The method reads raw font table bits (i.e. FindLangSys()). /// [SecurityCritical] public bool ValidateScriptTag (ScriptTags scriptTag) { bool isScriptTagValid = false; if (_useV2ScriptTag) { ScriptTags v2Tag = 0; // convert script tags to version 2... switch (scriptTag) { case ScriptTags.Devanagari: v2Tag = ScriptTags.Devanagari_v2; break; case ScriptTags.Bengali: v2Tag = ScriptTags.Bengali_v2; break; case ScriptTags.Gurmukhi: v2Tag = ScriptTags.Gurmukhi_v2; break; case ScriptTags.Gujarati: v2Tag = ScriptTags.Gujarati_v2; break; case ScriptTags.Oriya: v2Tag = ScriptTags.Oriya_v2; break; case ScriptTags.Tamil: v2Tag = ScriptTags.Tamil_v2; break; case ScriptTags.Telugu: v2Tag = ScriptTags.Telugu_v2; break; case ScriptTags.Kannada: v2Tag = ScriptTags.Kannada_v2; break; case ScriptTags.Malayalam: v2Tag = ScriptTags.Malayalam_v2; break; default: Debug.Assert(false, "Script tag is not Indic tag."); return false; } if (OpenTypeLayout.FindScript(this,(uint)v2Tag) != TagInfoFlags.None) { isScriptTagValid = true; // v2 script tag exists in this font } else { _useV2ScriptTag = false; } } if (OpenTypeLayout.FindScript(this,(uint)scriptTag) != TagInfoFlags.None) { isScriptTagValid = true; // v1 script tag exists in this font } return isScriptTagValid; } private uint[] GetGsubFeaturesList () { switch (IndicCharConverter.ScriptIx) { case IndicScriptIndices.Devanagari: return _hindiGsubFeatures; case IndicScriptIndices.Bengali: return _bengaliGsubFeatures; case IndicScriptIndices.Gurmukhi: return _gurmukhiGsubFeatures; case IndicScriptIndices.Gujarati: return _gujaratiGsubFeatures; case IndicScriptIndices.Oriya: return _oriyaGsubFeatures; case IndicScriptIndices.Tamil: return _tamilGsubFeatures; case IndicScriptIndices.Telugu: return _teluguGsubFeatures; case IndicScriptIndices.Kannada: return _kannadaGsubFeatures; case IndicScriptIndices.Malayalam: return _malayalamGsubFeatures; default: throw new NotSupportedException(); } } ////// Critical - calls critical code /// [SecurityCritical] public bool GetCachedCharacterFormsInfo ( byte[] charFormsInfo ) { return false; } private const CharShapeInfo IndicCharClassMask = (CharShapeInfo)IndicCharClass.CharClassMask; //////IndicCharClassifier.GetFontFormsInfo - gets the consonant forms features that this font supports /// ////// Critical - calls critical code /// [SecurityCritical] public bool GetCharacterFormsInfo ( byte[] formsInfo ) { if ( !_useV2ScriptTag && IndicCharConverter.ScriptIx == IndicScriptIndices.Tamil ) { return false; } bool isFontFormInfoValidated = GetCachedCharacterFormsInfo(formsInfo); if ( !isFontFormInfoValidated ) { // forms info isn't cached for this font, so do the work now... ushort halantGlyph = HalantGlyph; CharShapeInfo halantShape = IndicCharConverter.ToShapeInfo(IndicCharConverter.HalantCharacter); GlyphInfoList glyphs = new GlyphInfoList(2,1,false); UshortList charMap = new UshortList(2,1); glyphs.SetRange(0,2); charMap.SetRange(0,2); uint[] featureTags = GetGsubFeaturesList(); bool isOldStyleKartikaFont = !_useV2ScriptTag && IndicCharConverter.ScriptIx == IndicScriptIndices.Malayalam; Feature[] fontFeatures = new Feature[1]; fontFeatures[0] = new Feature(0,2,(uint)FeatureTags.RephForm,1); // test font for various consonant forms for (int i = 0; i < IndicCharClassifier.CharsPerIndicScript; ++i) { char consonantChar = (char)(IndicCharConverter.FirstCharacterInScriptRange + i); CharShapeInfo charShape = IndicCharConverter.ToShapeInfo(consonantChar); IndicCharClass charClass = (IndicCharClass)(charShape & IndicCharClassMask); // copy over non-consonant form info without modifying it // (assume this is a non-consonant) formsInfo[i] = (byte)IndicCharConverter.ToFormInfo(consonantChar); // now check if this is an interesting consonant if (charClass == IndicCharClass.Consonant || charClass == IndicCharClass.Ra || charClass == IndicCharClass.NuktaConsonant) { // clear any unverified consonant form info except bengali init form // (keep that flag because we're not going to try to validate 'init') formsInfo[i] = (byte)(formsInfo[i] & (byte)(IndicFormFlags.InitForm | (isOldStyleKartikaFont ? (IndicFormFlags.SubForm | IndicFormFlags.PostForm | IndicFormFlags.DravidianBase | IndicFormFlags.PostbaseReph ) : 0))); // apply features for (ushort tagIx = 0; tagIx < featureTags.Length; ++tagIx) { IndicFormFlags consonantFormFlags; bool isPostMainForm = true; bool useVCOrder = _useV2ScriptTag; // if v2 fonts, expect features to work with h+C, not C+h switch ( featureTags[tagIx] ) { case (uint)FeatureTags.PrebaseForms: if (isOldStyleKartikaFont) { continue; } consonantFormFlags = IndicFormFlags.PostbaseReph; break; case (uint)FeatureTags.BelowBaseForms: consonantFormFlags = IndicFormFlags.SubForm; if (isOldStyleKartikaFont) { if (((byte)consonantFormFlags & formsInfo[i]) != 0) { isFontFormInfoValidated = true; } continue; } break; case (uint)FeatureTags.PostbaseForms: consonantFormFlags = IndicFormFlags.PostForm; if (isOldStyleKartikaFont) { if (((byte)consonantFormFlags & formsInfo[i]) != 0) { isFontFormInfoValidated = true; } continue; } break; case (uint)FeatureTags.VattuVariants: consonantFormFlags = IndicFormFlags.VattuForm; if (!_useV2ScriptTag && i == IndicCharClassifier.RaOffset && (IndicCharConverter.ToFormInfo(consonantChar) & IndicFormFlags.VattuForm) != 0) { // for XP-style fonts, if the static table says the ra has a // vattu form, then assume that its so. formsInfo[i] |= (byte)consonantFormFlags; continue; } break; case (uint)FeatureTags.HalfForms: consonantFormFlags = IndicFormFlags.HalfForm; isPostMainForm = useVCOrder = false; break; case (uint)FeatureTags.RephForm: consonantFormFlags = IndicFormFlags.RephForm; isPostMainForm = useVCOrder = false; break; default: continue; } fontFeatures[0].Tag = featureTags[tagIx]; // initialize glyphs, charMap for (ushort ix = 0; ix < 2; ++ix) { glyphs.LigatureCounts[ix] = 1; glyphs.GlyphFlags[ix] = (ushort)GlyphFlags.Unresolved; glyphs.FirstChars[ix] = ix; glyphs.Glyphs[ix] = HalantGlyph; charMap[ix] = ix; } glyphs.Glyphs[useVCOrder ? 1 : 0] = IndicCharConverter.ToGlyph(consonantChar); // Apply the Indic Text Features from currentRun SubstituteGlyphs( fontFeatures, 1, charMap, glyphs); if (glyphs.Length == 1) // if the 2 characters became one glyph... { formsInfo[i] |= (byte)consonantFormFlags; if (isPostMainForm) { // we found a virama+consonant lookup! // (must be a good font!) isFontFormInfoValidated = true; } glyphs.SetLength(2); } } } } } // now would be a great time to cache the font's character form information _isFormsDiscoveryDone = true; return isFontFormInfoValidated; } // Indic (all scripts) required substitution presentation forms // private static readonly uint[] _indicSubstitutionFeatures = // { // (uint)FeatureTags.PrebaseSubstitutions, // (uint)FeatureTags.AboveBaseSubstitutions, // (uint)FeatureTags.BelowBaseSubstitutions, // (uint)FeatureTags.PostbaseSubstitutions, // (uint)FeatureTags.HalantForms, // (uint)FeatureTags.ContextualAlternates, // }; // Bengali Script required substitution form features // private static readonly uint[] _bengaliGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.HalfForms, (uint)FeatureTags.PostbaseForms, (uint)FeatureTags.VattuVariants, (uint)FeatureTags.Conjuncts, (uint)FeatureTags.InitialForms, }; // Gujarati Script required substitution form features // private static readonly uint[] _gujaratiGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.RakarForms, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.HalfForms, (uint)FeatureTags.VattuVariants, (uint)FeatureTags.Conjuncts, }; // Gurmukhi Script required substitution form features // private static readonly uint[] _gurmukhiGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.Akhands, (uint)FeatureTags.RephForm, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.HalfForms, (uint)FeatureTags.PostbaseForms, (uint)FeatureTags.VattuVariants, (uint)FeatureTags.Conjuncts, }; // Hindi (Devanagari) Script required substitution form features // private static readonly uint[] _hindiGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.RakarForms, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.HalfForms, (uint)FeatureTags.VattuVariants, (uint)FeatureTags.Conjuncts, }; // Kannada Script required substitution form features // private static readonly uint[] _kannadaGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.PrebaseForms, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.HalfForms, (uint)FeatureTags.PostbaseForms, (uint)FeatureTags.Conjuncts, }; // Malayalam Script required substitution form features // private static readonly uint[] _malayalamGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.PrebaseForms, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.HalfForms, (uint)FeatureTags.PostbaseForms, (uint)FeatureTags.Conjuncts, }; // Oriya Script required substitution form features // private static readonly uint[] _oriyaGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.PostbaseForms, (uint)FeatureTags.Conjuncts, }; // Tamil Script required substitution form features // private static readonly uint[] _tamilGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.NuktaForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.PrebaseForms, (uint)FeatureTags.HalfForms, }; // Telugu Script required substitution form features // private static readonly uint[] _teluguGsubFeatures = { (uint)FeatureTags.LocalizedForms, (uint)FeatureTags.RephForm, (uint)FeatureTags.Akhands, (uint)FeatureTags.PrebaseForms, (uint)FeatureTags.BelowBaseForms, (uint)FeatureTags.HalfForms, (uint)FeatureTags.PostbaseForms, (uint)FeatureTags.Conjuncts, }; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ProtectedUri.cs
- Site.cs
- DefaultTypeArgumentAttribute.cs
- ToolStripDropDownDesigner.cs
- BackStopAuthenticationModule.cs
- Mouse.cs
- AdCreatedEventArgs.cs
- LockRecursionException.cs
- QueryExpr.cs
- TextRunCache.cs
- DataContext.cs
- MdiWindowListItemConverter.cs
- Gdiplus.cs
- HttpRequestCacheValidator.cs
- MenuItemCollectionEditor.cs
- Size.cs
- TextEffectCollection.cs
- ArgIterator.cs
- SqlUserDefinedTypeAttribute.cs
- SourceInterpreter.cs
- EntityClientCacheEntry.cs
- TemplateParser.cs
- ToolStripCodeDomSerializer.cs
- EndpointInfoCollection.cs
- Slider.cs
- SwitchElementsCollection.cs
- Matrix3DConverter.cs
- SeekableReadStream.cs
- HttpModuleActionCollection.cs
- ExeConfigurationFileMap.cs
- UnsupportedPolicyOptionsException.cs
- GregorianCalendar.cs
- TrackingMemoryStreamFactory.cs
- AssemblyName.cs
- DataStorage.cs
- SimpleWorkerRequest.cs
- COM2ICategorizePropertiesHandler.cs
- SessionSymmetricTransportSecurityProtocolFactory.cs
- TemplatePagerField.cs
- PerformanceCountersElement.cs
- ComboBoxRenderer.cs
- IconHelper.cs
- ServiceCredentialsElement.cs
- ViewCellSlot.cs
- TrackingExtract.cs
- Byte.cs
- SoapFault.cs
- ActivityValidator.cs
- VideoDrawing.cs
- SvcMapFile.cs
- ParseHttpDate.cs
- BitSet.cs
- SizeConverter.cs
- parserscommon.cs
- EllipseGeometry.cs
- ControlBuilder.cs
- WebConfigurationManager.cs
- SeekableMessageNavigator.cs
- EmptyStringExpandableObjectConverter.cs
- QueueProcessor.cs
- DataGridTableCollection.cs
- LineBreak.cs
- MemberListBinding.cs
- DataGridRow.cs
- DrawingVisual.cs
- KeyboardInputProviderAcquireFocusEventArgs.cs
- ExpressionVisitor.cs
- StringValueSerializer.cs
- ComPlusSynchronizationContext.cs
- NestPullup.cs
- InfoCardRSAPKCS1SignatureDeformatter.cs
- MemberJoinTreeNode.cs
- AdornedElementPlaceholder.cs
- DiscoveryDocumentReference.cs
- RelatedEnd.cs
- EtwTrackingParticipant.cs
- SoapCodeExporter.cs
- IFlowDocumentViewer.cs
- RelationshipConverter.cs
- PixelShader.cs
- StreamInfo.cs
- BinHexDecoder.cs
- AppDomainFactory.cs
- FocusChangedEventArgs.cs
- PositiveTimeSpanValidatorAttribute.cs
- Trigger.cs
- BaseParser.cs
- XPathSelectionIterator.cs
- SubclassTypeValidatorAttribute.cs
- SerializationStore.cs
- InternalEnumValidator.cs
- SqlSelectClauseBuilder.cs
- WebPartHelpVerb.cs
- FragmentNavigationEventArgs.cs
- ChineseLunisolarCalendar.cs
- ButtonChrome.cs
- FtpCachePolicyElement.cs
- SecurityTokenProvider.cs
- GridProviderWrapper.cs
- UTF8Encoding.cs