PhysicalFontFamily.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / MS / Internal / FontFace / PhysicalFontFamily.cs / 1 / PhysicalFontFamily.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// 
// Description: The PhysicalFontFamily class 
//
// History: 
//  03/04/2004 : mleonov - Created a new file for PhysicalFontFamily. It was in FontCollection.cs before.
//
//---------------------------------------------------------------------------
 
using System;
using System.Collections; 
using System.Collections.Generic; 
using System.Diagnostics;
using System.Globalization; 
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Windows; 
using System.Windows.Markup;
using System.Windows.Media; 
using System.Windows.Media.TextFormatting; 

using MS.Internal; 
using MS.Internal.FontCache;
using MS.Internal.TextFormatting;

namespace MS.Internal.FontFace 
{
    ///  
    /// PhysicalFontFamily class represents a font family obtained from a collection of OpenType files. 
    /// 
    internal sealed class PhysicalFontFamily : IFontFamily 
    {
        internal PhysicalFontFamily(CachedFontFamily cachedFamily)
        {
            Invariant.Assert(!cachedFamily.IsNull); 
            _cachedFamily = cachedFamily;
        } 
 

        ///  
        /// Get typeface metrics of the specified typeface
        /// 
        ITypefaceMetrics IFontFamily.GetTypefaceMetrics(
            FontStyle       style, 
            FontWeight      weight,
            FontStretch     stretch 
            ) 
        {
            return GetGlyphTypeface(style, weight, stretch); 
        }


        ///  
        /// Look up device font for the typeface.
        ///  
        IDeviceFont IFontFamily.GetDeviceFont(FontStyle style, FontWeight weight, FontStretch stretch) 
        {
            return null; 
        }


        ///  
        /// Indexer that indexes the underlying family name table via CultureInfo
        ///  
        ///  
        IDictionary IFontFamily.Names
        { 
            get
            {
                return _cachedFamily.Names;
            } 
        }
 
 
        /// 
        /// Get the matching glyph typeface of a specified style 
        /// 
        /// font style
        /// font weight
        /// font stretch 
        /// matching font face
        ///  
        /// Critical - as this returns GlyphTypeface created from internal constructor 
        ///            which exposes windows font information.
        /// Safe - as this doesn't allow you to create a GlyphTypeface object for a specific 
        ///        font and thus won't allow you to figure what fonts might be installed on
        ///        the machine.
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal GlyphTypeface GetGlyphTypeface(
            FontStyle       style, 
            FontWeight      weight, 
            FontStretch     stretch
            ) 
        {
            MatchingStyle targetStyle = new MatchingStyle(style, weight, stretch);
            MatchingStyle bestMatch = new MatchingStyle();
 
            CachedFontFace bestMatchFontFace = CachedFontFace.Null;
 
            foreach (CachedFontFace fontFace in _cachedFamily) 
            {
                MatchingStyle current = fontFace.MatchingStyle; 

                if (    MatchingStyle.IsBetterMatch(
                            targetStyle,
                            bestMatch, 
                            ref current
                            ) 
                    ||  bestMatchFontFace.IsNull) 
                {
                    bestMatchFontFace = fontFace; 
                    bestMatch = current;
                }
            }
 
            Debug.Assert(!bestMatchFontFace.IsNull);
 
            return bestMatchFontFace.CreateGlyphTypeface(); 
        }
 
