<PackageReference Include="System.Drawing.Common" Version="10.0.0-preview.6.25358.103" />

FontFamily

Defines a group of type faces having a similar basic design and certain variations in styles. This class cannot be inherited.
using System.Diagnostics.CodeAnalysis; using System.Drawing.Text; using System.Globalization; using System.Runtime.CompilerServices; using Windows.Win32; using Windows.Win32.Foundation; using Windows.Win32.Graphics.GdiPlus; namespace System.Drawing { [NullableContext(1)] [Nullable(0)] public sealed class FontFamily : MarshalByRefObject, IDisposable, IPointer<GpFontFamily> { private const ushort NeutralLanguage = 0; [Nullable(0)] private unsafe GpFontFamily* _nativeFamily; private bool _fromInstalledFontCollection; unsafe IntPtr IPointer<GpFontFamily>.Pointer { get { return (IntPtr)_nativeFamily; } } [Nullable(0)] internal unsafe GpFontFamily* NativeFamily { [NullableContext(0)] get { return _nativeFamily; } } public string Name => GetName(CultureInfo.CurrentUICulture.LCID); public static FontFamily[] Families => InstalledFontCollection.Instance.Families; public unsafe static FontFamily GenericSansSerif => new FontFamily(GetGdipGenericSansSerif(), true); public static FontFamily GenericSerif => new FontFamily(GenericFontFamilies.Serif); public static FontFamily GenericMonospace => new FontFamily(GenericFontFamilies.Monospace); [NullableContext(0)] private unsafe void SetNativeFamily(GpFontFamily* family) { _nativeFamily = family; } [NullableContext(0)] internal unsafe FontFamily(GpFontFamily* family, bool fromInstalledFontCollection) { _fromInstalledFontCollection = fromInstalledFontCollection; if (fromInstalledFontCollection) GC.SuppressFinalize(this); else { GpFontFamily* ptr = default(GpFontFamily*); PInvokeGdiPlus.GdipCloneFontFamily(family, &ptr).ThrowIfFailed(); family = ptr; } SetNativeFamily(family); } internal unsafe FontFamily Clone() { if (_fromInstalledFontCollection) return this; return new FontFamily(_nativeFamily, false); } [NullableContext(0)] internal FontFamily(ReadOnlySpan<char> name, bool createDefaultOnFail) { CreateFontFamily(name, null, createDefaultOnFail); } public FontFamily(string name) { CreateFontFamily(name.OrThrowIfNull("name").AsSpan(), null, false); } public FontFamily(string name, [Nullable(2)] FontCollection fontCollection) { CreateFontFamily(name.OrThrowIfNull("name").AsSpan(), fontCollection, false); } [NullableContext(0)] private unsafe void CreateFontFamily(ReadOnlySpan<char> name, [Nullable(2)] FontCollection fontCollection, bool createDefaultOnFail = false) { GpFontCollection* ptr = fontCollection.Pointer(); _fromInstalledFontCollection = (ptr == null || ptr == InstalledFontCollection.Instance.Pointer()); Status status = Status.Ok; GpFontFamily* gdipGenericSansSerif = default(GpFontFamily*); fixed (char* value = &name.GetPinnableReference()) { status = PInvokeGdiPlus.GdipCreateFontFamilyFromName(value, ptr, &gdipGenericSansSerif); } if (status != 0) { if (createDefaultOnFail) gdipGenericSansSerif = GetGdipGenericSansSerif(); else { switch (status) { case Status.FontFamilyNotFound: throw new ArgumentException(System.SR.Format(System.SR.GdiplusFontFamilyNotFound, name.ToString())); case Status.NotTrueTypeFont: throw new ArgumentException(System.SR.Format(System.SR.GdiplusNotTrueTypeFont, name.ToString())); } status.ThrowIfFailed(); } } if (_fromInstalledFontCollection) GC.SuppressFinalize(this); GC.KeepAlive(fontCollection); SetNativeFamily(gdipGenericSansSerif); } public unsafe FontFamily(GenericFontFamilies genericFamily) { GpFontFamily* nativeFamily = default(GpFontFamily*); switch (genericFamily) { case GenericFontFamilies.Serif: PInvokeGdiPlus.GdipGetGenericFontFamilySerif(&nativeFamily).ThrowIfFailed(); break; case GenericFontFamilies.SansSerif: PInvokeGdiPlus.GdipGetGenericFontFamilySansSerif(&nativeFamily).ThrowIfFailed(); break; default: PInvokeGdiPlus.GdipGetGenericFontFamilyMonospace(&nativeFamily).ThrowIfFailed(); break; } _fromInstalledFontCollection = true; SetNativeFamily(nativeFamily); } ~FontFamily() { Dispose(false); } public override string ToString() { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(9, 2); defaultInterpolatedStringHandler.AppendLiteral("["); defaultInterpolatedStringHandler.AppendFormatted("FontFamily"); defaultInterpolatedStringHandler.AppendLiteral(": Name="); defaultInterpolatedStringHandler.AppendFormatted(Name); defaultInterpolatedStringHandler.AppendLiteral("]"); return defaultInterpolatedStringHandler.ToStringAndClear(); } [NullableContext(2)] public unsafe override bool Equals([NotNullWhen(true)] object obj) { if (obj == this) return true; FontFamily fontFamily = obj as FontFamily; if (fontFamily == null) return false; return fontFamily.NativeFamily == NativeFamily; } public unsafe override int GetHashCode() { Span<char> span = new Span<char>(stackalloc byte[64], 32); GetName(span, 0); return string.GetHashCode(span.SliceAtFirstNull()); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private unsafe void Dispose(bool disposing) { if (_nativeFamily != null && !_fromInstalledFontCollection) { PInvokeGdiPlus.GdipDeleteFontFamily(_nativeFamily); _nativeFamily = null; } } public unsafe string GetName(int language) { Span<char> span = new Span<char>(stackalloc byte[64], 32); GetName(span, (ushort)language); return new string(span.SliceAtFirstNull()); } [NullableContext(0)] private unsafe void GetName(Span<char> span, ushort language) { fixed (char* value = &span.GetPinnableReference()) { PInvokeGdiPlus.GdipGetFamilyName(NativeFamily, value, language).ThrowIfFailed(); } } [NullableContext(0)] private unsafe static GpFontFamily* GetGdipGenericSansSerif() { GpFontFamily* result = default(GpFontFamily*); PInvokeGdiPlus.GdipGetGenericFontFamilySansSerif(&result).ThrowIfFailed(); return result; } [Obsolete("FontFamily.GetFamilies has been deprecated. Use Families instead.")] public static FontFamily[] GetFamilies(Graphics graphics) { ArgumentNullException.ThrowIfNull(graphics, "graphics"); return InstalledFontCollection.Instance.Families; } public unsafe bool IsStyleAvailable(FontStyle style) { BOOL value = default(BOOL); PInvokeGdiPlus.GdipIsStyleAvailable(NativeFamily, (int)style, &value).ThrowIfFailed(); GC.KeepAlive(this); return value; } public unsafe int GetEmHeight(FontStyle style) { ushort result = default(ushort); PInvokeGdiPlus.GdipGetEmHeight(NativeFamily, (int)style, &result).ThrowIfFailed(); GC.KeepAlive(this); return result; } public unsafe int GetCellAscent(FontStyle style) { ushort result = default(ushort); PInvokeGdiPlus.GdipGetCellAscent(NativeFamily, (int)style, &result).ThrowIfFailed(); GC.KeepAlive(this); return result; } public unsafe int GetCellDescent(FontStyle style) { ushort result = default(ushort); PInvokeGdiPlus.GdipGetCellDescent(NativeFamily, (int)style, &result).ThrowIfFailed(); GC.KeepAlive(this); return result; } public unsafe int GetLineSpacing(FontStyle style) { ushort result = default(ushort); PInvokeGdiPlus.GdipGetLineSpacing(NativeFamily, (int)style, &result).ThrowIfFailed(); GC.KeepAlive(this); return result; } } }