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
- UnsafeNativeMethods.cs
- PathTooLongException.cs
- SmtpNegotiateAuthenticationModule.cs
- login.cs
- XmlSchemaExternal.cs
- XmlSchemaGroup.cs
- _ProxyRegBlob.cs
- IntegerCollectionEditor.cs
- TextEditorDragDrop.cs
- NativeMethods.cs
- AutoScrollExpandMessageFilter.cs
- DataViewSetting.cs
- GeometryValueSerializer.cs
- ClassHandlersStore.cs
- CultureInfoConverter.cs
- CompilerGlobalScopeAttribute.cs
- XmlElementAttributes.cs
- IIS7WorkerRequest.cs
- RightsManagementInformation.cs
- TransactionOptions.cs
- WebPageTraceListener.cs
- ImageListDesigner.cs
- NetworkCredential.cs
- AdornedElementPlaceholder.cs
- ComboBox.cs
- TextUtf8RawTextWriter.cs
- ItemType.cs
- _KerberosClient.cs
- ContextProperty.cs
- IChannel.cs
- CrossAppDomainChannel.cs
- Attribute.cs
- basemetadatamappingvisitor.cs
- DockPattern.cs
- NotificationContext.cs
- DependencyPropertyAttribute.cs
- SqlClientPermission.cs
- ParameterReplacerVisitor.cs
- EventData.cs
- RawStylusInputCustomDataList.cs
- DiscriminatorMap.cs
- SystemWebExtensionsSectionGroup.cs
- CreateUserWizard.cs
- MediaEntryAttribute.cs
- AdCreatedEventArgs.cs
- AttributeConverter.cs
- VectorCollection.cs
- SchemaComplexType.cs
- SmiSettersStream.cs
- SmtpException.cs
- X509IssuerSerialKeyIdentifierClause.cs
- CharAnimationBase.cs
- TTSEngineProxy.cs
- DayRenderEvent.cs
- DefaultValueAttribute.cs
- UIElement3DAutomationPeer.cs
- GlyphingCache.cs
- MailDefinition.cs
- unsafeIndexingFilterStream.cs
- UriTemplateLiteralPathSegment.cs
- BindingUtils.cs
- TagMapInfo.cs
- Publisher.cs
- LabelEditEvent.cs
- InplaceBitmapMetadataWriter.cs
- Guid.cs
- Int16Storage.cs
- DataGridPagerStyle.cs
- Typeface.cs
- CompilerErrorCollection.cs
- SwitchLevelAttribute.cs
- InstanceOwner.cs
- IIS7ConfigurationLoader.cs
- StreamAsIStream.cs
- DataTransferEventArgs.cs
- FrameworkTemplate.cs
- ComponentManagerBroker.cs
- ConfigXmlSignificantWhitespace.cs
- WorkBatch.cs
- loginstatus.cs
- StylusDownEventArgs.cs
- HtmlHistory.cs
- InfiniteIntConverter.cs
- LinqDataView.cs
- SerialErrors.cs
- TdsParserStateObject.cs
- DateTimeConstantAttribute.cs
- TransformGroup.cs
- DataGridTextBox.cs
- Type.cs
- SafeLibraryHandle.cs
- CurrentChangingEventArgs.cs
- KerberosRequestorSecurityTokenAuthenticator.cs
- _SSPISessionCache.cs
- CSharpCodeProvider.cs
- GridToolTip.cs
- XmlAttributeProperties.cs
- CaseInsensitiveComparer.cs
- Substitution.cs
- SQLInt16Storage.cs