Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / Misc / GDI / WindowsFont.cs / 1 / WindowsFont.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- #if WINFORMS_NAMESPACE namespace System.Windows.Forms.Internal #elif DRAWING_NAMESPACE namespace System.Drawing.Internal #else namespace System.Experimental.Gdi #endif { using System; using System.Internal; using System.Runtime.InteropServices; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Text; using System.Security; using System.Security.Permissions; using System.Globalization; ////// #if WINFORMS_PUBLIC_GRAPHICS_LIBRARY public #else internal #endif sealed partial class WindowsFont : MarshalByRefObject, ICloneable, IDisposable { const int LogFontNameOffset = 28; // Handle to the native Windows font object. // private IntPtr hFont; private float fontSize = -1.0f; //invalid value. private int lineSpacing; private bool ownHandle; private bool ownedByCacheManager; private bool everOwnedByCacheManager; private IntNativeMethods.LOGFONT logFont; private FontStyle style; // Note: These defaults are according to the ones in GDI+ but those are not necessarily the same as the system // default font. The GetSystemDefaultHFont() method should be used if needed. private const string defaultFaceName = "Microsoft Sans Serif"; private const float defaultFontSize = 8.25f; private const int defaultFontHeight = 13; #if GDI_FINALIZATION_WATCH private string AllocationSite = DbgUtil.StackTrace; #endif ////// Encapsulates a GDI Font object. /// ////// Creates the font handle. /// private void CreateFont() { Debug.Assert( hFont == IntPtr.Zero, "hFont is not null, this will generate a handle leak." ); Debug.Assert( this.logFont != null, "WindowsFont.logFont not initialized." ); this.hFont = IntUnsafeNativeMethods.CreateFontIndirect(this.logFont); #if TRACK_HFONT Debug.WriteLine( DbgUtil.StackTraceToStr(String.Format( "HFONT[0x{0:x8}] = CreateFontIndirect( LOGFONT={1} )", (int) this.hFont, this.logFont))); #endif if (this.hFont == IntPtr.Zero) { this.logFont.lfFaceName = defaultFaceName; this.logFont.lfOutPrecision = IntNativeMethods.OUT_TT_ONLY_PRECIS; // True Type only. this.hFont = IntUnsafeNativeMethods.CreateFontIndirect(this.logFont); #if TRACK_HFONT Debug.WriteLine( DbgUtil.StackTraceToStr(String.Format( "HFONT[0x{0:x8}] = CreateFontIndirect( LOGFONT={1} )", (int) this.hFont, this.logFont))); #endif } // Update logFont height and other adjusted parameters. // IntUnsafeNativeMethods.GetObject(new HandleRef(this, this.hFont), this.logFont); // We created the hFont, we will delete it on dispose. this.ownHandle = true; } /// Constructors. ////// Contructor to construct font from a face name. /// > public WindowsFont( string faceName ) : this(faceName, defaultFontSize, FontStyle.Regular, IntNativeMethods.DEFAULT_CHARSET, WindowsFontQuality.Default) { // Default size in WinForms is 8.25f. } ////// Contructor to construct font from a face name, a desired size and with the specified style. /// > public WindowsFont( string faceName, float size ) : this(faceName, size, FontStyle.Regular, IntNativeMethods.DEFAULT_CHARSET, WindowsFontQuality.Default) { } ////// Contructor to construct font from a face name, a desired size and with the specified style. /// > public WindowsFont( string faceName, float size, FontStyle style ) : this(faceName, size, style, IntNativeMethods.DEFAULT_CHARSET, WindowsFontQuality.Default) { } ////// Contructor to construct font from a face name, a desired size in points and with the specified style /// and character set. The screen dc is used for calculating the font em height. /// > public WindowsFont( string faceName, float size, FontStyle style, byte charSet, WindowsFontQuality fontQuality ) { Debug.Assert( size > 0.0f, "size has a negative value." ); const byte True = 1; const byte False = 0; this.logFont = new IntNativeMethods.LOGFONT(); // // Get the font height from the specified size. size is in point units and height in logical // units (pixels when using MM_TEXT) so we need to make the conversion using the number of // pixels per logical inch along the screen height. // int pixelsY = (int) Math.Ceiling( WindowsGraphicsCacheManager.MeasurementGraphics.DeviceContext.DpiY * size / 72); // 1 point = 1/72 inch.; // // The lfHeight represents the font cell height (line spacing) which includes the internal // leading; we specify a negative size value (in pixels) for the height so the font mapper // provides the closest match for the character height rather than the cell height (MSDN). // this.logFont.lfHeight = -pixelsY; this.logFont.lfFaceName = faceName != null ? faceName : defaultFaceName; this.logFont.lfCharSet = charSet; this.logFont.lfOutPrecision = IntNativeMethods.OUT_TT_PRECIS; this.logFont.lfQuality = (byte) fontQuality; this.logFont.lfWeight = (style & FontStyle.Bold) == FontStyle.Bold ? IntNativeMethods.FW_BOLD : IntNativeMethods.FW_NORMAL; this.logFont.lfItalic = (style & FontStyle.Italic) == FontStyle.Italic ? True : False; this.logFont.lfUnderline = (style & FontStyle.Underline) == FontStyle.Underline ? True : False; this.logFont.lfStrikeOut = (style & FontStyle.Strikeout) == FontStyle.Strikeout ? True : False; // Let the Size be recomputed to be consistent with the Height (there may be some precision loss coming from size to height). // this.fontSize = size; this.style = style; CreateFont(); } ////// Contructor to construct font from a LOGFONT structure. /// Pass false in the createHandle param to create a 'compatible' font (handle-less, to be used for measuring/comparing) or /// when the handle has already been created. /// private WindowsFont( IntNativeMethods.LOGFONT lf, bool createHandle ) { Debug.Assert( lf != null, "lf is null" ); this.logFont = lf; if (this.logFont.lfFaceName == null) { this.logFont.lfFaceName = defaultFaceName; } this.style = FontStyle.Regular; if (lf.lfWeight == IntNativeMethods.FW_BOLD) { this.style |= FontStyle.Bold; } if (lf.lfItalic == 1) { this.style |= FontStyle.Italic; } if (lf.lfUnderline == 1) { this.style |= FontStyle.Underline; } if (lf.lfStrikeOut == 1) { this.style |= FontStyle.Strikeout; } if( createHandle ) { CreateFont(); } } ////// Contructs a WindowsFont object from an existing System.Drawing.Font object (GDI+), based on the screen dc MapMode /// and resolution (normally: MM_TEXT and 96 dpi). /// public static WindowsFont FromFont(Font font) { return FromFont(font, WindowsFontQuality.Default); } public static WindowsFont FromFont(Font font, WindowsFontQuality fontQuality) { string familyName = font.FontFamily.Name; // Strip vertical-font mark from the name if needed. if (familyName != null && familyName.Length > 1 && familyName[0] == '@') { familyName = familyName.Substring(1); } // Note: Creating the WindowsFont from Font using a LOGFONT structure from GDI+ (Font.ToLogFont(logFont)) may sound like // a better choice (more accurate) for doing this but tests show that is not the case (see WindowsFontTests test suite), // the results are the same. Also, that approach has some issues when the Font is created in a different application // domain since the LOGFONT cannot be marshalled properly, see VSW#451960. // Now, creating it using the Font.SizeInPoints makes it GraphicsUnit-independent. return new WindowsFont(familyName, font.SizeInPoints, font.Style, font.GdiCharSet, fontQuality); } ////// Creates a WindowsFont from the font selected in the supplied dc. /// public static WindowsFont FromHdc( IntPtr hdc ) { IntPtr hFont = IntUnsafeNativeMethods.GetCurrentObject(new HandleRef(null, hdc), IntNativeMethods.OBJ_FONT); // don't call DeleteObject on handle from GetCurrentObject, it is the one selected in the hdc. return FromHfont( hFont ); } ////// Creates a WindowsFont from the handle to a native GDI font. It does not take ownership of the /// passed-in handle, the caller needs to delete the hFont when done with the WindowsFont. /// public static WindowsFont FromHfont( IntPtr hFont ) { return FromHfont( hFont, false ); } ////// Creates a WindowsFont from the handle to a native GDI font and optionally takes ownership of managing /// the lifetime of the handle. /// public static WindowsFont FromHfont( IntPtr hFont, bool takeOwnership ) { IntNativeMethods.LOGFONT lf = new IntNativeMethods.LOGFONT(); IntUnsafeNativeMethods.GetObject(new HandleRef(null, hFont), lf); WindowsFont wf = new WindowsFont( lf, /*createHandle*/ false ); wf.hFont = hFont; wf.ownHandle = takeOwnership; // if true, hFont will be deleted on dispose. return wf; } ~WindowsFont() { Dispose(false); } public void Dispose() { Dispose(true); } internal void Dispose(bool disposing) { bool deletedHandle = false; if (this.ownHandle) { if (!ownedByCacheManager || !disposing) { // If we were ever owned by the CacheManger and we're being disposed // we can be sure that we're not in use by any DC's (otherwise Dispose() wouldn't have been called) // skip the check IsFontInUse check in this case. // Also skip the check if disposing == false, because the cache is thread-static // and that means we're being called from the finalizer. if (everOwnedByCacheManager || !disposing || !DeviceContexts.IsFontInUse(this)) { Debug.Assert( this.hFont != IntPtr.Zero, "Unexpected null hFont." ); DbgUtil.AssertFinalization(this, disposing); IntUnsafeNativeMethods.DeleteObject(new HandleRef(this, this.hFont)); #if TRACK_HFONT Debug.WriteLine( DbgUtil.StackTraceToStr(String.Format( "DeleteObject(HFONT[0x{0:x8}]))", (int) this.hFont))); #endif this.hFont = IntPtr.Zero; this.ownHandle = false; deletedHandle = true; } } } if (disposing && (deletedHandle || !ownHandle)) { GC.SuppressFinalize(this); } } ////// Returns a value indicating whether the specified object is a WindowsFont equivalent to this object. /// public override bool Equals( object font ) { WindowsFont winFont = font as WindowsFont; if( winFont == null ) { return false; } if( winFont == this ) { return true; } // WARNING: don't use non-public fields/properties here, the passed-in font object could be a proxy in a // remoting scenario and proxies cannot access internal or private members. VSW#465265 & 465647 // Compare params used to create the font. return this.Name == winFont.Name && this.LogFontHeight == winFont.LogFontHeight && // Equivalent to comparing Size but always at hand. this.Style == winFont.Style && this.CharSet == winFont.CharSet && this.Quality == winFont.Quality; } ////// Gets the hash code for this WindowsFont. /// public override int GetHashCode() { // similar to Font.GetHashCode(). return (int)((((UInt32)this.Style << 13) | ((UInt32)this.Style >> 19)) ^ (((UInt32)this.CharSet << 26) | ((UInt32)this.CharSet >> 6)) ^ (((UInt32)this.Size << 7) | ((UInt32)this.Size >> 25))); } ////// Clones this object. /// public object Clone() { return new WindowsFont( this.logFont, true ); } public override string ToString() { return string.Format(CultureInfo.CurrentCulture, "[{0}: Name={1}, Size={2} points, Height={3} pixels, Sytle={4}]", GetType().Name, logFont.lfFaceName, this.Size, this.Height, this.Style); } //////////////////////////////////////////// /// Properties ////// Returns this object's native Win32 font handle. Should NOT be deleted externally. /// Compare with ToHfont method. /// public IntPtr Hfont { get { //Assert removed. We need to be able to check for Hfont == IntPtr.Zero to determine if the object was disposed. //Debug.Assert(this.hFont != IntPtr.Zero, "hFont is null, are you using a disposed object?"); return this.hFont; } } ////// Determines whether the font has the italic style or not. /// public bool Italic { get { return logFont.lfItalic == 1; } } public bool OwnedByCacheManager { get { return ownedByCacheManager; } set { if (value) { everOwnedByCacheManager = true; } ownedByCacheManager = value; } } ////// Rendering quality. /// public WindowsFontQuality Quality { get { return (WindowsFontQuality) this.logFont.lfQuality; } } ////// Gets the font style. /// public FontStyle Style { get { return this.style; } } ////// Gets the line spacing (cell height) of this font in (screen) pixels using the screen resolution. /// Gets the line spacing (cell height), in pixels (using the screen DC resolution), of this font. /// The line spacing is the vertical distance between the base lines of two consecutive lines of text. /// Thus, the line spacing includes the blank space between lines along with the height of the character /// itself. /// public int Height { // get { if( this.lineSpacing == 0 ) { // Observe that the font text metrics are obtained using the resolution of the screen. WindowsGraphics wg = WindowsGraphicsCacheManager.MeasurementGraphics; // No need to reset the font (if changed) since we always set the font before using the MeasurementGraphics // in WindowsGraphics methods. wg.DeviceContext.SelectFont(this); IntNativeMethods.TEXTMETRIC tm = (IntNativeMethods.TEXTMETRIC) wg.GetTextMetrics(); this.lineSpacing = tm.tmHeight; } return this.lineSpacing; } } ////// Gets the font character set. /// This is used by the system font mapper when searching for the physical font that best matches the logical font. /// public byte CharSet { get { return logFont.lfCharSet; } } ////// Specifies the height, in logical units, of the font's character cell or character. The character height value (em height) /// is the character cell height value minus the internal-leading value. /// public int LogFontHeight { get { return logFont.lfHeight; } } ////// The font's face name. /// public string Name { get { return logFont.lfFaceName; } } ////// Gets the character height (as opposed to the cell height) of the font represented by this object in points. /// Consider /// public float Size { get { if( this.fontSize < 0.0f ) { WindowsGraphics wg = WindowsGraphicsCacheManager.MeasurementGraphics; // No need to reset the font (if changed) since we always set the font before using the MeasurementGraphics // in WindowsGraphics methods. wg.DeviceContext.SelectFont(this); IntNativeMethods.TEXTMETRIC tm = (IntNativeMethods.TEXTMETRIC) wg.GetTextMetrics(); // // Convert the font character height to points. If lfHeight is negative, Windows // treats the absolute value of that number as a desired font height compatible with // the point size; in this case lfHeight will roughly match the tmHeight field of // the TEXTMETRIC structure less the tmInternalLeading field. // int height = this.logFont.lfHeight > 0 ? tm.tmHeight : (tm.tmHeight - tm.tmInternalLeading); // /* switch (this.unit) { case GraphicsUnit.Pixel: worldEmSize = height * dpi / 72.0f; break; case GraphicsUnit.Point: worldEmSize = height * dpi / 72.0f; break; case GraphicsUnit.Inch: worldEmSize = height * dpi; break; case GraphicsUnit.Document: worldEmSize = height * dpi / 300.0f; break; case GraphicsUnit.Millimeter: worldEmSize = height * dpi / 25.4f; break; } */ this.fontSize = height * 72f / wg.DeviceContext.DpiY; } return this.fontSize; } } ////// Attempts to match the TextRenderingHint of the specified Graphics object with a LOGFONT.lfQuality value. /// public static WindowsFontQuality WindowsFontQualityFromTextRenderingHint(Graphics g) { if (g == null) { return WindowsFontQuality.Default; } switch (g.TextRenderingHint) { case TextRenderingHint.ClearTypeGridFit: // See WindowsFontQuality enum for the flags supported in the different OS systems. if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) { return WindowsFontQuality.ClearTypeNatural; } else { return WindowsFontQuality.ClearType; } case TextRenderingHint.AntiAliasGridFit: return WindowsFontQuality.AntiAliased; case TextRenderingHint.AntiAlias: return WindowsFontQuality.AntiAliased; case TextRenderingHint.SingleBitPerPixelGridFit: return WindowsFontQuality.Proof; case TextRenderingHint.SingleBitPerPixel: return WindowsFontQuality.Draft; default: case TextRenderingHint.SystemDefault: return WindowsFontQuality.Default; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- #if WINFORMS_NAMESPACE namespace System.Windows.Forms.Internal #elif DRAWING_NAMESPACE namespace System.Drawing.Internal #else namespace System.Experimental.Gdi #endif { using System; using System.Internal; using System.Runtime.InteropServices; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Text; using System.Security; using System.Security.Permissions; using System.Globalization; ////// #if WINFORMS_PUBLIC_GRAPHICS_LIBRARY public #else internal #endif sealed partial class WindowsFont : MarshalByRefObject, ICloneable, IDisposable { const int LogFontNameOffset = 28; // Handle to the native Windows font object. // private IntPtr hFont; private float fontSize = -1.0f; //invalid value. private int lineSpacing; private bool ownHandle; private bool ownedByCacheManager; private bool everOwnedByCacheManager; private IntNativeMethods.LOGFONT logFont; private FontStyle style; // Note: These defaults are according to the ones in GDI+ but those are not necessarily the same as the system // default font. The GetSystemDefaultHFont() method should be used if needed. private const string defaultFaceName = "Microsoft Sans Serif"; private const float defaultFontSize = 8.25f; private const int defaultFontHeight = 13; #if GDI_FINALIZATION_WATCH private string AllocationSite = DbgUtil.StackTrace; #endif ////// Encapsulates a GDI Font object. /// ////// Creates the font handle. /// private void CreateFont() { Debug.Assert( hFont == IntPtr.Zero, "hFont is not null, this will generate a handle leak." ); Debug.Assert( this.logFont != null, "WindowsFont.logFont not initialized." ); this.hFont = IntUnsafeNativeMethods.CreateFontIndirect(this.logFont); #if TRACK_HFONT Debug.WriteLine( DbgUtil.StackTraceToStr(String.Format( "HFONT[0x{0:x8}] = CreateFontIndirect( LOGFONT={1} )", (int) this.hFont, this.logFont))); #endif if (this.hFont == IntPtr.Zero) { this.logFont.lfFaceName = defaultFaceName; this.logFont.lfOutPrecision = IntNativeMethods.OUT_TT_ONLY_PRECIS; // True Type only. this.hFont = IntUnsafeNativeMethods.CreateFontIndirect(this.logFont); #if TRACK_HFONT Debug.WriteLine( DbgUtil.StackTraceToStr(String.Format( "HFONT[0x{0:x8}] = CreateFontIndirect( LOGFONT={1} )", (int) this.hFont, this.logFont))); #endif } // Update logFont height and other adjusted parameters. // IntUnsafeNativeMethods.GetObject(new HandleRef(this, this.hFont), this.logFont); // We created the hFont, we will delete it on dispose. this.ownHandle = true; } /// Constructors. ////// Contructor to construct font from a face name. /// > public WindowsFont( string faceName ) : this(faceName, defaultFontSize, FontStyle.Regular, IntNativeMethods.DEFAULT_CHARSET, WindowsFontQuality.Default) { // Default size in WinForms is 8.25f. } ////// Contructor to construct font from a face name, a desired size and with the specified style. /// > public WindowsFont( string faceName, float size ) : this(faceName, size, FontStyle.Regular, IntNativeMethods.DEFAULT_CHARSET, WindowsFontQuality.Default) { } ////// Contructor to construct font from a face name, a desired size and with the specified style. /// > public WindowsFont( string faceName, float size, FontStyle style ) : this(faceName, size, style, IntNativeMethods.DEFAULT_CHARSET, WindowsFontQuality.Default) { } ////// Contructor to construct font from a face name, a desired size in points and with the specified style /// and character set. The screen dc is used for calculating the font em height. /// > public WindowsFont( string faceName, float size, FontStyle style, byte charSet, WindowsFontQuality fontQuality ) { Debug.Assert( size > 0.0f, "size has a negative value." ); const byte True = 1; const byte False = 0; this.logFont = new IntNativeMethods.LOGFONT(); // // Get the font height from the specified size. size is in point units and height in logical // units (pixels when using MM_TEXT) so we need to make the conversion using the number of // pixels per logical inch along the screen height. // int pixelsY = (int) Math.Ceiling( WindowsGraphicsCacheManager.MeasurementGraphics.DeviceContext.DpiY * size / 72); // 1 point = 1/72 inch.; // // The lfHeight represents the font cell height (line spacing) which includes the internal // leading; we specify a negative size value (in pixels) for the height so the font mapper // provides the closest match for the character height rather than the cell height (MSDN). // this.logFont.lfHeight = -pixelsY; this.logFont.lfFaceName = faceName != null ? faceName : defaultFaceName; this.logFont.lfCharSet = charSet; this.logFont.lfOutPrecision = IntNativeMethods.OUT_TT_PRECIS; this.logFont.lfQuality = (byte) fontQuality; this.logFont.lfWeight = (style & FontStyle.Bold) == FontStyle.Bold ? IntNativeMethods.FW_BOLD : IntNativeMethods.FW_NORMAL; this.logFont.lfItalic = (style & FontStyle.Italic) == FontStyle.Italic ? True : False; this.logFont.lfUnderline = (style & FontStyle.Underline) == FontStyle.Underline ? True : False; this.logFont.lfStrikeOut = (style & FontStyle.Strikeout) == FontStyle.Strikeout ? True : False; // Let the Size be recomputed to be consistent with the Height (there may be some precision loss coming from size to height). // this.fontSize = size; this.style = style; CreateFont(); } ////// Contructor to construct font from a LOGFONT structure. /// Pass false in the createHandle param to create a 'compatible' font (handle-less, to be used for measuring/comparing) or /// when the handle has already been created. /// private WindowsFont( IntNativeMethods.LOGFONT lf, bool createHandle ) { Debug.Assert( lf != null, "lf is null" ); this.logFont = lf; if (this.logFont.lfFaceName == null) { this.logFont.lfFaceName = defaultFaceName; } this.style = FontStyle.Regular; if (lf.lfWeight == IntNativeMethods.FW_BOLD) { this.style |= FontStyle.Bold; } if (lf.lfItalic == 1) { this.style |= FontStyle.Italic; } if (lf.lfUnderline == 1) { this.style |= FontStyle.Underline; } if (lf.lfStrikeOut == 1) { this.style |= FontStyle.Strikeout; } if( createHandle ) { CreateFont(); } } ////// Contructs a WindowsFont object from an existing System.Drawing.Font object (GDI+), based on the screen dc MapMode /// and resolution (normally: MM_TEXT and 96 dpi). /// public static WindowsFont FromFont(Font font) { return FromFont(font, WindowsFontQuality.Default); } public static WindowsFont FromFont(Font font, WindowsFontQuality fontQuality) { string familyName = font.FontFamily.Name; // Strip vertical-font mark from the name if needed. if (familyName != null && familyName.Length > 1 && familyName[0] == '@') { familyName = familyName.Substring(1); } // Note: Creating the WindowsFont from Font using a LOGFONT structure from GDI+ (Font.ToLogFont(logFont)) may sound like // a better choice (more accurate) for doing this but tests show that is not the case (see WindowsFontTests test suite), // the results are the same. Also, that approach has some issues when the Font is created in a different application // domain since the LOGFONT cannot be marshalled properly, see VSW#451960. // Now, creating it using the Font.SizeInPoints makes it GraphicsUnit-independent. return new WindowsFont(familyName, font.SizeInPoints, font.Style, font.GdiCharSet, fontQuality); } ////// Creates a WindowsFont from the font selected in the supplied dc. /// public static WindowsFont FromHdc( IntPtr hdc ) { IntPtr hFont = IntUnsafeNativeMethods.GetCurrentObject(new HandleRef(null, hdc), IntNativeMethods.OBJ_FONT); // don't call DeleteObject on handle from GetCurrentObject, it is the one selected in the hdc. return FromHfont( hFont ); } ////// Creates a WindowsFont from the handle to a native GDI font. It does not take ownership of the /// passed-in handle, the caller needs to delete the hFont when done with the WindowsFont. /// public static WindowsFont FromHfont( IntPtr hFont ) { return FromHfont( hFont, false ); } ////// Creates a WindowsFont from the handle to a native GDI font and optionally takes ownership of managing /// the lifetime of the handle. /// public static WindowsFont FromHfont( IntPtr hFont, bool takeOwnership ) { IntNativeMethods.LOGFONT lf = new IntNativeMethods.LOGFONT(); IntUnsafeNativeMethods.GetObject(new HandleRef(null, hFont), lf); WindowsFont wf = new WindowsFont( lf, /*createHandle*/ false ); wf.hFont = hFont; wf.ownHandle = takeOwnership; // if true, hFont will be deleted on dispose. return wf; } ~WindowsFont() { Dispose(false); } public void Dispose() { Dispose(true); } internal void Dispose(bool disposing) { bool deletedHandle = false; if (this.ownHandle) { if (!ownedByCacheManager || !disposing) { // If we were ever owned by the CacheManger and we're being disposed // we can be sure that we're not in use by any DC's (otherwise Dispose() wouldn't have been called) // skip the check IsFontInUse check in this case. // Also skip the check if disposing == false, because the cache is thread-static // and that means we're being called from the finalizer. if (everOwnedByCacheManager || !disposing || !DeviceContexts.IsFontInUse(this)) { Debug.Assert( this.hFont != IntPtr.Zero, "Unexpected null hFont." ); DbgUtil.AssertFinalization(this, disposing); IntUnsafeNativeMethods.DeleteObject(new HandleRef(this, this.hFont)); #if TRACK_HFONT Debug.WriteLine( DbgUtil.StackTraceToStr(String.Format( "DeleteObject(HFONT[0x{0:x8}]))", (int) this.hFont))); #endif this.hFont = IntPtr.Zero; this.ownHandle = false; deletedHandle = true; } } } if (disposing && (deletedHandle || !ownHandle)) { GC.SuppressFinalize(this); } } ////// Returns a value indicating whether the specified object is a WindowsFont equivalent to this object. /// public override bool Equals( object font ) { WindowsFont winFont = font as WindowsFont; if( winFont == null ) { return false; } if( winFont == this ) { return true; } // WARNING: don't use non-public fields/properties here, the passed-in font object could be a proxy in a // remoting scenario and proxies cannot access internal or private members. VSW#465265 & 465647 // Compare params used to create the font. return this.Name == winFont.Name && this.LogFontHeight == winFont.LogFontHeight && // Equivalent to comparing Size but always at hand. this.Style == winFont.Style && this.CharSet == winFont.CharSet && this.Quality == winFont.Quality; } ////// Gets the hash code for this WindowsFont. /// public override int GetHashCode() { // similar to Font.GetHashCode(). return (int)((((UInt32)this.Style << 13) | ((UInt32)this.Style >> 19)) ^ (((UInt32)this.CharSet << 26) | ((UInt32)this.CharSet >> 6)) ^ (((UInt32)this.Size << 7) | ((UInt32)this.Size >> 25))); } ////// Clones this object. /// public object Clone() { return new WindowsFont( this.logFont, true ); } public override string ToString() { return string.Format(CultureInfo.CurrentCulture, "[{0}: Name={1}, Size={2} points, Height={3} pixels, Sytle={4}]", GetType().Name, logFont.lfFaceName, this.Size, this.Height, this.Style); } //////////////////////////////////////////// /// Properties ////// Returns this object's native Win32 font handle. Should NOT be deleted externally. /// Compare with ToHfont method. /// public IntPtr Hfont { get { //Assert removed. We need to be able to check for Hfont == IntPtr.Zero to determine if the object was disposed. //Debug.Assert(this.hFont != IntPtr.Zero, "hFont is null, are you using a disposed object?"); return this.hFont; } } ////// Determines whether the font has the italic style or not. /// public bool Italic { get { return logFont.lfItalic == 1; } } public bool OwnedByCacheManager { get { return ownedByCacheManager; } set { if (value) { everOwnedByCacheManager = true; } ownedByCacheManager = value; } } ////// Rendering quality. /// public WindowsFontQuality Quality { get { return (WindowsFontQuality) this.logFont.lfQuality; } } ////// Gets the font style. /// public FontStyle Style { get { return this.style; } } ////// Gets the line spacing (cell height) of this font in (screen) pixels using the screen resolution. /// Gets the line spacing (cell height), in pixels (using the screen DC resolution), of this font. /// The line spacing is the vertical distance between the base lines of two consecutive lines of text. /// Thus, the line spacing includes the blank space between lines along with the height of the character /// itself. /// public int Height { // get { if( this.lineSpacing == 0 ) { // Observe that the font text metrics are obtained using the resolution of the screen. WindowsGraphics wg = WindowsGraphicsCacheManager.MeasurementGraphics; // No need to reset the font (if changed) since we always set the font before using the MeasurementGraphics // in WindowsGraphics methods. wg.DeviceContext.SelectFont(this); IntNativeMethods.TEXTMETRIC tm = (IntNativeMethods.TEXTMETRIC) wg.GetTextMetrics(); this.lineSpacing = tm.tmHeight; } return this.lineSpacing; } } ////// Gets the font character set. /// This is used by the system font mapper when searching for the physical font that best matches the logical font. /// public byte CharSet { get { return logFont.lfCharSet; } } ////// Specifies the height, in logical units, of the font's character cell or character. The character height value (em height) /// is the character cell height value minus the internal-leading value. /// public int LogFontHeight { get { return logFont.lfHeight; } } ////// The font's face name. /// public string Name { get { return logFont.lfFaceName; } } ////// Gets the character height (as opposed to the cell height) of the font represented by this object in points. /// Consider /// public float Size { get { if( this.fontSize < 0.0f ) { WindowsGraphics wg = WindowsGraphicsCacheManager.MeasurementGraphics; // No need to reset the font (if changed) since we always set the font before using the MeasurementGraphics // in WindowsGraphics methods. wg.DeviceContext.SelectFont(this); IntNativeMethods.TEXTMETRIC tm = (IntNativeMethods.TEXTMETRIC) wg.GetTextMetrics(); // // Convert the font character height to points. If lfHeight is negative, Windows // treats the absolute value of that number as a desired font height compatible with // the point size; in this case lfHeight will roughly match the tmHeight field of // the TEXTMETRIC structure less the tmInternalLeading field. // int height = this.logFont.lfHeight > 0 ? tm.tmHeight : (tm.tmHeight - tm.tmInternalLeading); // /* switch (this.unit) { case GraphicsUnit.Pixel: worldEmSize = height * dpi / 72.0f; break; case GraphicsUnit.Point: worldEmSize = height * dpi / 72.0f; break; case GraphicsUnit.Inch: worldEmSize = height * dpi; break; case GraphicsUnit.Document: worldEmSize = height * dpi / 300.0f; break; case GraphicsUnit.Millimeter: worldEmSize = height * dpi / 25.4f; break; } */ this.fontSize = height * 72f / wg.DeviceContext.DpiY; } return this.fontSize; } } ////// Attempts to match the TextRenderingHint of the specified Graphics object with a LOGFONT.lfQuality value. /// public static WindowsFontQuality WindowsFontQualityFromTextRenderingHint(Graphics g) { if (g == null) { return WindowsFontQuality.Default; } switch (g.TextRenderingHint) { case TextRenderingHint.ClearTypeGridFit: // See WindowsFontQuality enum for the flags supported in the different OS systems. if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) { return WindowsFontQuality.ClearTypeNatural; } else { return WindowsFontQuality.ClearType; } case TextRenderingHint.AntiAliasGridFit: return WindowsFontQuality.AntiAliased; case TextRenderingHint.AntiAlias: return WindowsFontQuality.AntiAliased; case TextRenderingHint.SingleBitPerPixelGridFit: return WindowsFontQuality.Proof; case TextRenderingHint.SingleBitPerPixel: return WindowsFontQuality.Draft; default: case TextRenderingHint.SystemDefault: return WindowsFontQuality.Default; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TextBreakpoint.cs
- Cursor.cs
- ConnectionStringSettingsCollection.cs
- EventHandlersDesigner.cs
- ToolBarButton.cs
- NetSectionGroup.cs
- AutoResizedEvent.cs
- DataGridViewCellParsingEventArgs.cs
- EncryptedPackage.cs
- Transform3DCollection.cs
- ColorAnimationUsingKeyFrames.cs
- DataBoundControlHelper.cs
- GPRECTF.cs
- PersonalizationStateInfo.cs
- DoubleUtil.cs
- InvalidPrinterException.cs
- DataControlCommands.cs
- ImageDrawing.cs
- FontEmbeddingManager.cs
- ConfigurationManagerInternal.cs
- WebBrowserPermission.cs
- ReservationCollection.cs
- SQlBooleanStorage.cs
- RsaSecurityToken.cs
- IApplicationTrustManager.cs
- ExecutionPropertyManager.cs
- TdsRecordBufferSetter.cs
- ObjectQueryProvider.cs
- CfgRule.cs
- TraceHwndHost.cs
- WebException.cs
- NetworkAddressChange.cs
- NGCSerializer.cs
- DataRecordInternal.cs
- StylusPointPropertyInfoDefaults.cs
- GuidelineCollection.cs
- ShimAsPublicXamlType.cs
- HtmlInputFile.cs
- RegexNode.cs
- XmlCharType.cs
- Cell.cs
- ManualResetEventSlim.cs
- TdsParserSessionPool.cs
- SizeAnimation.cs
- DesignSurfaceCollection.cs
- CultureTableRecord.cs
- OracleConnection.cs
- CDSCollectionETWBCLProvider.cs
- FieldAccessException.cs
- ForeignKeyConstraint.cs
- AsymmetricKeyExchangeDeformatter.cs
- SortedSet.cs
- StylusCollection.cs
- KerberosSecurityTokenParameters.cs
- EventWaitHandle.cs
- InputMethodStateTypeInfo.cs
- CallContext.cs
- ByteStream.cs
- SiteMap.cs
- ServiceReference.cs
- InternalConfigRoot.cs
- ScrollChangedEventArgs.cs
- TextTreeTextBlock.cs
- SliderAutomationPeer.cs
- TextElementAutomationPeer.cs
- Math.cs
- TableCell.cs
- FileLoadException.cs
- GridItemCollection.cs
- ScriptingScriptResourceHandlerSection.cs
- StdRegProviderWrapper.cs
- NumericPagerField.cs
- OdbcCommandBuilder.cs
- Viewport2DVisual3D.cs
- HttpModulesSection.cs
- StructuredTypeInfo.cs
- MetabaseServerConfig.cs
- InvokeWebService.cs
- ForwardPositionQuery.cs
- SafeJobHandle.cs
- ImageMap.cs
- ColorContext.cs
- CodeGeneratorOptions.cs
- RawStylusSystemGestureInputReport.cs
- WindowsTokenRoleProvider.cs
- KeyFrames.cs
- NumericUpDown.cs
- ComponentCommands.cs
- CreatingCookieEventArgs.cs
- ContentTypeSettingDispatchMessageFormatter.cs
- RootProfilePropertySettingsCollection.cs
- XmlQualifiedNameTest.cs
- HtmlHead.cs
- DesignerAttribute.cs
- State.cs
- ControlPaint.cs
- ReadOnlyCollectionBase.cs
- PenContexts.cs
- TraceContext.cs
- ILGenerator.cs