Skip to content

Commit

Permalink
Introduce AOT friendly version of ToLogFont and FromLogFont
Browse files Browse the repository at this point in the history
These methods used by WinForms
Closes #70358
  • Loading branch information
kant2002 committed Jan 24, 2023
1 parent ec5fffb commit 648f645
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ public void FillPie(System.Drawing.Brush brush, System.Drawing.RectangleF rect,
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public void GetContextInfo(out PointF offset, out Region? clip) { throw null; }
}
public sealed partial class Font
{
public void ToLogFont<T>(ref T logFont, Graphics graphics) where T: unmanaged { throw null; }
public static Font FromLogFont<T>(in T logFont) where T: unmanaged { throw null; }
public static Font FromLogFont<T>(in T logFont, IntPtr hdc) where T: unmanaged { throw null; }
public void ToLogFont<T>(ref T logFont) where T: unmanaged { throw null; }
}
}
namespace System.Drawing.Drawing2D
{
Expand Down
75 changes: 75 additions & 0 deletions src/libraries/System.Drawing.Common/src/System/Drawing/Font.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,29 @@ public unsafe void ToLogFont(object logFont, Graphics graphics)
}
}

/// <summary>
/// Update the given LOGFONT with data from given graphics.
/// </summary>
/// <param name="logFont">A structure to populate with LOGFONT data.</param>
/// <param name="graphics">Graphics object which provide information about font.</param>
public unsafe void ToLogFont<T>(ref T logFont, Graphics graphics)
where T: unmanaged
{
ArgumentNullException.ThrowIfNull(logFont);

if (sizeof(T) != sizeof(Interop.User32.LOGFONT))
{
// If we don't actually have an object that is LOGFONT in size, trying to pass
// it to GDI+ is likely to cause an AV.
throw new ArgumentException(null, nameof(logFont));
}

fixed (T* pLogFont = &logFont)
{
*(Interop.User32.LOGFONT*)pLogFont = ToLogFontInternal(graphics);
}
}

private unsafe Interop.User32.LOGFONT ToLogFontInternal(Graphics graphics)
{
ArgumentNullException.ThrowIfNull(graphics);
Expand Down Expand Up @@ -551,6 +574,20 @@ public static Font FromLogFont(object lf)
}
}

/// <summary>
/// Creates a <see cref="Font"/> from the given LOGFONT using the screen device context.
/// </summary>
/// <param name="logFont">A structure holding LOGFONT data.</param>
/// <returns>The newly created <see cref="Font"/>.</returns>
public static Font FromLogFont<T>(in T logFont)
where T: unmanaged
{
using (ScreenDC dc = ScreenDC.Create())
{
return FromLogFont<T>(in logFont, dc);
}
}

internal static Font FromLogFont(ref Interop.User32.LOGFONT logFont)
{
using (ScreenDC dc = ScreenDC.Create())
Expand Down Expand Up @@ -616,6 +653,30 @@ public static unsafe Font FromLogFont(object lf, IntPtr hdc)
return FromLogFontInternal(ref logFont, hdc);
}

/// <summary>
/// Creates a <see cref="Font"/> from the given LOGFONT using the given device context.
/// </summary>
/// <param name="logFont">A structure holding LOGFONT data.</param>
/// <param name="hdc">Handle to a device context (HDC).</param>
/// <returns>The newly created <see cref="Font"/>.</returns>
public static unsafe Font FromLogFont<T>(in T logFont, IntPtr hdc)
where T: unmanaged
{
ArgumentNullException.ThrowIfNull(logFont);

if (sizeof(T) != sizeof(Interop.User32.LOGFONT))
{
// If we don't actually have an object that is LOGFONT in size, trying to pass
// it to GDI+ is likely to cause an AV.
throw new ArgumentException(null, nameof(logFont));
}

fixed (T* pLogFont = &logFont)
{
return FromLogFontInternal(ref *(Interop.User32.LOGFONT*)pLogFont, hdc);
}
}

/// <summary>
/// Creates a <see cref="Font"/> from the specified handle to a device context (HDC).
/// </summary>
Expand Down Expand Up @@ -681,6 +742,20 @@ public void ToLogFont(object logFont)
}
}

/// <summary>
/// Update the given LOGFONT with data from the screen device context.
/// </summary>
/// <param name="logFont">A structure to populate with LOGFONT data.</param>
public void ToLogFont<T>(ref T logFont)
where T: unmanaged
{
using (ScreenDC dc = ScreenDC.Create())
using (Graphics graphics = Graphics.FromHdcInternal(dc))
{
ToLogFont<T>(ref logFont, graphics);
}
}

/// <summary>
/// Returns a handle to this <see cref='Font'/>.
/// </summary>
Expand Down

0 comments on commit 648f645

Please sign in to comment.