Runtime: System.Drawing.Font.ToLogFont runtime error on Ubuntu 18.04 LTS

Created on 18 Nov 2020  路  7Comments  路  Source: dotnet/runtime

Description

The System.Drawing.Font.ToLogFont method seems to work well in a Windows environment. Using it in a Linux environment produces runtime errors. I've prepared a sample console application which illustrates the issue.

Exceptions

Unhandled exception. System.ArgumentException: Value does not fall within the expected range. (Parameter 'logFont')
   at System.Drawing.Font.ToLogFont(Object logFont, Graphics graphics)
   at System.Drawing.Font.ToLogFont(Object logFont)
   at TestFonts.Program.Main(String[] args) in /home/hwfbcisod/Desktop/TestFontsNew/Program.cs:line 27

Source Code

```C#
using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace TestFonts
{
class Program
{
static void Main()
{
var font = new Font(new FontFamily("Arial"), 20, FontStyle.Bold);
var logFont = new LOGFONT();
font.ToLogFont(logFont);
Console.WriteLine(logFont.lfHeight);
}

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    private class LOGFONT
    {
        public int lfHeight;
        public int lfWidth;
        public int lfEscapement;
        public int lfOrientation;
        public int lfWeight;
        public byte lfItalic;
        public byte lfUnderline;
        public byte lfStrikeOut;
        public byte lfCharSet;
        public byte lfOutPrecision;
        public byte lfClipPrecision;
        public byte lfQuality;
        public byte lfPitchAndFamily;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string lfFaceName;
    }

}

}

### NuGet Packages

[System.Drawing.Common](https://www.nuget.org/packages/System.Drawing.Common/)

## Configuration

### .NET Info

.NET SDK (reflecting any global.json):V
Version: 5.0.100
Commit: 5044b93829

Runtime Environment:
OS Name: ubuntu
OS Version: 18.04
OS Platform: Linux
RID: ubuntu.18.04-x64
Base Path: /usr/share/dotnet/sdk/5.0.100/

Host (useful for support):
Version: 5.0.0
Commit: cf258a14b7

.NET SDKs installed:
5.0.100 [/usr/share/dotnet/sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 5.0.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 5.0.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

### OS Info

Distributor ID: Ubuntu
Description: Ubuntu 18.04.3 LTS
Release: 18.04
Codename: bionic
```

Note: The Ubuntu distribution is running in a VM. Reproduced on both a local Hyper-V instance and on an Azure VM.

Regression?

The above problems occur both in .NET Core 3.1 and .NET Core 5. I haven't tested with other versions.

area-System.Drawing needs more info untriaged

Most helpful comment

The size check is failing because size of LOGFONT type is different than the one defined by runtime: https://github.com/dotnet/runtime/blob/6cb16e12fd912c28f2ab4577414b4a2d8b321a28/src/libraries/Common/src/Interop/Windows/User32/Interop.LOGFONT.cs#L12

-       [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
-       private class LOGFONT
+       [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+       private unsafe struct LOGFONT
        {
            public int lfHeight;
            public int lfWidth;
            public int lfEscapement;
            public int lfOrientation;
            public int lfWeight;
            public byte lfItalic;
            public byte lfUnderline;
            public byte lfStrikeOut;
            public byte lfCharSet;
            public byte lfOutPrecision;
            public byte lfClipPrecision;
            public byte lfQuality;
            public byte lfPitchAndFamily;
-           [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
-           public string lfFaceName;
+           private fixed char _lfFaceName[32];
+           public string lfFaceName
+           {
+               get { fixed (char* c = _lfFaceName) { return new string(c); } }
+           }
+       }

build as dotnet build -p:AllowUnsafeBlocks=True and finally dotnet run.

All 7 comments

Tagging subscribers to this area: @safern, @tannergooding, @jeffhandley
See info in area-owners.md if you want to be subscribed.


Issue Details





















Description:

Description

The System.Drawing.Font.ToLogFont method seems to work well in a Windows environment. Using it in a Linux environment produces runtime errors. I've prepared a sample console application which illustrates the issue.

Exceptions

Unhandled exception. System.ArgumentException: Value does not fall within the expected range. (Parameter 'logFont')
   at System.Drawing.Font.ToLogFont(Object logFont, Graphics graphics)
   at System.Drawing.Font.ToLogFont(Object logFont)
   at TestFonts.Program.Main(String[] args) in /home/hwfbcisod/Desktop/TestFontsNew/Program.cs:line 27

Source Code

```C#
using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace TestFonts
{
class Program
{
static void Main()
{
var font = new Font(new FontFamily("Arial"), 20, FontStyle.Bold);
var logFont = new LOGFONT();
font.ToLogFont(logFont);
Console.WriteLine(logFont.lfHeight);
}

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    private class LOGFONT
    {
        public int lfHeight;
        public int lfWidth;
        public int lfEscapement;
        public int lfOrientation;
        public int lfWeight;
        public byte lfItalic;
        public byte lfUnderline;
        public byte lfStrikeOut;
        public byte lfCharSet;
        public byte lfOutPrecision;
        public byte lfClipPrecision;
        public byte lfQuality;
        public byte lfPitchAndFamily;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string lfFaceName;
    }

}

}

### NuGet Packages

[System.Drawing.Common](https://www.nuget.org/packages/System.Drawing.Common/)

## Configuration

### .NET Info

.NET SDK (reflecting any global.json):V
Version: 5.0.100
Commit: 5044b93829

Runtime Environment:
OS Name: ubuntu
OS Version: 18.04
OS Platform: Linux
RID: ubuntu.18.04-x64
Base Path: /usr/share/dotnet/sdk/5.0.100/

Host (useful for support):
Version: 5.0.0
Commit: cf258a14b7

.NET SDKs installed:
5.0.100 [/usr/share/dotnet/sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 5.0.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 5.0.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
```

OS Info

Distributor ID: Ubuntu
Description: Ubuntu 18.04.3 LTS
Release: 18.04
Codename: bionic

Note: The Ubuntu distribution is running in a VM. Reproduced on both a local Hyper-V instance and on an Azure VM.

Regression?

The above problems occur both in .NET Core 3.1 and .NET Core 5. I have't tested with other versions.

Author: hwfbcisod
Assignees: -
Labels:

area-System.Drawing, untriaged

Milestone: -

The size check is failing because size of LOGFONT type is different than the one defined by runtime: https://github.com/dotnet/runtime/blob/6cb16e12fd912c28f2ab4577414b4a2d8b321a28/src/libraries/Common/src/Interop/Windows/User32/Interop.LOGFONT.cs#L12

-       [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
-       private class LOGFONT
+       [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+       private unsafe struct LOGFONT
        {
            public int lfHeight;
            public int lfWidth;
            public int lfEscapement;
            public int lfOrientation;
            public int lfWeight;
            public byte lfItalic;
            public byte lfUnderline;
            public byte lfStrikeOut;
            public byte lfCharSet;
            public byte lfOutPrecision;
            public byte lfClipPrecision;
            public byte lfQuality;
            public byte lfPitchAndFamily;
-           [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
-           public string lfFaceName;
+           private fixed char _lfFaceName[32];
+           public string lfFaceName
+           {
+               get { fixed (char* c = _lfFaceName) { return new string(c); } }
+           }
+       }

build as dotnet build -p:AllowUnsafeBlocks=True and finally dotnet run.

Thanks, @am11 that seems accurate.

@hwfbcisod please confirm if that fixes your issue 馃槃

Thank you, @am11.

@safern Yes, that seems to work. At least it does on my Hyper-V VM.

Great. Thanks for confirming @hwfbcisod. Please let us know if we can help further. I'm closing the issue based on the conversation above.

@am11 Do you have an idea why example described in issue works on Windows and fails in Linux ?
If you search over internet one of the first sites describing LOGFONT is pinvoke.net and it gives you wrong signature.
Maybe we need a better documentation for this .

@TrayanZapryanov, the official docs of ToLogFont https://docs.microsoft.com/en-us/dotnet/api/system.drawing.font.tologfont?view=dotnet-plat-ext-5.0 points to this definition of win32 struct https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-logfonta.

In the pinvoke.net documentation you mentioned, we only need to change CharSet.Auto to CharSet.Unicode, because CharSet.Auto on Unix-y system is UTF8 in .NET and Unicode on Windows: https://docs.microsoft.com/en-us/dotnet/standard/native-interop/charset. (always better to explicitly specify the encoding, rather than relying on default behavior in such cases).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

btecu picture btecu  路  3Comments

matty-hall picture matty-hall  路  3Comments

iCodeWebApps picture iCodeWebApps  路  3Comments

Timovzl picture Timovzl  路  3Comments

omajid picture omajid  路  3Comments