Font.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / CommonUI / System / Drawing / Advanced / Font.cs / 1305376 / Font.cs

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

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;
    using System.Runtime.Versioning;

     /* 
     * 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. 
        ///
        [ResourceExposure(ResourceScope.Process)] 
        [ResourceConsumption(ResourceScope.Process)]
        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")]
        [ResourceExposure(ResourceScope.Process)] 
        [ResourceConsumption(ResourceScope.Process)]
        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 .
        ///     
        /// 
        [ResourceExposure(ResourceScope.Process)]
        [ResourceConsumption(ResourceScope.Process)]
        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.
        ///  
        [ResourceExposure(ResourceScope.Process)] 
        [ResourceConsumption(ResourceScope.Process)]
        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. 
        /// 
        [ResourceExposure(ResourceScope.Process)] 
        [ResourceConsumption(ResourceScope.Process)]
        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. 
        /// 
        [ResourceExposure(ResourceScope.Process)]
        [ResourceConsumption(ResourceScope.Process)]
        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.
        /// 
        [ResourceExposure(ResourceScope.Process)] 
        [ResourceConsumption(ResourceScope.Process)]
        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.
        ///  
        [ResourceExposure(ResourceScope.Process)] 
        [ResourceConsumption(ResourceScope.Process)]
        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.
        /// 
        [ResourceExposure(ResourceScope.Process)] 
        [ResourceConsumption(ResourceScope.Process)]
        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. 
        /// 
        [ResourceExposure(ResourceScope.Process)] 
        [ResourceConsumption(ResourceScope.Process)] 
        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. 
        ///  
        [ResourceExposure(ResourceScope.Process)]
        [ResourceConsumption(ResourceScope.Process)] 
        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.
        ///  
        [ResourceExposure(ResourceScope.Process)]
        [ResourceConsumption(ResourceScope.Process)]
        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.
        ///     
        /// 
        [ResourceExposure(ResourceScope.Process)] 
        [ResourceConsumption(ResourceScope.Process)] 
        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. 
        ///  
        [ResourceExposure(ResourceScope.Process)]
        [ResourceConsumption(ResourceScope.Process)] 
        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.
        ///  
        [ResourceExposure(ResourceScope.Process)]
        [ResourceConsumption(ResourceScope.Process)]
        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. 
        /// 
        [ResourceExposure(ResourceScope.Process)]
        [ResourceConsumption(ResourceScope.Process)]
        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. 
        /// 
        [ResourceExposure(ResourceScope.Process)] 
        [ResourceConsumption(ResourceScope.Process)]
        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.
        /// 
        [ResourceExposure(ResourceScope.Process)] 
        [ResourceConsumption(ResourceScope.Process)]
        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.
        /// 
        [ResourceExposure(ResourceScope.Process)] 
        [ResourceConsumption(ResourceScope.Process)]
        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.] 
        /// 
        [ResourceExposure(ResourceScope.Process)]
        [ResourceConsumption(ResourceScope.Process)]
        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.]
        /// 
        [ResourceExposure(ResourceScope.Process)]
        [ResourceConsumption(ResourceScope.Process)] 
        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. 
        /// 
        [ResourceExposure(ResourceScope.Process)] 
        [ResourceConsumption(ResourceScope.Process)] 
        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 . 
        /// 
        [ResourceExposure(ResourceScope.Process)]
        [ResourceConsumption(ResourceScope.Process)]
        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
        { 
            [System.Runtime.TargetedPatchingOptOutAttribute("Performance critical to inline across NGen image boundaries")] 
            get
            { 
                Debug.Assert( this.nativeFont != IntPtr.Zero, "this.nativeFont == IntPtr.Zero." );
                return this.nativeFont;
            }
        } 

        ///  
        ///  
        ///    Gets the  of this .
        ///  
        [Browsable(false)]
        public FontFamily FontFamily
        {
            [System.Runtime.TargetedPatchingOptOutAttribute("Performance critical to inline across NGen image boundaries")] 
            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.] 
        /// 
        [ResourceExposure(ResourceScope.None)] 
        [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
        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 .
        ///  
        [ResourceExposure(ResourceScope.Process)]
        [ResourceConsumption(ResourceScope.Process)]
        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;
        } 
 
                /// 
        ///  
        /// 
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
        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 {
             [ResourceExposure(ResourceScope.None)] 
             [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
             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 {
            [System.Runtime.TargetedPatchingOptOutAttribute("Performance critical to inline across NGen image boundaries")] 
            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.


                        

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