ShapingEngine.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / MS / Internal / Shaping / ShapingEngine.cs / 1 / ShapingEngine.cs

                            //+------------------------------------------------------------------------ 
//
//  Microsoft Windows Client Platform
//  Copyright (C) Microsoft Corporation, 2001
// 
//  File:      ShapingEngine.cs
// 
//  Contents:  The shaping engine interface & related stuffs 
//
//  Created:   12-25-2001 Worachai Chaoweeraprasit (wchao) 
//
//-----------------------------------------------------------------------

using System; 
using System.Collections;
using System.Globalization; 
using System.Diagnostics; 
using System.Windows;
using System.Windows.Media; 
using System.Windows.Media.TextFormatting;
using MS.Internal;
using MS.Internal.FontFace;
using MS.Internal.FontCache; 

namespace MS.Internal.Shaping 
{ 

    ///  
    /// Shaping engine
    /// 
    /// 
    /// Shaping engine encapsulates writing system shaping rules. A shaping engine may contain 
    /// multiple shapers, each for different shaping variation of the same writing system.
    ///  
    internal interface IShapingEngine 
    {
        ///  
        /// List of OpenType script tag supported by this shaping engine
        /// 
        ScriptTags[] SupportedScripts { get; }
 

        ///  
        /// Indexing associated shaper 
        /// 
        IShaper this[ItemFlags flags] { get; } 

        /// 
        /// Notify shaping engine of the first time the font is loaded for the specified script
        ///  
        /// Script tag
        /// font face 
        /// font-script specific shaping data or state 
        /// true if loading succeeds
        bool OnLoadFont( 
            ScriptTags          scriptTag,
            GlyphTypeface       glyphTypeface,
            out object          shapeState
            ); 
    }
 
 
    /// 
    /// IScriptCharConverter - interface to script/font character classifier/mapper 
    /// 
    internal interface IScriptCharConverter
    {
        ///  
        /// Returns the shape info for the unicode character
        ///  
        CharShapeInfo ToShapeInfo (char unicodeChar); 

        ///  
        /// Returns the font's glyph ix for the unicode char
        /// 
        ushort ToGlyph (char unicodeChar);
 
    }
 
 
    /// 
    /// Legacy shaping effects activated/deactivated by character codes 
    /// 
    /// 
    /// Flags enabled by the presence of Unicode 2.0's "Alternate Format
    /// Characters (U+206A - U+206F)" supported by Uniscribe but deprecated 
    /// in Unicode 3.0.
    ///  
    [Flags] 
    internal enum LegacyShapeFlags
    { 
        NA = 0,

        /// 
        /// Set by U+206A (ISS), cleared by U+206B (----) 
        /// 
        InhibitSymSwap    = 0x00000001, 
 
        /// 
        /// Set by U+206D (AAFS), cleared by U+206C (IAFS). 
        /// The only intent of this flag is to use with Arabic presentation form.
        /// By default, it is set to off to retain presentation forms in the font.
        /// 
        CharShape         = 0x00000002, 

        ///  
        /// Set by U+206E (NADS), cleared by U+206F (NODS) 
        /// 
        DigitSubstitute   = 0x00000004, 
    }

    internal struct GlyphOffset
    { 
        public int du;
        public int dv; 
    } 

    internal enum GlyphJustify : ushort 
    {
        JustifyNone = 0,            // Justification can't be applied at this glyph
        JustifyArabicBlank,         // This glyph represents a blank in an Arabic run
        JustifyCharacter,           // Inter-character justification point follows this glyph 
        JustifyReserved1,           // Reserved #1
        JustifyBlank,               // This glyph represents a blank outside an Arabic run 
        JustifyReserved2,           // Reserved #2 
        JustifyReserved3,           // Reserved #3
        JustifyArabicNormal,        // Normal Middle-Of-Word glyph that connects to the right (begin) 
        JustifyArabicKashida,       // Kashida(U+640) in middle of word
        JustifyArabicAlef,          // Final form of Alef-like (U+627, U+625, U+623, U+632)
        JustifyArabicHa,            // Final form of Ha (U+647)
        JustifyArabicRa,            // Final form of Ra (U+631) 
        JustifyArabicBa,            // Middle-Of-Word form of Ba (U+628)
        JustifyArabicBara,          // Ligature of alike (U+628,U+631) 
        JustifyArabicSeen,          // Highest priority: Initial shape of Seen(U+633) (end) 
        JustifyReserved4,           // Reserved #4
    } 


