Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / 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
- ClientApiGenerator.cs
- Clipboard.cs
- HtmlImageAdapter.cs
- BoundColumn.cs
- MarkupExtensionParser.cs
- SelectedDatesCollection.cs
- LookupNode.cs
- CheckBoxBaseAdapter.cs
- ReachDocumentSequenceSerializer.cs
- MouseDevice.cs
- IndependentlyAnimatedPropertyMetadata.cs
- ModelItem.cs
- MatrixTransform.cs
- baseaxisquery.cs
- SystemPens.cs
- KeyValuePair.cs
- StringStorage.cs
- AlphaSortedEnumConverter.cs
- MiniMapControl.xaml.cs
- Baml6Assembly.cs
- RealizationDrawingContextWalker.cs
- UpnEndpointIdentity.cs
- MaskInputRejectedEventArgs.cs
- DesignerSerializationVisibilityAttribute.cs
- ListSortDescriptionCollection.cs
- HtmlTableCellCollection.cs
- XmlSchemaComplexContentExtension.cs
- CodeNamespaceImport.cs
- VScrollProperties.cs
- CustomAttribute.cs
- FtpRequestCacheValidator.cs
- ReflectPropertyDescriptor.cs
- FontWeight.cs
- RequestUriProcessor.cs
- XmlFormatReaderGenerator.cs
- ComProxy.cs
- RightsManagementEncryptionTransform.cs
- TdsParserSafeHandles.cs
- SiteOfOriginContainer.cs
- TypeSemantics.cs
- PopupRoot.cs
- ParallelTimeline.cs
- TextBox.cs
- FieldTemplateUserControl.cs
- EventManager.cs
- SchemaObjectWriter.cs
- ObjectCloneHelper.cs
- AppliedDeviceFiltersEditor.cs
- Socket.cs
- FileVersion.cs
- SafeProcessHandle.cs
- PrintDialog.cs
- MouseButton.cs
- UnsafeNativeMethods.cs
- activationcontext.cs
- TextAnchor.cs
- ApplicationManager.cs
- WindowsPrincipal.cs
- SearchForVirtualItemEventArgs.cs
- SimpleWorkerRequest.cs
- DropDownButton.cs
- DataServiceException.cs
- HandlerBase.cs
- SoapTypeAttribute.cs
- DurableTimerExtension.cs
- Exceptions.cs
- ClonableStack.cs
- MessageContractExporter.cs
- StringReader.cs
- ClientSideQueueItem.cs
- Subset.cs
- CaseInsensitiveHashCodeProvider.cs
- SerializerDescriptor.cs
- ObjectStorage.cs
- ObjectReaderCompiler.cs
- CodeTypeMember.cs
- AttributeProviderAttribute.cs
- AngleUtil.cs
- BitmapEffectInput.cs
- EntityDescriptor.cs
- KeyTime.cs
- MsmqIntegrationInputMessage.cs
- PropertyIDSet.cs
- PackWebRequest.cs
- CornerRadiusConverter.cs
- DataFormat.cs
- UnsafeNativeMethods.cs
- Pen.cs
- QueueProcessor.cs
- DriveInfo.cs
- UnsafeNativeMethods.cs
- ListItem.cs
- _IPv4Address.cs
- ClientBase.cs
- MultipleViewPattern.cs
- XmlCharacterData.cs
- ContextBase.cs
- XmlStringTable.cs
- AutomationProperty.cs
- PageThemeBuildProvider.cs