mirror of
https://github.com/wmjordan/PDFPatcher.git
synced 2026-10-18 13:42:28 +08:00
111 lines
3.0 KiB
C#
111 lines
3.0 KiB
C#
using System;
|
|
using System.Globalization;
|
|
using System.Xml.Serialization;
|
|
|
|
namespace PDFPatcher.Common
|
|
{
|
|
public class UnitConverter
|
|
{
|
|
const string Null = "null";
|
|
internal const string ToStringFormat = "0.###";
|
|
|
|
/// <summary>
|
|
/// 获取单位转换因数。
|
|
/// </summary>
|
|
[XmlIgnore]
|
|
public float UnitFactor { get; private set; }
|
|
|
|
private int _Precision;
|
|
private float _PreservedValue;
|
|
///<summary>获取或指定转换精度的值。</summary>
|
|
[XmlIgnore]
|
|
public int Precision {
|
|
get => _Precision;
|
|
set {
|
|
if (value < 0 || value > 6) {
|
|
throw new ArgumentException("转换精度不能小于 0 或大于 6。");
|
|
}
|
|
_Precision = value;
|
|
_PreservedValue = (float)Math.Pow(0.1, _Precision);
|
|
}
|
|
}
|
|
|
|
private string _Unit;
|
|
///<summary>获取或指定转换使用的单位。</summary>
|
|
[XmlAttribute("单位")]
|
|
public string Unit {
|
|
get => _Unit;
|
|
set {
|
|
var f = ValueHelper.MapValue(value, Constants.Units.Names, Constants.Units.Factors, 0);
|
|
if (f == 0) {
|
|
throw new ArgumentException("尺寸单位无效。");
|
|
}
|
|
UnitFactor = f;
|
|
_Unit = value;
|
|
}
|
|
}
|
|
|
|
public UnitConverter() {
|
|
Unit = Constants.Units.CM;
|
|
Precision = 3;
|
|
}
|
|
|
|
internal float FromPoint(float point) {
|
|
return (point < _PreservedValue && point >= 0) // preserve small fragment
|
|
? point
|
|
: (float)Math.Round(point / UnitFactor, _Precision);
|
|
}
|
|
|
|
internal float ToPoint(float value) {
|
|
return (value < _PreservedValue && value >= 0 || value >= 10000) // preserve small fragment or extra large values
|
|
? value
|
|
: (float)Math.Round(value * UnitFactor, _Precision);
|
|
}
|
|
|
|
internal static string FromPoint(string point, float unitFactor) {
|
|
if (String.IsNullOrEmpty(point) || point == Null) {
|
|
return Null;
|
|
}
|
|
if (unitFactor == 1) {
|
|
return point;
|
|
}
|
|
if (point.TryParse(out float v)) {
|
|
return (v < 0.01 && v >= 0) // preserve small fragment
|
|
? point
|
|
: (v / unitFactor).ToString(ToStringFormat, NumberFormatInfo.InvariantInfo);
|
|
}
|
|
return point;
|
|
}
|
|
|
|
internal static string FromPoint(float point, float unitFactor) {
|
|
return ((point < 0.01 && point >= 0) || unitFactor == 1 // preserve small fragment
|
|
? point.ToString(NumberFormatInfo.InvariantInfo)
|
|
: (point / unitFactor).ToString(ToStringFormat, NumberFormatInfo.InvariantInfo));
|
|
}
|
|
|
|
internal static string ToPoint(string value, float unitFactor) {
|
|
if (String.IsNullOrEmpty(value) || value == Null) {
|
|
return Null;
|
|
}
|
|
if (value.TryParse(out float v)) {
|
|
return (v < 0.01 && v >= 0) // preserve small fragment
|
|
? value
|
|
: (v * unitFactor).ToString(ToStringFormat, NumberFormatInfo.InvariantInfo);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
internal static float ToPoint(float value, float unitFactor) {
|
|
return (value < 0.01 && value >= 0 || value >= 10000) // preserve small fragment or extra large values
|
|
? value
|
|
: (value * unitFactor);
|
|
}
|
|
|
|
internal static float[] ConvertUnit(float[] source, float factor) {
|
|
return Array.ConvertAll(source, i => ToPoint(i, factor));
|
|
}
|
|
|
|
|
|
}
|
|
}
|