    internal sealed class FeatureSet
    { 
        public FeatureSet(
            uint        langSysTag, 
            Feature[]   features, 
            int         featureCount
            ) 
        {
            _langSysTag = langSysTag;
            _features = features;
            _featureCount = featureCount; 
        }
 
        public uint LangSysTag 
        {
            get { return _langSysTag; } 
        }

        public Feature[] Features
        { 
            get { return _features; }
        } 
 
        public int FeatureCount
        { 
            get { return _featureCount; }
        }

        private Feature[]   _features; 
        private int         _featureCount;
        private uint        _langSysTag; 
    } 

 
    /// 
    /// Character token
    /// 
    internal struct CharToken 
    {
        private Item    _item; 
        private ushort  _faceIndex; 

        internal CharToken( 
            Item    item,
            ushort  faceIndex
            )
        { 
            _item = item;
            _faceIndex = faceIndex; 
        } 

        public static bool operator==( 
            CharToken   left,
            CharToken   right
            )
        { 
            return      left._item == right._item
                    &&  left._faceIndex == right._faceIndex; 
        } 

        public static bool operator!=( 
            CharToken   left,
            CharToken   right
            )
        { 
            return !(left == right);
        } 
 
        public override bool Equals(object o)
        { 
            if(o == null)
            {
                return false;
            } 

            if(o is CharToken) 
            { 
                CharToken token = (CharToken)o;
                return this == token; 
            }
            else
            {
                return false; 
            }
        } 
 
        public override int GetHashCode()
        { 
            return _item.GetHashCode() ^ (int)_faceIndex;
        }
    }
 

    ///  
    /// CharShapeInfo - enumeration of shaping flag values.  These values are used 
    ///                 in all the text shaping engines.
    ///  
    [Flags]
    internal enum CharShapeInfo : ushort
    {
        // These first flags (through IsStartOfCluster) must all stay in the lower 
        // byte as they may be encoded in the various shaper's byte[] classification
        // tables. 
        NoFlagsSet              = 0x0000,   // no flags set 
        ShaperFeatureIxMask     = 0x000F,   // the lower nibble is reserved for feature ix
        ShaperClassMask         = 0x001F,   // some engines use the lower byte for char class 
        RequiresReordering      = 0x0020,   // reordering flag - action taken is shaper dependent
        RequiresSpecialHandling = 0x0040,   // shaper dependent action needed
        IsStartOfCluster        = 0x0080,
 
        IsUnicodeLayoutControl  = 0x0100,   // this is a ZWJ/ZWNJ or similar control char
        RequiresInsertedBase    = 0x0280,   // this character requires a dotted circle base 
        ShapeFlagsMask          = 0x03E0    // mask for shaping flags 
    };
 
    /// 
    /// UnicodeCharacter - list of Unicode character names.  These values are used
    ///                 in all the text shaping engines.
    ///  
    internal struct UnicodeCharacter
    { 
        // Any shape engine might use these 
        internal const char Space         =   '\u0020'; // space character
        internal const char NoBreakSpace  =   '\u00A0'; // space character 
        internal const char NarrowNoBreakSpace  =   '\u202f'; // narrow no-break space character
        internal const char DottedCircle  =   '\u25CC'; // inserted base character
        internal const char SHY           =   '\u00AD'; // soft hyphen character
        internal const char ZWSP          =   '\u200B'; // zero-width non-joining mark 
        internal const char ZWNJ          =   '\u200C'; // zero-width non-joining mark
        internal const char ZWJ           =   '\u200D'; // zero-width joining mark 
        internal const char LRM           =   '\u200E'; // left to right mark 
        internal const char RLM           =   '\u200F'; // right to left mark
        internal const char CGJ           =   '\u034F'; // combining grapheme joiner 
    }

