Files
DCIT/DCIT.Core/Utilities/DisplayWidthUtility.cs

104 lines
2.9 KiB
C#
Raw Normal View History

2026-07-13 09:39:56 +08:00
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;
}
}
}