        /// 
        /// Get the matching typeface for the specified target style that also supports
        /// glyph mapping of the specified character string.
        ///  
        /// font style
        /// font weight 
        /// font stretch 
        /// character string
        /// culture used for digit substitution or null 
        /// number of characters with valid glyph mapped
        /// offset to the character mapping to a valid glyph
        /// matching typeface
        ///  
        /// Critical - as this returns GlyphTypeface created from internal constructor
        ///            which exposes windows font information. 
        /// Safe - as this doesn't allow you to create a GlyphTypeface object for a specific 
        ///        font and thus won't allow you to figure what fonts might be installed on
        ///        the machine. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal GlyphTypeface MapGlyphTypeface(
            FontStyle               style, 
            FontWeight              weight,
            FontStretch             stretch, 
            CharacterBufferRange    charString, 
            CultureInfo             digitCulture,
            ref int                 advance, 
            ref int                 nextValid
            )
        {
            int smallestInvalid = charString.Length; 

            // Add all the cached font faces to a priority queue. 
            MatchingStyle targetStyle = new MatchingStyle(style, weight, stretch); 

            PriorityQueue queue = new PriorityQueue( 
                _cachedFamily.NumberOfFaces,
                new MatchingFaceComparer(targetStyle));

            foreach (CachedFontFace face in _cachedFamily) 
            {
                queue.Push(new MatchingFace(face, targetStyle)); 
            } 

            // Remember the best style match. 
            GlyphTypeface bestStyleTypeface = null;

            // Iterate in priority order.
            for (; queue.Count != 0; queue.Pop()) 
            {
                GlyphTypeface typeface = queue.Top.FontFace.CreateGlyphTypeface(); 
 
                int invalid = 0;
                int valid = MapCharacters(typeface, charString, digitCulture, ref invalid); 
                if (valid > 0)
                {
                    if (smallestInvalid > 0 && smallestInvalid < valid)
                    { 
                        // advance only to smallestInvalid because there's a better match after that
                        advance = smallestInvalid; 
                        nextValid = 0; 
                    }
                    else 
                    {
                        advance = valid;
                        nextValid = invalid;
                    } 

                    return typeface; 
                } 
                else
                { 
                    if (invalid < smallestInvalid)
                    {
                        // keep track of the current shortest length of invalid characters,
                        smallestInvalid = invalid; 
                    }
 
                    if (bestStyleTypeface == null) 
                    {
                        bestStyleTypeface = typeface; 
                    }
                }
            }
 
            // no face can map the specified character string,
            // fall back to the closest style match 
            advance = 0; 
            nextValid = smallestInvalid;
            Debug.Assert(bestStyleTypeface != null); 
            return bestStyleTypeface;
        }

        ///  
        /// Element type for priority queue used by MapGlyphTypeface.
        ///  
        private struct MatchingFace 
        {
            internal MatchingFace(CachedFontFace face, MatchingStyle targetStyle) 
            {
                _face = face;
                _style = face.MatchingStyle;
            } 

            internal CachedFontFace FontFace 
            { 
                get { return _face; }
            } 

            internal MatchingStyle MatchingStyle
            {
                get { return _style; } 
            }
 
            private CachedFontFace _face; 
            private MatchingStyle _style;
        } 

        /// 
        /// Comparer for priority queue used by MapGlyphTypeface.
        ///  
        private class MatchingFaceComparer : IComparer
        { 
            internal MatchingFaceComparer(MatchingStyle targetStyle) 
            {
                _targetStyle = targetStyle; 
            }

            int IComparer.Compare(MatchingFace a, MatchingFace b)
            { 
                return a.MatchingStyle.IsBetterMatch(_targetStyle, b.MatchingStyle) ? -1 : 1;
            } 
 
            private MatchingStyle _targetStyle;
        } 


