Font.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / CommonUI / System / Drawing / Advanced / Font.cs / 3 / Font.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/*************************************************************************\ 
* 
* Copyright (c) 1998-1999, Microsoft Corp.  All Rights Reserved.
* 
* Module Name:
*
*   font.cs
* 
* Abstract:
* 
*   COM+ wrapper for GDI+ font objects 
*
* Revision History: 
*
*   10/04/1999 [...]
*       Created it.
* 
\**************************************************************************/
 
namespace System.Drawing { 
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis; 
    using System;
    using System.Drawing.Design;
    using System.Runtime.InteropServices;
    using System.Runtime.Serialization; 
    using System.ComponentModel;
    using Microsoft.Win32; 
    using System.Drawing; 
    using System.Drawing.Internal;
    using System.Globalization; 
    using System.Security;
    using System.Security.Permissions;

 
     /*
     * Represent a font object 
     */ 

    ///  
    /// 
    ///    Defines a particular format for text,
    ///    including font face, size, and style attributes.
    ///  
    [
    TypeConverterAttribute(typeof(FontConverter)), 
    EditorAttribute("System.Drawing.Design.FontEditor, " + AssemblyRef.SystemDrawingDesign, typeof(UITypeEditor)), 
    ]
    [Serializable] 
    [ComVisible(true)]
    public sealed class Font : MarshalByRefObject, ICloneable, ISerializable, IDisposable {
        const int LogFontCharSetOffset = 23;
        const int LogFontNameOffset = 28; 

        IntPtr          nativeFont; 
        float           fontSize; 
        FontStyle       fontStyle;
        FontFamily      fontFamily; 
        GraphicsUnit    fontUnit;
        byte            gdiCharSet = SafeNativeMethods.DEFAULT_CHARSET;
        bool            gdiVerticalFont;
        string          systemFontName = ""; 
        string          originalFontName;
 
        /// 
        ///     Creates the GDI+ native font object.
        /// 
        private void CreateNativeFont()
        {
            Debug.Assert(this.nativeFont == IntPtr.Zero, "nativeFont already initialized, this will generate a handle leak.");
            Debug.Assert(this.fontFamily != null, "fontFamily not initialized."); 

            // Note: GDI+ creates singleton font family objects (from the corresponding font file) and reference count them so 
            // if creating the font object from an external FontFamily, this object's FontFamily will share the same native object. 
            int status = SafeNativeMethods.Gdip.GdipCreateFont(
                                    new HandleRef(this, this.fontFamily.NativeFamily), 
                                    this.fontSize,
                                    this.fontStyle,
                                    this.fontUnit,
                                    out this.nativeFont ); 

            // Special case this common error message to give more information 
            if (status == SafeNativeMethods.Gdip.FontStyleNotFound) 
            {
                throw new ArgumentException(SR.GetString(SR.GdiplusFontStyleNotFound, this.fontFamily.Name, this.fontStyle.ToString())); 
            }
            else if (status != SafeNativeMethods.Gdip.Ok)
            {
                throw SafeNativeMethods.Gdip.StatusException(status); 
            }
        } 
 
        /**
         * Constructor used in deserialization 
         */
        [SuppressMessage("Microsoft.Performance", "CA1808:AvoidCallsThatBoxValueTypes")]
        private Font(SerializationInfo info, StreamingContext context) {
            Debug.Assert(info != null, "Didn't expect a null parameter"); 

            string name = null; 
            float size = -1f; 
            FontStyle style = FontStyle.Regular;
            GraphicsUnit unit = GraphicsUnit.Point; 
            SingleConverter sc = new SingleConverter();

            SerializationInfoEnumerator sie = info.GetEnumerator();
            for (; sie.MoveNext();) { 
                if (String.Equals(sie.Name, "Name", StringComparison.OrdinalIgnoreCase))
                    name = (string) sie.Value; 
                else if (String.Equals(sie.Name, "Size", StringComparison.OrdinalIgnoreCase)) 
                {
                    if (sie.Value is System.String) 
                    {
                        size = (float) sc.ConvertFrom(sie.Value);
                    }
                    else 
                    {
                        size = (float) sie.Value; 
                    } 
                }
                else if (String.Compare(sie.Name, "Style", true, CultureInfo.InvariantCulture) == 0) 
                    style = (FontStyle) sie.Value;
                else if (String.Compare(sie.Name, "Unit", true, CultureInfo.InvariantCulture) == 0)
                    unit = (GraphicsUnit) sie.Value;
                else { 
                    Debug.Fail("Unknown serialization item for font: " + sie.Name);
                } 
            } 

            Initialize(name, size, style, unit, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(name)); 
        }

