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
- BulletChrome.cs
- FontDifferentiator.cs
- StringConverter.cs
- RectAnimationBase.cs
- MetadataCacheItem.cs
- DataServiceHostFactory.cs
- JournalEntry.cs
- FormsAuthenticationTicket.cs
- DataSourceControlBuilder.cs
- ButtonChrome.cs
- Pen.cs
- WindowsGraphics.cs
- MetadataPropertyAttribute.cs
- MailAddressCollection.cs
- TripleDES.cs
- WebHeaderCollection.cs
- DataMemberFieldEditor.cs
- XamlFrame.cs
- CollectionViewGroup.cs
- PropertyKey.cs
- EntityDataSourceReferenceGroup.cs
- PerformanceCounterLib.cs
- ObjectStateFormatter.cs
- PropertyGridView.cs
- NetworkInterface.cs
- TypeConverterHelper.cs
- CharConverter.cs
- MarshalByRefObject.cs
- TdsParserHelperClasses.cs
- HashStream.cs
- CodeTypeParameter.cs
- QuarticEase.cs
- InkCanvasInnerCanvas.cs
- EditorPart.cs
- VersionedStream.cs
- smtppermission.cs
- TransportSecurityProtocolFactory.cs
- SiteMapSection.cs
- MeshGeometry3D.cs
- ByteAnimationUsingKeyFrames.cs
- KeyFrames.cs
- ResourceExpressionBuilder.cs
- SqlProviderUtilities.cs
- SmtpReplyReaderFactory.cs
- HandlerFactoryWrapper.cs
- QfeChecker.cs
- InfoCardSymmetricAlgorithm.cs
- ControlPager.cs
- ControlEvent.cs
- Panel.cs
- MessageSecurityOverHttpElement.cs
- CompositeDataBoundControl.cs
- UnsafeNativeMethods.cs
- GradientBrush.cs
- Vector3DAnimationUsingKeyFrames.cs
- DeleteMemberBinder.cs
- FormViewDesigner.cs
- keycontainerpermission.cs
- GC.cs
- webeventbuffer.cs
- OpCodes.cs
- QueryLifecycle.cs
- ObjectViewEntityCollectionData.cs
- HttpPostedFile.cs
- ClientTargetSection.cs
- OletxTransactionManager.cs
- RectKeyFrameCollection.cs
- KeyedCollection.cs
- BlockCollection.cs
- XmlSchemaAnnotated.cs
- NumberFormatInfo.cs
- FileDialog.cs
- MediaCommands.cs
- IBuiltInEvidence.cs
- SmiEventSink_DeferedProcessing.cs
- DateTimeFormatInfoScanner.cs
- ConfigurationStrings.cs
- MetadataCache.cs
- UnsafeNativeMethods.cs
- SEHException.cs
- InheritablePropertyChangeInfo.cs
- Wildcard.cs
- CalendarDataBindingHandler.cs
- ObjectDataSourceSelectingEventArgs.cs
- TextOutput.cs
- OdbcConnectionHandle.cs
- TextEncodedRawTextWriter.cs
- VectorValueSerializer.cs
- GeneralTransform2DTo3DTo2D.cs
- DbConnectionStringCommon.cs
- Transform.cs
- FunctionParameter.cs
- RegexGroup.cs
- ServiceProviders.cs
- HotSpotCollectionEditor.cs
- X509Certificate2.cs
- PriorityBinding.cs
- StandardToolWindows.cs
- validationstate.cs
- RelOps.cs