        /// 
        /// Map character supported by the typeface 
        /// 
        ///  
        /// Combining mark is considered part of the character that may be supported 
        /// thru precomposed form or OpenType glyph substitution table.
        ///  
        private int MapCharacters(
            GlyphTypeface        typeface,
            CharacterBufferRange unicodeString,
            CultureInfo          digitCulture, 
            ref int              nextValid
            ) 
        { 
            IDictionary cmap = typeface.CharacterToGlyphMap;
            DigitMap digitMap = new DigitMap(digitCulture); 

            int sizeofChar = 0;
            int advance;
 
            // skip all the leading joiner characters. They need to be shaped with the
            // surrounding strong characters. 
            advance = Classification.AdvanceWhile(unicodeString, ItemClass.JoinerClass); 
            if (advance >= unicodeString.Length)
            { 
                // It is rare that the run only contains joiner characters.
                // If it really happens, just return.
                return advance;
            } 

            // 
            // If the run starts with combining marks, we will not be able to find base characters for them 
            // within the run. These combining marks will be mapped to their best fonts as normal characters.
            // 
            bool hasBaseChar = false;

            // Determine how many characters we can advance, i.e., find the first invalid character.
            for (; advance < unicodeString.Length; advance += sizeofChar) 
            {
                // Get the character and apply digit substitution, if any. 
                int originalChar = Classification.UnicodeScalar( 
                    new CharacterBufferRange(unicodeString, advance, unicodeString.Length - advance),
                    out sizeofChar 
                    );

                if (Classification.IsJoiner(originalChar))
                    continue; 

                if (!Classification.IsCombining(originalChar)) 
                { 
                    hasBaseChar = true;
                } 
                else if (hasBaseChar)
                {
                    // continue to advance for combining mark with base char
                    continue; 
                }
 
                int ch = digitMap[originalChar]; 

                if (cmap.ContainsKey(ch)) 
                    continue;

                // If ch is a substituted character, can we substitute a different character instead?
                if (ch != originalChar) 
                {
                    ch = DigitMap.GetFallbackCharacter(ch); 
                    if (ch != 0 && cmap.ContainsKey(ch)) 
                        continue;
                } 

                // If we fall through to here it's invalid.
                break;
            } 

            // UnicodeScalar won't return a sizeofChar that exceeds the string length. 
            Debug.Assert(advance <= unicodeString.Length); 

            // Find the next valid character. 
            if (advance < unicodeString.Length)
            {
                // UnicodeScalar won't return a sizeofChar that exceeds the string length.
                Debug.Assert(advance + sizeofChar <= unicodeString.Length); 

                for (nextValid = advance + sizeofChar; nextValid < unicodeString.Length; nextValid += sizeofChar) 
                { 
                    // Get the character.
                    int originalChar = Classification.UnicodeScalar( 
                        new CharacterBufferRange(unicodeString, nextValid, unicodeString.Length - nextValid),
                        out sizeofChar
                        );
 
                    // Apply digit substitution, if any.
                    int ch = digitMap[originalChar]; 
 
                    //
                    // Combining mark should always be shaped by the same font as the base char. 
                    // If the physical font is invalid for the base char, it should also be invalid for the
                    // following combining mark so that both characters will go onto the same fallback font.
                    // - When the fallback font is physical font, the font will be valid for both characters
                    //   if and only if it is valid for the base char. Otherwise, it will be invalid for both. 
                    // - When the fallback font is composite font, it maps the combining mark to the same font
                    //   as the base char such that they will eventually be resolved to the same physical font. 
                    //   That means FamilyMap for the combining mark is not used when it follows a base char. 
                    //
                    // The same goes for joiner. Note that "hasBaseChar" here indicates if there is an invalid base 
                    // char in front.
                    if (Classification.IsJoiner(ch)
                       || (hasBaseChar && Classification.IsCombining(ch))
                       ) 
                       continue;
 
                    // If we have a glyph it's valid. 
                    if (cmap.ContainsKey(ch))
                        break; 

                    // If ch is a substituted character, can we substitute a different character instead?
                    if (ch != originalChar)
                    { 
                        ch = DigitMap.GetFallbackCharacter(ch);
                        if (ch != 0 && cmap.ContainsKey(ch)) 
                            break; 
                    }
                } 
            }

            return advance;
        } 

 
        ///  
        /// Distance from character cell top to English baseline relative to em size.
        ///  
        double IFontFamily.Baseline
        {
            get
            { 
                unsafe
                { 
                    return _cachedFamily.Baseline; 
                }
            } 
        }


        ///  
        /// Recommended baseline-to-baseline distance for text in this font
        ///  
        double IFontFamily.LineSpacing 
        {
            get 
            {
                unsafe
                {
                    return _cachedFamily.LineSpacing; 
                }
            } 
        } 

        ICollection IFontFamily.GetTypefaces(FontFamilyIdentifier familyIdentifier) 
        {
            return new TypefaceCollection(new FontFamily(familyIdentifier), _cachedFamily);
        }
 

        ///  
        /// Get family name correspondent to the first n-characters of the specified character string 
        /// 
        bool IFontFamily.GetMapTargetFamilyNameAndScale( 
            CharacterBufferRange    unicodeString,
            CultureInfo             culture,
            CultureInfo             digitCulture,
            double                  defaultSizeInEm, 
            out int                 cchAdvance,
            out string              targetFamilyName, 
            out double              scaleInEm 
            )
        { 
            cchAdvance = unicodeString.Length;
            targetFamilyName = null;
            scaleInEm = defaultSizeInEm;
            return false; 
        }
 