    /// 
    /// Shaper of shape variation supported by a shaping engine 
    /// 
    internal interface IShaper 
    { 
        /// 
        /// Maps Unicode character string to glyph indices according to 
        /// script/component rules
        /// 
        /// 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 
        bool GetGlyphs(
            Item                                        item, 
            CultureInfo                                 culture,
            GlyphTypeface                               fontFace,
            FeatureSet                                  featureSet,
            ShapingOptions                              shapingFlags, 

            object                                      shapeFontFaceInfo, 
 
            CheckedCharPointer                          chars,
            int                                         charCount, 

            CheckedCharacterShapingPropertiesPointer    charProperties,
            CheckedUShortPointer                        charClusterMap,
 
            out ushort[]                                glyphIndices,
            out GlyphShapingProperties[]                glyphProperties, 
            out int                                     glyphCount 
            );
 

        /// 
        /// Positions each glyph generated by GetGlyphs according to script/component rules
        ///  
        /// 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
        bool GetGlyphPlacements(
            Item                                        item, 
            CultureInfo                                 culture,
            GlyphTypeface                               fontFace, 
            FeatureSet                                  featureSet, 
            ShapingOptions                              shapingFlags,
 
            object                                      shapeFontFaceInfo,

            CheckedCharacterShapingPropertiesPointer    charProperties,
            CheckedUShortPointer                        charClusterMap, 
            int                                         charCount,
 
            CheckedUShortPointer                        glyphIndices, 
            CheckedGlyphShapingPropertiesPointer        glyphProperties,
            int                                         glyphCount, 

            double                                      scaleFactor,
            CheckedIntPointer                           glyphAdvances,
            CheckedGlyphOffsetPointer                   glyphOffsets 
            );
 
    } 

    ///  
    /// Object managing shaping engines
    /// 
    internal sealed class ShapingEngineManager
    { 
        private ArrayList[]     _shapeTable = new ArrayList[(int)ScriptID.Max];
 
        // Average number of shaping engines for one script 
        private const int ShapingEnginePerScript = 2;
 
        private IShapingEngine  _defaultShape;

        /// 
        /// Construct a shaping engine manager 
        /// 
        internal ShapingEngineManager() 
        { 
            _defaultShape = new DefaultShape();
 
            //
            // The list of installed shapes.
            //
            IShapingEngine[] installedShapes = new IShapingEngine[] { 
                // Shaping engine get installed in the following order
                new DigitShape      (), 
                new ControlShape    (), 
                new MirroringShape  (),
                new ArabicShape     (), 
                new HebrewShape     (),
                new ThaiShape       (),
                new TibetanShape    (),
                new MongolianShape  (), 
                new IndicShape      (),
                new LatinShape      () 
                }; 

            // populate every installed shaping engine into the shape table 
            for(int i = 0; i < installedShapes.Length; i++)
            {
                IShapingEngine shape = installedShapes[i];
 
                if(shape.SupportedScripts != null)
                { 
                    for(int j = 0; j < shape.SupportedScripts.Length; j++) 
                    {
                        ScriptTags script = shape.SupportedScripts[j]; 
                        int scriptID = (int)Script.ToID(script);

                        if(_shapeTable[scriptID] == null)
                        { 
                            _shapeTable[scriptID] = new ArrayList(ShapingEnginePerScript);
                        } 
 
                        _shapeTable[scriptID].Add(shape);
                    } 
                }
            }
        }
 

        ///  
        /// Font is first loaded for the specified script 
        /// 
        /// script ID 
        /// font face
        /// font-script specific data
        /// shaping engine
        internal IShapingEngine OnLoadFont( 
            ScriptID            script,
            GlyphTypeface       glyphTypeface, 
            out object          shapeState 
            )
        { 
            ScriptTags scriptTag = Script.ToTag(script);
            ArrayList shapes = _shapeTable[(int)script];

            if(shapes != null && shapes.Count > 0) 
            {
                foreach(IShapingEngine shape in shapes) 
                { 
                    if(shape.OnLoadFont(
                        scriptTag, 
                        glyphTypeface,
                        out shapeState
                        ))
                    { 
                        return shape;
                    } 
                } 
            }
 
            bool success = _defaultShape.OnLoadFont(
                scriptTag,
                glyphTypeface,
                out shapeState 
                );
 
            Debug.Assert(success); 
            return _defaultShape;
        } 
    }
}

