AngleSharp by Florian Rappl

<PackageReference Include="AngleSharp" Version="0.8.1" />

.NET API 1,172,480 bytes

 CssFontProperty

More information available: https://developer.mozilla.org/en-US/docs/Web/CSS/font
using AngleSharp.Css; using AngleSharp.Extensions; using System; using System.Collections.Generic; using System.Linq; namespace AngleSharp.Dom.Css { internal sealed class CssFontProperty : CssShorthandProperty, ICssFontProperty, ICssProperty, ICssFontStyleProperty, ICssFontVariantProperty, ICssFontWeightProperty, ICssFontStretchProperty, ICssFontSizeProperty, ICssFontFamilyProperty, ICssLineHeightProperty { private static readonly Dictionary<string, SystemFont> _parts; private readonly CssFontStyleProperty _style; private readonly CssFontVariantProperty _variant; private readonly CssFontWeightProperty _weight; private readonly CssFontStretchProperty _stretch; private readonly CssFontSizeProperty _size; private readonly CssLineHeightProperty _height; private readonly CssFontFamilyProperty _families; internal static readonly IValueConverter<SystemFont> SystemFontConverter; internal static readonly IValueConverter<Tuple<Tuple<ICssValue, ICssValue, ICssValue, ICssValue>, Tuple<ICssValue, ICssValue>, ICssValue>> Converter; public int Weight => _weight.Weight; public bool IsRelative => _weight.IsRelative; public FontStyle Style => _style.Style; public FontVariant Variant => _variant.Variant; public FontStretch Stretch => _stretch.Stretch; public Length Size => _size.Size; public Length Height => _height.Height; public IEnumerable<string> Families => _families.Families; static CssFontProperty() { _parts = new Dictionary<string, SystemFont>(); SystemFontConverter = _parts.ToConverter(); Converter = Converters.WithOrder(Converters.WithAny(CssFontStyleProperty.Converter.Val().Option(), CssFontVariantProperty.Converter.Val().Option(), CssFontWeightProperty.Converter.Val().Option(), CssFontStretchProperty.Converter.Val().Option()), Converters.WithOrder(CssFontSizeProperty.Converter.Val().Required(), CssLineHeightProperty.Converter.Val().StartsWithDelimiter().Option()), CssFontFamilyProperty.Converter.Val().Required()); _parts.Add(Keywords.Caption, SystemFont.Caption); _parts.Add(Keywords.Icon, SystemFont.Icon); _parts.Add(Keywords.Menu, SystemFont.Menu); _parts.Add(Keywords.MessageBox, SystemFont.MessageBox); _parts.Add(Keywords.SmallCaption, SystemFont.SmallCaption); _parts.Add(Keywords.StatusBar, SystemFont.StatusBar); } internal CssFontProperty(CssStyleDeclaration rule) : base(PropertyNames.Font, rule, PropertyFlags.Inherited | PropertyFlags.Animatable) { _style = Get<CssFontStyleProperty>(); _variant = Get<CssFontVariantProperty>(); _weight = Get<CssFontWeightProperty>(); _stretch = Get<CssFontStretchProperty>(); _size = Get<CssFontSizeProperty>(); _height = Get<CssLineHeightProperty>(); _families = Get<CssFontFamilyProperty>(); } protected override bool IsValid(ICssValue value) { if (!Converter.TryConvert(value, delegate(Tuple<Tuple<ICssValue, ICssValue, ICssValue, ICssValue>, Tuple<ICssValue, ICssValue>, ICssValue> m) { _style.TrySetValue(m.Item1.Item1); _variant.TrySetValue(m.Item1.Item2); _weight.TrySetValue(m.Item1.Item3); _stretch.TrySetValue(m.Item1.Item4); _size.TrySetValue(m.Item2.Item1); _height.TrySetValue(m.Item2.Item2); _families.TrySetValue(m.Item3); })) return SystemFontConverter.TryConvert(value, SetSystemFont); return true; } private void SetSystemFont(SystemFont font) { switch (font) { case SystemFont.Caption: case SystemFont.Icon: case SystemFont.MessageBox: SetFont("Arial", "16px"); break; case SystemFont.Menu: case SystemFont.StatusBar: SetFont("Segoe UI", "12px"); break; case SystemFont.SmallCaption: SetFont("Segoe UI", "15px"); break; } } private void SetFont(string family, string size) { string propertyValue = size + " " + family.CssString(); base.Rule.SetPropertyValue(base.Name, propertyValue); } internal override string SerializeValue(IEnumerable<CssProperty> properties) { if (!properties.Contains(_families) || !properties.Contains(_size)) return string.Empty; List<string> list = new List<string>(); if (_style.HasValue && properties.Contains(_style)) list.Add(_style.SerializeValue()); if (_variant.HasValue && properties.Contains(_variant)) list.Add(_variant.SerializeValue()); if (_weight.HasValue && properties.Contains(_weight)) list.Add(_weight.SerializeValue()); if (_stretch.HasValue && properties.Contains(_stretch)) list.Add(_stretch.SerializeValue()); list.Add(_size.SerializeValue()); if (_height.HasValue && properties.Contains(_height)) { list.Add("/"); list.Add(_height.SerializeValue()); } list.Add(_families.SerializeValue()); list.RemoveAll((string m) => string.IsNullOrEmpty(m)); return string.Join(" ", list); } } }