Rename Wcwidth class to UnicodeCalculator
Also cleans up GetWidth method a bit.
This commit is contained in:
Родитель
9070f660de
Коммит
a57f43b716
|
@ -73,7 +73,7 @@ dotnet_naming_style.non_private_readonly_field_style.capitalization = pascal_cas
|
|||
dotnet_naming_rule.constants_should_be_pascal_case.severity = suggestion
|
||||
dotnet_naming_rule.constants_should_be_pascal_case.symbols = constants
|
||||
dotnet_naming_rule.constants_should_be_pascal_case.style = constant_style
|
||||
dotnet_naming_symbols.constants.applicable_kinds = field, local
|
||||
dotnet_naming_symbols.constants.applicable_kinds = field
|
||||
dotnet_naming_symbols.constants.required_modifiers = const
|
||||
dotnet_naming_style.constant_style.capitalization = pascal_case
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ written by Jeff Quast, which originally was written by Markus Kuhn.
|
|||
using Wcwidth;
|
||||
|
||||
// Get the width
|
||||
var width = Wcwidth.GetWidth('コ');
|
||||
var width = UnicodeCalculator.GetWidth('コ');
|
||||
|
||||
// It should be 2 cells wide
|
||||
Debug.Assert(width == 2);
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wcwidth
|
||||
{
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace Wcwidth.Tests
|
|||
public void Test_Favorite_Emoji()
|
||||
{
|
||||
// Given
|
||||
var length = "💩".Select(c => Wcwidth.GetWidth(c)).Sum();
|
||||
var length = "💩".Select(c => UnicodeCalculator.GetWidth(c)).Sum();
|
||||
|
||||
// Then
|
||||
length.ShouldBe(2);
|
||||
|
@ -24,7 +24,7 @@ namespace Wcwidth.Tests
|
|||
var expected = new[] { 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1 };
|
||||
|
||||
// When
|
||||
var length = phrase.Select(c => Wcwidth.GetWidth(c));
|
||||
var length = phrase.Select(c => UnicodeCalculator.GetWidth(c));
|
||||
|
||||
// Then
|
||||
length.ShouldBe(expected);
|
||||
|
@ -38,7 +38,7 @@ namespace Wcwidth.Tests
|
|||
var expected = new[] { 1, 1, 1, 0, 1, 1, 1 };
|
||||
|
||||
// When
|
||||
var length = phrase.Select(c => Wcwidth.GetWidth(c));
|
||||
var length = phrase.Select(c => UnicodeCalculator.GetWidth(c));
|
||||
|
||||
// Then
|
||||
length.ShouldBe(expected);
|
||||
|
@ -52,7 +52,7 @@ namespace Wcwidth.Tests
|
|||
var expected = new[] { -1, 1, 1, 1 };
|
||||
|
||||
// When
|
||||
var length = phrase.Select(c => Wcwidth.GetWidth(c));
|
||||
var length = phrase.Select(c => UnicodeCalculator.GetWidth(c));
|
||||
|
||||
// Then
|
||||
length.ShouldBe(expected);
|
||||
|
@ -66,7 +66,7 @@ namespace Wcwidth.Tests
|
|||
var expected = new[] { 1, 1, 0, 1, 1 };
|
||||
|
||||
// When
|
||||
var length = phrase.Select(c => Wcwidth.GetWidth(c));
|
||||
var length = phrase.Select(c => UnicodeCalculator.GetWidth(c));
|
||||
|
||||
// Then
|
||||
length.ShouldBe(expected);
|
||||
|
@ -80,7 +80,7 @@ namespace Wcwidth.Tests
|
|||
var expected = new[] { 1, 1, 1, 1, 0 };
|
||||
|
||||
// When
|
||||
var length = phrase.Select(c => Wcwidth.GetWidth(c));
|
||||
var length = phrase.Select(c => UnicodeCalculator.GetWidth(c));
|
||||
|
||||
// Then
|
||||
length.ShouldBe(expected);
|
||||
|
@ -94,7 +94,7 @@ namespace Wcwidth.Tests
|
|||
var expected = new[] { 1, 0 };
|
||||
|
||||
// When
|
||||
var length = phrase.Select(c => Wcwidth.GetWidth(c));
|
||||
var length = phrase.Select(c => UnicodeCalculator.GetWidth(c));
|
||||
|
||||
// Then
|
||||
length.ShouldBe(expected);
|
||||
|
@ -108,7 +108,7 @@ namespace Wcwidth.Tests
|
|||
var expected = new[] { 1, 1, 1, 1 };
|
||||
|
||||
// When
|
||||
var length = phrase.Select(c => Wcwidth.GetWidth(c));
|
||||
var length = phrase.Select(c => UnicodeCalculator.GetWidth(c));
|
||||
|
||||
// Then
|
||||
length.ShouldBe(expected);
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
|
||||
namespace Wcwidth
|
||||
{
|
||||
internal static class IntegerExtensions
|
||||
{
|
||||
public static bool Exist(this uint[,] table, uint value)
|
||||
{
|
||||
return Find(table, value) != 0;
|
||||
}
|
||||
|
||||
public static int Find(this uint[,] table, uint value)
|
||||
{
|
||||
if (table is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(table));
|
||||
}
|
||||
|
||||
var min = 0;
|
||||
var max = table.GetUpperBound(0);
|
||||
int mid;
|
||||
|
||||
if (value < table[0, 0] || value > table[max, 1])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (max >= min)
|
||||
{
|
||||
mid = (min + max) / 2;
|
||||
if (value > table[mid, 1])
|
||||
{
|
||||
min = mid + 1;
|
||||
}
|
||||
else if (value < table[mid, 0])
|
||||
{
|
||||
max = mid - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,6 @@
|
|||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wcwidth
|
||||
{
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Wcwidth
|
||||
{
|
||||
|
|
|
@ -46,18 +46,15 @@ namespace Wcwidth
|
|||
/// <summary>
|
||||
/// A utility for calculating the width of Unicode characters.
|
||||
/// </summary>
|
||||
public static class Wcwidth
|
||||
public static class UnicodeCalculator
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the latest unicode version.
|
||||
/// </summary>
|
||||
public static Unicode Latest { get; } = Unicode.Version_13_0_0;
|
||||
private const Unicode Latest = Unicode.Version_13_0_0;
|
||||
|
||||
// NOTE: created by hand, there isn't anything identifiable other than
|
||||
// general Cf category code to identify these, and some characters in Cf
|
||||
// category code are of non-zero width.
|
||||
// Also includes some Cc, Mn, Zl, and Zp characters
|
||||
private static readonly HashSet<uint> ZeroWidthCf = new HashSet<uint>
|
||||
private static readonly HashSet<uint> _zeroWidthCf = new HashSet<uint>
|
||||
{
|
||||
0, // Null (Cc)
|
||||
0x034F, // Combining grapheme joiner (Mn)
|
||||
|
@ -92,7 +89,7 @@ namespace Wcwidth
|
|||
// NOTE: created by hand, there isn't anything identifiable other than
|
||||
// general Cf category code to identify these, and some characters in Cf
|
||||
// category code are of non-zero width.
|
||||
if (ZeroWidthCf.Contains(value))
|
||||
if (_zeroWidthCf.Contains(value))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -104,43 +101,15 @@ namespace Wcwidth
|
|||
}
|
||||
|
||||
// Combining characters with zero width?
|
||||
if (BinarySearch(value, ZeroTable.GetTable(version.Value)) != 0)
|
||||
var zeroTable = ZeroTable.GetTable(version.Value);
|
||||
if (zeroTable.Exist(value))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1 + BinarySearch(value, WideTable.GetTable(version.Value));
|
||||
}
|
||||
|
||||
private static int BinarySearch(uint rune, uint[,] table)
|
||||
{
|
||||
var min = 0;
|
||||
var max = table.GetUpperBound(0);
|
||||
int mid;
|
||||
|
||||
if (rune < table[0, 0] || rune > table[max, 1])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (max >= min)
|
||||
{
|
||||
mid = (min + max) / 2;
|
||||
if (rune > table[mid, 1])
|
||||
{
|
||||
min = mid + 1;
|
||||
}
|
||||
else if (rune < table[mid, 0])
|
||||
{
|
||||
max = mid - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
// Wide character?
|
||||
var wideTable = WideTable.GetTable(version.Value);
|
||||
return wideTable.Exist(value) ? 2 : 1;
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче