diff --git a/UnicodeCharacterInspector/App.xaml b/UnicodeCharacterInspector/App.xaml index 281b4f0..126262f 100644 --- a/UnicodeCharacterInspector/App.xaml +++ b/UnicodeCharacterInspector/App.xaml @@ -10,6 +10,7 @@ - + + diff --git a/UnicodeCharacterInspector/CharacterInfoViewModel.cs b/UnicodeCharacterInspector/CharacterInfoViewModel.cs index 973fd06..4b371b1 100644 --- a/UnicodeCharacterInspector/CharacterInfoViewModel.cs +++ b/UnicodeCharacterInspector/CharacterInfoViewModel.cs @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; using System.Globalization; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Unicode; namespace UnicodeCharacterInspector @@ -67,6 +63,7 @@ namespace UnicodeCharacterInspector NotifyPropertyChanged(nameof(NumericValue)); NotifyPropertyChanged(nameof(ContributoryProperties)); NotifyPropertyChanged(nameof(CoreProperties)); + NotifyPropertyChanged(nameof(EmojiProperties)); NotifyPropertyChanged(nameof(RadicalStrokeCounts)); NotifyPropertyChanged(nameof(CrossReferences)); NotifyPropertyChanged(nameof(MandarinReading)); @@ -88,145 +85,49 @@ namespace UnicodeCharacterInspector displayText = character != null ? UnicodeInfo.GetDisplayText(characterInfo) : null; - if (displayText != oldValue) - NotifyPropertyChanged(nameof(DisplayText)); + if (displayText != oldValue) NotifyPropertyChanged(nameof(DisplayText)); } public string DisplayText { get { return displayText; } } - public int? CodePoint - { - get { return character != null ? codePoint : null as int?; } - } + public int? CodePoint => character != null ? codePoint : null as int?; - public string Name - { - get { return character != null ? characterInfo.Name : null; } - } + public string Name => character != null ? characterInfo.Name : null; + public string OldName => character != null ? characterInfo.OldName : null; + public UnicodeNameAliasCollection NameAliases => character != null ? characterInfo.NameAliases : UnicodeNameAliasCollection.Empty; - public UnicodeNameAliasCollection NameAliases - { - get { return character != null ? characterInfo.NameAliases : UnicodeNameAliasCollection.Empty; } - } + public string Definition => character != null ? characterInfo.Definition : null; - public string OldName - { - get { return character != null ? characterInfo.OldName : null; } - } + public UnicodeCategory? Category => character != null ? characterInfo.Category : null as UnicodeCategory?; + public string Block => character != null ? characterInfo.Block : null; - public string Definition - { - get { return character != null ? characterInfo.Definition : null; } - } + public CanonicalCombiningClass? CanonicalCombiningClass => character != null ? characterInfo.CanonicalCombiningClass : null as CanonicalCombiningClass?; + public BidirectionalClass? BidirectionalClass => character != null ? characterInfo.BidirectionalClass : null as BidirectionalClass?; + public CompatibilityFormattingTag? DecompositionType => character != null && characterInfo.DecompositionMapping != null ? characterInfo.DecompositionType : null as CompatibilityFormattingTag?; - public UnicodeCategory? Category - { - get { return character != null ? characterInfo.Category : null as UnicodeCategory?; } - } + public string DecompositionMapping => character != null ? characterInfo.DecompositionMapping : null; - public string Block - { - get { return character != null ? characterInfo.Block : null; } - } + public UnicodeNumericType? NumericType => character != null ? characterInfo.NumericType : null as UnicodeNumericType?; + public UnihanNumericType? UnihanNumericType => character != null ? characterInfo.UnihanNumericType : null as UnihanNumericType?; + public UnicodeRationalNumber? NumericValue => character != null && characterInfo.NumericType != UnicodeNumericType.None ? characterInfo.NumericValue : null as UnicodeRationalNumber?; - public CanonicalCombiningClass? CanonicalCombiningClass - { - get { return character != null ? characterInfo.CanonicalCombiningClass : null as CanonicalCombiningClass?; } - } + public ContributoryProperties? ContributoryProperties => character != null ? characterInfo.ContributoryProperties : null as ContributoryProperties?; + public CoreProperties? CoreProperties => character != null ? characterInfo.CoreProperties : null as CoreProperties?; + public EmojiProperties? EmojiProperties => character != null ? characterInfo.EmojiProperties : null as EmojiProperties?; - public BidirectionalClass? BidirectionalClass - { - get { return character != null ? characterInfo.BidirectionalClass : null as BidirectionalClass?; } - } + public UnicodeRadicalStrokeCountCollection RadicalStrokeCounts => character != null ? characterInfo.UnicodeRadicalStrokeCounts : UnicodeRadicalStrokeCountCollection.Empty; - public CompatibilityFormattingTag? DecompositionType - { - get { return character != null && characterInfo.DecompositionMapping != null ? characterInfo.DecompositionType : null as CompatibilityFormattingTag?; } - } + public UnicodeCrossReferenceCollection CrossReferences => character != null ? characterInfo.CrossRerefences : UnicodeCrossReferenceCollection.Empty; - public string DecompositionMapping - { - get { return character != null ? characterInfo.DecompositionMapping : null; } - } + public string MandarinReading => character != null ? characterInfo.MandarinReading : null; + public string CantoneseReading => character != null ? characterInfo.CantoneseReading : null; + public string JapaneseKunReading => character != null ? characterInfo.JapaneseKunReading : null; + public string JapaneseOnReading => character != null ? characterInfo.JapaneseOnReading : null; + public string KoreanReading => character != null ? characterInfo.KoreanReading : null; + public string HangulReading => character != null ? characterInfo.HangulReading : null; + public string VietnameseReading => character != null ? characterInfo.VietnameseReading : null; - public UnicodeNumericType? NumericType - { - get { return character != null ? characterInfo.NumericType : null as UnicodeNumericType?; } - } - - public UnihanNumericType? UnihanNumericType - { - get { return character != null ? characterInfo.UnihanNumericType : null as UnihanNumericType?; } - } - - public UnicodeRationalNumber? NumericValue - { - get { return character != null && characterInfo.NumericType != UnicodeNumericType.None ? characterInfo.NumericValue : null as UnicodeRationalNumber?; } - } - - public ContributoryProperties? ContributoryProperties - { - get { return character != null ? characterInfo.ContributoryProperties : null as ContributoryProperties?; } - } - - public CoreProperties? CoreProperties - { - get { return character != null ? characterInfo.CoreProperties : null as CoreProperties?; } - } - - public UnicodeRadicalStrokeCountCollection RadicalStrokeCounts - { - get { return character != null ? characterInfo.UnicodeRadicalStrokeCounts : UnicodeRadicalStrokeCountCollection.Empty; } - } - - public UnicodeCrossReferenceCollection CrossReferences - { - get { return character != null ? characterInfo.CrossRerefences : UnicodeCrossReferenceCollection.Empty; } - } - - public string MandarinReading - { - get { return character != null ? characterInfo.MandarinReading : null; } - } - - public string CantoneseReading - { - get { return character != null ? characterInfo.CantoneseReading : null; } - } - - public string JapaneseKunReading - { - get { return character != null ? characterInfo.JapaneseKunReading : null; } - } - - public string JapaneseOnReading - { - get { return character != null ? characterInfo.JapaneseOnReading : null; } - } - - public string KoreanReading - { - get { return character != null ? characterInfo.KoreanReading : null; } - } - - public string HangulReading - { - get { return character != null ? characterInfo.HangulReading : null; } - } - - public string VietnameseReading - { - get { return character != null ? characterInfo.VietnameseReading : null; } - } - - public string SimplifiedVariant - { - get { return character != null ? characterInfo.SimplifiedVariant : null; } - } - - public string TraditionalVariant - { - get { return character != null ? characterInfo.TraditionalVariant : null; } - } + public string SimplifiedVariant => character != null ? characterInfo.SimplifiedVariant : null; + public string TraditionalVariant => character != null ? characterInfo.TraditionalVariant : null; } } diff --git a/UnicodeCharacterInspector/CodePointToFontFamilyConverter.cs b/UnicodeCharacterInspector/CodePointToFontFamilyConverter.cs new file mode 100644 index 0000000..063c00e --- /dev/null +++ b/UnicodeCharacterInspector/CodePointToFontFamilyConverter.cs @@ -0,0 +1,23 @@ +using System; +using System.Globalization; +using System.Unicode; +using System.Windows.Data; +using System.Windows.Media; + +namespace UnicodeCharacterInspector +{ + internal sealed class CodePointToFontFamilyConverter : IValueConverter + { + public FontFamily DefaultFontFamily { get; set; } + + public FontFamily EmojiFontFamily { get; set; } + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + => value is int codePoint && UnicodeInfo.GetCharInfo(codePoint).EmojiProperties != 0 ? + EmojiFontFamily : + DefaultFontFamily; + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + => throw new NotSupportedException(); + } +} diff --git a/UnicodeCharacterInspector/MainWindow.xaml b/UnicodeCharacterInspector/MainWindow.xaml index 601871f..9c54909 100644 --- a/UnicodeCharacterInspector/MainWindow.xaml +++ b/UnicodeCharacterInspector/MainWindow.xaml @@ -38,14 +38,14 @@ - + - + - + @@ -86,7 +86,8 @@ - + + @@ -158,8 +159,10 @@ - - + + + + diff --git a/UnicodeCharacterInspector/UnicodeCharacterInspector.csproj b/UnicodeCharacterInspector/UnicodeCharacterInspector.csproj index e31bbd9..28442f1 100644 --- a/UnicodeCharacterInspector/UnicodeCharacterInspector.csproj +++ b/UnicodeCharacterInspector/UnicodeCharacterInspector.csproj @@ -42,9 +42,9 @@ UnicodeCharacterInspector.ico - - en-US - + + en-US + @@ -79,6 +79,7 @@ + Placeholder.cs diff --git a/UnicodeInformation.Builder/HttpDataSource.cs b/UnicodeInformation.Builder/HttpDataSource.cs index 0c11b2e..a0ab78a 100644 --- a/UnicodeInformation.Builder/HttpDataSource.cs +++ b/UnicodeInformation.Builder/HttpDataSource.cs @@ -1,28 +1,17 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; +using System.IO; using System.Net.Http; -using System.Text; using System.Threading.Tasks; namespace System.Unicode.Builder { public class HttpDataSource : IDataSource { - public static readonly Uri UnicodeCharacterDataUri = new Uri("http://www.unicode.org/Public/UCD/latest/ucd/", UriKind.Absolute); - private readonly HttpClient httpClient; private readonly Uri baseUri; - - public HttpDataSource() - : this(UnicodeCharacterDataUri) + + public HttpDataSource(Uri baseUri, HttpClient httpClient) { - } - - public HttpDataSource(Uri baseUri) - { - this.httpClient = new HttpClient(); + this.httpClient = httpClient ?? new HttpClient(); this.baseUri = baseUri; } diff --git a/UnicodeInformation.Builder/Program.cs b/UnicodeInformation.Builder/Program.cs index a60bed1..c3db4ab 100644 --- a/UnicodeInformation.Builder/Program.cs +++ b/UnicodeInformation.Builder/Program.cs @@ -11,6 +11,9 @@ namespace System.Unicode.Builder { internal class Program { + public static readonly Uri UnicodeCharacterDataUri = new Uri("http://www.unicode.org/Public/UCD/latest/ucd/", UriKind.Absolute); + public static readonly Uri EmojiDataUri = new Uri("http://www.unicode.org/Public/emoji/latest/", UriKind.Absolute); + public const string UnihanDirectoryName = "Unihan"; public const string UnihanArchiveName = "Unihan.zip"; public const string UcdDirectoryName = "UCD"; @@ -36,22 +39,28 @@ namespace System.Unicode.Builder "Unihan_IRGSources.txt", }; + public static readonly string[] emojiRequiredFiles = new[] + { + "emoji-data.txt", + "emoji-sequences.txt", + "emoji-variation-sequences.txt", + "emoji-zwj-sequences.txt", + }; + private static HttpClient httpClient; // The only purpose of this is for tests… internal static void SetHttpMessageHandler(HttpMessageHandler handler) { httpClient = new HttpClient(handler ?? new HttpClientHandler()); - } - - private static HttpClient HttpClient { get { return httpClient ?? (httpClient = new HttpClient()); } } - - private static byte[] DownloadDataArchive(string archiveName) - { - return HttpClient.GetByteArrayAsync(HttpDataSource.UnicodeCharacterDataUri + archiveName).Result; } - internal static IDataSource GetDataSource(string archiveName, string directoryName, string[] requiredFiles, bool? shouldDownload, bool? shouldSaveArchive, bool? shouldExtract) + internal static HttpClient HttpClient { get { return httpClient ?? (httpClient = new HttpClient()); } } + + private static Task DownloadDataArchiveAsync(string archiveName) + => HttpClient.GetByteArrayAsync(UnicodeCharacterDataUri + archiveName); + + internal static async Task GetDataSourceAsync(string archiveName, string directoryName, string[] requiredFiles, bool? shouldDownload, bool? shouldSaveArchive, bool? shouldExtract) { string baseDirectory = Directory.GetCurrentDirectory(); string dataDirectory = Path.Combine(baseDirectory, UcdDirectoryName); @@ -94,15 +103,14 @@ namespace System.Unicode.Builder if (shouldDownload != false) { - var dataArchiveData = DownloadDataArchive(archiveName); + var dataArchiveData = await DownloadDataArchiveAsync(archiveName).ConfigureAwait(false); if (shouldSaveArchive == true) { - var stream = File.Open(dataArchiveFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); - try + using (var stream = File.Open(dataArchiveFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) { - stream.Write(dataArchiveData, 0, dataArchiveData.Length); - dataArchiveData = null; // Release the reference now, since we won't need it anymore. + await stream.WriteAsync(dataArchiveData, 0, dataArchiveData.Length).ConfigureAwait(false); + dataArchiveData = null; // Release the reference now, since we won't need it anymore. if (shouldExtract == true) { @@ -118,11 +126,6 @@ namespace System.Unicode.Builder return new ZipDataSource(stream); } } - catch - { - stream.Dispose(); - throw; - } } else { @@ -133,18 +136,21 @@ namespace System.Unicode.Builder throw new InvalidOperationException(); } - private static void Main(string[] args) + private static async Task MainAsync(string[] args) { UnicodeInfoBuilder data; - using (var ucdSource = GetDataSource(UcdArchiveName, UcdDirectoryName, ucdRequiredFiles, null, null, null)) - using (var unihanSource = GetDataSource(UnihanArchiveName, UnihanDirectoryName, unihanRequiredFiles, null, null, null)) + using (var ucdSource = await GetDataSourceAsync(UcdArchiveName, UcdDirectoryName, ucdRequiredFiles, null, null, null)) + using (var unihanSource = await GetDataSourceAsync(UnihanArchiveName, UnihanDirectoryName, unihanRequiredFiles, null, null, null)) + using (var emojiSource = new HttpDataSource(EmojiDataUri, HttpClient)) { - data = UnicodeDataProcessor.BuildDataAsync(ucdSource, unihanSource).Result; + data = await UnicodeDataProcessor.BuildDataAsync(ucdSource, unihanSource, emojiSource); } using (var stream = new DeflateStream(File.Create("ucd.dat"), CompressionLevel.Optimal, false)) data.WriteToStream(stream); } + + private static void Main(string[] args) => MainAsync(args).Wait(); } } diff --git a/UnicodeInformation.Builder/UnicodeDataProcessor.cs b/UnicodeInformation.Builder/UnicodeDataProcessor.cs index 77fa19b..bec96ce 100644 --- a/UnicodeInformation.Builder/UnicodeDataProcessor.cs +++ b/UnicodeInformation.Builder/UnicodeDataProcessor.cs @@ -23,6 +23,7 @@ namespace System.Unicode.Builder public const string UnihanVariantsFileName = "Unihan_Variants.txt"; public const string UnihanNumericValuesFileName = "Unihan_NumericValues.txt"; public const string UnihanIrgSourcesFileName = "Unihan_IRGSources.txt"; + public const string EmojiDataFileName = "emoji-data.txt"; private static string ParseSimpleCaseMapping(string mapping) { @@ -36,13 +37,14 @@ namespace System.Unicode.Builder return string.IsNullOrEmpty(s) ? null : s; } - public static async Task BuildDataAsync(IDataSource ucdSource, IDataSource unihanSource) + public static async Task BuildDataAsync(IDataSource ucdSource, IDataSource unihanSource, IDataSource emojiSource) { var builder = new UnicodeInfoBuilder(await ReadUnicodeVersionAsync(ucdSource).ConfigureAwait(false)); await ProcessUnicodeDataFile(ucdSource, builder).ConfigureAwait(false); await ProcessPropListFile(ucdSource, builder).ConfigureAwait(false); await ProcessDerivedCorePropertiesFile(ucdSource, builder).ConfigureAwait(false); + await ProcessEmojiDataFile(emojiSource, builder).ConfigureAwait(false); await ProcessCjkRadicalsFile(ucdSource, builder).ConfigureAwait(false); await ProcessNameAliasesFile(ucdSource, builder).ConfigureAwait(false); await ProcessNamesListFile(ucdSource, builder).ConfigureAwait(false); @@ -219,6 +221,21 @@ namespace System.Unicode.Builder } } + private static async Task ProcessEmojiDataFile(IDataSource emojiSource, UnicodeInfoBuilder builder) + { + using (var reader = new UnicodeDataFileReader(await emojiSource.OpenDataFileAsync(EmojiDataFileName).ConfigureAwait(false), ';')) + { + while (reader.MoveToNextLine()) + { + var range = UnicodeCodePointRange.Parse(reader.ReadTrimmedField()); + if (EnumHelper.TryGetNamedValue(reader.ReadTrimmedField(), out var property)) + { + builder.SetProperties(property, range); + } + } + } + } + private static async Task ProcessCjkRadicalsFile(IDataSource ucdSource, UnicodeInfoBuilder builder) { using (var reader = new UnicodeDataFileReader(await ucdSource.OpenDataFileAsync(CjkRadicalsFileName).ConfigureAwait(false), ';')) diff --git a/UnicodeInformation.Builder/UnicodeInfoBuilder.cs b/UnicodeInformation.Builder/UnicodeInfoBuilder.cs index 452c93f..5be241d 100644 --- a/UnicodeInformation.Builder/UnicodeInfoBuilder.cs +++ b/UnicodeInformation.Builder/UnicodeInfoBuilder.cs @@ -226,7 +226,7 @@ namespace System.Unicode.Builder || ucdEntries[firstIndex].CodePointRange.FirstCodePoint < codePointRange.FirstCodePoint || ucdEntries[lastIndex].CodePointRange.LastCodePoint > codePointRange.LastCodePoint) { - throw new InvalidOperationException(); + throw new InvalidOperationException("Unable to find code point for setting core property."); } int i = firstIndex; @@ -241,6 +241,37 @@ namespace System.Unicode.Builder } } + public void SetProperties(EmojiProperties property, UnicodeCodePointRange codePointRange) + { + int firstIndex = FindUcdCodePoint(codePointRange.FirstCodePoint); + int lastIndex = FindUcdCodePoint(codePointRange.LastCodePoint); + + if (firstIndex < 0 && lastIndex < 0) + { + Insert(new UnicodeCharacterDataBuilder(codePointRange) { EmojiProperties = property }); + return; + } + + if (firstIndex < 0 + || lastIndex < 0 + || ucdEntries[firstIndex].CodePointRange.FirstCodePoint < codePointRange.FirstCodePoint + || ucdEntries[lastIndex].CodePointRange.LastCodePoint > codePointRange.LastCodePoint) + { + throw new InvalidOperationException("Unable to find code point for setting emoji property."); + } + + int i = firstIndex; + + while (true) + { + ucdEntries[i].EmojiProperties |= property; + + if (i == lastIndex) break; + + ++i; + } + } + public void SetRadicalInfo(int radicalIndex, CjkRadicalData data) { if (radicalIndex < 1 || radicalIndex > CjkRadicalCount) throw new ArgumentOutOfRangeException(nameof(radicalIndex)); diff --git a/UnicodeInformation.Builder/ucd.dat b/UnicodeInformation.Builder/ucd.dat index e788c4f..e7288b9 100644 Binary files a/UnicodeInformation.Builder/ucd.dat and b/UnicodeInformation.Builder/ucd.dat differ diff --git a/UnicodeInformation.Tests/UnicodeInfoBuilderTests.cs b/UnicodeInformation.Tests/UnicodeInfoBuilderTests.cs index 45f691c..7f3d0e8 100644 --- a/UnicodeInformation.Tests/UnicodeInfoBuilderTests.cs +++ b/UnicodeInformation.Tests/UnicodeInfoBuilderTests.cs @@ -8,6 +8,7 @@ using System.Text; using System.Net.Http; using System.Collections.Generic; using Xunit; +using System.Linq; namespace System.Unicode.Tests { @@ -65,8 +66,9 @@ namespace System.Unicode.Tests var handler = new FileHttpResponseHandler(); - var ucdTask = RegisterAndDownloadFile(handler, httpCacheDirectory, HttpDataSource.UnicodeCharacterDataUri, Program.UcdArchiveName); - var unihanTask = RegisterAndDownloadFile(handler, httpCacheDirectory, HttpDataSource.UnicodeCharacterDataUri, Program.UnihanArchiveName); + var ucdTask = RegisterAndDownloadFile(handler, httpCacheDirectory, Program.UnicodeCharacterDataUri, Program.UcdArchiveName); + var unihanTask = RegisterAndDownloadFile(handler, httpCacheDirectory, Program.UnicodeCharacterDataUri, Program.UnihanArchiveName); + var emojiTasks = Program.emojiRequiredFiles.Select(f => RegisterAndDownloadFile(handler, httpCacheDirectory, Program.EmojiDataUri, f)).ToArray(); Program.SetHttpMessageHandler(handler); @@ -75,13 +77,13 @@ namespace System.Unicode.Tests if (Directory.Exists(Program.UnihanDirectoryName)) Directory.Delete(Program.UnihanDirectoryName, true); if (File.Exists(Program.UnihanArchiveName)) File.Delete(Program.UnihanArchiveName); - Task.WaitAll(ucdTask, unihanTask); + Task.WaitAll(ucdTask, unihanTask, Task.WhenAll(emojiTasks)); } [Fact] public void DownloadUcdArchive() { - using (var source = Program.GetDataSource(Program.UcdArchiveName, Program.UcdDirectoryName, Program.ucdRequiredFiles, true, false, false)) + using (var source = Program.GetDataSourceAsync(Program.UcdArchiveName, Program.UcdDirectoryName, Program.ucdRequiredFiles, true, false, false).Result) { } } @@ -89,7 +91,7 @@ namespace System.Unicode.Tests [Fact] public void DownloadAndSaveUcdArchive() { - using (var source = Program.GetDataSource(Program.UcdArchiveName, Program.UcdDirectoryName, Program.ucdRequiredFiles, true, true, false)) + using (var source = Program.GetDataSourceAsync(Program.UcdArchiveName, Program.UcdDirectoryName, Program.ucdRequiredFiles, true, true, false).Result) { } } @@ -97,7 +99,7 @@ namespace System.Unicode.Tests [Fact] public void ExtractUcdArchive() { - using (var source = Program.GetDataSource(Program.UcdArchiveName, Program.UcdDirectoryName, Program.ucdRequiredFiles, true, true, true)) + using (var source = Program.GetDataSourceAsync(Program.UcdArchiveName, Program.UcdDirectoryName, Program.ucdRequiredFiles, true, true, true).Result) { } } @@ -105,7 +107,7 @@ namespace System.Unicode.Tests [Fact] public void DownloadUnihanArchive() { - using (var source = Program.GetDataSource(Program.UnihanArchiveName, Program.UnihanDirectoryName, Program.ucdRequiredFiles, true, false, false)) + using (var source = Program.GetDataSourceAsync(Program.UnihanArchiveName, Program.UnihanDirectoryName, Program.ucdRequiredFiles, true, false, false).Result) { } } @@ -113,7 +115,7 @@ namespace System.Unicode.Tests [Fact] public void DownloadAndSaveUnihanArchive() { - using (var source = Program.GetDataSource(Program.UnihanArchiveName, Program.UnihanDirectoryName, Program.ucdRequiredFiles, true, true, false)) + using (var source = Program.GetDataSourceAsync(Program.UnihanArchiveName, Program.UnihanDirectoryName, Program.ucdRequiredFiles, true, true, false).Result) { } } @@ -121,7 +123,7 @@ namespace System.Unicode.Tests [Fact] public void ExtractUnihanArchive() { - using (var source = Program.GetDataSource(Program.UnihanArchiveName, Program.UnihanDirectoryName, Program.ucdRequiredFiles, true, true, true)) + using (var source = Program.GetDataSourceAsync(Program.UnihanArchiveName, Program.UnihanDirectoryName, Program.ucdRequiredFiles, true, true, true).Result) { } } @@ -129,10 +131,11 @@ namespace System.Unicode.Tests [Fact] public async Task BuildDataAsync() { - using (var ucdSource = Program.GetDataSource(Program.UcdArchiveName, Program.UcdDirectoryName, Program.ucdRequiredFiles, null, null, null)) - using (var unihanSource = Program.GetDataSource(Program.UnihanArchiveName, Program.UnihanDirectoryName, Program.ucdRequiredFiles, null, null, null)) + using (var ucdSource = await Program.GetDataSourceAsync(Program.UcdArchiveName, Program.UcdDirectoryName, Program.ucdRequiredFiles, null, null, null)) + using (var unihanSource = await Program.GetDataSourceAsync(Program.UnihanArchiveName, Program.UnihanDirectoryName, Program.ucdRequiredFiles, null, null, null)) + using (var emojiSource = new HttpDataSource(Program.EmojiDataUri, Program.HttpClient)) { - var data = (await UnicodeDataProcessor.BuildDataAsync(ucdSource, unihanSource)); + var data = (await UnicodeDataProcessor.BuildDataAsync(ucdSource, unihanSource, emojiSource)); Assert.Equal((int)'\t', data.GetUcd('\t').CodePointRange.FirstCodePoint); } @@ -141,10 +144,11 @@ namespace System.Unicode.Tests [Fact] public async Task BuildAndWriteDataAsync() { - using (var ucdSource = Program.GetDataSource(Program.UcdArchiveName, Program.UcdDirectoryName, Program.ucdRequiredFiles, null, null, null)) - using (var unihanSource = Program.GetDataSource(Program.UnihanArchiveName, Program.UnihanDirectoryName, Program.ucdRequiredFiles, null, null, null)) + using (var ucdSource = await Program.GetDataSourceAsync(Program.UcdArchiveName, Program.UcdDirectoryName, Program.ucdRequiredFiles, null, null, null)) + using (var unihanSource = await Program.GetDataSourceAsync(Program.UnihanArchiveName, Program.UnihanDirectoryName, Program.ucdRequiredFiles, null, null, null)) + using (var emojiSource = new HttpDataSource(Program.EmojiDataUri, Program.HttpClient)) { - var data = (await UnicodeDataProcessor.BuildDataAsync(ucdSource, unihanSource)); + var data = (await UnicodeDataProcessor.BuildDataAsync(ucdSource, unihanSource, emojiSource)); //using (var stream = new DeflateStream(File.Create("ucd.dat"), CompressionLevel.Optimal, false)) using (var stream = File.Create("ucd.dat")) diff --git a/UnicodeInformation/EmojiProperties.cs b/UnicodeInformation/EmojiProperties.cs index eac0e11..68e4921 100644 --- a/UnicodeInformation/EmojiProperties.cs +++ b/UnicodeInformation/EmojiProperties.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Text; +using System.ComponentModel.DataAnnotations; namespace System.Unicode { @@ -16,13 +13,13 @@ namespace System.Unicode /// Represents the Emoji property. [ValueName("Emoji"), Display(Name = "Emoji")] Emoji = 0x1, - /// Represents the Emoji property. + /// Represents the Emoji_Presentation property. [ValueName("Emoji_Presentation"), Display(Name = "Emoji_Presentation")] EmojiPresentation = 0x2, - /// Represents the Emoji property. + /// Represents the Emoji_Modifier_Base property. [ValueName("Emoji_Modifier_Base"), Display(Name = "Emoji_Modifier_Base")] EmojiModifierBase = 0x4, - /// Represents the Emoji property. + /// Represents the Emoji_Component property. [ValueName("Emoji_Component"), Display(Name = "Emoji_Component")] EmojiComponent = 0x8, } diff --git a/UnicodeInformation/UnicodeCharInfo.cs b/UnicodeInformation/UnicodeCharInfo.cs index 46f0e51..3e03607 100644 --- a/UnicodeInformation/UnicodeCharInfo.cs +++ b/UnicodeInformation/UnicodeCharInfo.cs @@ -123,6 +123,9 @@ namespace System.Unicode /// Gets a value indicating which of the boolean core properties are defined for the code point. /// The core properties are computed by combining various character information together with contributory properties. public CoreProperties CoreProperties => UnicodeCharacterData.CoreProperties; + /// Gets a value indicating which of the boolean emoji properties are defined for the code point. + /// The emoji properties are provided by the Unicode Emoji standard, which is not directly part of UCD. + public EmojiProperties EmojiProperties => UnicodeCharacterData.EmojiProperties; /// Gets a collection of cross references associated with the code point. /// The cross references have been extracted from Unicode data but are not normative. public UnicodeCrossReferenceCollection CrossRerefences => new UnicodeCrossReferenceCollection(UnicodeCharacterData.CrossRerefences); diff --git a/UnicodeInformation/UnicodeInfo.cs b/UnicodeInformation/UnicodeInfo.cs index 56798d7..20e04ce 100644 --- a/UnicodeInformation/UnicodeInfo.cs +++ b/UnicodeInformation/UnicodeInfo.cs @@ -1,12 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Globalization; +using System.Globalization; using System.IO; using System.IO.Compression; -using System.Linq; using System.Reflection; using System.Text; -using System.Threading.Tasks; namespace System.Unicode { @@ -82,14 +78,14 @@ namespace System.Unicode for (i = 0; i < blockEntries.Length; ++i) { - blockEntries[i] = ReadBlockEntry(reader); + ReadBlockEntry(reader, out blockEntries[i]); } var cjkRadicalEntries = new CjkRadicalData[reader.ReadByte()]; for (i = 0; i < cjkRadicalEntries.Length; ++i) { - cjkRadicalEntries[i] = ReadCjkRadicalInfo(reader); + ReadCjkRadicalInfo(reader, out cjkRadicalEntries[i]); } var unihanCharacterDataEntries = new UnihanCharacterData[ReadCodePoint(reader)]; @@ -247,7 +243,7 @@ namespace System.Unicode ); } - private static CjkRadicalData ReadCjkRadicalInfo(BinaryReader reader) + private static void ReadCjkRadicalInfo(BinaryReader reader, out CjkRadicalData value) { char tr; char tc; @@ -255,11 +251,13 @@ namespace System.Unicode tr = (char)reader.ReadUInt16(); tc = (char)reader.ReadUInt16(); - return (tr & 0x8000) == 0 ? new CjkRadicalData(tr, tc) : new CjkRadicalData((char)(tr & 0x7FFF), tc, (char)reader.ReadUInt16(), (char)reader.ReadUInt16()); + value = (tr & 0x8000) == 0 ? + new CjkRadicalData(tr, tc) : + new CjkRadicalData((char)(tr & 0x7FFF), tc, (char)reader.ReadUInt16(), (char)reader.ReadUInt16()); } - private static UnicodeBlock ReadBlockEntry(BinaryReader reader) - => new UnicodeBlock(new UnicodeCodePointRange(ReadCodePoint(reader), ReadCodePoint(reader)), reader.ReadString()); + private static void ReadBlockEntry(BinaryReader reader, out UnicodeBlock value) + => value = new UnicodeBlock(new UnicodeCodePointRange(ReadCodePoint(reader), ReadCodePoint(reader)), reader.ReadString()); private static int ReadInt24(BinaryReader reader) => reader.ReadByte() | ((reader.ReadByte() | (reader.ReadByte() << 8)) << 8); diff --git a/UnicodeInformation/ucd.dat b/UnicodeInformation/ucd.dat index e788c4f..e7288b9 100644 Binary files a/UnicodeInformation/ucd.dat and b/UnicodeInformation/ucd.dat differ