Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / MS / Internal / Shaping / FontClient.cs / 1 / FontClient.cs
//----------------------------------------------------------------------
//
// Microsoft Windows Client Platform
// Copyright (C) Microsoft Corporation, 2001
//
// File: BaseShape.cs
//
// Contents: base shaping engine classes
//
// Created: 10-22-2003
//
//-----------------------------------------------------------------------
using System;
using System.Security;
using System.Security.Permissions;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using MS.Internal.FontCache;
using MS.Internal.FontFace;
using System.Windows.Media;
using System.Windows.Media.TextFormatting;
using MS.Internal.PresentationCore;
using MS.Utility;
namespace MS.Internal.Shaping
{
///
/// OpenTypeFontClient provides the shaping engines' font/OTLS interface
///
///
/// Provides IOpenTypeFont interface for shaping engine. Also keeps
/// some basic char-to-glyph mappings as well as exposes the font's
/// cmap via an indexer.
///
internal class OpenTypeFontClient : IOpenTypeFont
{
public OpenTypeFontClient(GlyphTypeface fontFace)
{
Invariant.Assert(fontFace != null, "Null font face.");
_fontFace = fontFace;
_cmap = _fontFace.CharacterToGlyphMap;
Invariant.Assert(_cmap != null, "Null char map");
_maxValidGlyphIx = _fontFace.GlyphCount > 1 ? _fontFace.GlyphCount - 1 : 0;
}
internal IDictionary CMap
{
get { return _cmap; }
}
internal GlyphTypeface FontFace
{
get { return _fontFace; }
}
internal ushort GetMaxGlyphId
{
get { return (ushort)_maxValidGlyphIx; }
}
///
/// IOpenTypeFont implemention - Returns array containing font table data
/// Return empty array if table does not exist.
///
///
/// Critical - as this accesses FontFaceLayoutInfo.Gdef which exposes font info.
///
[SecurityCritical]
public unsafe FontTable GetFontTable(OpenTypeTags TableTag)
{
switch (TableTag)
{
case OpenTypeTags.GDEF:
if (_GdefTable == null) _GdefTable = new FontTable(_fontFace.FontFaceLayoutInfo.Gdef());
return _GdefTable;
case OpenTypeTags.GSUB:
if (_GsubTable == null) _GsubTable = new FontTable(_fontFace.FontFaceLayoutInfo.Gsub());
return _GsubTable;
case OpenTypeTags.GPOS:
if (_GposTable == null) _GposTable = new FontTable(_fontFace.FontFaceLayoutInfo.Gpos());
return _GposTable;
}
Invariant.Assert(false,"Unexpected OpenTypeLayout table tag");
return null;
}
///
/// IOpenTypeFont implementation - Returns glyph coordinate
///
public LayoutOffset GetGlyphPointCoord(ushort Glyph, ushort PointIndex)
{
return new LayoutOffset(0,0);
}
///
/// Returns cache for layout table. If cache not found, return null Checked pointer
///
/// Tag for the table requested
///
/// Critical: Calls critical code
///
[SecurityCritical]
public CheckedPointer GetTableCache(OpenTypeTags tableTag)
{
return _fontFace.FontFaceLayoutInfo.GetTableCache(tableTag);
}
///
/// Allocate space for layout table cache. If space is not available
/// return null checked pointer.
/// Only font cache implementation need to implement this interface.
/// Normal layout funcitons will not call it.
///
///
/// Critical: Calls critical code
///
[SecurityCritical]
public CheckedPointer AllocateTableCache(OpenTypeTags tableTag, int size)
{
return _fontFace.FontFaceLayoutInfo.AllocateTableCache(tableTag, size);
}
// private data
private GlyphTypeface _fontFace;
private FontTable _GposTable;
private FontTable _GsubTable;
private FontTable _GdefTable;
private int _maxValidGlyphIx;
private IDictionary _cmap;
}
///
/// DependentCharacterList - used to define any decompositions needed for composite chars in a script
///
///
///
internal struct DependentCharacterList
{
char _keyChar;
char[] _listElements;
public DependentCharacterList (char keyChar, char[] dependentElements)
{
_keyChar = keyChar;
_listElements = dependentElements;
}
public char BaseChar
{
get { return _keyChar; }
}
public char[] DependentCharacters
{
get { return _listElements; }
}
};
///
/// ShaperCharMapper - each font/script has its own char classifier
///
///
/// A ShaperCharacterClassifier is created during the IShapingEngine.OnLoadFont interface
/// methods and is then passed as a parameter for all IShaper methods.
///
internal class ShaperCharacterClassifier : IScriptCharConverter
{
protected char _firstChar; // this should be set to the scirpt's first Unicode char
protected char _lastChar; // this should be set to the script's last Unicode char
protected ushort _xorMask; // this mask is used in GetCharShapeInfo (0x7f is the most common value)
protected ushort _xorRange; // this is used in GetCharShapeInfo (0x80 is the most common value)
protected byte[] _charClassTable; // this shaper's character classification table
protected byte _spaceClass;
protected byte _shyClass;
protected byte _zwjClass;
protected byte _zwnjClass;
protected byte _zwControlClass;
protected byte _unknownClass;
private ScriptTags _scriptTag;
private GlyphTypeface _fontFace;
// these glyphs might be used to find/suppress Unicode control chars.
// private ushort _noBreakSpaceGlyph;// UnicodeNoBreakSpace = '\u00A0'; // space character
// private ushort _zwspGlyph; // UnicodeZWSP = '\u200B'; // zero-width non-joining mark
private ushort _shyGlyph; // UnicodeSHY = '\u00AD'; // soft hyphen character
private ushort _zwnjGlyph; // UnicodeZWNJ = '\u200C'; // zero-width non-joining mark
private ushort _zwjGlyph; // UnicodeZWJ = '\u200D'; // zero-width joining mark
private ushort _lrmGlyph; // UnicodeLRM = '\u200E'; // left to right mark
private ushort _rlmGlyph; // UnicodeRLM = '\u200F'; // right to left mark
public ShaperCharacterClassifier(ScriptTags scriptTag, GlyphTypeface fontFace)
{
_scriptTag = scriptTag;
_fontFace = fontFace;
}
///
/// ToGlyph - returns the glyph for the requested unicode
///
public ushort ToGlyph ( char unicodeChar )
{
ushort glyphIndex;
return _fontFace.CharacterToGlyphMap.TryGetValue(unicodeChar, out glyphIndex) ?
glyphIndex : (ushort)0;
}
///
/// Returns the shape info for the unicode character
///
public virtual CharShapeInfo ToShapeInfo (char unicodeChar)
{
if (_charClassTable != null && ((ushort)unicodeChar ^ _xorMask) < _xorRange)
{
return (CharShapeInfo)_charClassTable[unicodeChar - _firstChar];
}
else if (unicodeChar == UnicodeCharacter.Space || unicodeChar == UnicodeCharacter.NoBreakSpace)
{
return CharShapeInfo.IsStartOfCluster | (CharShapeInfo)_spaceClass;
}
else if ( (unicodeChar ^ UnicodeCharacter.RLM) < 5 || unicodeChar == '\ufeff')
{
return (CharShapeInfo.IsUnicodeLayoutControl | (CharShapeInfo)
(unicodeChar == UnicodeCharacter.ZWNJ ? _zwnjClass :
(unicodeChar == UnicodeCharacter.ZWJ ? _zwjClass : _zwControlClass))) ;
}
else if ( unicodeChar == UnicodeCharacter.SHY)
{
return (CharShapeInfo)_shyClass;
}
return CharShapeInfo.IsStartOfCluster | (CharShapeInfo)_unknownClass;
}
///
/// SetUnicodeControlGlyph - called to save local copy of pertinent glyph ids
///
///
/// This function is called by ShapingWorkspace (via ShaperFontClient)
/// when a Unicode control character is detected in the text run.
/// This allows us to cache the glyph id for use in IsUnicodeControlGlyph
/// (which may be used to suppress the display of Unicode control
/// characters). This function may be overridden for those scripts
/// that have a more extensive list of control characters
/// (see MongolianCharacterClassifier)
///
public virtual void SetUnicodeControlGlyph (char unicodeChar, ushort glyph)
{
if (glyph != 0)
{
switch (unicodeChar)
{
case UnicodeCharacter.LRM:
_lrmGlyph = glyph;
break;
case UnicodeCharacter.RLM:
_rlmGlyph = glyph;
break;
case UnicodeCharacter.ZWJ:
_zwjGlyph = glyph;
break;
case UnicodeCharacter.ZWNJ:
_zwnjGlyph = glyph;
break;
case UnicodeCharacter.SHY:
_shyGlyph = glyph;
break;
default:
break;
}
}
}
///
/// IsUnicodeControlGlyph - called to determine of the glyph is a recognized Unicode control
///
///
/// This function is called by ShapingWorkspace when it is desired to
/// suppress the display of Unicode control characters. This
/// function may be overridden for those scripts that have a more
/// extensive list of control characters (see MongolianCharacterClassifier)
///
public virtual bool IsUnicodeControlGlyph( ushort glyph )
{
if (glyph != 0)
{
if (glyph == _zwjGlyph ||
glyph == _zwnjGlyph ||
glyph == _rlmGlyph ||
glyph == _lrmGlyph)
{
return true;
}
}
return false;
}
///
/// GetDependentCharacterList - returns the character list by the base key character
/// (if one exists)
///
protected char[] GetDependentCharacterList ( char unicodeChar, DependentCharacterList[] componentList )
{
if (componentList!= null)
{
for (int i = 0; i < componentList.Length; ++i)
{
if (componentList[i].BaseChar == unicodeChar)
{
return componentList[i].DependentCharacters;
}
}
}
return null;
}
}
///
/// ShaperFontClient -instantiates the font/OTLS interface and the char classifier
///
///
/// A ShaperFontClient is created during the IShapingEngine.OnLoadFont interface
/// methods and is then passed as a parameter for all IShaper methods. This
/// extension of the OpenTypeFontClient class contains all the properties and
/// methods a shaping engine will need from the font.
///
internal class ShaperFontClient : OpenTypeFontClient
{
private ShaperCharacterClassifier _charConverter;
private bool _isScriptSupportedByFont;
private OpenTypeLayoutResult _initResult;
private OpenTypeLayoutWorkspace _layoutWorkspace;
private uint _langSysTag;
protected uint _scriptTag;
private ushort _spaceGlyph; // UnicodeSpace = '\u0020'; // space character
private ushort _dottedCircleGlyph; // UnicodeDottedCircle = '\u25CC'; // inserted base character
internal ShaperFontClient(GlyphTypeface fontFace) : base(fontFace)
{
// This constructor is used by shapers that don't care whether
// the font support the script (ie, DefaultShape) because they
// don't use the OpenType tables
_charConverter = new ShaperCharacterClassifier ((ScriptTags)0, fontFace);
_isScriptSupportedByFont = false;
_scriptTag = (uint) ScriptTags.Default;
_langSysTag = (uint) LanguageTags.Default;
}
internal ShaperFontClient(GlyphTypeface fontFace, ShaperCharacterClassifier charConverter) : base(fontFace)
{
// This constructor is used by all the complex script shapers that
// require the use of OpenType tables to shape text in the script
_charConverter = charConverter;
_isScriptSupportedByFont = true;
_scriptTag = (uint) ScriptTags.Default;
_langSysTag = (uint) LanguageTags.Default;
}
internal IScriptCharConverter CharConverter
{
get { return _charConverter; }
}
///
/// Critical - calls critical code, passes pointer parameters
///
public ushort DottedCircleGlyph
{
[SecurityCritical]
get { if (_dottedCircleGlyph == 0)
{
_dottedCircleGlyph = CharConverter.ToGlyph(UnicodeCharacter.DottedCircle);
}
return _dottedCircleGlyph;
}
}
public virtual ScriptTags ToScriptTag (ScriptID scriptID)
{
return Script.ToTag(scriptID);
}
///
/// ShaperFontClient.Initialize - initializer
///
///
/// Critical - The method reads raw font table bits (i.e. FindLangSys()).
///
[SecurityCritical]
public virtual bool Initialize(
OpenTypeLayoutWorkspace layoutWorkspace,
OpenTypeTags featureType,
ScriptID scriptID,
LanguageTags langSysTag
)
{
// Get the language & script ID to be used for the shaping process. If defined values are null
// default tags for language and script id are used.
_scriptTag = (uint) ToScriptTag(scriptID);
_langSysTag = (uint) langSysTag;
_initResult = OpenTypeLayoutResult.Success;
if (_isScriptSupportedByFont)
{
TagInfoFlags featureClass = (featureType == OpenTypeTags.GSUB ?
TagInfoFlags.Substitution : TagInfoFlags.Positioning);
if( (OpenTypeLayout.FindLangSys(this, _scriptTag, _langSysTag) &
featureClass) != featureClass )
{
_langSysTag = (uint)LanguageTags.Default;
// Check font for language system, if not supported, try to check for Default Language system
if((OpenTypeLayout.FindLangSys(this, _scriptTag, _langSysTag) & featureClass)
!= featureClass)
{
_initResult = OpenTypeLayoutResult.LangSysNotFound;
}
}
if (_initResult == OpenTypeLayoutResult.Success)
{
_layoutWorkspace = layoutWorkspace;
_initResult = layoutWorkspace.Init( this,
featureType,
_scriptTag,
_langSysTag );
}
}
return (_initResult == OpenTypeLayoutResult.Success);
}
public bool IsScriptSupportedByFont
{
get { return _isScriptSupportedByFont; }
set { _isScriptSupportedByFont = value; }
}
public bool IsFeatureTypeSupportedByFont
{
get { return _isScriptSupportedByFont && _initResult == OpenTypeLayoutResult.Success; }
}
public bool IsUnicodeControlGlyph( ushort glyph )
{
return _charConverter.IsUnicodeControlGlyph(glyph);
}
///
/// Critical - calls critical code, passes pointer parameters
///
[SecurityCritical]
public bool IsUnicodeSpaceGlyph( ushort glyph )
{
if (_spaceGlyph == 0)
{
_spaceGlyph = _charConverter.ToGlyph(UnicodeCharacter.Space);
}
return (glyph != 0 && _spaceGlyph == glyph);
}
///
/// ShaperFontClient.PositionGlyphs - GetGlyphPlacement helper.
/// This method goes through a list of glyphs and fills the glyph advances and offsets
/// arrays.
///
///
/// Most shape engines will override this method. If not overridden, this implementation
/// will attempt to apply the featureSet passed in, if the current font provides OpenType
/// GPOS support for the current script.
///
/// the wrapper for glyph advances, offset arrays
/// metrics for all the positioning features
/// Set of gpos features.
/// count of gpos features in array to be applied.
/// result of applying features
///
/// Critical - calls critical code, passes pointer parameters
///
[SecurityCritical]
unsafe public OpenTypeLayoutResult PositionGlyphs(
ref PlacementWorkspace placementInfo,
ref LayoutMetrics layoutMetrics,
Feature[] features,
int featuresCount )
{
if ( !IsFeatureTypeSupportedByFont )
{
return _initResult;
}
UshortList charMap = placementInfo.CharMap;
OpenTypeLayoutResult layoutResult = OpenTypeLayout.PositionGlyphs(
this, // In: Font access interface
_layoutWorkspace, // In/out: Workspace for OTL internal use
_scriptTag, // In: Script tag
_langSysTag, // In: LangSys tag
layoutMetrics,
features, // In: List of features to apply
featuresCount,
0,
charMap.Length, // Char count (i.e. charmaps Length);
charMap, // In/out: Char to glyph mapping
placementInfo.GlyphInfoList, // In/out: List of GlyphInfo structs
placementInfo.GlyphAdvances,
(LayoutOffset *)placementInfo.GlyphOffsets);
return layoutResult;
}
public uint ScriptTag
{
get { return _scriptTag; }
}
public void SetUnicodeControlGlyph (char unicodeChar, ushort glyph)
{
_charConverter.SetUnicodeControlGlyph(unicodeChar, glyph);
}
///
/// Critical - calls critical code, passes pointer parameters
///
public ushort SpaceGlyph
{
[SecurityCritical]
get { if (_spaceGlyph == 0)
{
_spaceGlyph = CharConverter.ToGlyph(UnicodeCharacter.Space);
}
return _spaceGlyph;
}
}
///
/// ShaperFontClient.SubstituteGlyphs - GetGlyphs() helper function.
///
///
///
/// current run of glyphs.
/// Set of gsub features.
/// count of gpos features in array to be applied.
/// result of applying features
///
/// Critical - calls critical code
///
[SecurityCritical]
public OpenTypeLayoutResult SubstituteGlyphs(
ref ShapingWorkspace currentRun,
Feature[] features,
int featuresCount )
{
return SubstituteGlyphs(features,
featuresCount,
currentRun.CharMap,
currentRun.GlyphInfoList);
}
///
/// ShaperFontClient.SubstituteGlyphs - GetGlyphs() helper function.
///
///
///
/// Set of gsub features.
/// count of gpos features in array to be applied.
/// current charMap (mapping a glyph to each character).
/// current run of glyphs.
/// result of applying features
///
/// Critical - calls critical code
///
[SecurityCritical]
public OpenTypeLayoutResult SubstituteGlyphs(
Feature[] features,
int featuresCount,
UshortList charMap,
GlyphInfoList glyphs)
{
if ( !IsFeatureTypeSupportedByFont)
{
return _initResult;
}
OpenTypeLayoutResult layoutResult = OpenTypeLayout.SubstituteGlyphs(
this, // In: Font access interface
_layoutWorkspace, // In/out: Workspace for OTL internal use
_scriptTag, // In: Script tag
_langSysTag, // In: LangSys tag
features, // In: List of features to apply
featuresCount,
0,
charMap.Length, // Char count (i.e. charmaps Length);
charMap, // In/out: Char to glyph mapping
glyphs); // In/out: List of GlyphInfo structs
return layoutResult;
}
}
}
// 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, 2001
//
// File: BaseShape.cs
//
// Contents: base shaping engine classes
//
// Created: 10-22-2003
//
//-----------------------------------------------------------------------
using System;
using System.Security;
using System.Security.Permissions;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using MS.Internal.FontCache;
using MS.Internal.FontFace;
using System.Windows.Media;
using System.Windows.Media.TextFormatting;
using MS.Internal.PresentationCore;
using MS.Utility;
namespace MS.Internal.Shaping
{
///
/// OpenTypeFontClient provides the shaping engines' font/OTLS interface
///
///
/// Provides IOpenTypeFont interface for shaping engine. Also keeps
/// some basic char-to-glyph mappings as well as exposes the font's
/// cmap via an indexer.
///
internal class OpenTypeFontClient : IOpenTypeFont
{
public OpenTypeFontClient(GlyphTypeface fontFace)
{
Invariant.Assert(fontFace != null, "Null font face.");
_fontFace = fontFace;
_cmap = _fontFace.CharacterToGlyphMap;
Invariant.Assert(_cmap != null, "Null char map");
_maxValidGlyphIx = _fontFace.GlyphCount > 1 ? _fontFace.GlyphCount - 1 : 0;
}
internal IDictionary CMap
{
get { return _cmap; }
}
internal GlyphTypeface FontFace
{
get { return _fontFace; }
}
internal ushort GetMaxGlyphId
{
get { return (ushort)_maxValidGlyphIx; }
}
///
/// IOpenTypeFont implemention - Returns array containing font table data
/// Return empty array if table does not exist.
///
///
/// Critical - as this accesses FontFaceLayoutInfo.Gdef which exposes font info.
///
[SecurityCritical]
public unsafe FontTable GetFontTable(OpenTypeTags TableTag)
{
switch (TableTag)
{
case OpenTypeTags.GDEF:
if (_GdefTable == null) _GdefTable = new FontTable(_fontFace.FontFaceLayoutInfo.Gdef());
return _GdefTable;
case OpenTypeTags.GSUB:
if (_GsubTable == null) _GsubTable = new FontTable(_fontFace.FontFaceLayoutInfo.Gsub());
return _GsubTable;
case OpenTypeTags.GPOS:
if (_GposTable == null) _GposTable = new FontTable(_fontFace.FontFaceLayoutInfo.Gpos());
return _GposTable;
}
Invariant.Assert(false,"Unexpected OpenTypeLayout table tag");
return null;
}
///
/// IOpenTypeFont implementation - Returns glyph coordinate
///
public LayoutOffset GetGlyphPointCoord(ushort Glyph, ushort PointIndex)
{
return new LayoutOffset(0,0);
}
///
/// Returns cache for layout table. If cache not found, return null Checked pointer
///
/// Tag for the table requested
///
/// Critical: Calls critical code
///
[SecurityCritical]
public CheckedPointer GetTableCache(OpenTypeTags tableTag)
{
return _fontFace.FontFaceLayoutInfo.GetTableCache(tableTag);
}
///
/// Allocate space for layout table cache. If space is not available
/// return null checked pointer.
/// Only font cache implementation need to implement this interface.
/// Normal layout funcitons will not call it.
///
///
/// Critical: Calls critical code
///
[SecurityCritical]
public CheckedPointer AllocateTableCache(OpenTypeTags tableTag, int size)
{
return _fontFace.FontFaceLayoutInfo.AllocateTableCache(tableTag, size);
}
// private data
private GlyphTypeface _fontFace;
private FontTable _GposTable;
private FontTable _GsubTable;
private FontTable _GdefTable;
private int _maxValidGlyphIx;
private IDictionary _cmap;
}
///
/// DependentCharacterList - used to define any decompositions needed for composite chars in a script
///
///
///
internal struct DependentCharacterList
{
char _keyChar;
char[] _listElements;
public DependentCharacterList (char keyChar, char[] dependentElements)
{
_keyChar = keyChar;
_listElements = dependentElements;
}
public char BaseChar
{
get { return _keyChar; }
}
public char[] DependentCharacters
{
get { return _listElements; }
}
};
///
/// ShaperCharMapper - each font/script has its own char classifier
///
///
/// A ShaperCharacterClassifier is created during the IShapingEngine.OnLoadFont interface
/// methods and is then passed as a parameter for all IShaper methods.
///
internal class ShaperCharacterClassifier : IScriptCharConverter
{
protected char _firstChar; // this should be set to the scirpt's first Unicode char
protected char _lastChar; // this should be set to the script's last Unicode char
protected ushort _xorMask; // this mask is used in GetCharShapeInfo (0x7f is the most common value)
protected ushort _xorRange; // this is used in GetCharShapeInfo (0x80 is the most common value)
protected byte[] _charClassTable; // this shaper's character classification table
protected byte _spaceClass;
protected byte _shyClass;
protected byte _zwjClass;
protected byte _zwnjClass;
protected byte _zwControlClass;
protected byte _unknownClass;
private ScriptTags _scriptTag;
private GlyphTypeface _fontFace;
// these glyphs might be used to find/suppress Unicode control chars.
// private ushort _noBreakSpaceGlyph;// UnicodeNoBreakSpace = '\u00A0'; // space character
// private ushort _zwspGlyph; // UnicodeZWSP = '\u200B'; // zero-width non-joining mark
private ushort _shyGlyph; // UnicodeSHY = '\u00AD'; // soft hyphen character
private ushort _zwnjGlyph; // UnicodeZWNJ = '\u200C'; // zero-width non-joining mark
private ushort _zwjGlyph; // UnicodeZWJ = '\u200D'; // zero-width joining mark
private ushort _lrmGlyph; // UnicodeLRM = '\u200E'; // left to right mark
private ushort _rlmGlyph; // UnicodeRLM = '\u200F'; // right to left mark
public ShaperCharacterClassifier(ScriptTags scriptTag, GlyphTypeface fontFace)
{
_scriptTag = scriptTag;
_fontFace = fontFace;
}
///
/// ToGlyph - returns the glyph for the requested unicode
///
public ushort ToGlyph ( char unicodeChar )
{
ushort glyphIndex;
return _fontFace.CharacterToGlyphMap.TryGetValue(unicodeChar, out glyphIndex) ?
glyphIndex : (ushort)0;
}
///
/// Returns the shape info for the unicode character
///
public virtual CharShapeInfo ToShapeInfo (char unicodeChar)
{
if (_charClassTable != null && ((ushort)unicodeChar ^ _xorMask) < _xorRange)
{
return (CharShapeInfo)_charClassTable[unicodeChar - _firstChar];
}
else if (unicodeChar == UnicodeCharacter.Space || unicodeChar == UnicodeCharacter.NoBreakSpace)
{
return CharShapeInfo.IsStartOfCluster | (CharShapeInfo)_spaceClass;
}
else if ( (unicodeChar ^ UnicodeCharacter.RLM) < 5 || unicodeChar == '\ufeff')
{
return (CharShapeInfo.IsUnicodeLayoutControl | (CharShapeInfo)
(unicodeChar == UnicodeCharacter.ZWNJ ? _zwnjClass :
(unicodeChar == UnicodeCharacter.ZWJ ? _zwjClass : _zwControlClass))) ;
}
else if ( unicodeChar == UnicodeCharacter.SHY)
{
return (CharShapeInfo)_shyClass;
}
return CharShapeInfo.IsStartOfCluster | (CharShapeInfo)_unknownClass;
}
///
/// SetUnicodeControlGlyph - called to save local copy of pertinent glyph ids
///
///
/// This function is called by ShapingWorkspace (via ShaperFontClient)
/// when a Unicode control character is detected in the text run.
/// This allows us to cache the glyph id for use in IsUnicodeControlGlyph
/// (which may be used to suppress the display of Unicode control
/// characters). This function may be overridden for those scripts
/// that have a more extensive list of control characters
/// (see MongolianCharacterClassifier)
///
public virtual void SetUnicodeControlGlyph (char unicodeChar, ushort glyph)
{
if (glyph != 0)
{
switch (unicodeChar)
{
case UnicodeCharacter.LRM:
_lrmGlyph = glyph;
break;
case UnicodeCharacter.RLM:
_rlmGlyph = glyph;
break;
case UnicodeCharacter.ZWJ:
_zwjGlyph = glyph;
break;
case UnicodeCharacter.ZWNJ:
_zwnjGlyph = glyph;
break;
case UnicodeCharacter.SHY:
_shyGlyph = glyph;
break;
default:
break;
}
}
}
///
/// IsUnicodeControlGlyph - called to determine of the glyph is a recognized Unicode control
///
///
/// This function is called by ShapingWorkspace when it is desired to
/// suppress the display of Unicode control characters. This
/// function may be overridden for those scripts that have a more
/// extensive list of control characters (see MongolianCharacterClassifier)
///
public virtual bool IsUnicodeControlGlyph( ushort glyph )
{
if (glyph != 0)
{
if (glyph == _zwjGlyph ||
glyph == _zwnjGlyph ||
glyph == _rlmGlyph ||
glyph == _lrmGlyph)
{
return true;
}
}
return false;
}
///
/// GetDependentCharacterList - returns the character list by the base key character
/// (if one exists)
///
protected char[] GetDependentCharacterList ( char unicodeChar, DependentCharacterList[] componentList )
{
if (componentList!= null)
{
for (int i = 0; i < componentList.Length; ++i)
{
if (componentList[i].BaseChar == unicodeChar)
{
return componentList[i].DependentCharacters;
}
}
}
return null;
}
}
///
/// ShaperFontClient -instantiates the font/OTLS interface and the char classifier
///
///
/// A ShaperFontClient is created during the IShapingEngine.OnLoadFont interface
/// methods and is then passed as a parameter for all IShaper methods. This
/// extension of the OpenTypeFontClient class contains all the properties and
/// methods a shaping engine will need from the font.
///
internal class ShaperFontClient : OpenTypeFontClient
{
private ShaperCharacterClassifier _charConverter;
private bool _isScriptSupportedByFont;
private OpenTypeLayoutResult _initResult;
private OpenTypeLayoutWorkspace _layoutWorkspace;
private uint _langSysTag;
protected uint _scriptTag;
private ushort _spaceGlyph; // UnicodeSpace = '\u0020'; // space character
private ushort _dottedCircleGlyph; // UnicodeDottedCircle = '\u25CC'; // inserted base character
internal ShaperFontClient(GlyphTypeface fontFace) : base(fontFace)
{
// This constructor is used by shapers that don't care whether
// the font support the script (ie, DefaultShape) because they
// don't use the OpenType tables
_charConverter = new ShaperCharacterClassifier ((ScriptTags)0, fontFace);
_isScriptSupportedByFont = false;
_scriptTag = (uint) ScriptTags.Default;
_langSysTag = (uint) LanguageTags.Default;
}
internal ShaperFontClient(GlyphTypeface fontFace, ShaperCharacterClassifier charConverter) : base(fontFace)
{
// This constructor is used by all the complex script shapers that
// require the use of OpenType tables to shape text in the script
_charConverter = charConverter;
_isScriptSupportedByFont = true;
_scriptTag = (uint) ScriptTags.Default;
_langSysTag = (uint) LanguageTags.Default;
}
internal IScriptCharConverter CharConverter
{
get { return _charConverter; }
}
///
/// Critical - calls critical code, passes pointer parameters
///
public ushort DottedCircleGlyph
{
[SecurityCritical]
get { if (_dottedCircleGlyph == 0)
{
_dottedCircleGlyph = CharConverter.ToGlyph(UnicodeCharacter.DottedCircle);
}
return _dottedCircleGlyph;
}
}
public virtual ScriptTags ToScriptTag (ScriptID scriptID)
{
return Script.ToTag(scriptID);
}
///
/// ShaperFontClient.Initialize - initializer
///
///
/// Critical - The method reads raw font table bits (i.e. FindLangSys()).
///
[SecurityCritical]
public virtual bool Initialize(
OpenTypeLayoutWorkspace layoutWorkspace,
OpenTypeTags featureType,
ScriptID scriptID,
LanguageTags langSysTag
)
{
// Get the language & script ID to be used for the shaping process. If defined values are null
// default tags for language and script id are used.
_scriptTag = (uint) ToScriptTag(scriptID);
_langSysTag = (uint) langSysTag;
_initResult = OpenTypeLayoutResult.Success;
if (_isScriptSupportedByFont)
{
TagInfoFlags featureClass = (featureType == OpenTypeTags.GSUB ?
TagInfoFlags.Substitution : TagInfoFlags.Positioning);
if( (OpenTypeLayout.FindLangSys(this, _scriptTag, _langSysTag) &
featureClass) != featureClass )
{
_langSysTag = (uint)LanguageTags.Default;
// Check font for language system, if not supported, try to check for Default Language system
if((OpenTypeLayout.FindLangSys(this, _scriptTag, _langSysTag) & featureClass)
!= featureClass)
{
_initResult = OpenTypeLayoutResult.LangSysNotFound;
}
}
if (_initResult == OpenTypeLayoutResult.Success)
{
_layoutWorkspace = layoutWorkspace;
_initResult = layoutWorkspace.Init( this,
featureType,
_scriptTag,
_langSysTag );
}
}
return (_initResult == OpenTypeLayoutResult.Success);
}
public bool IsScriptSupportedByFont
{
get { return _isScriptSupportedByFont; }
set { _isScriptSupportedByFont = value; }
}
public bool IsFeatureTypeSupportedByFont
{
get { return _isScriptSupportedByFont && _initResult == OpenTypeLayoutResult.Success; }
}
public bool IsUnicodeControlGlyph( ushort glyph )
{
return _charConverter.IsUnicodeControlGlyph(glyph);
}
///
/// Critical - calls critical code, passes pointer parameters
///
[SecurityCritical]
public bool IsUnicodeSpaceGlyph( ushort glyph )
{
if (_spaceGlyph == 0)
{
_spaceGlyph = _charConverter.ToGlyph(UnicodeCharacter.Space);
}
return (glyph != 0 && _spaceGlyph == glyph);
}
///
/// ShaperFontClient.PositionGlyphs - GetGlyphPlacement helper.
/// This method goes through a list of glyphs and fills the glyph advances and offsets
/// arrays.
///
///
/// Most shape engines will override this method. If not overridden, this implementation
/// will attempt to apply the featureSet passed in, if the current font provides OpenType
/// GPOS support for the current script.
///
/// the wrapper for glyph advances, offset arrays
/// metrics for all the positioning features
/// Set of gpos features.
/// count of gpos features in array to be applied.
/// result of applying features
///
/// Critical - calls critical code, passes pointer parameters
///
[SecurityCritical]
unsafe public OpenTypeLayoutResult PositionGlyphs(
ref PlacementWorkspace placementInfo,
ref LayoutMetrics layoutMetrics,
Feature[] features,
int featuresCount )
{
if ( !IsFeatureTypeSupportedByFont )
{
return _initResult;
}
UshortList charMap = placementInfo.CharMap;
OpenTypeLayoutResult layoutResult = OpenTypeLayout.PositionGlyphs(
this, // In: Font access interface
_layoutWorkspace, // In/out: Workspace for OTL internal use
_scriptTag, // In: Script tag
_langSysTag, // In: LangSys tag
layoutMetrics,
features, // In: List of features to apply
featuresCount,
0,
charMap.Length, // Char count (i.e. charmaps Length);
charMap, // In/out: Char to glyph mapping
placementInfo.GlyphInfoList, // In/out: List of GlyphInfo structs
placementInfo.GlyphAdvances,
(LayoutOffset *)placementInfo.GlyphOffsets);
return layoutResult;
}
public uint ScriptTag
{
get { return _scriptTag; }
}
public void SetUnicodeControlGlyph (char unicodeChar, ushort glyph)
{
_charConverter.SetUnicodeControlGlyph(unicodeChar, glyph);
}
///
/// Critical - calls critical code, passes pointer parameters
///
public ushort SpaceGlyph
{
[SecurityCritical]
get { if (_spaceGlyph == 0)
{
_spaceGlyph = CharConverter.ToGlyph(UnicodeCharacter.Space);
}
return _spaceGlyph;
}
}
///
/// ShaperFontClient.SubstituteGlyphs - GetGlyphs() helper function.
///
///
///
/// current run of glyphs.
/// Set of gsub features.
/// count of gpos features in array to be applied.
/// result of applying features
///
/// Critical - calls critical code
///
[SecurityCritical]
public OpenTypeLayoutResult SubstituteGlyphs(
ref ShapingWorkspace currentRun,
Feature[] features,
int featuresCount )
{
return SubstituteGlyphs(features,
featuresCount,
currentRun.CharMap,
currentRun.GlyphInfoList);
}
///
/// ShaperFontClient.SubstituteGlyphs - GetGlyphs() helper function.
///
///
///
/// Set of gsub features.
/// count of gpos features in array to be applied.
/// current charMap (mapping a glyph to each character).
/// current run of glyphs.
/// result of applying features
///
/// Critical - calls critical code
///
[SecurityCritical]
public OpenTypeLayoutResult SubstituteGlyphs(
Feature[] features,
int featuresCount,
UshortList charMap,
GlyphInfoList glyphs)
{
if ( !IsFeatureTypeSupportedByFont)
{
return _initResult;
}
OpenTypeLayoutResult layoutResult = OpenTypeLayout.SubstituteGlyphs(
this, // In: Font access interface
_layoutWorkspace, // In/out: Workspace for OTL internal use
_scriptTag, // In: Script tag
_langSysTag, // In: LangSys tag
features, // In: List of features to apply
featuresCount,
0,
charMap.Length, // Char count (i.e. charmaps Length);
charMap, // In/out: Char to glyph mapping
glyphs); // In/out: List of GlyphInfo structs
return layoutResult;
}
}
}
// 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
- webclient.cs
- GetPageNumberCompletedEventArgs.cs
- SafeEventLogWriteHandle.cs
- DataServiceExpressionVisitor.cs
- BasicBrowserDialog.designer.cs
- httpstaticobjectscollection.cs
- AccessText.cs
- StylusPlugin.cs
- InternalTransaction.cs
- ServerProtocol.cs
- BuildProviderUtils.cs
- TableCell.cs
- UnmanagedMemoryStream.cs
- DiscardableAttribute.cs
- SocketInformation.cs
- Zone.cs
- EventLogEntryCollection.cs
- DataControlFieldCollection.cs
- DataKeyArray.cs
- PropertiesTab.cs
- InputScopeAttribute.cs
- JournalEntryStack.cs
- SchemaCollectionPreprocessor.cs
- SignatureHelper.cs
- XmlSchemaSimpleTypeList.cs
- DataGridViewLinkColumn.cs
- DataGridViewTopRowAccessibleObject.cs
- ThreadStaticAttribute.cs
- WS2007HttpBindingCollectionElement.cs
- SoapExtensionTypeElement.cs
- LogicalChannelCollection.cs
- StorageRoot.cs
- EditingCommands.cs
- X509CertificateRecipientClientCredential.cs
- ContractMapping.cs
- SafeCryptContextHandle.cs
- EntitySetDataBindingList.cs
- SchemaElementDecl.cs
- HitTestWithGeometryDrawingContextWalker.cs
- SynchronizationFilter.cs
- GeneralTransformGroup.cs
- ISCIIEncoding.cs
- RelationshipNavigation.cs
- Compensation.cs
- QilTargetType.cs
- ExpressionHelper.cs
- Point4DValueSerializer.cs
- MimeTypeMapper.cs
- GeometryModel3D.cs
- SmiGettersStream.cs
- ClientApiGenerator.cs
- MsmqAuthenticationMode.cs
- GridViewPageEventArgs.cs
- DocumentGridPage.cs
- Win32Native.cs
- ConfigXmlAttribute.cs
- GridViewHeaderRowPresenter.cs
- DataContractSet.cs
- FrameworkTextComposition.cs
- TextContainerChangedEventArgs.cs
- RectangleConverter.cs
- XmlName.cs
- ADMembershipProvider.cs
- XD.cs
- ActiveXSite.cs
- BitmapEffectCollection.cs
- Rss20ItemFormatter.cs
- OuterGlowBitmapEffect.cs
- PowerModeChangedEventArgs.cs
- SqlDataSourceCache.cs
- UnsafeNativeMethods.cs
- TraceHandlerErrorFormatter.cs
- PackageRelationship.cs
- OrderByBuilder.cs
- LineServices.cs
- CounterCreationDataConverter.cs
- Compiler.cs
- autovalidator.cs
- TableCell.cs
- UriSection.cs
- ApplicationDirectoryMembershipCondition.cs
- QueueSurrogate.cs
- NativeMethods.cs
- MissingSatelliteAssemblyException.cs
- Pair.cs
- PointLight.cs
- MailBnfHelper.cs
- TypeElement.cs
- MemberDomainMap.cs
- OciEnlistContext.cs
- OleDbSchemaGuid.cs
- NavigationPropertyAccessor.cs
- ModelVisual3D.cs
- BamlVersionHeader.cs
- AttributeCollection.cs
- TextReader.cs
- WindowAutomationPeer.cs
- SchemaManager.cs
- FilterQuery.cs
- Logging.cs