// 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:      ShapingEngine.cs
// 
//  Contents:  The shaping engine interface & related stuffs 
//
//  Created:   12-25-2001 Worachai Chaoweeraprasit (wchao) 
//
//-----------------------------------------------------------------------

using System; 
using System.Collections;
using System.Globalization; 
using System.Diagnostics; 
using System.Windows;
using System.Windows.Media; 
using System.Windows.Media.TextFormatting;
using MS.Internal;
using MS.Internal.FontFace;
using MS.Internal.FontCache; 

namespace MS.Internal.Shaping 
{ 

    ///  
    /// Shaping engine
    /// 
    /// 
    /// Shaping engine encapsulates writing system shaping rules. A shaping engine may contain 
    /// multiple shapers, each for different shaping variation of the same writing system.
    ///  
    internal interface IShapingEngine 
    {
        ///  
        /// List of OpenType script tag supported by this shaping engine
        /// 
        ScriptTags[] SupportedScripts { get; }
 

        ///  
        /// Indexing associated shaper 
        /// 
        IShaper this[ItemFlags flags] { get; } 

        /// 
        /// Notify shaping engine of the first time the font is loaded for the specified script
        ///  
        /// Script tag
        /// font face 
        /// font-script specific shaping data or state 
        /// true if loading succeeds
        bool OnLoadFont( 
            ScriptTags          scriptTag,
            GlyphTypeface       glyphTypeface,
            out object          shapeState
            ); 
    }
 
 
    /// 
    /// IScriptCharConverter - interface to script/font character classifier/mapper 
    /// 
    internal interface IScriptCharConverter
    {
        ///  
        /// Returns the shape info for the unicode character
        ///  
        CharShapeInfo ToShapeInfo (char unicodeChar); 

        ///  
        /// Returns the font's glyph ix for the unicode char
        /// 
        ushort ToGlyph (char unicodeChar);
 
    }
 
 
    /// 
    /// Legacy shaping effects activated/deactivated by character codes 
    /// 
    /// 
    /// Flags enabled by the presence of Unicode 2.0's "Alternate Format
    /// Characters (U+206A - U+206F)" supported by Uniscribe but deprecated 
    /// in Unicode 3.0.
    ///  
    [Flags] 
    internal enum LegacyShapeFlags
    { 
        NA = 0,

        /// 
        /// Set by U+206A (ISS), cleared by U+206B (----) 
        /// 
        InhibitSymSwap    = 0x00000001, 
 
        /// 
        /// Set by U+206D (AAFS), cleared by U+206C (IAFS). 
        /// The only intent of this flag is to use with Arabic presentation form.
        /// By default, it is set to off to retain presentation forms in the font.
        /// 
        CharShape         = 0x00000002, 

        ///  
        /// Set by U+206E (NADS), cleared by U+206F (NODS) 
        /// 
        DigitSubstitute   = 0x00000004, 
    }

    internal struct GlyphOffset
    { 
        public int du;
        public int dv; 
    } 

    internal enum GlyphJustify : ushort 
    {
        JustifyNone = 0,            // Justification can't be applied at this glyph
        JustifyArabicBlank,         // This glyph represents a blank in an Arabic run
        JustifyCharacter,           // Inter-character justification point follows this glyph 
        JustifyReserved1,           // Reserved #1
        JustifyBlank,               // This glyph represents a blank outside an Arabic run 
        JustifyReserved2,           // Reserved #2 
        JustifyReserved3,           // Reserved #3
        JustifyArabicNormal,        // Normal Middle-Of-Word glyph that connects to the right (begin) 
        JustifyArabicKashida,       // Kashida(U+640) in middle of word
        JustifyArabicAlef,          // Final form of Alef-like (U+627, U+625, U+623, U+632)
        JustifyArabicHa,            // Final form of Ha (U+647)
        JustifyArabicRa,            // Final form of Ra (U+631) 
        JustifyArabicBa,            // Middle-Of-Word form of Ba (U+628)
        JustifyArabicBara,          // Ligature of alike (U+628,U+631) 
        JustifyArabicSeen,          // Highest priority: Initial shape of Seen(U+633) (end) 
        JustifyReserved4,           // Reserved #4
    } 