        private CachedFontFamily    _cachedFamily; 
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// 
// Description: The PhysicalFontFamily class 
//
// History: 
//  03/04/2004 : mleonov - Created a new file for PhysicalFontFamily. It was in FontCollection.cs before.
//
//---------------------------------------------------------------------------
 
using System;
using System.Collections; 
using System.Collections.Generic; 
using System.Diagnostics;
using System.Globalization; 
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Windows; 
using System.Windows.Markup;
using System.Windows.Media; 
using System.Windows.Media.TextFormatting; 

using MS.Internal; 
using MS.Internal.FontCache;
using MS.Internal.TextFormatting;

namespace MS.Internal.FontFace 
{
    ///  
    /// PhysicalFontFamily class represents a font family obtained from a collection of OpenType files. 
    /// 
    internal sealed class PhysicalFontFamily : IFontFamily 
    {
        internal PhysicalFontFamily(CachedFontFamily cachedFamily)
        {
            Invariant.Assert(!cachedFamily.IsNull); 
            _cachedFamily = cachedFamily;
        } 
 

        ///  
        /// Get typeface metrics of the specified typeface
        /// 
        ITypefaceMetrics IFontFamily.GetTypefaceMetrics(
            FontStyle       style, 
            FontWeight      weight,
            FontStretch     stretch 
            ) 
        {
            return GetGlyphTypeface(style, weight, stretch); 
        }


        ///  
        /// Look up device font for the typeface.
        ///  
        IDeviceFont IFontFamily.GetDeviceFont(FontStyle style, FontWeight weight, FontStretch stretch) 
        {
            return null; 
        }


        ///  
        /// Indexer that indexes the underlying family name table via CultureInfo
        ///  
        ///  
        IDictionary IFontFamily.Names
        { 
            get
            {
                return _cachedFamily.Names;
            } 
        }
 
 
        /// 
        /// Get the matching glyph typeface of a specified style 
        /// 
        /// font style
        /// font weight
        /// font stretch 
        /// matching font face
        ///  
        /// Critical - as this returns GlyphTypeface created from internal constructor 
        ///            which exposes windows font information.
        /// Safe - as this doesn't allow you to create a GlyphTypeface object for a specific 
        ///        font and thus won't allow you to figure what fonts might be installed on
        ///        the machine.
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal GlyphTypeface GetGlyphTypeface(
            FontStyle       style, 
            FontWeight      weight, 
            FontStretch     stretch
            ) 
        {
            MatchingStyle targetStyle = new MatchingStyle(style, weight, stretch);
            MatchingStyle bestMatch = new MatchingStyle();
 
            CachedFontFace bestMatchFontFace = CachedFontFace.Null;
 
            foreach (CachedFontFace fontFace in _cachedFamily) 
            {
                MatchingStyle current = fontFace.MatchingStyle; 

                if (    MatchingStyle.IsBetterMatch(
                            targetStyle,
                            bestMatch, 
                            ref current
                            ) 
                    ||  bestMatchFontFace.IsNull) 
                {
                    bestMatchFontFace = fontFace; 
                    bestMatch = current;
                }
            }
 
            Debug.Assert(!bestMatchFontFace.IsNull);
 
            return bestMatchFontFace.CreateGlyphTypeface(); 
        }
 
