Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Core / CSharp / MS / Internal / Shaping / baseshape.cs / 1 / baseshape.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 { ////// Base implementation of IShaper /// internal class BaseShaper : IShaper { protected ShaperBuffers _shaperBuffers; protected TextFlowDirection _textFlowDirection; protected bool _forceDiacriticsToZeroWidth; internal BaseShaper () { // the shaper's persistent buffers will be created at the first InitializeFontClient // call. _shaperBuffers = null; // default text flow direction is left-to-right. Some shapers // (e.g., Arabic, Hebrew) will need to override this _textFlowDirection = TextFlowDirection.LTR; // Most shapers don't want diacritics to have any width, so this needn't be changed. // Overriding this to false will cause the GetGlyphs helper, PopulateClusterMap to // not flag diacritics as zero-width _forceDiacriticsToZeroWidth = true; } // required substitution features. The optional ligature features are not applied // if the shaper client passes in a custom set of features to apply // private static readonly Feature[] _defaultSubstitutionFeatures = new Feature[] { new Feature(0,ushort.MaxValue,(uint)FeatureTags.LocalizedForms,1), new Feature(0,ushort.MaxValue,(uint)FeatureTags.GlyphCompositionDecomposition,1), new Feature(0,ushort.MaxValue,(uint)FeatureTags.RequiredLigatures,1), new Feature(0,ushort.MaxValue,(uint)FeatureTags.ContextualAlternates,1), new Feature(0,ushort.MaxValue,(uint)FeatureTags.StandardLigatures,1), // optional new Feature(0,ushort.MaxValue,(uint)FeatureTags.ContextualLigatures,1) // optional }; private const int _countOfInhibitableLigatureFeatures = 2; // // protected static readonly Feature[] _defaultPositioningFeatures = new Feature[] { new Feature(0,ushort.MaxValue,(uint)FeatureTags.MarkPositioning,1), new Feature(0,ushort.MaxValue,(uint)FeatureTags.MarktoMarkPositioning,1), new Feature(0,ushort.MaxValue,(uint)FeatureTags.Kerning,1) }; private bool _isTracingEnabled = false; protected void RecordTraceEvent (byte eventType, String traceString ) { if (_isTracingEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.GENERICSTRINGGUID), eventType, traceString); } } ////// BaseShaper.ApplyFinalSubstitutionFeatures - default implementation of the GetGlyphs() helper function. /// /// shaping currentRun /// Set of gsub features to be applied to the unicode run. ///result of applying features ////// Critical - this method calls unsafe methods. /// [SecurityCritical] protected virtual OpenTypeLayoutResult ApplyFinalSubstitutionFeatures( ref ShapingWorkspace currentRun, FeatureSet featureSet ) { return OpenTypeLayoutResult.Success; } ////// BaseShaper.ApplyPositioningFeatures - default implementation of the 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 to be applied to the unicode run. ///result of applying features ////// Critical - this method calls unsafe methods. /// [SecurityCritical] protected virtual OpenTypeLayoutResult ApplyPositioningFeatures( ref PlacementWorkspace placementInfo, ref LayoutMetrics layoutMetrics, FeatureSet featureSet ) { ShaperFontClient fontClient = placementInfo.FontClient; OpenTypeLayoutResult layoutResult; if (featureSet != null && featureSet.FeatureCount > 0) { layoutResult = fontClient.PositionGlyphs( ref placementInfo, ref layoutMetrics, featureSet.Features, // In: List of features to apply featureSet.FeatureCount ); } else { layoutResult = fontClient.PositionGlyphs( ref placementInfo, ref layoutMetrics, _defaultPositioningFeatures, // In: List of features to apply _defaultPositioningFeatures.Length ); } return layoutResult; } ////// BaseShaper.ApplySubstitutionFeatures - default implementation of the GetGlyphs() helper function. /// This is called after every cluster (or whatever shaping "chunk" is applicable for /// the script shaper). /// /// shaping currentRun /// Set of gsub features to be applied to the unicode run. ///result of applying features ////// Critical - this method calls unsafe methods. /// [SecurityCritical] protected virtual OpenTypeLayoutResult ApplySubstitutionFeatures( ref ShapingWorkspace currentRun, FeatureSet featureSet ) { ShaperFontClient fontClient = currentRun.FontClient; OpenTypeLayoutResult layoutResult; if (featureSet != null && featureSet.FeatureCount > 0) { layoutResult = fontClient.SubstituteGlyphs( ref currentRun, featureSet.Features, // In: List of features to apply featureSet.FeatureCount ); } else { int featureCount = _defaultSubstitutionFeatures.Length; if (currentRun.AreLigaturesInhibited) { // no ligature features to be applied (except required) if inhibited // flag is set, or if featureSet exists... featureCount -= _countOfInhibitableLigatureFeatures; } layoutResult = fontClient.SubstituteGlyphs( ref currentRun, _defaultSubstitutionFeatures, // In: List of features to apply featureCount); } return layoutResult; } ////// BaseShaper.GetGlyphs - default implementation of the IShaper method. /// This method returns a list of glyphs, a character-to-glyph map, and /// a cluster map. /// ////// Most shape engines will not override this method, but rather its helper /// function, GetGlyphsList. This base implementation will call GetGlyphsList /// if the font supports OpenType GSUB features. /// The shapers in DefaultShape.cs do implement override for this function. /// /// Text item /// text culture info /// font face layout info /// OpenType features /// Controlling flags /// Shaping engine font specific data /// Incoming text /// text length /// properties of text /// Character to glyph map /// Result glyph info array /// glyph properties array /// number of glyphs produced ///true if succeeds ////// Critical - this method calls unsafe methods. /// Safe - this method returns glyph indices and shaping properties which are safe. /// [SecurityCritical, SecurityTreatAsSafe] public bool GetGlyphs( Item item, CultureInfo culture, GlyphTypeface fontFace, FeatureSet featureSet, ShapingOptions shapingFlags, object shapeFontInfo, CheckedCharPointer chars, int charCount, CheckedCharacterShapingPropertiesPointer charProperties, CheckedUShortPointer charClusterMap, out ushort[] glyphIndices, out GlyphShapingProperties[] glyphProperties, out int glyphCount ) { _isTracingEnabled = EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose); RecordTraceEvent(MS.Utility.EventType.StartEvent, "BaseShaper GetGlyphs Start"); RecordTraceEvent(MS.Utility.EventType.StartEvent, "BaseShaper Init Start"); if (charCount <= 0) { glyphCount = 0; glyphIndices = null; glyphProperties = null; return false; } ShaperFontClient fontClient = InitializeFontClient( item, culture, fontFace, OpenTypeTags.GSUB, shapeFontInfo); Invariant.Assert(_shaperBuffers != null && fontClient != null); // initialize wrapper for managing the unsafe arrays. ShapingWorkspace currentRun = new ShapingWorkspace( item, shapingFlags, fontClient, _shaperBuffers, chars, charCount, charProperties, charClusterMap); OpenTypeLayoutResult layoutResult; RecordTraceEvent(MS.Utility.EventType.EndEvent, "BaseShaper Init End"); // get character shapes and the glyphs... while (!currentRun.IsFinished) { int glyphsCount = GetGlyphs ( ref currentRun, item ); Invariant.Assert( glyphsCount > 0 ); // We've successfully created our initial list of glyphs. // Now apply the appropriate features if this is a font client // that supports this script/lang. Normally, the typographic // properties in featureSet are not applied now, but rather // in the ApplyFinalSubstitutionFeatures function (after processing // all the characters. layoutResult = ApplySubstitutionFeatures ( ref currentRun, featureSet ); if ( layoutResult != OpenTypeLayoutResult.Success ) { // we can't successfully apply our substitution features so // get glyph info for every character - no pre-substitution shaping, // just cmap lookup. return DefaultShape.DefaultShaper.GetGlyphs( item, culture, fontFace, featureSet, shapingFlags, shapeFontInfo, chars, charCount, charProperties, charClusterMap, out glyphIndices, out glyphProperties, out glyphCount ); } } // normally, the client's featureSet will be applied now to the entire glyph list. layoutResult = ApplyFinalSubstitutionFeatures ( ref currentRun, featureSet ); if ( layoutResult != OpenTypeLayoutResult.Success ) { // we can't successfully apply our substitution features so // get glyph info for every character - no pre-substitution shaping, // just cmap lookup. return DefaultShape.DefaultShaper.GetGlyphs( item, culture, fontFace, featureSet, shapingFlags, shapeFontInfo, chars, charCount, charProperties, charClusterMap, out glyphIndices, out glyphProperties, out glyphCount ); } RecordTraceEvent(MS.Utility.EventType.StartEvent, "BaseShaper PopulateClusterMap Start"); // Define the Clusters for the unicode text and set up the returned arrays. currentRun.PopulateClusterMap(); RecordTraceEvent(MS.Utility.EventType.EndEvent, "BaseShaper PopulateClusterMap End"); RecordTraceEvent(MS.Utility.EventType.StartEvent, "BaseShaper CompileShapingProperties Start"); currentRun.CompileShapingProperties( _forceDiacriticsToZeroWidth, out glyphCount, out glyphIndices, out glyphProperties ); RecordTraceEvent(MS.Utility.EventType.EndEvent, "BaseShaper CompileShapingProperties End"); RecordTraceEvent(MS.Utility.EventType.EndEvent, "BaseShaper GetGlyphs End"); return (glyphCount > 0); } ////// BaseShaper.GetGlyphs - default implementation of the GetGlyphs() helper function. /// ////// Most shape engines will override this method. If successful, the function /// will return true and will have filled the glyphInfo class, the character map, /// and the shapes list. Note that a class that wants to override this function /// must also initialize the openTypeLayoutWorkspace class member. /// /// shaping currentRun /// Text item ///number of glyphs ////// Critical - this method calls unsafe methods. /// [SecurityCritical] protected virtual int GetGlyphs ( ref ShapingWorkspace currentRun, Item item ) { // get glyph info for every character // no pre-substitution shaping, just cmap lookup. CharShapeInfo currShape; while ( currentRun.SetNextGlyphProperties (out currShape) ); return currentRun.GlyphsCount; // we're done } ////// BaseShaper.GetGlyphPlacements - default implementation of the IShaper method. /// This method goes through a list of glyphs and adds placement information. /// ////// Most shape engines will not override this method, but instead its helper function - /// GetGlyphPositions. This base implementation will call GetGlyphsList /// if the font supports OpenType GPOS features. /// /// Text item /// text culture info /// font face layout info /// OpenType features /// Controlling flags /// Shaping engine font specific data /// properties of text /// Character to glyph map /// text length /// Result glyph info array /// glyph properties array /// number of glyphs produced /// scale factor from font design unit /// List of glyph advance width /// List of glyph positioning offset ///true if succeeds ////// Critical - this method calls unsafe methods. /// Safe - this method returns glyph indices and shaping properties which are safe. /// [SecurityCritical, SecurityTreatAsSafe] public bool GetGlyphPlacements( Item item, CultureInfo culture, GlyphTypeface fontFace, FeatureSet featureSet, ShapingOptions shapingFlags, object shapeFontInfo, CheckedCharacterShapingPropertiesPointer charProperties, CheckedUShortPointer charClusterMap, int charCount, CheckedUShortPointer glyphIndices, CheckedGlyphShapingPropertiesPointer glyphProperties, int glyphCount, double scaleFactor, CheckedIntPointer glyphAdvances, CheckedGlyphOffsetPointer glyphOffsets ) { if (charCount <= 0 || glyphCount <= 0) { return false; } _isTracingEnabled = EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose); RecordTraceEvent(MS.Utility.EventType.StartEvent, "BaseShaper GetGlyphPlacements Start"); ShaperFontClient fontClient = InitializeFontClient( item, culture, fontFace, OpenTypeTags.GPOS, shapeFontInfo); bool fontSupportsScript = fontClient.IsFeatureTypeSupportedByFont; // initialize currentRun PlacementWorkspace placementInfo = new PlacementWorkspace( shapingFlags, fontClient, _shaperBuffers, charProperties, charClusterMap, charCount, glyphIndices, glyphProperties, glyphCount, glyphAdvances, glyphOffsets, fontSupportsScript, _textFlowDirection); // this is the "basic" positioning step. We just set all spacing glyphs to // the glpyh's "default" width and set all diacritics to zero width. placementInfo.InitializeGlyphInfoWidths(); // if we have a font client for this shaping engine, then check that // we support this script/language (ie, check if layoutResult from the // shapingWorkspace initialization was "success"). If so, apply the features. if ( fontSupportsScript ) { LayoutMetrics layoutMetrics = new LayoutMetrics(_textFlowDirection,0,0,0); OpenTypeLayoutResult layoutResult = ApplyPositioningFeatures ( ref placementInfo, ref layoutMetrics, featureSet ); if (layoutResult != OpenTypeLayoutResult.Success) { return false; // something's wrong, can't get glyph positions } } placementInfo.ScaleGlyphInfoWidths( scaleFactor ); RecordTraceEvent(MS.Utility.EventType.EndEvent, "BaseShaper GetGlyphPlacements End"); return true; } ////// BaseShaper.InitializeFontClient -IShaper methods helper. /// ////// This function is called from GetGlyphs and GetGlyphPlacements /// (IShaper methods) to do the necessary shaper initialization /// ////// Critical - this method calls critical methods. /// Safe - this method doesn't expose anything unsafe to the world. /// [SecurityCritical, SecurityTreatAsSafe] protected virtual ShaperFontClient InitializeFontClient ( Item item, CultureInfo culture, GlyphTypeface fontFace, OpenTypeTags featureType, object shapeFontInfo ) { ShaperFontClient fontClient = shapeFontInfo as ShaperFontClient; if (fontClient != null) { if (_shaperBuffers == null) { // if there's no buffer set created for this shaper, create one. _shaperBuffers = new ShaperBuffers( 16, 0 ); if (_shaperBuffers == null) { return null; } } fontClient.Initialize ( _shaperBuffers.LayoutWorkspace, featureType, item.Script, LanguageTags.Default ); } return fontClient; } internal ShaperBuffers ShaperBuffers // also { get { return _shaperBuffers; } } } ////// Base implementation of shaping engine with single shaper based on BaseShaper /// internal abstract class BaseShape : BaseShaper, IShapingEngine { internal BaseShape() { } ////// BaseShape.this[] - returns IShaper interface for this object /// ////// This will normally not be overridden by derived shapers /// /// run description ///this object's interface public virtual IShaper this[ItemFlags flags] { get { return (flags & ItemFlags.HasExtendedCharacter) != 0 ? DefaultShape.SurrogateShaper as IShaper : this; } } ////// BaseShaper.GetCharClassifier - IShapingEngine.OnLoadFont helper /// ////// This will normally be overridden by derived shapers. /// protected virtual ShaperCharacterClassifier GetCharClassifier(ScriptTags scriptTag, GlyphTypeface fontFace) { return new ShaperCharacterClassifier(scriptTag, fontFace); } ////// BaseShape.OnLoadFont - IShapingEngine method override. /// ////// This should normally be sufficient for most shapers - the only /// exceptions are those shapers that want to always return true /// /// Script of interest. /// Font face being loaded /// the font client ///True if font supports script. ////// Critical - This method reads into raw font table bits. /// Safe - This method doesn't expose any critical data. /// [SecurityCritical, SecurityTreatAsSafe] public virtual bool OnLoadFont( ScriptTags scriptTag, GlyphTypeface fontFace, out object shaperFontClient ) { // create the font client for this font/script ShaperFontClient fontClient = new ShaperFontClient( fontFace, GetCharClassifier (scriptTag, fontFace) ); // if font is happy with this script, return true and give caller the ShaperFontClient // to use in all method calls to us. if (OpenTypeLayout.FindScript(fontClient,(uint)scriptTag) != TagInfoFlags.None) { shaperFontClient = fontClient; return true; } else { shaperFontClient = null; return false; } } ////// BaseShape.SupportedScripts - IShapingEngine method override. /// ////// This will normally be overridden by derived shapers /// public virtual ScriptTags[] SupportedScripts { get { return Script.AllTags; } } } } // 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 { ////// Base implementation of IShaper /// internal class BaseShaper : IShaper { protected ShaperBuffers _shaperBuffers; protected TextFlowDirection _textFlowDirection; protected bool _forceDiacriticsToZeroWidth; internal BaseShaper () { // the shaper's persistent buffers will be created at the first InitializeFontClient // call. _shaperBuffers = null; // default text flow direction is left-to-right. Some shapers // (e.g., Arabic, Hebrew) will need to override this _textFlowDirection = TextFlowDirection.LTR; // Most shapers don't want diacritics to have any width, so this needn't be changed. // Overriding this to false will cause the GetGlyphs helper, PopulateClusterMap to // not flag diacritics as zero-width _forceDiacriticsToZeroWidth = true; } // required substitution features. The optional ligature features are not applied // if the shaper client passes in a custom set of features to apply // private static readonly Feature[] _defaultSubstitutionFeatures = new Feature[] { new Feature(0,ushort.MaxValue,(uint)FeatureTags.LocalizedForms,1), new Feature(0,ushort.MaxValue,(uint)FeatureTags.GlyphCompositionDecomposition,1), new Feature(0,ushort.MaxValue,(uint)FeatureTags.RequiredLigatures,1), new Feature(0,ushort.MaxValue,(uint)FeatureTags.ContextualAlternates,1), new Feature(0,ushort.MaxValue,(uint)FeatureTags.StandardLigatures,1), // optional new Feature(0,ushort.MaxValue,(uint)FeatureTags.ContextualLigatures,1) // optional }; private const int _countOfInhibitableLigatureFeatures = 2; // // protected static readonly Feature[] _defaultPositioningFeatures = new Feature[] { new Feature(0,ushort.MaxValue,(uint)FeatureTags.MarkPositioning,1), new Feature(0,ushort.MaxValue,(uint)FeatureTags.MarktoMarkPositioning,1), new Feature(0,ushort.MaxValue,(uint)FeatureTags.Kerning,1) }; private bool _isTracingEnabled = false; protected void RecordTraceEvent (byte eventType, String traceString ) { if (_isTracingEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.GENERICSTRINGGUID), eventType, traceString); } } ////// BaseShaper.ApplyFinalSubstitutionFeatures - default implementation of the GetGlyphs() helper function. /// /// shaping currentRun /// Set of gsub features to be applied to the unicode run. ///result of applying features ////// Critical - this method calls unsafe methods. /// [SecurityCritical] protected virtual OpenTypeLayoutResult ApplyFinalSubstitutionFeatures( ref ShapingWorkspace currentRun, FeatureSet featureSet ) { return OpenTypeLayoutResult.Success; } ////// BaseShaper.ApplyPositioningFeatures - default implementation of the 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 to be applied to the unicode run. ///result of applying features ////// Critical - this method calls unsafe methods. /// [SecurityCritical] protected virtual OpenTypeLayoutResult ApplyPositioningFeatures( ref PlacementWorkspace placementInfo, ref LayoutMetrics layoutMetrics, FeatureSet featureSet ) { ShaperFontClient fontClient = placementInfo.FontClient; OpenTypeLayoutResult layoutResult; if (featureSet != null && featureSet.FeatureCount > 0) { layoutResult = fontClient.PositionGlyphs( ref placementInfo, ref layoutMetrics, featureSet.Features, // In: List of features to apply featureSet.FeatureCount ); } else { layoutResult = fontClient.PositionGlyphs( ref placementInfo, ref layoutMetrics, _defaultPositioningFeatures, // In: List of features to apply _defaultPositioningFeatures.Length ); } return layoutResult; } ////// BaseShaper.ApplySubstitutionFeatures - default implementation of the GetGlyphs() helper function. /// This is called after every cluster (or whatever shaping "chunk" is applicable for /// the script shaper). /// /// shaping currentRun /// Set of gsub features to be applied to the unicode run. ///result of applying features ////// Critical - this method calls unsafe methods. /// [SecurityCritical] protected virtual OpenTypeLayoutResult ApplySubstitutionFeatures( ref ShapingWorkspace currentRun, FeatureSet featureSet ) { ShaperFontClient fontClient = currentRun.FontClient; OpenTypeLayoutResult layoutResult; if (featureSet != null && featureSet.FeatureCount > 0) { layoutResult = fontClient.SubstituteGlyphs( ref currentRun, featureSet.Features, // In: List of features to apply featureSet.FeatureCount ); } else { int featureCount = _defaultSubstitutionFeatures.Length; if (currentRun.AreLigaturesInhibited) { // no ligature features to be applied (except required) if inhibited // flag is set, or if featureSet exists... featureCount -= _countOfInhibitableLigatureFeatures; } layoutResult = fontClient.SubstituteGlyphs( ref currentRun, _defaultSubstitutionFeatures, // In: List of features to apply featureCount); } return layoutResult; } ////// BaseShaper.GetGlyphs - default implementation of the IShaper method. /// This method returns a list of glyphs, a character-to-glyph map, and /// a cluster map. /// ////// Most shape engines will not override this method, but rather its helper /// function, GetGlyphsList. This base implementation will call GetGlyphsList /// if the font supports OpenType GSUB features. /// The shapers in DefaultShape.cs do implement override for this function. /// /// Text item /// text culture info /// font face layout info /// OpenType features /// Controlling flags /// Shaping engine font specific data /// Incoming text /// text length /// properties of text /// Character to glyph map /// Result glyph info array /// glyph properties array /// number of glyphs produced ///true if succeeds ////// Critical - this method calls unsafe methods. /// Safe - this method returns glyph indices and shaping properties which are safe. /// [SecurityCritical, SecurityTreatAsSafe] public bool GetGlyphs( Item item, CultureInfo culture, GlyphTypeface fontFace, FeatureSet featureSet, ShapingOptions shapingFlags, object shapeFontInfo, CheckedCharPointer chars, int charCount, CheckedCharacterShapingPropertiesPointer charProperties, CheckedUShortPointer charClusterMap, out ushort[] glyphIndices, out GlyphShapingProperties[] glyphProperties, out int glyphCount ) { _isTracingEnabled = EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose); RecordTraceEvent(MS.Utility.EventType.StartEvent, "BaseShaper GetGlyphs Start"); RecordTraceEvent(MS.Utility.EventType.StartEvent, "BaseShaper Init Start"); if (charCount <= 0) { glyphCount = 0; glyphIndices = null; glyphProperties = null; return false; } ShaperFontClient fontClient = InitializeFontClient( item, culture, fontFace, OpenTypeTags.GSUB, shapeFontInfo); Invariant.Assert(_shaperBuffers != null && fontClient != null); // initialize wrapper for managing the unsafe arrays. ShapingWorkspace currentRun = new ShapingWorkspace( item, shapingFlags, fontClient, _shaperBuffers, chars, charCount, charProperties, charClusterMap); OpenTypeLayoutResult layoutResult; RecordTraceEvent(MS.Utility.EventType.EndEvent, "BaseShaper Init End"); // get character shapes and the glyphs... while (!currentRun.IsFinished) { int glyphsCount = GetGlyphs ( ref currentRun, item ); Invariant.Assert( glyphsCount > 0 ); // We've successfully created our initial list of glyphs. // Now apply the appropriate features if this is a font client // that supports this script/lang. Normally, the typographic // properties in featureSet are not applied now, but rather // in the ApplyFinalSubstitutionFeatures function (after processing // all the characters. layoutResult = ApplySubstitutionFeatures ( ref currentRun, featureSet ); if ( layoutResult != OpenTypeLayoutResult.Success ) { // we can't successfully apply our substitution features so // get glyph info for every character - no pre-substitution shaping, // just cmap lookup. return DefaultShape.DefaultShaper.GetGlyphs( item, culture, fontFace, featureSet, shapingFlags, shapeFontInfo, chars, charCount, charProperties, charClusterMap, out glyphIndices, out glyphProperties, out glyphCount ); } } // normally, the client's featureSet will be applied now to the entire glyph list. layoutResult = ApplyFinalSubstitutionFeatures ( ref currentRun, featureSet ); if ( layoutResult != OpenTypeLayoutResult.Success ) { // we can't successfully apply our substitution features so // get glyph info for every character - no pre-substitution shaping, // just cmap lookup. return DefaultShape.DefaultShaper.GetGlyphs( item, culture, fontFace, featureSet, shapingFlags, shapeFontInfo, chars, charCount, charProperties, charClusterMap, out glyphIndices, out glyphProperties, out glyphCount ); } RecordTraceEvent(MS.Utility.EventType.StartEvent, "BaseShaper PopulateClusterMap Start"); // Define the Clusters for the unicode text and set up the returned arrays. currentRun.PopulateClusterMap(); RecordTraceEvent(MS.Utility.EventType.EndEvent, "BaseShaper PopulateClusterMap End"); RecordTraceEvent(MS.Utility.EventType.StartEvent, "BaseShaper CompileShapingProperties Start"); currentRun.CompileShapingProperties( _forceDiacriticsToZeroWidth, out glyphCount, out glyphIndices, out glyphProperties ); RecordTraceEvent(MS.Utility.EventType.EndEvent, "BaseShaper CompileShapingProperties End"); RecordTraceEvent(MS.Utility.EventType.EndEvent, "BaseShaper GetGlyphs End"); return (glyphCount > 0); } ////// BaseShaper.GetGlyphs - default implementation of the GetGlyphs() helper function. /// ////// Most shape engines will override this method. If successful, the function /// will return true and will have filled the glyphInfo class, the character map, /// and the shapes list. Note that a class that wants to override this function /// must also initialize the openTypeLayoutWorkspace class member. /// /// shaping currentRun /// Text item ///number of glyphs ////// Critical - this method calls unsafe methods. /// [SecurityCritical] protected virtual int GetGlyphs ( ref ShapingWorkspace currentRun, Item item ) { // get glyph info for every character // no pre-substitution shaping, just cmap lookup. CharShapeInfo currShape; while ( currentRun.SetNextGlyphProperties (out currShape) ); return currentRun.GlyphsCount; // we're done } ////// BaseShaper.GetGlyphPlacements - default implementation of the IShaper method. /// This method goes through a list of glyphs and adds placement information. /// ////// Most shape engines will not override this method, but instead its helper function - /// GetGlyphPositions. This base implementation will call GetGlyphsList /// if the font supports OpenType GPOS features. /// /// Text item /// text culture info /// font face layout info /// OpenType features /// Controlling flags /// Shaping engine font specific data /// properties of text /// Character to glyph map /// text length /// Result glyph info array /// glyph properties array /// number of glyphs produced /// scale factor from font design unit /// List of glyph advance width /// List of glyph positioning offset ///true if succeeds ////// Critical - this method calls unsafe methods. /// Safe - this method returns glyph indices and shaping properties which are safe. /// [SecurityCritical, SecurityTreatAsSafe] public bool GetGlyphPlacements( Item item, CultureInfo culture, GlyphTypeface fontFace, FeatureSet featureSet, ShapingOptions shapingFlags, object shapeFontInfo, CheckedCharacterShapingPropertiesPointer charProperties, CheckedUShortPointer charClusterMap, int charCount, CheckedUShortPointer glyphIndices, CheckedGlyphShapingPropertiesPointer glyphProperties, int glyphCount, double scaleFactor, CheckedIntPointer glyphAdvances, CheckedGlyphOffsetPointer glyphOffsets ) { if (charCount <= 0 || glyphCount <= 0) { return false; } _isTracingEnabled = EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.verbose); RecordTraceEvent(MS.Utility.EventType.StartEvent, "BaseShaper GetGlyphPlacements Start"); ShaperFontClient fontClient = InitializeFontClient( item, culture, fontFace, OpenTypeTags.GPOS, shapeFontInfo); bool fontSupportsScript = fontClient.IsFeatureTypeSupportedByFont; // initialize currentRun PlacementWorkspace placementInfo = new PlacementWorkspace( shapingFlags, fontClient, _shaperBuffers, charProperties, charClusterMap, charCount, glyphIndices, glyphProperties, glyphCount, glyphAdvances, glyphOffsets, fontSupportsScript, _textFlowDirection); // this is the "basic" positioning step. We just set all spacing glyphs to // the glpyh's "default" width and set all diacritics to zero width. placementInfo.InitializeGlyphInfoWidths(); // if we have a font client for this shaping engine, then check that // we support this script/language (ie, check if layoutResult from the // shapingWorkspace initialization was "success"). If so, apply the features. if ( fontSupportsScript ) { LayoutMetrics layoutMetrics = new LayoutMetrics(_textFlowDirection,0,0,0); OpenTypeLayoutResult layoutResult = ApplyPositioningFeatures ( ref placementInfo, ref layoutMetrics, featureSet ); if (layoutResult != OpenTypeLayoutResult.Success) { return false; // something's wrong, can't get glyph positions } } placementInfo.ScaleGlyphInfoWidths( scaleFactor ); RecordTraceEvent(MS.Utility.EventType.EndEvent, "BaseShaper GetGlyphPlacements End"); return true; } ////// BaseShaper.InitializeFontClient -IShaper methods helper. /// ////// This function is called from GetGlyphs and GetGlyphPlacements /// (IShaper methods) to do the necessary shaper initialization /// ////// Critical - this method calls critical methods. /// Safe - this method doesn't expose anything unsafe to the world. /// [SecurityCritical, SecurityTreatAsSafe] protected virtual ShaperFontClient InitializeFontClient ( Item item, CultureInfo culture, GlyphTypeface fontFace, OpenTypeTags featureType, object shapeFontInfo ) { ShaperFontClient fontClient = shapeFontInfo as ShaperFontClient; if (fontClient != null) { if (_shaperBuffers == null) { // if there's no buffer set created for this shaper, create one. _shaperBuffers = new ShaperBuffers( 16, 0 ); if (_shaperBuffers == null) { return null; } } fontClient.Initialize ( _shaperBuffers.LayoutWorkspace, featureType, item.Script, LanguageTags.Default ); } return fontClient; } internal ShaperBuffers ShaperBuffers // also { get { return _shaperBuffers; } } } ////// Base implementation of shaping engine with single shaper based on BaseShaper /// internal abstract class BaseShape : BaseShaper, IShapingEngine { internal BaseShape() { } ////// BaseShape.this[] - returns IShaper interface for this object /// ////// This will normally not be overridden by derived shapers /// /// run description ///this object's interface public virtual IShaper this[ItemFlags flags] { get { return (flags & ItemFlags.HasExtendedCharacter) != 0 ? DefaultShape.SurrogateShaper as IShaper : this; } } ////// BaseShaper.GetCharClassifier - IShapingEngine.OnLoadFont helper /// ////// This will normally be overridden by derived shapers. /// protected virtual ShaperCharacterClassifier GetCharClassifier(ScriptTags scriptTag, GlyphTypeface fontFace) { return new ShaperCharacterClassifier(scriptTag, fontFace); } ////// BaseShape.OnLoadFont - IShapingEngine method override. /// ////// This should normally be sufficient for most shapers - the only /// exceptions are those shapers that want to always return true /// /// Script of interest. /// Font face being loaded /// the font client ///True if font supports script. ////// Critical - This method reads into raw font table bits. /// Safe - This method doesn't expose any critical data. /// [SecurityCritical, SecurityTreatAsSafe] public virtual bool OnLoadFont( ScriptTags scriptTag, GlyphTypeface fontFace, out object shaperFontClient ) { // create the font client for this font/script ShaperFontClient fontClient = new ShaperFontClient( fontFace, GetCharClassifier (scriptTag, fontFace) ); // if font is happy with this script, return true and give caller the ShaperFontClient // to use in all method calls to us. if (OpenTypeLayout.FindScript(fontClient,(uint)scriptTag) != TagInfoFlags.None) { shaperFontClient = fontClient; return true; } else { shaperFontClient = null; return false; } } ////// BaseShape.SupportedScripts - IShapingEngine method override. /// ////// This will normally be overridden by derived shapers /// public virtual ScriptTags[] SupportedScripts { get { return Script.AllTags; } } } } // 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
- CuspData.cs
- EventsTab.cs
- EntityClassGenerator.cs
- ResourceType.cs
- DispatcherHooks.cs
- CodeSubDirectoriesCollection.cs
- SiteOfOriginPart.cs
- ReflectionPermission.cs
- PassportIdentity.cs
- ValidationEventArgs.cs
- TabOrder.cs
- TimeSpanStorage.cs
- IisNotInstalledException.cs
- SmiEventSink.cs
- ExtractCollection.cs
- GeneralTransform3D.cs
- StringDictionaryCodeDomSerializer.cs
- formatter.cs
- COAUTHIDENTITY.cs
- RecognitionResult.cs
- Int16Converter.cs
- TimeSpanStorage.cs
- ToolboxItemSnapLineBehavior.cs
- DrawingContextDrawingContextWalker.cs
- BlurBitmapEffect.cs
- NullableDecimalAverageAggregationOperator.cs
- Typography.cs
- WorkflowServiceHostFactory.cs
- SemanticResultValue.cs
- BreakSafeBase.cs
- WMIGenerator.cs
- TypefaceCollection.cs
- ScrollViewer.cs
- AbandonedMutexException.cs
- MsmqIntegrationMessagePool.cs
- WhiteSpaceTrimStringConverter.cs
- LockedActivityGlyph.cs
- IConvertible.cs
- BitmapCodecInfo.cs
- BuildManager.cs
- BinarySerializer.cs
- RSAPKCS1KeyExchangeFormatter.cs
- XPathDocumentNavigator.cs
- XmlName.cs
- Model3DGroup.cs
- StylusPointDescription.cs
- WindowShowOrOpenTracker.cs
- MenuItemBindingCollection.cs
- CalendarButton.cs
- elementinformation.cs
- InfiniteIntConverter.cs
- DBDataPermission.cs
- querybuilder.cs
- SchemaTableOptionalColumn.cs
- TranslateTransform.cs
- ExtentCqlBlock.cs
- DataPagerCommandEventArgs.cs
- KeyConverter.cs
- TextDecorationLocationValidation.cs
- ApplicationDirectory.cs
- PropertyStore.cs
- DeflateStream.cs
- VersionPair.cs
- AnnotationDocumentPaginator.cs
- EventSinkHelperWriter.cs
- AttributeCollection.cs
- PropertyFilter.cs
- DbProviderManifest.cs
- ShaderRenderModeValidation.cs
- ToolStripRendererSwitcher.cs
- VisualStyleTypesAndProperties.cs
- DragStartedEventArgs.cs
- HostingEnvironment.cs
- FloaterBaseParagraph.cs
- RuleSettingsCollection.cs
- ListInitExpression.cs
- AvTraceFormat.cs
- ISFClipboardData.cs
- ObjectStateEntryBaseUpdatableDataRecord.cs
- SingleObjectCollection.cs
- SystemFonts.cs
- SystemDropShadowChrome.cs
- ObjectDataProvider.cs
- Block.cs
- UnsafeNativeMethods.cs
- GeneralTransformCollection.cs
- SystemTcpStatistics.cs
- FileSystemWatcher.cs
- SymbolUsageManager.cs
- RuntimeArgumentHandle.cs
- FlowLayout.cs
- XmlDataLoader.cs
- ScrollProperties.cs
- GradientStop.cs
- XmlCountingReader.cs
- RC2CryptoServiceProvider.cs
- DataGridViewRowHeaderCell.cs
- SqlGatherProducedAliases.cs
- CompatibleComparer.cs
- UserPreferenceChangedEventArgs.cs