using System; using System.Text; namespace DCIT.Core.Utilities { public static class DisplayWidthUtility { public static int Measure(string value) { if (string.IsNullOrEmpty(value)) { return 0; } var width = 0; foreach (var character in value) { width += GetCharacterWidth(character); } return width; } public static string TruncateToWidth(string value, int maxWidth, out bool truncated) { if (string.IsNullOrEmpty(value) || maxWidth <= 0) { truncated = !string.IsNullOrEmpty(value); return string.Empty; } var builder = new StringBuilder(); var width = 0; truncated = false; foreach (var character in value) { var charWidth = GetCharacterWidth(character); if (width + charWidth > maxWidth) { truncated = true; break; } builder.Append(character); width += charWidth; } if (!truncated && builder.Length < value.Length) { truncated = true; } return builder.ToString(); } public static string PadToWidth(string value, int targetWidth, out bool padded) { var builder = new StringBuilder(value ?? string.Empty); var currentWidth = Measure(builder.ToString()); padded = currentWidth < targetWidth; while (currentWidth + 2 <= targetWidth) { builder.Append('\u3000'); currentWidth += 2; } while (currentWidth < targetWidth) { builder.Append(' '); currentWidth += 1; } return builder.ToString(); } private static int GetCharacterWidth(char character) { if (character == '\u3000') { return 2; } if (character >= 0x1100 && (character <= 0x115F || character == 0x2329 || character == 0x232A || (character >= 0x2E80 && character <= 0xA4CF && character != 0x303F) || (character >= 0xAC00 && character <= 0xD7A3) || (character >= 0xF900 && character <= 0xFAFF) || (character >= 0xFE10 && character <= 0xFE19) || (character >= 0xFE30 && character <= 0xFE6F) || (character >= 0xFF00 && character <= 0xFF60) || (character >= 0xFFE0 && character <= 0xFFE6))) { return 2; } return 1; } } }