        /// 
        /// Get the matching typeface for the specified target style that also supports
        /// glyph mapping of the specified character string.
        ///  
        /// font style
        /// font weight 
        /// font stretch 
        /// character string
        /// culture used for digit substitution or null 
        /// number of characters with valid glyph mapped
        /// offset to the character mapping to a valid glyph
        /// matching typeface
        ///  
        /// Critical - as this returns GlyphTypeface created from internal constructor
        ///            which exposes windows font information. 
        /// Safe - as this doesn't allow you to create a GlyphTypeface object for a specific 
        ///        font and thus won't allow you to figure what fonts might be installed on
        ///        the machine. 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal GlyphTypeface MapGlyphTypeface(
            FontStyle               style, 
            FontWeight              weight,
            FontStretch             stretch, 
            CharacterBufferRange    charString, 
            CultureInfo             digitCulture,
            ref int                 advance, 
            ref int                 nextValid
            )
        {
            int smallestInvalid = charString.Length; 

            // Add all the cached font faces to a priority queue. 
            MatchingStyle targetStyle = new MatchingStyle(style, weight, stretch); 

            PriorityQueue queue = new PriorityQueue( 
                _cachedFamily.NumberOfFaces,
                new MatchingFaceComparer(targetStyle));

            foreach (CachedFontFace face in _cachedFamily) 
            {
                queue.Push(new MatchingFace(face, targetStyle)); 
            } 

            // Remember the best style match. 
            GlyphTypeface bestStyleTypeface = null;

            // Iterate in priority order.
            for (; queue.Count != 0; queue.Pop()) 
            {
                GlyphTypeface typeface = queue.Top.FontFace.CreateGlyphTypeface(); 
 
                int invalid = 0;
                int valid = MapCharacters(typeface, charString, digitCulture, ref invalid); 
                if (valid > 0)
                {
                    if (smallestInvalid > 0 && smallestInvalid < valid)
                    { 
                        // advance only to smallestInvalid because there's a better match after that
                        advance = smallestInvalid; 
                        nextValid = 0; 
                    }
                    else 
                    {
                        advance = valid;
                        nextValid = invalid;
                    } 

                    return typeface; 
                } 
                else
                { 
                    if (invalid < smallestInvalid)
                    {
                        // keep track of the current shortest length of invalid characters,
                        smallestInvalid = invalid; 
                    }
 
                    if (bestStyleTypeface == null) 
                    {
                        bestStyleTypeface = typeface; 
                    }
                }
            }
 
            // no face can map the specified character string,
            // fall back to the closest style match 
            advance = 0; 
            nextValid = smallestInvalid;
            Debug.Assert(bestStyleTypeface != null); 
            return bestStyleTypeface;
        }

        ///  
        /// Element type for priority queue used by MapGlyphTypeface.
        ///  
        private struct MatchingFace 
        {
            internal MatchingFace(CachedFontFace face, MatchingStyle targetStyle) 
            {
                _face = face;
                _style = face.MatchingStyle;
            } 

            internal CachedFontFace FontFace 
            { 
                get { return _face; }
            } 

            internal MatchingStyle MatchingStyle
            {
                get { return _style; } 
            }
 
            private CachedFontFace _face; 
            private MatchingStyle _style;
        } 

        /// 
        /// Comparer for priority queue used by MapGlyphTypeface.
        ///  
        private class MatchingFaceComparer : IComparer
        { 
            internal MatchingFaceComparer(MatchingStyle targetStyle) 
            {
                _targetStyle = targetStyle; 
            }

            int IComparer.Compare(MatchingFace a, MatchingFace b)
            { 
                return a.MatchingStyle.IsBetterMatch(_targetStyle, b.MatchingStyle) ? -1 : 1;
            } 
 
            private MatchingStyle _targetStyle;
        } 


