FontConverter
Converts Font objects from one data type to another.
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Diagnostics.CodeAnalysis;
using System.Drawing.Text;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
namespace System.Drawing
{
[NullableContext(1)]
[Nullable(0)]
public class FontConverter : TypeConverter
{
[Nullable(0)]
public sealed class FontNameConverter : TypeConverter, IDisposable
{
private readonly FontFamily[] _fonts;
public FontNameConverter()
{
_fonts = FontFamily.Families;
}
void IDisposable.Dispose()
{
}
public override bool CanConvertFrom([Nullable(2)] ITypeDescriptorContext context, Type sourceType)
{
if (!(sourceType == typeof(string)))
return base.CanConvertFrom(context, sourceType);
return true;
}
[NullableContext(2)]
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, [Nullable(1)] object value)
{
string text = value as string;
if (text == null)
return base.ConvertFrom(context, culture, value);
return MatchFontName(text, context);
}
public override StandardValuesCollection GetStandardValues([Nullable(2)] ITypeDescriptorContext context)
{
string[] array = new string[_fonts.Length];
for (int i = 0; i < _fonts.Length; i++) {
array[i] = _fonts[i].Name;
}
Array.Sort(array, Comparer.Default);
return new StandardValuesCollection(array);
}
[NullableContext(2)]
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return false;
}
[NullableContext(2)]
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
private string MatchFontName(string name, [Nullable(2)] ITypeDescriptorContext context)
{
string text = null;
foreach (string standardValue in GetStandardValues(context)) {
if (standardValue.Equals(name, StringComparison.InvariantCultureIgnoreCase))
return standardValue;
if (standardValue.StartsWith(name, StringComparison.InvariantCultureIgnoreCase) && (text == null || standardValue.Length <= text.Length))
text = standardValue;
}
return text ?? name;
}
}
[NullableContext(0)]
public class FontUnitConverter : EnumConverter
{
public FontUnitConverter()
: base(typeof(GraphicsUnit))
{
}
[NullableContext(1)]
public override StandardValuesCollection GetStandardValues([Nullable(2)] ITypeDescriptorContext context)
{
if (base.Values == null) {
base.GetStandardValues(context);
ArrayList arrayList = new ArrayList(base.Values);
arrayList.Remove(GraphicsUnit.Display);
base.Values = new StandardValuesCollection(arrayList);
}
return base.Values;
}
}
private const string StylePrefix = "style=";
public override bool CanConvertFrom([Nullable(2)] ITypeDescriptorContext context, Type sourceType)
{
if (!(sourceType == typeof(string)))
return base.CanConvertFrom(context, sourceType);
return true;
}
[NullableContext(2)]
public override bool CanConvertTo(ITypeDescriptorContext context, [NotNullWhen(true)] Type destinationType)
{
if (!(destinationType == typeof(string)))
return destinationType == typeof(InstanceDescriptor);
return true;
}
[NullableContext(2)]
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, [Nullable(1)] Type destinationType)
{
Font font = value as Font;
if (font != null) {
if (destinationType == typeof(string)) {
if (culture == null)
culture = CultureInfo.CurrentCulture;
System.Text.ValueStringBuilder valueStringBuilder = default(System.Text.ValueStringBuilder);
valueStringBuilder.Append(font.Name);
valueStringBuilder.Append(culture.TextInfo.ListSeparator[0]);
valueStringBuilder.Append(' ');
valueStringBuilder.Append(font.Size.ToString(culture.NumberFormat));
switch (font.Unit) {
case GraphicsUnit.Display:
valueStringBuilder.Append("display");
break;
case GraphicsUnit.Document:
valueStringBuilder.Append("doc");
break;
case GraphicsUnit.Point:
valueStringBuilder.Append("pt");
break;
case GraphicsUnit.Inch:
valueStringBuilder.Append("in");
break;
case GraphicsUnit.Millimeter:
valueStringBuilder.Append("mm");
break;
case GraphicsUnit.Pixel:
valueStringBuilder.Append("px");
break;
case GraphicsUnit.World:
valueStringBuilder.Append("world");
break;
}
if (font.Style != 0) {
valueStringBuilder.Append(culture.TextInfo.ListSeparator[0]);
valueStringBuilder.Append(" style=");
valueStringBuilder.Append(font.Style.ToString());
}
return valueStringBuilder.ToString();
}
if (destinationType == typeof(InstanceDescriptor)) {
int num = 2;
if (font.GdiVerticalFont)
num = 6;
else if (font.GdiCharSet != 1) {
num = 5;
} else if (font.Unit != GraphicsUnit.Point) {
num = 4;
} else if (font.Style != 0) {
num++;
}
object[] array = new object[num];
Type[] array2 = new Type[num];
array[0] = font.Name;
array2[0] = typeof(string);
array[1] = font.Size;
array2[1] = typeof(float);
if (num > 2) {
array[2] = font.Style;
array2[2] = typeof(FontStyle);
}
if (num > 3) {
array[3] = font.Unit;
array2[3] = typeof(GraphicsUnit);
}
if (num > 4) {
array[4] = font.GdiCharSet;
array2[4] = typeof(byte);
}
if (num > 5) {
array[5] = font.GdiVerticalFont;
array2[5] = typeof(bool);
}
ConstructorInfo constructor = typeof(Font).GetConstructor(array2);
if ((object)constructor != null)
return new InstanceDescriptor(constructor, array);
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
[NullableContext(2)]
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, [Nullable(1)] object value)
{
string text = value as string;
if (text == null)
return base.ConvertFrom(context, culture, value);
text = text.Trim();
if (text.Length == 0)
return null;
if (culture == null)
culture = CultureInfo.CurrentCulture;
char c = culture.TextInfo.ListSeparator[0];
string familyName = text;
string text2 = null;
float emSize = 8.25;
FontStyle fontStyle = FontStyle.Regular;
GraphicsUnit unit = GraphicsUnit.Point;
int num = text.IndexOf(c);
if (num < 0)
return new Font(familyName, emSize, fontStyle, unit);
familyName = text.Substring(0, num);
if (num < text.Length - 1) {
int num2 = culture.CompareInfo.IndexOf(text, "style=", CompareOptions.IgnoreCase);
string text4;
if (num2 != -1) {
string text3 = text;
int num3 = num2;
text2 = text3.Substring(num3, text3.Length - num3);
text4 = text.Substring(num + 1, num2 - num - 1);
} else {
string text3 = text;
int num3 = num + 1;
text4 = text3.Substring(num3, text3.Length - num3);
}
(string, string) valueTuple = ParseSizeTokens(text4, c);
string item = valueTuple.Item1;
string item2 = valueTuple.Item2;
if (item != null)
try {
emSize = (float)<ConvertFrom>g__GetFloatConverter|4_0().ConvertFromString(context, culture, item);
} catch {
string textParseFailedFormat = System.SR.TextParseFailedFormat;
string p = text;
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(44, 4);
defaultInterpolatedStringHandler.AppendLiteral("name");
defaultInterpolatedStringHandler.AppendFormatted(c);
defaultInterpolatedStringHandler.AppendLiteral(" size[units[");
defaultInterpolatedStringHandler.AppendFormatted(c);
defaultInterpolatedStringHandler.AppendLiteral(" style=style1[");
defaultInterpolatedStringHandler.AppendFormatted(c);
defaultInterpolatedStringHandler.AppendLiteral(" style2");
defaultInterpolatedStringHandler.AppendFormatted(c);
defaultInterpolatedStringHandler.AppendLiteral(" ...]]]");
throw new ArgumentException(System.SR.Format(textParseFailedFormat, p, defaultInterpolatedStringHandler.ToStringAndClear()), "value");
}
if (item2 != null)
unit = ParseGraphicsUnits(item2);
if (text2 != null) {
string text3 = text2;
text2 = text3.Substring(6, text3.Length - 6);
string[] array = text2.Split(c, StringSplitOptions.None);
foreach (string text5 in array) {
string text5 = text5.Trim();
fontStyle |= Enum.Parse<FontStyle>(text5, true);
FontStyle fontStyle2 = FontStyle.Bold | FontStyle.Italic | FontStyle.Underline | FontStyle.Strikeout;
if ((fontStyle | fontStyle2) != fontStyle2)
throw new InvalidEnumArgumentException("style", (int)fontStyle, typeof(FontStyle));
}
}
}
return new Font(familyName, emSize, fontStyle, unit);
}
[return: Nullable(new byte[] {
0,
2,
2
})]
private static (string, string) ParseSizeTokens(string text, char separator)
{
string item = null;
string item2 = null;
text = text.Trim();
int length = text.Length;
if (length > 0) {
int i;
for (i = 0; i < length && !char.IsLetter(text[i]); i++) {
}
char[] trimChars = new char[2] {
separator,
' '
};
if (i > 0) {
item = text.Substring(0, i);
item = item.Trim(trimChars);
}
if (i < length) {
string text2 = text;
int num = i;
item2 = text2.Substring(num, text2.Length - num);
item2 = item2.TrimEnd(trimChars);
}
}
return (item, item2);
}
private static GraphicsUnit ParseGraphicsUnits(string units)
{
if (units != null) {
switch (units.Length) {
case 2:
switch (units[1]) {
case 't':
if (units == "pt")
return GraphicsUnit.Point;
break;
case 'n':
if (units == "in")
return GraphicsUnit.Inch;
break;
case 'm':
if (units == "mm")
return GraphicsUnit.Millimeter;
break;
case 'x':
if (units == "px")
return GraphicsUnit.Pixel;
break;
}
break;
case 7:
if (units == "display")
return GraphicsUnit.Display;
break;
case 3:
if (units == "doc")
return GraphicsUnit.Document;
break;
case 5:
if (units == "world")
return GraphicsUnit.World;
break;
}
}
throw new ArgumentException(System.SR.Format(System.SR.InvalidArgumentValueFontConverter, units), "units");
}
public override object CreateInstance([Nullable(2)] ITypeDescriptorContext context, IDictionary propertyValues)
{
ArgumentNullException.ThrowIfNull(propertyValues, "propertyValues");
byte gdiCharSet = 1;
float emSize = 8;
string text = null;
bool gdiVerticalFont = false;
FontStyle fontStyle = FontStyle.Regular;
FontFamily fontFamily = null;
GraphicsUnit unit = GraphicsUnit.Point;
object obj;
if ((obj = propertyValues["GdiCharSet"]) != null)
gdiCharSet = (byte)obj;
if ((obj = propertyValues["Size"]) != null)
emSize = (float)obj;
if ((obj = propertyValues["Unit"]) != null)
unit = (GraphicsUnit)obj;
if ((obj = propertyValues["Name"]) != null)
text = (string)obj;
if ((obj = propertyValues["GdiVerticalFont"]) != null)
gdiVerticalFont = (bool)obj;
if ((obj = propertyValues["Bold"]) != null && (bool)obj)
fontStyle |= FontStyle.Bold;
if ((obj = propertyValues["Italic"]) != null && (bool)obj)
fontStyle |= FontStyle.Italic;
if ((obj = propertyValues["Strikeout"]) != null && (bool)obj)
fontStyle |= FontStyle.Strikeout;
if ((obj = propertyValues["Underline"]) != null && (bool)obj)
fontStyle |= FontStyle.Underline;
if (text == null)
fontFamily = new FontFamily("Tahoma");
else {
FontFamily[] families = InstalledFontCollection.Instance.Families;
foreach (FontFamily fontFamily2 in families) {
if (text.Equals(fontFamily2.Name, StringComparison.OrdinalIgnoreCase)) {
fontFamily = fontFamily2;
break;
}
}
if (fontFamily == null)
fontFamily = FontFamily.GenericSansSerif;
}
return new Font(fontFamily, emSize, fontStyle, unit, gdiCharSet, gdiVerticalFont);
}
[NullableContext(2)]
public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
{
return true;
}
[NullableContext(2)]
[RequiresUnreferencedCode("The Type of value cannot be statically discovered. The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")]
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, [Nullable(1)] object value, [Nullable(new byte[] {
2,
1
})] Attribute[] attributes)
{
if (!(value is Font))
return base.GetProperties(context, value, attributes);
return TypeDescriptor.GetProperties(value, attributes).Sort(new string[3] {
"Name",
"Size",
"Unit"
});
}
[NullableContext(2)]
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
}
}