    internal sealed class FeatureSet
    { 
        public FeatureSet(
            uint        langSysTag, 
            Feature[]   features, 
            int         featureCount
            ) 
        {
            _langSysTag = langSysTag;
            _features = features;
            _featureCount = featureCount; 
        }
 
        public uint LangSysTag 
        {
            get { return _langSysTag; } 
        }

        public Feature[] Features
        { 
            get { return _features; }
        } 
 
        public int FeatureCount
        { 
            get { return _featureCount; }
        }

        private Feature[]   _features; 
        private int         _featureCount;
        private uint        _langSysTag; 
    } 

 
    /// 
    /// Character token
    /// 
    internal struct CharToken 
    {
        private Item    _item; 
        private ushort  _faceIndex; 

        internal CharToken( 
            Item    item,
            ushort  faceIndex
            )
        { 
            _item = item;
            _faceIndex = faceIndex; 
        } 

        public static bool operator==( 
            CharToken   left,
            CharToken   right
            )
        { 
            return      left._item == right._item
                    &&  left._faceIndex == right._faceIndex; 
        } 

        public static bool operator!=( 
            CharToken   left,
            CharToken   right
            )
        { 
            return !(left == right);
        } 
 
        public override bool Equals(object o)
        { 
            if(o == null)
            {
                return false;
            } 

            if(o is CharToken) 
            { 
                CharToken token = (CharToken)o;
                return this == token; 
            }
            else
            {
                return false; 
            }
        } 
 
        public override int GetHashCode()
        { 
            return _item.GetHashCode() ^ (int)_faceIndex;
        }
    }
 

    ///  
    /// CharShapeInfo - enumeration of shaping flag values.  These values are used 
    ///                 in all the text shaping engines.
    ///  
    [Flags]
    internal enum CharShapeInfo : ushort
    {
        // These first flags (through IsStartOfCluster) must all stay in the lower 
        // byte as they may be encoded in the various shaper's byte[] classification
        // tables. 
        NoFlagsSet              = 0x0000,   // no flags set 
        ShaperFeatureIxMask     = 0x000F,   // the lower nibble is reserved for feature ix
        ShaperClassMask         = 0x001F,   // some engines use the lower byte for char class 
        RequiresReordering      = 0x0020,   // reordering flag - action taken is shaper dependent
        RequiresSpecialHandling = 0x0040,   // shaper dependent action needed
        IsStartOfCluster        = 0x0080,
 
        IsUnicodeLayoutControl  = 0x0100,   // this is a ZWJ/ZWNJ or similar control char
        RequiresInsertedBase    = 0x0280,   // this character requires a dotted circle base 
        ShapeFlagsMask          = 0x03E0    // mask for shaping flags 
    };
 
    /// 
    /// UnicodeCharacter - list of Unicode character names.  These values are used
    ///                 in all the text shaping engines.
    ///  
    internal struct UnicodeCharacter
    { 
        // Any shape engine might use these 
        internal const char Space         =   '\u0020'; // space character
        internal const char NoBreakSpace  =   '\u00A0'; // space character 
        internal const char NarrowNoBreakSpace  =   '\u202f'; // narrow no-break space character
        internal const char DottedCircle  =   '\u25CC'; // inserted base character
        internal const char SHY           =   '\u00AD'; // soft hyphen character
        internal const char ZWSP          =   '\u200B'; // zero-width non-joining mark 
        internal const char ZWNJ          =   '\u200C'; // zero-width non-joining mark
        internal const char ZWJ           =   '\u200D'; // zero-width joining mark 
        internal const char LRM           =   '\u200E'; // left to right mark 
        internal const char RLM           =   '\u200F'; // right to left mark
        internal const char CGJ           =   '\u034F'; // combining grapheme joiner 
    }