        /// 
        /// Map character supported by the typeface 
        /// 
        ///  
        /// Combining mark is considered part of the character that may be supported 
        /// thru precomposed form or OpenType glyph substitution table.
        ///  
        private int MapCharacters(
            GlyphTypeface        typeface,
            CharacterBufferRange unicodeString,
            CultureInfo          digitCulture, 
            ref int              nextValid
            ) 
        { 
            IDictionary cmap = typeface.CharacterToGlyphMap;
            DigitMap digitMap = new DigitMap(digitCulture); 

            int sizeofChar = 0;
            int advance;
 
            // skip all the leading joiner characters. They need to be shaped with the
            // surrounding strong characters. 
            advance = Classification.AdvanceWhile(unicodeString, ItemClass.JoinerClass); 
            if (advance >= unicodeString.Length)
            { 
                // It is rare that the run only contains joiner characters.
                // If it really happens, just return.
                return advance;
            } 

            // 
            // If the run starts with combining marks, we will not be able to find base characters for them 
            // within the run. These combining marks will be mapped to their best fonts as normal characters.
            // 
            bool hasBaseChar = false;

            // Determine how many characters we can advance, i.e., find the first invalid character.
            for (; advance < unicodeString.Length; advance += sizeofChar) 
            {
                // Get the character and apply digit substitution, if any. 
                int originalChar = Classification.UnicodeScalar( 
                    new CharacterBufferRange(unicodeString, advance, unicodeString.Length - advance),
                    out sizeofChar 
                    );

                if (Classification.IsJoiner(originalChar))
                    continue; 

                if (!Classification.IsCombining(originalChar)) 
                { 
                    hasBaseChar = true;
                } 
                else if (hasBaseChar)
                {
                    // continue to advance for combining mark with base char
                    continue; 
                }
 
                int ch = digitMap[originalChar]; 

                if (cmap.ContainsKey(ch)) 
                    continue;

                // If ch is a substituted character, can we substitute a different character instead?
                if (ch != originalChar) 
                {
                    ch = DigitMap.GetFallbackCharacter(ch); 
                    if (ch != 0 && cmap.ContainsKey(ch)) 
                        continue;
                } 

                // If we fall through to here it's invalid.
                break;
            } 

            // UnicodeScalar won't return a sizeofChar that exceeds the string length. 
            Debug.Assert(advance <= unicodeString.Length); 

            // Find the next valid character. 
            if (advance < unicodeString.Length)
            {
                // UnicodeScalar won't return a sizeofChar that exceeds the string length.
                Debug.Assert(advance + sizeofChar <= unicodeString.Length); 

                for (nextValid = advance + sizeofChar; nextValid < unicodeString.Length; nextValid += sizeofChar) 
                { 
                    // Get the character.
                    int originalChar = Classification.UnicodeScalar( 
                        new CharacterBufferRange(unicodeString, nextValid, unicodeString.Length - nextValid),
                        out sizeofChar
                        );
 
                    // Apply digit substitution, if any.
                    int ch = digitMap[originalChar]; 
 
                    //
                    // Combining mark should always be shaped by the same font as the base char. 
                    // If the physical font is invalid for the base char, it should also be invalid for the
                    // following combining mark so that both characters will go onto the same fallback font.
                    // - When the fallback font is physical font, the font will be valid for both characters
                    //   if and only if it is valid for the base char. Otherwise, it will be invalid for both. 
                    // - When the fallback font is composite font, it maps the combining mark to the same font
                    //   as the base char such that they will eventually be resolved to the same physical font. 
                    //   That means FamilyMap for the combining mark is not used when it follows a base char. 
                    //
                    // The same goes for joiner. Note that "hasBaseChar" here indicates if there is an invalid base 
                    // char in front.
                    if (Classification.IsJoiner(ch)
                       || (hasBaseChar && Classification.IsCombining(ch))
                       ) 
                       continue;
 
                    // If we have a glyph it's valid. 
                    if (cmap.ContainsKey(ch))
                        break; 

                    // If ch is a substituted character, can we substitute a different character instead?
                    if (ch != originalChar)
                    { 
                        ch = DigitMap.GetFallbackCharacter(ch);
                        if (ch != 0 && cmap.ContainsKey(ch)) 
                            break; 
                    }
                } 
            }

            return advance;
        } 

 
        ///  
        /// Distance from character cell top to English baseline relative to em size.
        ///  
        double IFontFamily.Baseline
        {
            get
            { 
                unsafe
                { 
                    return _cachedFamily.Baseline; 
                }
            } 
        }


        ///  
        /// Recommended baseline-to-baseline distance for text in this font
        ///  
        double IFontFamily.LineSpacing 
        {
            get 
            {
                unsafe
                {
                    return _cachedFamily.LineSpacing; 
                }
            } 
        } 

        ICollection IFontFamily.GetTypefaces(FontFamilyIdentifier familyIdentifier) 
        {
            return new TypefaceCollection(new FontFamily(familyIdentifier), _cachedFamily);
        }
 

        ///  
        /// Get family name correspondent to the first n-characters of the specified character string 
        /// 
        bool IFontFamily.GetMapTargetFamilyNameAndScale( 
            CharacterBufferRange    unicodeString,
            CultureInfo             culture,
            CultureInfo             digitCulture,
            double                  defaultSizeInEm, 
            out int                 cchAdvance,
            out string              targetFamilyName, 
            out double              scaleInEm 
            )
        { 
            cchAdvance = unicodeString.Length;
            targetFamilyName = null;
            scaleInEm = defaultSizeInEm;
            return false; 
        }
 
        private CachedFontFamily    _cachedFamily; 
    }
} 


// 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