        /// 
        ///  
        ///     ISerializable private implementation
        ///  
        ///  
        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
        void ISerializable.GetObjectData(SerializationInfo si, StreamingContext context) { 
            // Serialize the original Font name rather than the fallback font name if we have one
            // See VSWhidbey 602074
            si.AddValue("Name", String.IsNullOrEmpty(OriginalFontName) ? Name : OriginalFontName);
            si.AddValue("Size", Size); 
            si.AddValue("Style", Style);
            si.AddValue("Unit", Unit); 
        } 

 
        /// 
        /// 
        ///    
        ///       Initializes a new instance of the  class from 
        ///       the specified existing  and .
        ///     
        ///  
        public Font(Font prototype, FontStyle newStyle)
        { 
            // Copy over the originalFontName because it won't get initialized
            this.originalFontName = prototype.OriginalFontName;
            Initialize(prototype.FontFamily, prototype.Size, newStyle, prototype.Unit, SafeNativeMethods.DEFAULT_CHARSET, false);
        } 

        ///  
        ///  
        ///    Initializes a new instance of the  class with
        ///    the specified attributes. 
        /// 
        public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit)  {
            Initialize(family, emSize, style, unit, SafeNativeMethods.DEFAULT_CHARSET, false);
        } 

        ///  
        ///  
        ///    Initializes a new instance of the  class with
        ///    the specified attributes. 
        /// 
        public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) {
            Initialize(family, emSize, style, unit, gdiCharSet, false);
        } 

        ///  
        ///  
        ///    Initializes a new instance of the  class with
        ///    the specified attributes. 
        /// 
        public Font(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) {
            Initialize(family, emSize, style, unit, gdiCharSet, gdiVerticalFont);
        } 

        ///  
        ///  
        ///    Initializes a new instance of the  class with
        ///    the specified attributes. 
        /// 
        public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet) {
            Initialize(familyName, emSize, style, unit, gdiCharSet, IsVerticalName(familyName));
        } 

 
        ///  
        /// 
        ///    Initializes a new instance of the  class with 
        ///    the specified attributes.
        /// 
        public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) {
            if (float.IsNaN(emSize) || float.IsInfinity(emSize) || emSize <= 0) { 
                throw new ArgumentException(SR.GetString(SR.InvalidBoundArgument, "emSize", emSize, 0, "System.Single.MaxValue"), "emSize");
            } 
 
            Initialize(familyName, emSize, style, unit, gdiCharSet, gdiVerticalFont);
        } 

        /// 
        /// 
        ///    Initializes a new instance of the  class with 
        ///    the specified attributes.
        ///  
        public Font(FontFamily family, float emSize, FontStyle style) { 
            Initialize(family, emSize, style, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, false);
        } 

        /// 
        /// 
        ///    Initializes a new instance of the  class with 
        ///    the specified attributes.
        ///  
        public Font(FontFamily family, float emSize, GraphicsUnit unit) { 
            Initialize(family, emSize, FontStyle.Regular, unit, SafeNativeMethods.DEFAULT_CHARSET, false);
        } 

        /// 
        /// 
        ///    Initializes a new instance of the  class with 
        ///    the specified attributes.
        ///  
        public Font(FontFamily family, float emSize) { 
            Initialize(family, emSize, FontStyle.Regular, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, false);
        } 

        /// 
        /// 
        ///    Initializes a new instance of the  class with 
        ///    the specified attributes.
        ///  
        public Font(string familyName, float emSize, FontStyle style, GraphicsUnit unit) { 
            Initialize(familyName, emSize, style, unit, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName));
        } 

        /// 
        /// 
        ///     
        ///       Initializes a new instance of the  class with
        ///       the specified 
        ///       attributes. 
        ///    
        ///  
        public Font(string familyName, float emSize, FontStyle style) {
            Initialize(familyName, emSize, style, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName));
        }
 
        /// 
        ///  
        ///    Initializes a new instance of the  class with 
        ///    the specified attributes.
        ///  
        public Font(string familyName, float emSize, GraphicsUnit unit) {
            Initialize(familyName, emSize, FontStyle.Regular, unit, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName));
        }
 
        /// 
        ///  
        ///    Initializes a new instance of the  class with 
        ///    the specified attributes.
        ///  
        public Font(string familyName, float emSize) {
            Initialize(familyName, emSize, FontStyle.Regular, GraphicsUnit.Point, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(familyName));
        }
 
        /// 
        ///     Constructor to initialize fields from an exisiting native GDI+ object reference. 
        ///     Used by ToLogFont. 
        /// 
        private Font(IntPtr nativeFont, byte gdiCharSet, bool gdiVerticalFont) 
        {
            Debug.Assert(this.nativeFont == IntPtr.Zero, "GDI+ native font already initialized, this will generate a handle leak" );
            Debug.Assert(nativeFont != IntPtr.Zero, "nativeFont is null");
 
            int          status       = 0;
            float        size         = 0; 
            GraphicsUnit unit         = GraphicsUnit.Point; 
            FontStyle    style        = FontStyle.Regular;
            IntPtr       nativeFamily = IntPtr.Zero; 

            this.nativeFont = nativeFont;

            status = SafeNativeMethods.Gdip.GdipGetFontUnit(new HandleRef(this, nativeFont), out unit); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status); 

            status = SafeNativeMethods.Gdip.GdipGetFontSize(new HandleRef(this, nativeFont), out size); 

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            status = SafeNativeMethods.Gdip.GdipGetFontStyle(new HandleRef(this, nativeFont), out style);
 
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            status = SafeNativeMethods.Gdip.GdipGetFamily(new HandleRef(this, nativeFont), out nativeFamily);

            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 

            SetFontFamily(new FontFamily(nativeFamily)); 
 
            Initialize(this.fontFamily, size, style, unit, gdiCharSet, gdiVerticalFont);
        } 

        /// 
        ///     Initializes this object's fields.
        ///  
        private void Initialize(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont)
        { 
            this.originalFontName = familyName; 

            SetFontFamily(new FontFamily(StripVerticalName(familyName), true /* createDefaultOnFail */ )); 
            Initialize( this.fontFamily, emSize, style, unit, gdiCharSet, gdiVerticalFont );
        }

        ///  
        ///     Initializes this object's fields.
        ///  
        private void Initialize(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte gdiCharSet, bool gdiVerticalFont) 
        {
            if (family == null) 
            {
                throw new ArgumentNullException("family");
            }
 
            if ( float.IsNaN( emSize ) || float.IsInfinity(emSize) || emSize <= 0 )
            { 
                throw new ArgumentException(SR.GetString(SR.InvalidBoundArgument, "emSize", emSize, 0, "System.Single.MaxValue"), "emSize"); 
            }
 
            int status;

            this.fontSize        = emSize;
            this.fontStyle       = style; 
            this.fontUnit        = unit;
            this.gdiCharSet      = gdiCharSet; 
            this.gdiVerticalFont = gdiVerticalFont; 

            if (this.fontFamily == null) 
            {
                // GDI+ FontFamily is a singleton object.
                SetFontFamily(new FontFamily(family.NativeFamily));
            } 

            if( this.nativeFont == IntPtr.Zero ) 
            { 
                CreateNativeFont();
            } 

            // Get actual size.
            status = SafeNativeMethods.Gdip.GdipGetFontSize(new HandleRef(this, this.nativeFont), out this.fontSize);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
        } 

        ///  
        /// 
        ///    Creates a  from the specified Windows
        ///    handle.
        ///  
        public static Font FromHfont(IntPtr hfont) {
            IntSecurity.ObjectFromWin32Handle.Demand(); 
 
            SafeNativeMethods.LOGFONT lf = new SafeNativeMethods.LOGFONT();
            SafeNativeMethods.GetObject(new HandleRef(null, hfont), lf); 

            Font result;
            IntPtr screenDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef);
            try { 
                result = Font.FromLogFont(lf, screenDC);
            } 
            finally { 
                UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, screenDC));
            } 

            return result;
        }
 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        public static Font FromLogFont(object lf) {
            IntPtr screenDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef);
            Font result;
            try { 
                result = Font.FromLogFont(lf, screenDC);
            } 
            finally { 
                UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, screenDC));
            } 
            return result;

        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public static Font FromLogFont(object lf, IntPtr hdc) { 
            IntSecurity.ObjectFromWin32Handle.Demand();

            IntPtr font = IntPtr.Zero;
            int status; 

            if (Marshal.SystemDefaultCharSize == 1) 
                status = SafeNativeMethods.Gdip.GdipCreateFontFromLogfontA(new HandleRef(null, hdc), lf, out font); 
            else
                status = SafeNativeMethods.Gdip.GdipCreateFontFromLogfontW(new HandleRef(null, hdc), lf, out font); 

            // Special case this incredibly common error message to give more information
            if (status == SafeNativeMethods.Gdip.NotTrueTypeFont)
                throw new ArgumentException(SR.GetString(SR.GdiplusNotTrueTypeFont_NoName)); 
            else if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status); 
 
            // GDI+ returns font = 0 even though the status is Ok.
            if (font == IntPtr.Zero) 
                throw new ArgumentException(SR.GetString(SR.GdiplusNotTrueTypeFont, lf.ToString()));

            bool gdiVerticalFont;
            if (Marshal.SystemDefaultCharSize == 1) { 
                gdiVerticalFont = (Marshal.ReadByte(lf, LogFontNameOffset) == (byte)(short)'@');
            } 
            else { 
                gdiVerticalFont = (Marshal.ReadInt16(lf, LogFontNameOffset) == (short)'@');
            } 

            return new Font(font, Marshal.ReadByte(lf, LogFontCharSetOffset), gdiVerticalFont);
        }
 
        /// 
        ///  
        ///    Creates a Font from the specified Windows 
        ///    handle to a device context.
        ///  
        public static Font FromHdc(IntPtr hdc) {
            IntSecurity.ObjectFromWin32Handle.Demand();

            IntPtr font = IntPtr.Zero; 

            int status = SafeNativeMethods.Gdip.GdipCreateFontFromDC(new HandleRef(null, hdc), ref font); 
 
            // Special case this incredibly common error message to give more information
            if (status == SafeNativeMethods.Gdip.NotTrueTypeFont) 
                throw new ArgumentException(SR.GetString(SR.GdiplusNotTrueTypeFont_NoName));
            else if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            return new Font(font, 0, false);
        } 
 

        ///  
        /// 
        ///    Creates an exact copy of this .
        /// 
        public object Clone() 
        {
            IntPtr cloneFont = IntPtr.Zero; 
 
            int status = SafeNativeMethods.Gdip.GdipCloneFont(new HandleRef(this, nativeFont), out cloneFont);
 
            if (status != SafeNativeMethods.Gdip.Ok)
                throw SafeNativeMethods.Gdip.StatusException(status);

            Font newCloneFont = new Font(cloneFont, this.gdiCharSet, this.gdiVerticalFont); 

            return newCloneFont; 
        } 

 
        /// 
        ///     Get native GDI+ object pointer.
        ///     This property triggers the creation of the GDI+ native object if not initialized yet.
        ///  
        internal IntPtr NativeFont
        { 
            get 
            {
                Debug.Assert( this.nativeFont != IntPtr.Zero, "this.nativeFont == IntPtr.Zero." ); 
                return this.nativeFont;
            }
        }
 
        /// 
        ///  
        ///    Gets the  of this . 
        /// 
        [ 
        Browsable(false)
        ]
        public FontFamily FontFamily
        { 
            get
            { 
                Debug.Assert(this.fontFamily != null, "fontFamily should never be null"); 
                return this.fontFamily;
            } 
        }

        [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts")]
 	private void SetFontFamily(FontFamily family) { 
            this.fontFamily = family;
 
            // GDI+ creates ref-counted singleton FontFamily objects based on the family name so all managed 
            // objects with same family name share the underlying GDI+ native pointer.  The unmanged object is
            // destroyed when its ref-count gets to zero. 
            // Make sure this.fontFamily is not finalized so the underlying singleton object is kept alive.
	    // SECREVIEW : This security assert here is safe.
            //
            new System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode).Assert(); 
            GC.SuppressFinalize(this.fontFamily);
        } 
 
        /// 
        ///  
        ///    Cleans up Windows resources for this .
        /// 
        ~Font()
        { 
            Dispose(false);
        } 
 
        /// 
        ///  
        ///    Cleans up Windows resources for this .
        /// 
        public void Dispose() {
            Dispose(true); 
            GC.SuppressFinalize(this);
        } 
 
        [SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed")]
        void Dispose(bool disposing) { 
            if (this.nativeFont != IntPtr.Zero) {
                try {
#if DEBUG
                    int status = 
#endif
                    SafeNativeMethods.Gdip.GdipDeleteFont(new HandleRef(this, this.nativeFont)); 
#if DEBUG 
                    Debug.Assert(status == SafeNativeMethods.Gdip.Ok, "GDI+ returned an error status: " + status.ToString(CultureInfo.InvariantCulture));
#endif 
                }
                catch( Exception ex ) {
                    if( ClientUtils.IsCriticalException( ex ) ) {
                        throw; 
                    }
 
                    Debug.Fail( "Exception thrown during Dispose: " + ex.ToString() ); 
                }
                finally { 
                    this.nativeFont = IntPtr.Zero;
                }
            }
        } 

        private static bool IsVerticalName(string familyName) 
        { 
            return familyName != null && familyName.Length > 0 && familyName[0] == '@';
        } 

        /// 
        /// 
        ///     
        ///       Gets a value indicating whether this  is bold.
        ///     
        ///  
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool Bold { 
            get {
                return(Style & FontStyle.Bold) != 0;
            }
        } 

        ///  
        ///  
        ///     Returns the GDI char set for this instance of a font. This will only
        ///     be valid if this font was created from a classic GDI font definition, 
        ///     like a LOGFONT or HFONT, or it was passed into the constructor.
        ///
        ///     This is here for compatability with native Win32 intrinsic controls
        ///     on non-Unicode platforms. 
        /// 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public byte GdiCharSet { 
            get {
                return gdiCharSet; 
            }
        }

        ///  
        /// 
        ///     Determines if this font was created to represt a GDI vertical font. 
        ///     his will only be valid if this font was created from a classic GDI 
        ///     font definition, like a LOGFONT or HFONT, or it was passed into the
        ///     constructor. 
        ///
        ///     This is here for compatability with native Win32 intrinsic controls
        ///     on non-Unicode platforms.
        ///  
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool GdiVerticalFont { 
            get { 
                return gdiVerticalFont;
            } 
        }

        /// 
        ///  
        ///    
        ///       Gets a value indicating whether this  is Italic. 
        ///     
        /// 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public bool Italic {
            get {
                return(Style & FontStyle.Italic) != 0;
            } 
        }
 
        ///  
        /// 
        ///     
        ///       Gets the face name of this  .
        ///    
        /// 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        [Editor("System.Drawing.Design.FontNameEditor, " + AssemblyRef.SystemDrawingDesign, typeof(UITypeEditor))]
        [TypeConverterAttribute(typeof(FontConverter.FontNameConverter))] 
        public string Name { 
            get { return this.FontFamily.Name;}
        } 

        /// 
        /// 
        ///     
        ///       This property is required by the framework and not intended to be used directly.
        ///     
        ///  
        [Browsable(false)]
        public string OriginalFontName 
        {
            get { return this.originalFontName; }
        }
 
        /// 
        ///  
        ///     
        ///       Gets a value indicating whether this  is strikeout (has a line
        ///       through it). 
        ///    
        /// 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool Strikeout { 
            get {
                return(Style & FontStyle.Strikeout) != 0; 
            } 
        }
 
        /// 
        /// 
        ///    
        ///       Gets a value indicating whether this  is underlined. 
        ///    
        ///  
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public bool Underline {
            get { 
                return(Style & FontStyle.Underline) != 0;
            }
        }
 
        /// 
        ///  
        ///    Returns a value indicating whether the 
        ///    specified object is a  equivalent to this .
        ///  
        public override bool Equals(object obj)
        {
            if (obj == this)
            { 
                return true;
            } 
 
            Font font = obj as Font;
 
            if (font == null)
            {
                return false;
            } 

            // Note: If this and/or the passed-in font are disposed, this method can still return true since we check for cached properties 
            // here - We cannot fix this, see VSW#484721. 

            // We need to call properties on the passed-in object since it could be a proxy in a remoting scenario and proxies don't 
            // have access to private/internal fields - See VSW#464151.
            return  font.FontFamily.Equals(this.FontFamily)  &&
                font.GdiVerticalFont == this.GdiVerticalFont &&
                font.GdiCharSet      == this.GdiCharSet      && 
                font.Style           == this.Style           &&
                font.Size            == this.Size            && 
                font.Unit            == this.Unit; 
        }
 


        /// 
        ///  
        ///    Gets the hash code for this .
        ///  
        public override int GetHashCode() 
        {
            return (int)((((UInt32)fontStyle << 13) | ((UInt32)fontStyle >> 19)) ^ 
                         (((UInt32)fontUnit  << 26) | ((UInt32)fontUnit  >>  6)) ^
                         (((UInt32)fontSize  <<  7) | ((UInt32)fontSize  >> 25)));
        }
 
        private static string StripVerticalName(string familyName) {
            if (familyName != null && familyName.Length > 1 && familyName[0] == '@') { 
                return familyName.Substring(1); 
            }
            return familyName; 
        }

        /// 
        ///  
        ///    Returns a human-readable string
        ///    representation of this . 
        ///  
        public override string ToString()
        { 
            return string.Format(   CultureInfo.CurrentCulture, "[{0}: Name={1}, Size={2}, Units={3}, GdiCharSet={4}, GdiVerticalFont={5}]",
                                    GetType().Name,
                                    this.FontFamily.Name,
                                    this.fontSize, 
                                    (int) this.fontUnit,
                                    this.gdiCharSet, 
                                    this.gdiVerticalFont ); 
        }
 


        // Operations
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public void ToLogFont(object logFont) { 
            IntPtr screenDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef);
            try {
                Graphics graphics = Graphics.FromHdcInternal(screenDC);
 
                try {
                    this.ToLogFont(logFont, graphics); 
                } 
                finally {
                    graphics.Dispose(); 
                }
            }
            finally {
                UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, screenDC)); 
            }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public unsafe void ToLogFont(object logFont, Graphics graphics) {
            IntSecurity.ObjectFromWin32Handle.Demand(); 

            if (graphics == null) 
                throw new ArgumentNullException("graphics"); 

            int status; 

            // handle proper marshalling of LogFontName as Unicode or ANSI
            if (Marshal.SystemDefaultCharSize == 1)
                status = SafeNativeMethods.Gdip.GdipGetLogFontA(new HandleRef(this, this.NativeFont), new HandleRef(graphics, graphics.NativeGraphics), logFont); 
            else
                status = SafeNativeMethods.Gdip.GdipGetLogFontW(new HandleRef(this, this.NativeFont), new HandleRef(graphics, graphics.NativeGraphics), logFont); 
 
            // append "@" to the begining of the string if we are
            // a gdiVerticalFont. 
            //
            if (gdiVerticalFont) {
                if (Marshal.SystemDefaultCharSize == 1) {
 
                    // copy contents of name, over 1 byte
                    // 
                    for (int i=30; i>=0; i--) { 
                        Marshal.WriteByte(logFont,
                                          LogFontNameOffset + i + 1, 
                                          Marshal.ReadByte(logFont, LogFontNameOffset + i));
                    }

                    // write ANSI '@' sign at begining of name 
                    //
                    Marshal.WriteByte(logFont, LogFontNameOffset, (byte)(int)'@'); 
                } 
                else {
                    // copy contents of name, over 2 bytes (UNICODE) 
                    //
                    for (int i=60; i>=0; i-=2) {
                        Marshal.WriteInt16(logFont,
                                           LogFontNameOffset + i + 2, 
                                           Marshal.ReadInt16(logFont, LogFontNameOffset + i));
                    } 
 
                    // write UNICODE '@' sign at begining of name
                    // 
                    Marshal.WriteInt16(logFont, LogFontNameOffset, (short)'@');
                }
            }
 
            if (Marshal.ReadByte(logFont, LogFontCharSetOffset) == 0) {
                Marshal.WriteByte(logFont, LogFontCharSetOffset, gdiCharSet); 
            } 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
        }

        ///  
        /// 
        ///    Returns a handle to this . 
        ///  
        public IntPtr ToHfont() {
            SafeNativeMethods.LOGFONT lf = new SafeNativeMethods.LOGFONT(); 

            IntSecurity.ObjectFromWin32Handle.Assert();

            try { 
                this.ToLogFont(lf);
            } 
            finally { 
                System.Security.CodeAccessPermission.RevertAssert();
            } 

            IntPtr handle = IntUnsafeNativeMethods.IntCreateFontIndirect(lf);

            if (handle == IntPtr.Zero) { 
                throw new Win32Exception();
            } 
 
            return handle;
 
        }

        /// 
        ///  
        ///    Returns the height of this Font in the
        ///    specified graphics context. 
        ///  
        public float GetHeight(Graphics graphics) {
            if (graphics == null) 
                throw new ArgumentNullException("graphics");

            float ht;
 
            int status = SafeNativeMethods.Gdip.GdipGetFontHeight(new HandleRef(this, this.NativeFont), new HandleRef(graphics, graphics.NativeGraphics), out ht);
 
            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status);
 
            return ht;
        }

                ///  
        /// 
        ///  
        public float GetHeight() { 

            IntPtr screenDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef); 
            float height = 0.0f;
            try {
                using (Graphics graphics = Graphics.FromHdcInternal(screenDC)) {
                    height = GetHeight(graphics); 
                }
            } 
            finally { 
                UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, screenDC));
            } 

            return height;
        }
 

        ///  
        ///  
        /// 
        public float GetHeight(float dpi) { 

            float ht;

            int status = SafeNativeMethods.Gdip.GdipGetFontHeightGivenDPI(new HandleRef(this, this.NativeFont), dpi, out ht); 

            if (status != SafeNativeMethods.Gdip.Ok) 
                throw SafeNativeMethods.Gdip.StatusException(status); 

            return ht; 
        }


        ///  
        /// 
        ///    Gets style information for this . 
        ///  
        [
        Browsable(false) 
        ]
        public FontStyle Style {
            get {
                return fontStyle; 
            }
        } 
 
        // Return value is in Unit (the unit the font was created in)
        ///  
        /// 
        ///    Gets the size of this .
        /// 
        public float Size { 
            get {
                return fontSize; 
            } 
        }
 
        /// 
        /// 
        ///    Gets the size, in points, of this .
        ///  
        [Browsable(false)]
        public float SizeInPoints { 
             get { 
                if (Unit == GraphicsUnit.Point)
                    return Size; 
                else {
                    float emHeightInPoints;

                    IntPtr screenDC = UnsafeNativeMethods.GetDC(NativeMethods.NullHandleRef); 

                    try { 
                        using( Graphics graphics = Graphics.FromHdcInternal(screenDC)){ 
                            float pixelsPerPoint      = (float) (graphics.DpiY / 72.0);
                            float lineSpacingInPixels = this.GetHeight(graphics); 
                            float emHeightInPixels    = lineSpacingInPixels * FontFamily.GetEmHeight(Style)  / FontFamily.GetLineSpacing(Style);

                            emHeightInPoints    = emHeightInPixels / pixelsPerPoint;
                        } 
                    }
                    finally { 
                        UnsafeNativeMethods.ReleaseDC(NativeMethods.NullHandleRef, new HandleRef(null, screenDC)); 
                    }
 
                    return emHeightInPoints;
                }
            }
        } 

        ///  
        ///  
        ///    Gets the unit of measure for this .
        ///  
        [TypeConverterAttribute(typeof(FontConverter.FontUnitConverter))]
        public GraphicsUnit Unit {
            get {
                return fontUnit; 
            }
        } 
 
        /// 
        ///  
        ///    Gets the height of this .
        /// 
        [
        Browsable(false) 
        ]
        public int Height { 
            get { 
                return(int) Math.Ceiling(GetHeight());
            } 
        }

        /// 
        ///  
        ///    Returns true if this  is a SystemFont.
        ///  
        [ 
        Browsable(false)
        ] 
        public bool IsSystemFont {
            get {
                return !String.IsNullOrEmpty(this.systemFontName);
            } 
        }
 
        ///  
        /// 
        ///    Gets the name of this . 
        /// 
        [
        Browsable(false)
        ] 
        public string SystemFontName {
            get { 
                return this.systemFontName; 
            }
        } 

        // This is used by SystemFonts when constructing a system Font objects.
        internal void SetSystemFontName(string systemFontName) {
            this.systemFontName = systemFontName; 
        }
    } 
} 

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