Rename Wcwidth class to UnicodeCalculator

Also cleans up GetWidth method a bit.
This commit is contained in:
Patrik Svensson 2020-09-17 10:22:34 +02:00
Родитель 9070f660de
Коммит a57f43b716
8 изменённых файлов: 67 добавлений и 53 удалений

Просмотреть файл

@ -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;
}
}
}