From 694a749046f0d237a9f0212f0b2f383f355a1529 Mon Sep 17 00:00:00 2001 From: GoldenCrystal Date: Thu, 20 Nov 2014 21:26:50 +0100 Subject: [PATCH] Added hangul syllable naming algorithm from Unicode 7.0. --- UnicodeInformation.Tests/UnicodeInfoTests.cs | 10 ++++ UnicodeInformation/HangulInfo.cs | 62 ++++++++++++++++++++ UnicodeInformation/UnicodeCharInfo.cs | 16 ++--- UnicodeInformation/UnicodeInfo.cs | 18 +++++- UnicodeInformation/UnicodeInformation.csproj | 1 + 5 files changed, 93 insertions(+), 14 deletions(-) create mode 100644 UnicodeInformation/HangulInfo.cs diff --git a/UnicodeInformation.Tests/UnicodeInfoTests.cs b/UnicodeInformation.Tests/UnicodeInfoTests.cs index 246f747..e95dcbe 100644 --- a/UnicodeInformation.Tests/UnicodeInfoTests.cs +++ b/UnicodeInformation.Tests/UnicodeInfoTests.cs @@ -78,6 +78,7 @@ namespace UnicodeInformation.Tests AssertChar(0x0041, UnicodeCategory.UppercaseLetter, "LATIN CAPITAL LETTER A"); AssertChar(0x1F600, UnicodeCategory.OtherSymbol, "GRINNING FACE"); AssertChar(0x00E9, UnicodeCategory.LowercaseLetter, "LATIN SMALL LETTER E WITH ACUTE"); + AssertChar(0xD4DB, UnicodeCategory.OtherLetter, "HANGUL SYLLABLE PWILH"); } [TestMethod] @@ -131,6 +132,15 @@ namespace UnicodeInformation.Tests Assert.AreEqual(false, hashSet.Add(number)); } + [TestMethod] + public void HangulNameTest() + { + Assert.AreEqual("HANGUL SYLLABLE PWILH", UnicodeInfo.GetName(0xD4DB)); + Assert.AreEqual("HANGUL SYLLABLE PWAENG", UnicodeInfo.GetName(0xD439)); + Assert.AreEqual("HANGUL SYLLABLE PANJ", UnicodeInfo.GetName(0xD311)); + Assert.AreEqual("HANGUL SYLLABLE TOLM", UnicodeInfo.GetName(0xD1AA)); + } + #if DEBUG [TestMethod] public void UnihanCodePointPackingTest() diff --git a/UnicodeInformation/HangulInfo.cs b/UnicodeInformation/HangulInfo.cs new file mode 100644 index 0000000..23789c9 --- /dev/null +++ b/UnicodeInformation/HangulInfo.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace System.Unicode +{ + internal static class HangulInfo + { + // Constants defined at page 144 of the Unicode 7.0 Standard (3.12) + private const ushort SBase = 0xAC00; + private const ushort LBase = 0x1100; + private const ushort VBase = 0x1161; + private const ushort TBase = 0x11A7; + private const int LCount = 19; + private const int VCount = 21; + private const int TCount = 28; + private const int NCount = VCount * TCount; + private const int SCount = LCount * NCount; + + private static readonly string[] JamoLTable = + { + "G", "GG", "N", "D", "DD", "R", "M", "B", "BB", + "S", "SS", "", "J", "JJ", "C", "K", "T", "P", "H" + }; + + private static readonly string[] JamoVTable = + { + "A", "AE", "YA", "YAE", "EO", "E", "YEO", "YE", "O", + "WA", "WAE", "OE", "YO", "U", "WEO", "WE", "WI", + "YU", "EU", "YI", "I" + }; + + private static readonly string[] JamoTTable = + { + "", "G", "GG", "GS", "N", "NJ", "NH", "D", "L", "LG", "LM", + "LB", "LS", "LT", "LP", "LH", "M", "B", "BS", + "S", "SS", "NG", "J", "C", "K", "T", "P", "H" + }; + private static int lIndex; + + // Algorithm defined on page 150 of the Unicode 7.0 Standard (3.12) + internal static string GetHangulName(char codePoint) + { + int sIndex = codePoint - SBase; + + if (sIndex < 0 || sIndex >= SCount) throw new ArgumentOutOfRangeException("codePoint"); + + int lIndex = sIndex / NCount; + int vIndex = (sIndex % NCount) / TCount; + int tIndex = sIndex % TCount; + + return "HANGUL SYLLABLE " + JamoLTable[lIndex] + JamoVTable[vIndex] + JamoTTable[tIndex]; + } + + internal static bool IsHangul(int codePoint) + { + return codePoint >= SBase && codePoint <= SBase + SCount; + } + } +} diff --git a/UnicodeInformation/UnicodeCharInfo.cs b/UnicodeInformation/UnicodeCharInfo.cs index 780a1e8..e089918 100644 --- a/UnicodeInformation/UnicodeCharInfo.cs +++ b/UnicodeInformation/UnicodeCharInfo.cs @@ -10,23 +10,14 @@ namespace System.Unicode public struct UnicodeCharInfo { private readonly int codePoint; + private readonly string name; private readonly UnicodeCharacterData unicodeCharacterData; private readonly UnihanCharacterData unihanCharacterData; private readonly string block; public int CodePoint { get { return codePoint; } } - public string Name - { - get - { - return unicodeCharacterData != null ? - unicodeCharacterData.Name == null || unicodeCharacterData.CodePointRange.IsSingleCodePoint ? - unicodeCharacterData.Name : - unicodeCharacterData.Name + "-" + codePoint.ToString("X4") : - null; - } - } + public string Name { get { return name; } } public UnicodeCategory Category { get { return unicodeCharacterData?.Category ?? UnicodeCategory.OtherNotAssigned; } } public string Block { get { return block ?? "No_Block"; } } @@ -60,7 +51,8 @@ namespace System.Unicode internal UnicodeCharInfo(int codePoint, UnicodeCharacterData unicodeCharacterData, UnihanCharacterData unihanCharacterData, string block) { this.codePoint = codePoint; - this.unicodeCharacterData = unicodeCharacterData; + this.name = UnicodeInfo.GetName(codePoint, unicodeCharacterData); + this.unicodeCharacterData = unicodeCharacterData; this.unihanCharacterData = unihanCharacterData; this.block = block; } diff --git a/UnicodeInformation/UnicodeInfo.cs b/UnicodeInformation/UnicodeInfo.cs index d89694c..eb01445 100644 --- a/UnicodeInformation/UnicodeInfo.cs +++ b/UnicodeInformation/UnicodeInfo.cs @@ -264,9 +264,9 @@ namespace System.Unicode public static UnicodeCategory GetCategory(int codePoint) { - var charInfo = FindUnicodeCodePoint(codePoint); + var charData = FindUnicodeCodePoint(codePoint); - return charInfo != null ? charInfo.Category : UnicodeCategory.OtherNotAssigned; + return charData != null ? charData.Category : UnicodeCategory.OtherNotAssigned; } public static string GetDisplayText(UnicodeCharInfo charInfo) @@ -283,6 +283,20 @@ namespace System.Unicode else return char.ConvertFromUtf32(codePoint); } + public static string GetName(int codePoint) + { + if (HangulInfo.IsHangul(codePoint)) return HangulInfo.GetHangulName((char)codePoint); + else return GetName(codePoint, FindUnicodeCodePoint(codePoint)); + } + + internal static string GetName(int codePoint, UnicodeCharacterData characterData) + { + if (characterData.CodePointRange.IsSingleCodePoint) return characterData.Name; + else if (HangulInfo.IsHangul(codePoint)) return HangulInfo.GetHangulName((char)codePoint); + else if (characterData.Name != null) return characterData.Name + "-" + codePoint.ToString("X4"); + else return null; + } + public static UnicodeBlock[] GetBlocks() { return (UnicodeBlock[])blocks.Clone(); diff --git a/UnicodeInformation/UnicodeInformation.csproj b/UnicodeInformation/UnicodeInformation.csproj index 34c6758..344722d 100644 --- a/UnicodeInformation/UnicodeInformation.csproj +++ b/UnicodeInformation/UnicodeInformation.csproj @@ -65,6 +65,7 @@ +