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
- SimplePropertyEntry.cs
- XXXInfos.cs
- DelegateTypeInfo.cs
- LogStore.cs
- AttributeEmitter.cs
- LexicalChunk.cs
- StdRegProviderWrapper.cs
- WebPartPersonalization.cs
- DictionaryEntry.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- ThreadStartException.cs
- CssClassPropertyAttribute.cs
- ObjectConverter.cs
- EventProxy.cs
- CryptoApi.cs
- Keyboard.cs
- WebSysDefaultValueAttribute.cs
- SinglePhaseEnlistment.cs
- WebPartHeaderCloseVerb.cs
- StrongNamePublicKeyBlob.cs
- FixedDocumentSequencePaginator.cs
- DataControlFieldCollection.cs
- _TransmitFileOverlappedAsyncResult.cs
- CatalogPart.cs
- ClientSettingsStore.cs
- PrintDialog.cs
- OleDbDataAdapter.cs
- RuntimeArgumentHandle.cs
- OuterGlowBitmapEffect.cs
- StatusBarDesigner.cs
- Hex.cs
- PolyQuadraticBezierSegment.cs
- TextRunCacheImp.cs
- TableLayoutRowStyleCollection.cs
- IntSecurity.cs
- HttpRuntime.cs
- FastPropertyAccessor.cs
- Bezier.cs
- DataAdapter.cs
- TemplateAction.cs
- InstanceHandleReference.cs
- GroupPartitionExpr.cs
- TextSegment.cs
- MediaTimeline.cs
- FixedSOMSemanticBox.cs
- Stylus.cs
- TypeSystemProvider.cs
- HttpHeaderCollection.cs
- Pair.cs
- Thread.cs
- ClientProxyGenerator.cs
- PasswordRecovery.cs
- Point4D.cs
- Internal.cs
- DbProviderFactories.cs
- InvokeGenerator.cs
- XPathChildIterator.cs
- RefreshEventArgs.cs
- ConfigurationPropertyAttribute.cs
- XPathAncestorIterator.cs
- GraphicsPath.cs
- HtmlPageAdapter.cs
- HebrewNumber.cs
- ProcessHost.cs
- FileRecordSequenceCompletedAsyncResult.cs
- PersonalizablePropertyEntry.cs
- SafeNativeMethods.cs
- ColumnResizeAdorner.cs
- LessThan.cs
- ListBindingConverter.cs
- DeploymentSection.cs
- LinqMaximalSubtreeNominator.cs
- PartialClassGenerationTask.cs
- NullableDecimalMinMaxAggregationOperator.cs
- InstrumentationTracker.cs
- EncodingInfo.cs
- WeakReferenceKey.cs
- HasRunnableWorkflowEvent.cs
- SortQueryOperator.cs
- TextUtf8RawTextWriter.cs
- WindowsPrincipal.cs
- ProcessProtocolHandler.cs
- XmlSerializationWriter.cs
- WorkflowApplicationAbortedEventArgs.cs
- SourceFilter.cs
- DSGeneratorProblem.cs
- Parameter.cs
- SQLInt64.cs
- DataGridViewCellStyle.cs
- StrokeFIndices.cs
- ReflectTypeDescriptionProvider.cs
- UnsafeNativeMethods.cs
- Attributes.cs
- RepeatBehavior.cs
- SourceFileInfo.cs
- WindowsToolbarItemAsMenuItem.cs
- FormViewInsertEventArgs.cs
- WsatServiceAddress.cs
- ControlCachePolicy.cs
- BaseProcessProtocolHandler.cs