    /// 
    /// Shaper of shape variation supported by a shaping engine 
    /// 
    internal interface IShaper 
    { 
        /// 
        /// Maps Unicode character string to glyph indices according to 
        /// script/component rules
        /// 
        /// 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 
        bool GetGlyphs(
            Item                                        item, 
            CultureInfo                                 culture,
            GlyphTypeface                               fontFace,
            FeatureSet                                  featureSet,
            ShapingOptions                              shapingFlags, 

            object                                      shapeFontFaceInfo, 
 
            CheckedCharPointer                          chars,
            int                                         charCount, 

            CheckedCharacterShapingPropertiesPointer    charProperties,
            CheckedUShortPointer                        charClusterMap,
 
            out ushort[]                                glyphIndices,
            out GlyphShapingProperties[]                glyphProperties, 
            out int                                     glyphCount 
            );
 

        /// 
        /// Positions each glyph generated by GetGlyphs according to script/component rules
        ///  
        /// 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
        bool GetGlyphPlacements(
            Item                                        item, 
            CultureInfo                                 culture,
            GlyphTypeface                               fontFace, 
            FeatureSet                                  featureSet, 
            ShapingOptions                              shapingFlags,
 
            object                                      shapeFontFaceInfo,

            CheckedCharacterShapingPropertiesPointer    charProperties,
            CheckedUShortPointer                        charClusterMap, 
            int                                         charCount,
 
            CheckedUShortPointer                        glyphIndices, 
            CheckedGlyphShapingPropertiesPointer        glyphProperties,
            int                                         glyphCount, 

            double                                      scaleFactor,
            CheckedIntPointer                           glyphAdvances,
            CheckedGlyphOffsetPointer                   glyphOffsets 
            );
 
    } 

    ///  
    /// Object managing shaping engines
    /// 
    internal sealed class ShapingEngineManager
    { 
        private ArrayList[]     _shapeTable = new ArrayList[(int)ScriptID.Max];
 
        // Average number of shaping engines for one script 
        private const int ShapingEnginePerScript = 2;
 
        private IShapingEngine  _defaultShape;

        /// 
        /// Construct a shaping engine manager 
        /// 
        internal ShapingEngineManager() 
        { 
            _defaultShape = new DefaultShape();
 
            //
            // The list of installed shapes.
            //
            IShapingEngine[] installedShapes = new IShapingEngine[] { 
                // Shaping engine get installed in the following order
                new DigitShape      (), 
                new ControlShape    (), 
                new MirroringShape  (),
                new ArabicShape     (), 
                new HebrewShape     (),
                new ThaiShape       (),
                new TibetanShape    (),
                new MongolianShape  (), 
                new IndicShape      (),
                new LatinShape      () 
                }; 

            // populate every installed shaping engine into the shape table 
            for(int i = 0; i < installedShapes.Length; i++)
            {
                IShapingEngine shape = installedShapes[i];
 
                if(shape.SupportedScripts != null)
                { 
                    for(int j = 0; j < shape.SupportedScripts.Length; j++) 
                    {
                        ScriptTags script = shape.SupportedScripts[j]; 
                        int scriptID = (int)Script.ToID(script);

                        if(_shapeTable[scriptID] == null)
                        { 
                            _shapeTable[scriptID] = new ArrayList(ShapingEnginePerScript);
                        } 
 
                        _shapeTable[scriptID].Add(shape);
                    } 
                }
            }
        }
 

        ///  
        /// Font is first loaded for the specified script 
        /// 
        /// script ID 
        /// font face
        /// font-script specific data
        /// shaping engine
        internal IShapingEngine OnLoadFont( 
            ScriptID            script,
            GlyphTypeface       glyphTypeface, 
            out object          shapeState 
            )
        { 
            ScriptTags scriptTag = Script.ToTag(script);
            ArrayList shapes = _shapeTable[(int)script];

            if(shapes != null && shapes.Count > 0) 
            {
                foreach(IShapingEngine shape in shapes) 
                { 
                    if(shape.OnLoadFont(
                        scriptTag, 
                        glyphTypeface,
                        out shapeState
                        ))
                    { 
                        return shape;
                    } 
                } 
            }
 
            bool success = _defaultShape.OnLoadFont(
                scriptTag,
                glyphTypeface,
                out shapeState 
                );
 
            Debug.Assert(success); 
            return _defaultShape;
        } 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK