diff --git a/src/System.Drawing.Common/src/System.Drawing.Common.csproj b/src/System.Drawing.Common/src/System.Drawing.Common.csproj index 404150d91ccb..7b8e89253fc6 100644 --- a/src/System.Drawing.Common/src/System.Drawing.Common.csproj +++ b/src/System.Drawing.Common/src/System.Drawing.Common.csproj @@ -118,7 +118,6 @@ - diff --git a/src/System.Drawing.Common/src/System/Drawing/Font.NotSerializable.cs b/src/System.Drawing.Common/src/System/Drawing/Font.NotSerializable.cs deleted file mode 100644 index d4bf27db712e..000000000000 --- a/src/System.Drawing.Common/src/System/Drawing/Font.NotSerializable.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Runtime.Serialization; - -namespace System.Drawing -{ - partial class Font - { - void ISerializable.GetObjectData(SerializationInfo si, StreamingContext context) - { - throw new PlatformNotSupportedException(); - } - } -} diff --git a/src/System.Drawing.Common/src/System/Drawing/Font.Unix.cs b/src/System.Drawing.Common/src/System/Drawing/Font.Unix.cs index ac17be876fc8..be890005e535 100644 --- a/src/System.Drawing.Common/src/System/Drawing/Font.Unix.cs +++ b/src/System.Drawing.Common/src/System/Drawing/Font.Unix.cs @@ -65,7 +65,7 @@ private void CreateFont(string familyName, float emSize, FontStyle style, Graphi family = FontFamily.GenericSansSerif; } - setProperties(family, emSize, style, unit, charSet, isVertical); + Initialize(family, emSize, style, unit, charSet, isVertical); int status = Gdip.GdipCreateFont(new HandleRef(this, family.NativeFamily), emSize, style, unit, out _nativeFont); if (status == Gdip.FontStyleNotFound) @@ -130,7 +130,25 @@ internal void unitConversion(GraphicsUnit fromUnit, GraphicsUnit toUnit, float n } } - void setProperties(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte charSet, bool isVertical) + private void Initialize(string familyName, float emSize, FontStyle style, GraphicsUnit unit, byte charSet, bool isVertical) + { + _originalFontName = familyName; + FontFamily family; + // NOTE: If family name is null, empty or invalid, + // MS creates Microsoft Sans Serif font. + try + { + family = new FontFamily(familyName); + } + catch (Exception) + { + family = FontFamily.GenericSansSerif; + } + + Initialize(family, emSize, style, unit, charSet, isVertical); + } + + private void Initialize(FontFamily family, float emSize, FontStyle style, GraphicsUnit unit, byte charSet, bool isVertical) { _fontFamily = family; _fontSize = emSize; @@ -205,25 +223,14 @@ public IntPtr ToHfont() internal Font(IntPtr nativeFont, string familyName, FontStyle style, float size) { - FontFamily fontFamily; - - try - { - fontFamily = new FontFamily(familyName); - } - catch (Exception) - { - fontFamily = FontFamily.GenericSansSerif; - } - - setProperties(fontFamily, size, style, GraphicsUnit.Pixel, 0, false); + Initialize(familyName, size, style, GraphicsUnit.Pixel, 0, false); _nativeFont = nativeFont; } public Font(Font prototype, FontStyle newStyle) { // no null checks, MS throws a NullReferenceException if original is null - setProperties(prototype.FontFamily, prototype.Size, newStyle, prototype.Unit, prototype.GdiCharSet, prototype.GdiVerticalFont); + Initialize(prototype.FontFamily, prototype.Size, newStyle, prototype.Unit, prototype.GdiCharSet, prototype.GdiVerticalFont); int status = Gdip.GdipCreateFont(new HandleRef(_fontFamily, _fontFamily.NativeFamily), Size, Style, Unit, out _nativeFont); Gdip.CheckStatus(status); @@ -266,7 +273,7 @@ public Font(FontFamily family, float emSize, FontStyle style, throw new ArgumentNullException(nameof(family)); int status; - setProperties(family, emSize, style, unit, gdiCharSet, gdiVerticalFont); + Initialize(family, emSize, style, unit, gdiCharSet, gdiVerticalFont); status = Gdip.GdipCreateFont(new HandleRef(this, family.NativeFamily), emSize, style, unit, out _nativeFont); Gdip.CheckStatus(status); } diff --git a/src/System.Drawing.Common/src/System/Drawing/Font.Windows.cs b/src/System.Drawing.Common/src/System/Drawing/Font.Windows.cs index 5e9db2f489c1..14d984ba3344 100644 --- a/src/System.Drawing.Common/src/System/Drawing/Font.Windows.cs +++ b/src/System.Drawing.Common/src/System/Drawing/Font.Windows.cs @@ -340,8 +340,6 @@ private void SetFontFamily(FontFamily family) GC.SuppressFinalize(_fontFamily); } - private static bool IsVerticalName(string familyName) => familyName?.Length > 0 && familyName[0] == '@'; - private static string StripVerticalName(string familyName) { if (familyName?.Length > 1 && familyName[0] == '@') diff --git a/src/System.Drawing.Common/src/System/Drawing/Font.cs b/src/System.Drawing.Common/src/System/Drawing/Font.cs index 62fc66e40e34..b280bda4ce12 100644 --- a/src/System.Drawing.Common/src/System/Drawing/Font.cs +++ b/src/System.Drawing.Common/src/System/Drawing/Font.cs @@ -17,6 +17,7 @@ namespace System.Drawing #if netcoreapp [TypeConverter("System.Drawing.FontConverter, System.Windows.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")] #endif + [Serializable] public sealed partial class Font : MarshalByRefObject, ICloneable, IDisposable, ISerializable { private IntPtr _nativeFont; @@ -143,6 +144,27 @@ public sealed partial class Font : MarshalByRefObject, ICloneable, IDisposable, /// ~Font() => Dispose(false); + private Font(SerializationInfo info, StreamingContext context) + { + string name = info.GetString("Name"); // Do not rename (binary serialization) + FontStyle style = (FontStyle)info.GetValue("Style", typeof(FontStyle)); // Do not rename (binary serialization) + GraphicsUnit unit = (GraphicsUnit)info.GetValue("Unit", typeof(GraphicsUnit)); // Do not rename (binary serialization) + float size = info.GetSingle("Size"); // Do not rename (binary serialization) + + Initialize(name, size, style, unit, SafeNativeMethods.DEFAULT_CHARSET, IsVerticalName(name)); + } + + void ISerializable.GetObjectData(SerializationInfo si, StreamingContext context) + { + string name = string.IsNullOrEmpty(OriginalFontName) ? Name : OriginalFontName; + si.AddValue("Name", name); // Do not rename (binary serialization) + si.AddValue("Size", Size); // Do not rename (binary serialization) + si.AddValue("Style", Style); // Do not rename (binary serialization) + si.AddValue("Unit", Unit); // Do not rename (binary serialization) + } + + private static bool IsVerticalName(string familyName) => familyName?.Length > 0 && familyName[0] == '@'; + /// /// Cleans up Windows resources for this . /// diff --git a/src/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs b/src/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs index 791050ad5660..f9a907d55804 100644 --- a/src/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs +++ b/src/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs @@ -1216,6 +1216,11 @@ private static IEnumerable SerializableObjects() yield return new object[] { ContentAlignment.BottomCenter, new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAAB9TeXN0ZW0uRHJhd2luZy5Db250ZW50QWxpZ25tZW50AQAAAAd2YWx1ZV9fAAgCAAAAAAIAAAs=", TargetFrameworkMoniker.netcoreapp21), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAAB9TeXN0ZW0uRHJhd2luZy5Db250ZW50QWxpZ25tZW50AQAAAAd2YWx1ZV9fAAgCAAAAAAIAAAs=", TargetFrameworkMoniker.netfx461) } }; yield return new object[] { LinearGradientMode.BackwardDiagonal, new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAACtTeXN0ZW0uRHJhd2luZy5EcmF3aW5nMkQuTGluZWFyR3JhZGllbnRNb2RlAQAAAAd2YWx1ZV9fAAgCAAAAAwAAAAs=", TargetFrameworkMoniker.netcoreapp21), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAACtTeXN0ZW0uRHJhd2luZy5EcmF3aW5nMkQuTGluZWFyR3JhZGllbnRNb2RlAQAAAAd2YWx1ZV9fAAgCAAAAAwAAAAs=", TargetFrameworkMoniker.netfx461) } }; yield return new object[] { FontStyle.Bold, new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABhTeXN0ZW0uRHJhd2luZy5Gb250U3R5bGUBAAAAB3ZhbHVlX18ACAIAAAABAAAACw==", TargetFrameworkMoniker.netcoreapp21), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABhTeXN0ZW0uRHJhd2luZy5Gb250U3R5bGUBAAAAB3ZhbHVlX18ACAIAAAABAAAACw==", TargetFrameworkMoniker.netfx461) } }; + // libgdiplus is not supported on some Windows variants. + if (PlatformDetection.IsDrawingSupported) + { + yield return new object[] { new Font("coreFxAwesomeFont", 8.5f, FontStyle.Strikeout, GraphicsUnit.Pixel), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFhTeXN0ZW0uRHJhd2luZy5Db21tb24sIFZlcnNpb249NC4wLjEuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1jYzdiMTNmZmNkMmRkZDUxDAMAAABRU3lzdGVtLkRyYXdpbmcsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iMDNmNWY3ZjExZDUwYTNhBQEAAAATU3lzdGVtLkRyYXdpbmcuRm9udAQAAAAETmFtZQRTaXplBVN0eWxlBFVuaXQBAAQECxhTeXN0ZW0uRHJhd2luZy5Gb250U3R5bGUDAAAAG1N5c3RlbS5EcmF3aW5nLkdyYXBoaWNzVW5pdAMAAAACAAAABgQAAAARY29yZUZ4QXdlc29tZUZvbnQAAAhBBfv///8YU3lzdGVtLkRyYXdpbmcuRm9udFN0eWxlAQAAAAd2YWx1ZV9fAAgDAAAACAAAAAX6////G1N5c3RlbS5EcmF3aW5nLkdyYXBoaWNzVW5pdAEAAAAHdmFsdWVfXwAIAwAAAAIAAAAL", TargetFrameworkMoniker.netcoreapp30), new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABNTeXN0ZW0uRHJhd2luZy5Gb250BAAAAAROYW1lBFNpemUFU3R5bGUEVW5pdAEABAQLGFN5c3RlbS5EcmF3aW5nLkZvbnRTdHlsZQIAAAAbU3lzdGVtLkRyYXdpbmcuR3JhcGhpY3NVbml0AgAAAAIAAAAGAwAAABFjb3JlRnhBd2Vzb21lRm9udAAACEEF/P///xhTeXN0ZW0uRHJhd2luZy5Gb250U3R5bGUBAAAAB3ZhbHVlX18ACAIAAAAIAAAABfv///8bU3lzdGVtLkRyYXdpbmcuR3JhcGhpY3NVbml0AQAAAAd2YWx1ZV9fAAgCAAAAAgAAAAs=", TargetFrameworkMoniker.netfx461) } }; + } } // Custom object