/// <summary> /// Creates a WindowsFont from the handle to a native GDI font and optionally takes ownership of managing /// the lifetime of the handle. /// </summary> public unsafe static WindowsFont FromHfont(Gdi32.HFONT hFont, bool takeOwnership = false) { Gdi32.GetObjectW(hFont, out User32.LOGFONTW logFont); FontStyle style = FontStyle.Regular; if (logFont.lfWeight == Gdi32.FW.BOLD) { style |= FontStyle.Bold; } if (logFont.lfItalic == True) { style |= FontStyle.Italic; } if (logFont.lfUnderline == True) { style |= FontStyle.Underline; } if (logFont.lfStrikeOut == True) { style |= FontStyle.Strikeout; } WindowsFont wf = new WindowsFont(logFont, style, createHandle: false) { Hfont = hFont, _ownHandle = takeOwnership // if true, hFont will be deleted on dispose. }; return(wf); }
/// <summary> /// Creates a WindowsFont from the font selected in the supplied dc. /// </summary> public static WindowsFont FromHdc(Gdi32.HDC hdc) { Gdi32.HFONT hFont = (Gdi32.HFONT)Gdi32.GetCurrentObject(hdc, Gdi32.ObjectType.OBJ_FONT); // don't call DeleteObject on handle from GetCurrentObject, it is the one selected in the hdc. return(FromHfont(hFont)); }
private void Dispose(bool disposing) { if (!_handle.IsNull) { Gdi32.DeleteObject(_handle); _handle = default; } }
public unsafe void CreateFontIndirect() { LOGFONTW logFont = default; Gdi32.HFONT handle = Gdi32.CreateFontIndirectW(ref logFont); Assert.False(handle.IsNull); Assert.True(Gdi32.DeleteObject(handle).IsTrue()); }
/// <summary> /// Constructs 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). /// </summary> private static Gdi32.HFONT FromFont(Font font, Gdi32.QUALITY quality = Gdi32.QUALITY.DEFAULT) { 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); } // Now, creating it using the Font.SizeInPoints makes it GraphicsUnit-independent. Debug.Assert(font.SizeInPoints > 0.0f, "size has a negative value."); // Get the font height from the specified size. The 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. (1 point = 1/72 inch.) int pixelsY = (int)Math.Ceiling(DpiHelper.DeviceDpi * font.SizeInPoints / 72); // 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. User32.LOGFONTW logFont = new User32.LOGFONTW { lfHeight = -pixelsY, lfCharSet = font.GdiCharSet, lfOutPrecision = Gdi32.OUT_PRECIS.TT, lfQuality = quality, lfWeight = (font.Style & FontStyle.Bold) == FontStyle.Bold ? Gdi32.FW.BOLD : Gdi32.FW.NORMAL, lfItalic = (font.Style & FontStyle.Italic) == FontStyle.Italic ? True : False, lfUnderline = (font.Style & FontStyle.Underline) == FontStyle.Underline ? True : False, lfStrikeOut = (font.Style & FontStyle.Strikeout) == FontStyle.Strikeout ? True : False, FaceName = familyName }; if (logFont.FaceName.IsEmpty) { logFont.FaceName = DefaultFaceName; } Gdi32.HFONT hfont = Gdi32.CreateFontIndirectW(ref logFont); if (hfont.IsNull) { // Get the default font if we couldn't get what we requested. logFont.FaceName = DefaultFaceName; logFont.lfOutPrecision = Gdi32.OUT_PRECIS.TT_ONLY; hfont = Gdi32.CreateFontIndirectW(ref logFont); Debug.Assert(!hfont.IsNull); } return(hfont); }
public static FontCache.Scope GetHFONT(Font?font, Gdi32.QUALITY quality, Gdi32.HDC hdc) { if (font != null) { return(GetHFONT(font, quality)); } // Font is null, build off of the specified HDC's current font. Gdi32.HFONT hfont = (Gdi32.HFONT)Gdi32.GetCurrentObject(hdc, Gdi32.OBJ.FONT); return(new FontCache.Scope(hfont)); }
/// <summary> /// Returns the Size of the given text using the specified font if not null, otherwise the font currently /// set in the dc is used. /// This method is used to get the size in points of a line of text; it uses GetTextExtentPoint32 function /// which computes the width and height of the text ignoring TAB\CR\LF characters. /// A text extent is the distance between the beginning of the space and a character that will fit in the space. /// </summary> public static Size GetTextExtent(this Gdi32.HDC hdc, string?text, Gdi32.HFONT hfont) { if (string.IsNullOrEmpty(text)) { return(Size.Empty); } Size size = new Size(); using var selectFont = new Gdi32.SelectObjectScope(hdc, hfont); Gdi32.GetTextExtentPoint32W(hdc, text, text.Length, ref size); return(new Size(size.Width, size.Height)); }
internal FontHandleWrapper(Font font) { _handle = (Gdi32.HFONT)font.ToHfont(); }