using System.Globalization; namespace SheetMe.Core.Serialization; /// /// 레거시 TypeConverter invariant 문자열 포맷 도우미. /// 읽기는 관용적으로, 쓰기는 레거시 원문 형식("X, Y" / "이름, 11.25pt, style=Bold")과 동일하게. /// public static class LegacyFormat { #region Point / Size /// "336, 1064" 형식 파싱 — 실패 시 (0,0) public static (double X, double Y) ParsePoint(string? text) { if (TryParsePair(text, out var x, out var y)) { return (x, y); } return (0, 0); } /// "174, 18" 형식 파싱 — 실패 시 (0,0) public static (double W, double H) ParseSize(string? text) => ParsePoint(text); /// Point/Size invariant 문자열 생성 — 레거시와 동일한 "X, Y" (정수 반올림) public static string FormatPair(double a, double b) => string.Create(CultureInfo.InvariantCulture, $"{(int)Math.Round(a)}, {(int)Math.Round(b)}"); private static bool TryParsePair(string? text, out double a, out double b) { a = 0; b = 0; if (string.IsNullOrWhiteSpace(text)) { return false; } var parts = text.Split(','); if (parts.Length != 2) { return false; } return double.TryParse(parts[0].Trim(), NumberStyles.Number, CultureInfo.InvariantCulture, out a) && double.TryParse(parts[1].Trim(), NumberStyles.Number, CultureInfo.InvariantCulture, out b); } #endregion #region Font /// /// 레거시 FontConverter invariant 문자열 파싱 — "굴림, 11.25pt, style=Bold, Underline". /// 실패 시 기본(굴림 9pt) 반환. /// public static LegacyFont ParseFont(string? text) { var font = new LegacyFont(); if (string.IsNullOrWhiteSpace(text)) { return font; } var parts = text.Split(','); if (parts.Length > 0) { font.Family = parts[0].Trim(); } for (var i = 1; i < parts.Length; i++) { var part = parts[i].Trim(); if (part.EndsWith("pt", StringComparison.OrdinalIgnoreCase)) { if (double.TryParse(part[..^2], NumberStyles.Number, CultureInfo.InvariantCulture, out var size)) { font.SizePt = size; } } else if (part.StartsWith("style=", StringComparison.OrdinalIgnoreCase)) { ApplyStyle(font, part[6..]); } else { // "style=Bold, Italic" 처럼 콤마로 이어진 후속 스타일 토큰 ApplyStyle(font, part); } } return font; } /// 레거시 FontConverter invariant 형식으로 생성 — "이름, 11.25pt[, style=Bold, Italic]" public static string FormatFont(LegacyFont font) { var size = font.SizePt.ToString("0.##", CultureInfo.InvariantCulture); var styles = new List(4); if (font.Bold) { styles.Add("Bold"); } if (font.Italic) { styles.Add("Italic"); } if (font.Underline) { styles.Add("Underline"); } if (font.Strikeout) { styles.Add("Strikeout"); } return styles.Count == 0 ? $"{font.Family}, {size}pt" : $"{font.Family}, {size}pt, style={string.Join(", ", styles)}"; } private static void ApplyStyle(LegacyFont font, string token) { switch (token.Trim()) { case "Bold": font.Bold = true; break; case "Italic": font.Italic = true; break; case "Underline": font.Underline = true; break; case "Strikeout": font.Strikeout = true; break; } } #endregion #region Color /// /// 레거시 ColorConverter invariant 문자열 파싱 — "224, 224, 224" / "255, 0, 0, 0"(ARGB) / "White" / "ControlDarkDark". /// 반환: (A,R,G,B). 이름 색은 System.Drawing 으로 해석, 실패 시 검정. /// public static (byte A, byte R, byte G, byte B) ParseColor(string? text) { if (string.IsNullOrWhiteSpace(text)) { return (255, 0, 0, 0); } var parts = text.Split(','); if (parts.Length is 3 or 4 && byte.TryParse(parts[0].Trim(), out _)) { var values = new byte[parts.Length]; for (var i = 0; i < parts.Length; i++) { if (!byte.TryParse(parts[i].Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out values[i])) { return (255, 0, 0, 0); } } return parts.Length == 3 ? ((byte)255, values[0], values[1], values[2]) : (values[0], values[1], values[2], values[3]); } // 명명색/시스템색 — System.Drawing 의 KnownColor 해석 사용(레거시와 동일 의미론) var named = System.Drawing.Color.FromName(text.Trim()); if (named.IsKnownColor || named.A != 0 || named.R != 0 || named.G != 0 || named.B != 0) { return (named.A, named.R, named.G, named.B); } return (255, 0, 0, 0); } /// ColorConverter invariant 형식으로 생성 — 불투명 색은 "R, G, B", 반투명은 "A, R, G, B" public static string FormatColor(byte a, byte r, byte g, byte b) => a == 255 ? string.Create(CultureInfo.InvariantCulture, $"{r}, {g}, {b}") : string.Create(CultureInfo.InvariantCulture, $"{a}, {r}, {g}, {b}"); #endregion } /// 레거시 폰트 표현 — WinForms Font invariant 문자열과 1:1 public sealed class LegacyFont { /// 글꼴 패밀리명 public string Family { get; set; } = "굴림"; /// 크기(pt) public double SizePt { get; set; } = 9; /// 굵게 public bool Bold { get; set; } /// 기울임 public bool Italic { get; set; } /// 밑줄 public bool Underline { get; set; } /// 취소선 public bool Strikeout { get; set; } }