using System; using System.ComponentModel; using System.Text.RegularExpressions; namespace Volian.Svg.Library { [TypeConverter(typeof(MeasurementTypeConverter))] public class SvgMeasurement { #region Operators public static SvgMeasurement operator +(SvgMeasurement x1, SvgMeasurement x2) { E_MeasurementUnits tmpUnits = x1.Units; SvgMeasurement tmp = new SvgMeasurement(x1.GetSizeInPoints(DPI) + x2.GetSizeInPoints(DPI),E_MeasurementUnits.PT); tmp.Units = x1.Units; return tmp; } public static SvgMeasurement operator -(SvgMeasurement x1, SvgMeasurement x2) { E_MeasurementUnits tmpUnits = x1.Units; SvgMeasurement tmp = new SvgMeasurement(x1.GetSizeInPoints(DPI) - x2.GetSizeInPoints(DPI), E_MeasurementUnits.PT); tmp.Units = x1.Units; return tmp; } public static SvgMeasurement operator *(SvgMeasurement x1, float scaler) { E_MeasurementUnits tmpUnits = x1.Units; SvgMeasurement tmp = new SvgMeasurement(x1.GetSizeInPoints(DPI) * scaler, E_MeasurementUnits.PT); tmp.Units = x1.Units; return tmp; } public static SvgMeasurement operator *(float scaler, SvgMeasurement x1) { E_MeasurementUnits tmpUnits = x1.Units; SvgMeasurement tmp = new SvgMeasurement(x1.GetSizeInPoints(DPI) * scaler, E_MeasurementUnits.PT); tmp.Units = x1.Units; return tmp; } #endregion #region DPI private static float _DPI; public static float DPI { get { if (_DPI == 0) _DPI = 96; return _DPI; } } #endregion #region ctor public SvgMeasurement() { ;} public SvgMeasurement(int value) { Value = Convert.ToSingle(value); _Units = E_MeasurementUnits.PX; } public SvgMeasurement(float value) { Value = value; _Units = E_MeasurementUnits.PX; } public SvgMeasurement(float value, E_MeasurementUnits units) { Value = value; _Units = units; } public SvgMeasurement(string val) { val = val.Replace("{size}", "10");// B2020-145 BWD SAMG TSG-6 Fix for Base Format {size} parameter rather than font size MatchCollection mc = Regex.Matches(val.ToLower(), "([+-]?[.0-9]+)|(in|cm|mm|em|ex|pc|pt|px|percentage)"); Value = Convert.ToSingle(mc[0].Value); if (mc.Count == 2) { //Console.WriteLine("{0} - '{1}'", val, mc[1].Value.ToUpper()); _Units = (E_MeasurementUnits)Enum.Parse(typeof(E_MeasurementUnits), mc[1].Value.ToUpper()); } else _Units = E_MeasurementUnits.PX; } #endregion #region Properties private E_MeasurementUnits _Units; public E_MeasurementUnits Units { get { return _Units; } set { float tmp = GetSizeInPoints(DPI); _Units = value; Value *= (tmp / GetSizeInPoints(DPI)); } } public float Value { get; set; } #endregion #region ToString public override string ToString() { switch (_Units) { case E_MeasurementUnits.PX: // Default return string.Format("{0}", Value); case E_MeasurementUnits.PERCENTAGE: // Precentage is preceded by a space return string.Format("{0} {1}", Value, _Units); } return string.Format("{0}{1}", Value, _Units); } #endregion public float GetSizeInPoints(float myDPI) { switch (_Units) { case E_MeasurementUnits.PX: //Pixels myDPI per inch return Value * 72F / myDPI; case E_MeasurementUnits.PC: //Picas - 6 per inch return Value * 72F / 6F; case E_MeasurementUnits.IN: //inches return Value * 72F; case E_MeasurementUnits.CM: // Centimeter return Value * 72F / 2.54F; case E_MeasurementUnits.MM: // Millimeter return Value * 72F / 25.4F; case E_MeasurementUnits.EM: // EMs return Value * 72F / 8; case E_MeasurementUnits.EX: // EXs return Value * 72F / 16; default: // Points return Value; } } public float GetSizeInPixels(float myDPI) => GetSizeInPoints(myDPI) * myDPI / 72F; public float GetSizeInInches(float myDPI) => GetSizeInPoints(myDPI) / 72F; public float GetSizeInCentimeters(float myDPI) => GetSizeInPoints(myDPI) * 2.54F / 72F; public float GetSizeInMillimeters(float myDPI) => GetSizeInPoints(myDPI) * 25.4F / 72F; public float GetSizeInEms(float myDPI) => GetSizeInPoints(myDPI) * 5 / (6 * 72F); public float GetSizeInExs(float myDPI) => GetSizeInPoints(myDPI) * 5 / (6 * 72F); public float GetSizeInPicas(float myDPI) => GetSizeInPoints(myDPI) * 6 / 72F; public static float StringToPoints(string value) { SvgMeasurement tmp = new SvgMeasurement(value); float myPoints = tmp.GetSizeInPoints(72); return myPoints; } } public enum E_MeasurementUnits : int { [Description("Pixels")] PX, [Description("Points")] PT, [Description("Inches")] IN, [Description("Centimeters")] CM, [Description("Millimeters")] MM, [Description("EMs")] EM, [Description("EXs")] EX, [Description("Percentage")] PERCENTAGE, [Description("Picas")] PC } public class MeasurementTypeConverter : ExpandableObjectConverter { public override bool CanConvertTo(ITypeDescriptorContext context, Type t) => t == typeof(String); public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destType) => destType == typeof(string) && value is SvgMeasurement ? value.ToString() : base.ConvertTo(context, culture, value, destType); public override bool CanConvertFrom(ITypeDescriptorContext context, Type t) => t == typeof(String); public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object val) => new SvgMeasurement((string)val); } }