Added support for CJK radicals.
Addded CJK radical & stroke count information to the UI.
This commit is contained in:
@@ -7,7 +7,9 @@
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
|
||||
<local:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||
<local:ZeroToVisibilityConverter x:Key="ZeroToVisibilityConverter" />
|
||||
<local:Utf32ToDisplayTextConverter x:Key="Utf32ToStringConverter" />
|
||||
<local:Utf32ToDisplayTextConverter x:Key="Utf32ToDisplayTextConverter" />
|
||||
<local:Utf32ToNameConverter x:Key="Utf32ToNameConverter" />
|
||||
<local:StringToUtf32Converter x:Key="StringToUtf32Converter" />
|
||||
<local:RadicalStrokeCountToCharConverter x:Key="RadicalStrokeCountToCharConverter" />
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
|
||||
@@ -67,6 +67,7 @@ namespace UnicodeCharacterInspector
|
||||
NotifyPropertyChanged(nameof(NumericValue));
|
||||
NotifyPropertyChanged(nameof(ContributoryProperties));
|
||||
NotifyPropertyChanged(nameof(CoreProperties));
|
||||
NotifyPropertyChanged(nameof(RadicalStrokeCounts));
|
||||
NotifyPropertyChanged(nameof(CrossReferences));
|
||||
NotifyPropertyChanged(nameof(MandarinReading));
|
||||
NotifyPropertyChanged(nameof(CantoneseReading));
|
||||
@@ -173,6 +174,11 @@ namespace UnicodeCharacterInspector
|
||||
get { return character != null ? characterInfo.CoreProperties : null as CoreProperties?; }
|
||||
}
|
||||
|
||||
public UnicodeRadicalStrokeCountCollection RadicalStrokeCounts
|
||||
{
|
||||
get { return character != null ? characterInfo.UnicodeRadicalStrokeCounts : new UnicodeRadicalStrokeCountCollection(); }
|
||||
}
|
||||
|
||||
public UnicodeCrossReferenceCollection CrossReferences
|
||||
{
|
||||
get { return character != null ? characterInfo.CrossRerefences : new UnicodeCrossReferenceCollection(); }
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.CodePoint, Converter={StaticResource NullToVisibilityConverter}}" Text="Code Point" />
|
||||
@@ -105,52 +106,64 @@
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<TextBlock Grid.Row="4" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.SimplifiedVariant, Converter={StaticResource NullToVisibilityConverter}}" Text="Simplified Variant" />
|
||||
<TextBlock Grid.Row="4" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.SimplifiedVariant, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.SimplifiedVariant}" />
|
||||
<TextBlock Grid.Row="5" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.TraditionalVariant, Converter={StaticResource NullToVisibilityConverter}}" Text="Traditional Variant" />
|
||||
<TextBlock Grid.Row="5" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.TraditionalVariant, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.TraditionalVariant}" />
|
||||
<TextBlock Grid.Row="6" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.Definition, Converter={StaticResource NullToVisibilityConverter}}" Text="Unihan Definition" />
|
||||
<TextBlock Grid.Row="6" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.Definition, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.Definition}" />
|
||||
<TextBlock Grid.Row="7" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.MandarinReading, Converter={StaticResource NullToVisibilityConverter}}" Text="Mandarin Reading" />
|
||||
<TextBlock Grid.Row="7" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.MandarinReading, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.MandarinReading}" />
|
||||
<TextBlock Grid.Row="8" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.CantoneseReading, Converter={StaticResource NullToVisibilityConverter}}" Text="Cantonese Reading" />
|
||||
<TextBlock Grid.Row="8" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.CantoneseReading, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.CantoneseReading}" />
|
||||
<TextBlock Grid.Row="9" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.JapaneseKunReading, Converter={StaticResource NullToVisibilityConverter}}" Text="Japanese Kun Reading" />
|
||||
<TextBlock Grid.Row="9" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.JapaneseKunReading, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.JapaneseKunReading}" />
|
||||
<TextBlock Grid.Row="10" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.JapaneseOnReading, Converter={StaticResource NullToVisibilityConverter}}" Text="Japanese On Reading" />
|
||||
<TextBlock Grid.Row="10" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.JapaneseOnReading, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.JapaneseOnReading}" />
|
||||
<TextBlock Grid.Row="11" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.KoreanReading, Converter={StaticResource NullToVisibilityConverter}}" Text="Korean Reading" />
|
||||
<TextBlock Grid.Row="11" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.KoreanReading, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.KoreanReading}" />
|
||||
<TextBlock Grid.Row="12" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.HangulReading, Converter={StaticResource NullToVisibilityConverter}}" Text="Hangul Reading" />
|
||||
<TextBlock Grid.Row="12" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.HangulReading, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.HangulReading}" />
|
||||
<TextBlock Grid.Row="13" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.Category, Converter={StaticResource NullToVisibilityConverter}}" Text="Category" />
|
||||
<TextBlock Grid.Row="13" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.Category, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.Category}" />
|
||||
<TextBlock Grid.Row="14" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.Block, Converter={StaticResource NullToVisibilityConverter}}" Text="Block" />
|
||||
<TextBlock Grid.Row="14" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.Block, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.Block}" />
|
||||
<TextBlock Grid.Row="15" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.CanonicalCombiningClass, Converter={StaticResource NullToVisibilityConverter}}" Text="Canonical Combining Class" />
|
||||
<TextBlock Grid.Row="15" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.CanonicalCombiningClass, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.CanonicalCombiningClass}" />
|
||||
<TextBlock Grid.Row="16" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.BidirectionalClass, Converter={StaticResource NullToVisibilityConverter}}" Text="Bidirectional Class" />
|
||||
<TextBlock Grid.Row="16" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.BidirectionalClass, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.BidirectionalClass}" />
|
||||
<TextBlock Grid.Row="17" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.DecompositionType, Converter={StaticResource NullToVisibilityConverter}}" Text="Decomposition Type" />
|
||||
<TextBlock Grid.Row="17" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.DecompositionType, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.DecompositionType}" />
|
||||
<TextBlock Grid.Row="18" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.DecompositionMapping, Converter={StaticResource NullToVisibilityConverter}}" Text="Decomposition Mapping" />
|
||||
<TextBlock Grid.Row="18" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.DecompositionMapping, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.DecompositionMapping}" />
|
||||
<TextBlock Grid.Row="19" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.NumericType, Converter={StaticResource ZeroToVisibilityConverter}}" Text="Numeric Type" />
|
||||
<TextBlock Grid.Row="19" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.NumericType, Converter={StaticResource ZeroToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.NumericType}" />
|
||||
<TextBlock Grid.Row="20" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.UnihanNumericType, Converter={StaticResource ZeroToVisibilityConverter}}" Text="Numeric Type (Unihan)" />
|
||||
<TextBlock Grid.Row="20" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.UnihanNumericType, Converter={StaticResource ZeroToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.UnihanNumericType}" />
|
||||
<TextBlock Grid.Row="21" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.NumericValue, Converter={StaticResource NullToVisibilityConverter}}" Text="Numeric Value" />
|
||||
<TextBlock Grid.Row="21" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.NumericValue, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.NumericValue}" />
|
||||
<TextBlock Grid.Row="22" Grid.Column="0" VerticalAlignment="Top" Visibility="{Binding SelectedCharacterInfo.ContributoryProperties, Converter={StaticResource ZeroToVisibilityConverter}}" Text="Contributory Properties" />
|
||||
<TextBlock Grid.Row="22" Grid.Column="1" VerticalAlignment="Top" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.ContributoryProperties, Converter={StaticResource ZeroToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.ContributoryProperties}" />
|
||||
<TextBlock Grid.Row="23" Grid.Column="0" VerticalAlignment="Top" Visibility="{Binding SelectedCharacterInfo.CoreProperties, Converter={StaticResource ZeroToVisibilityConverter}}" Text="Core Properties" />
|
||||
<TextBlock Grid.Row="23" Grid.Column="1" VerticalAlignment="Top" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.CoreProperties, Converter={StaticResource ZeroToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.CoreProperties}" />
|
||||
<TextBlock Grid.Row="24" Grid.Column="0" VerticalAlignment="Top" Visibility="{Binding SelectedCharacterInfo.CrossReferences.Count, Converter={StaticResource ZeroToVisibilityConverter}}" Text="Cross-References" />
|
||||
<ItemsControl Grid.Row="24" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.CrossReferences.Count, Converter={StaticResource ZeroToVisibilityConverter}}" ItemsSource="{Binding SelectedCharacterInfo.CrossReferences}">
|
||||
<TextBlock Grid.Row="4" Grid.Column="0" VerticalAlignment="Top" Visibility="{Binding SelectedCharacterInfo.RadicalStrokeCounts.Count, Converter={StaticResource ZeroToVisibilityConverter}}" Text="Radical & Stroke Count" />
|
||||
<ItemsControl Grid.Row="4" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.RadicalStrokeCounts.Count, Converter={StaticResource ZeroToVisibilityConverter}}" ItemsSource="{Binding SelectedCharacterInfo.RadicalStrokeCounts}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock TextWrapping="WrapWithOverflow">
|
||||
• “<Run Text="{Binding Mode=OneTime, Converter={StaticResource Utf32ToStringConverter}}" />” U+<Run Text="{Binding Mode=OneTime, StringFormat=X4}" /> <Run Text="{Binding Mode=OneTime, Converter={StaticResource Utf32ToNameConverter}}" />
|
||||
Radical <Run Text="{Binding Radical, Mode=OneTime}" /> (<Run Text="{Binding Mode=OneTime, Converter={StaticResource RadicalStrokeCountToCharConverter}}" />), <Run Text="{Binding StrokeCount, Mode=OneTime}" /> strokes
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<TextBlock Grid.Row="5" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.SimplifiedVariant, Converter={StaticResource NullToVisibilityConverter}}" Text="Simplified Variant" />
|
||||
<TextBlock Grid.Row="5" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.SimplifiedVariant, Converter={StaticResource NullToVisibilityConverter}}">
|
||||
“<Run Text="{Binding SelectedCharacterInfo.SimplifiedVariant, Mode=OneWay}" />” U+<Run Text="{Binding SelectedCharacterInfo.SimplifiedVariant, Mode=OneWay, Converter={StaticResource StringToUtf32Converter}, StringFormat=X4}" />
|
||||
</TextBlock>
|
||||
<TextBlock Grid.Row="6" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.TraditionalVariant, Converter={StaticResource NullToVisibilityConverter}}" Text="Traditional Variant" />
|
||||
<TextBlock Grid.Row="6" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.TraditionalVariant, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.TraditionalVariant}" />
|
||||
<TextBlock Grid.Row="7" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.Definition, Converter={StaticResource NullToVisibilityConverter}}" Text="Unihan Definition" />
|
||||
<TextBlock Grid.Row="7" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.Definition, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.Definition}" />
|
||||
<TextBlock Grid.Row="8" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.MandarinReading, Converter={StaticResource NullToVisibilityConverter}}" Text="Mandarin Reading" />
|
||||
<TextBlock Grid.Row="8" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.MandarinReading, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.MandarinReading}" />
|
||||
<TextBlock Grid.Row="9" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.CantoneseReading, Converter={StaticResource NullToVisibilityConverter}}" Text="Cantonese Reading" />
|
||||
<TextBlock Grid.Row="9" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.CantoneseReading, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.CantoneseReading}" />
|
||||
<TextBlock Grid.Row="10" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.JapaneseKunReading, Converter={StaticResource NullToVisibilityConverter}}" Text="Japanese Kun Reading" />
|
||||
<TextBlock Grid.Row="10" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.JapaneseKunReading, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.JapaneseKunReading}" />
|
||||
<TextBlock Grid.Row="11" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.JapaneseOnReading, Converter={StaticResource NullToVisibilityConverter}}" Text="Japanese On Reading" />
|
||||
<TextBlock Grid.Row="11" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.JapaneseOnReading, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.JapaneseOnReading}" />
|
||||
<TextBlock Grid.Row="12" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.KoreanReading, Converter={StaticResource NullToVisibilityConverter}}" Text="Korean Reading" />
|
||||
<TextBlock Grid.Row="12" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.KoreanReading, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.KoreanReading}" />
|
||||
<TextBlock Grid.Row="13" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.HangulReading, Converter={StaticResource NullToVisibilityConverter}}" Text="Hangul Reading" />
|
||||
<TextBlock Grid.Row="13" Grid.Column="1" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.HangulReading, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.HangulReading}" />
|
||||
<TextBlock Grid.Row="14" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.Category, Converter={StaticResource NullToVisibilityConverter}}" Text="Category" />
|
||||
<TextBlock Grid.Row="14" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.Category, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.Category}" />
|
||||
<TextBlock Grid.Row="15" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.Block, Converter={StaticResource NullToVisibilityConverter}}" Text="Block" />
|
||||
<TextBlock Grid.Row="15" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.Block, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.Block}" />
|
||||
<TextBlock Grid.Row="16" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.CanonicalCombiningClass, Converter={StaticResource NullToVisibilityConverter}}" Text="Canonical Combining Class" />
|
||||
<TextBlock Grid.Row="16" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.CanonicalCombiningClass, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.CanonicalCombiningClass}" />
|
||||
<TextBlock Grid.Row="17" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.BidirectionalClass, Converter={StaticResource NullToVisibilityConverter}}" Text="Bidirectional Class" />
|
||||
<TextBlock Grid.Row="17" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.BidirectionalClass, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.BidirectionalClass}" />
|
||||
<TextBlock Grid.Row="18" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.DecompositionType, Converter={StaticResource NullToVisibilityConverter}}" Text="Decomposition Type" />
|
||||
<TextBlock Grid.Row="18" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.DecompositionType, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.DecompositionType}" />
|
||||
<TextBlock Grid.Row="19" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.DecompositionMapping, Converter={StaticResource NullToVisibilityConverter}}" Text="Decomposition Mapping" />
|
||||
<TextBlock Grid.Row="19" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.DecompositionMapping, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.DecompositionMapping}" />
|
||||
<TextBlock Grid.Row="20" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.NumericType, Converter={StaticResource ZeroToVisibilityConverter}}" Text="Numeric Type" />
|
||||
<TextBlock Grid.Row="20" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.NumericType, Converter={StaticResource ZeroToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.NumericType}" />
|
||||
<TextBlock Grid.Row="21" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.UnihanNumericType, Converter={StaticResource ZeroToVisibilityConverter}}" Text="Numeric Type (Unihan)" />
|
||||
<TextBlock Grid.Row="21" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.UnihanNumericType, Converter={StaticResource ZeroToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.UnihanNumericType}" />
|
||||
<TextBlock Grid.Row="22" Grid.Column="0" Visibility="{Binding SelectedCharacterInfo.NumericValue, Converter={StaticResource NullToVisibilityConverter}}" Text="Numeric Value" />
|
||||
<TextBlock Grid.Row="22" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.NumericValue, Converter={StaticResource NullToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.NumericValue}" />
|
||||
<TextBlock Grid.Row="23" Grid.Column="0" VerticalAlignment="Top" Visibility="{Binding SelectedCharacterInfo.ContributoryProperties, Converter={StaticResource ZeroToVisibilityConverter}}" Text="Contributory Properties" />
|
||||
<TextBlock Grid.Row="23" Grid.Column="1" VerticalAlignment="Top" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.ContributoryProperties, Converter={StaticResource ZeroToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.ContributoryProperties}" />
|
||||
<TextBlock Grid.Row="24" Grid.Column="0" VerticalAlignment="Top" Visibility="{Binding SelectedCharacterInfo.CoreProperties, Converter={StaticResource ZeroToVisibilityConverter}}" Text="Core Properties" />
|
||||
<TextBlock Grid.Row="24" Grid.Column="1" VerticalAlignment="Top" TextWrapping="WrapWithOverflow" Visibility="{Binding SelectedCharacterInfo.CoreProperties, Converter={StaticResource ZeroToVisibilityConverter}}" Text="{Binding SelectedCharacterInfo.CoreProperties}" />
|
||||
<TextBlock Grid.Row="25" Grid.Column="0" VerticalAlignment="Top" Visibility="{Binding SelectedCharacterInfo.CrossReferences.Count, Converter={StaticResource ZeroToVisibilityConverter}}" Text="Cross-References" />
|
||||
<ItemsControl Grid.Row="25" Grid.Column="1" Visibility="{Binding SelectedCharacterInfo.CrossReferences.Count, Converter={StaticResource ZeroToVisibilityConverter}}" ItemsSource="{Binding SelectedCharacterInfo.CrossReferences}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock TextWrapping="WrapWithOverflow">
|
||||
“<Run Text="{Binding Mode=OneTime, Converter={StaticResource Utf32ToDisplayTextConverter}}" />” U+<Run Text="{Binding Mode=OneTime, StringFormat=X4}" /> <Run Text="{Binding Mode=OneTime, Converter={StaticResource Utf32ToNameConverter}}" />
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Unicode;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace UnicodeCharacterInspector
|
||||
{
|
||||
internal sealed class RadicalStrokeCountToCharConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value == null) return null;
|
||||
|
||||
var radicalStrokeCount = (UnicodeRadicalStrokeCount)value;
|
||||
var radical = UnicodeInfo.GetCjkRadicalInfo(radicalStrokeCount.Radical);
|
||||
|
||||
return radicalStrokeCount.IsSimplified ? radical.TraditionalRadicalCodePoint : radical.SimplifiedRadicalCodePoint;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace UnicodeCharacterInspector
|
||||
{
|
||||
internal class StringToUtf32Converter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
string text = value as string;
|
||||
|
||||
if (!string.IsNullOrEmpty(text)) return char.ConvertToUtf32(text, 0);
|
||||
else return null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,6 +77,8 @@
|
||||
<Compile Include="PlaceholderAdorner.cs">
|
||||
<DependentUpon>Placeholder.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="RadicalStrokeCountToCharConverter.cs" />
|
||||
<Compile Include="StringToUtf32Converter.cs" />
|
||||
<Compile Include="Utf32ToNameConverter.cs" />
|
||||
<Compile Include="Utf32ToDisplayTextConverter.cs" />
|
||||
<Compile Include="ZeroToVisibilityConverter.cs" />
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace System.Unicode.Builder
|
||||
"UnicodeData.txt",
|
||||
"PropList.txt",
|
||||
"DerivedCoreProperties.txt",
|
||||
"CJKRadicals.txt",
|
||||
//"Jamo.txt", // Not used right now, as the hangul syllable algorithm implementation takes care of this.
|
||||
"NameAliases.txt",
|
||||
"NamesList.txt",
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace System.Unicode.Builder
|
||||
set { name = value; }
|
||||
}
|
||||
|
||||
public ICollection<UnicodeNameAlias> NameAliases { get { return nameAliases; } }
|
||||
public IList<UnicodeNameAlias> NameAliases { get { return nameAliases; } }
|
||||
|
||||
public UnicodeCategory Category
|
||||
{
|
||||
@@ -124,7 +124,7 @@ namespace System.Unicode.Builder
|
||||
set { coreProperties = value; }
|
||||
}
|
||||
|
||||
public ICollection<int> CrossRerefences { get { return crossRerefences; } }
|
||||
public IList<int> CrossRerefences { get { return crossRerefences; } }
|
||||
|
||||
public UnicodeCharacterDataBuilder(int codePoint)
|
||||
: this(new UnicodeCharacterRange(codePoint))
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace System.Unicode.Builder
|
||||
public const string UnicodeDataFileName = "UnicodeData.txt";
|
||||
public const string PropListFileName = "PropList.txt";
|
||||
public const string DerivedCorePropertiesFileName = "DerivedCoreProperties.txt";
|
||||
public const string CjkRadicalsFileName = "CJKRadicals.txt";
|
||||
public const string NameAliasesFileName = "NameAliases.txt";
|
||||
public const string NamesListFileName = "NamesList.txt";
|
||||
public const string BlocksFileName = "Blocks.txt";
|
||||
@@ -40,6 +41,7 @@ namespace System.Unicode.Builder
|
||||
await ProcessUnicodeDataFile(ucdSource, builder).ConfigureAwait(false);
|
||||
await ProcessPropListFile(ucdSource, builder).ConfigureAwait(false);
|
||||
await ProcessDerivedCorePropertiesFile(ucdSource, builder).ConfigureAwait(false);
|
||||
await ProcessCjkRadicalsFile(ucdSource, builder).ConfigureAwait(false);
|
||||
await ProcessNameAliasesFile(ucdSource, builder).ConfigureAwait(false);
|
||||
await ProcessNamesListFile(ucdSource, builder).ConfigureAwait(false);
|
||||
await ProcessBlocksFile(ucdSource, builder).ConfigureAwait(false);
|
||||
@@ -202,6 +204,53 @@ namespace System.Unicode.Builder
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task ProcessCjkRadicalsFile(IDataSource ucdSource, UnicodeInfoBuilder builder)
|
||||
{
|
||||
using (var reader = new UnicodeDataFileReader(await ucdSource.OpenDataFileAsync(CjkRadicalsFileName).ConfigureAwait(false), ';'))
|
||||
{
|
||||
int lastReadRadical = 0;
|
||||
|
||||
while (reader.MoveToNextLine())
|
||||
{
|
||||
string radicalIndexText = reader.ReadField();
|
||||
bool isSimplified = radicalIndexText[radicalIndexText.Length - 1] == '\'';
|
||||
int radicalIndex = int.Parse(isSimplified ? radicalIndexText.Substring(0, radicalIndexText.Length - 1) : radicalIndexText);
|
||||
|
||||
if (isSimplified ? radicalIndex != lastReadRadical : lastReadRadical + 1 != (lastReadRadical = radicalIndex))
|
||||
throw new InvalidDataException("Did not expect radical number " + radicalIndexText + ".");
|
||||
|
||||
char radicalCodePoint = checked((char)int.Parse(reader.ReadTrimmedField(), NumberStyles.HexNumber));
|
||||
char characterCodePoint = checked((char)int.Parse(reader.ReadTrimmedField(), NumberStyles.HexNumber));
|
||||
|
||||
if (!isSimplified && (radicalCodePoint & 0x8000) != 0)
|
||||
throw new InvalidOperationException("Did not expect the radical code point to be higher than U+8000 for radical " + radicalIndex.ToString() + ".");
|
||||
|
||||
if (isSimplified)
|
||||
{
|
||||
builder.SetRadicalInfo(radicalIndex, UpdateRadicalData(builder.GetRadicalInfo(radicalIndex), radicalCodePoint, characterCodePoint));
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.SetRadicalInfo(radicalIndex, new CjkRadicalData(radicalCodePoint, characterCodePoint));
|
||||
}
|
||||
}
|
||||
|
||||
if (lastReadRadical != UnicodeInfoBuilder.CjkRadicalCount)
|
||||
throw new InvalidOperationException("There was not enough data for the 214 CJK radicals.");
|
||||
}
|
||||
}
|
||||
|
||||
private static CjkRadicalData UpdateRadicalData(CjkRadicalData traditionalData, char simplifiedRadicalCodePoint, char simplifiedCharacterCodePoint)
|
||||
{
|
||||
return new CjkRadicalData
|
||||
(
|
||||
traditionalData.TraditionalRadicalCodePoint,
|
||||
traditionalData.TraditionalCharacterCodePoint,
|
||||
simplifiedRadicalCodePoint,
|
||||
simplifiedCharacterCodePoint
|
||||
);
|
||||
}
|
||||
|
||||
private static async Task ProcessNameAliasesFile(IDataSource ucdSource, UnicodeInfoBuilder builder)
|
||||
{
|
||||
using (var reader = new UnicodeDataFileReader(await ucdSource.OpenDataFileAsync(NameAliasesFileName).ConfigureAwait(false), ';'))
|
||||
|
||||
@@ -9,12 +9,15 @@ namespace System.Unicode.Builder
|
||||
{
|
||||
internal class UnicodeInfoBuilder
|
||||
{
|
||||
public const int CjkRadicalCount = 214; // The number of radicals (214) shouldn't change in the near future…
|
||||
|
||||
private readonly Version unicodeVersion;
|
||||
private UnicodeCharacterDataBuilder[] ucdEntries = new UnicodeCharacterDataBuilder[10000];
|
||||
private int ucdEntryCount;
|
||||
private UnihanCharacterDataBuilder[] unihanEntries = new UnihanCharacterDataBuilder[10000];
|
||||
private int unihanEntryCount;
|
||||
private List<UnicodeBlock> blockEntries = new List<UnicodeBlock>(100);
|
||||
private readonly List<UnicodeBlock> blockEntries = new List<UnicodeBlock>(100);
|
||||
private readonly CjkRadicalData[] cjkRadicals = new CjkRadicalData[CjkRadicalCount];
|
||||
|
||||
public UnicodeInfoBuilder(Version unicodeVersion)
|
||||
{
|
||||
@@ -238,6 +241,20 @@ namespace System.Unicode.Builder
|
||||
}
|
||||
}
|
||||
|
||||
public void SetRadicalInfo(int radicalIndex, CjkRadicalData data)
|
||||
{
|
||||
if (radicalIndex < 1 || radicalIndex > CjkRadicalCount) throw new ArgumentOutOfRangeException(nameof(radicalIndex));
|
||||
|
||||
cjkRadicals[radicalIndex - 1] = data;
|
||||
}
|
||||
|
||||
public CjkRadicalData GetRadicalInfo(int radicalIndex)
|
||||
{
|
||||
if (radicalIndex < 1 || radicalIndex > CjkRadicalCount) throw new ArgumentOutOfRangeException(nameof(radicalIndex));
|
||||
|
||||
return cjkRadicals[radicalIndex - 1];
|
||||
}
|
||||
|
||||
public void AddBlockEntry(UnicodeBlock block)
|
||||
{
|
||||
blockEntries.Add(block);
|
||||
@@ -283,6 +300,20 @@ namespace System.Unicode.Builder
|
||||
{
|
||||
WriteUnicodeBlockToFile(writer, blockEntries[i]);
|
||||
}
|
||||
writer.Write((byte)CjkRadicalCount);
|
||||
for (int i = 0; i < cjkRadicals.Length; ++i)
|
||||
{
|
||||
var radical = cjkRadicals[i];
|
||||
|
||||
writer.Write((ushort)(radical.HasSimplifiedForm ? 0x8000 | radical.TraditionalRadicalCodePoint : radical.TraditionalRadicalCodePoint));
|
||||
writer.Write((ushort)radical.TraditionalCharacterCodePoint);
|
||||
|
||||
if (radical.HasSimplifiedForm)
|
||||
{
|
||||
writer.Write((ushort)radical.SimplifiedRadicalCodePoint);
|
||||
writer.Write((ushort)radical.SimplifiedCharacterCodePoint);
|
||||
}
|
||||
}
|
||||
writer.WriteCodePoint(unihanEntryCount);
|
||||
for (int i = 0; i < unihanEntryCount; ++i)
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace System.Unicode.Builder
|
||||
public string VietnameseReading { get { return vietnameseReading; } set { vietnameseReading = value; } }
|
||||
public string SimplifiedVariant { get { return simplifiedVariant; } set { simplifiedVariant = value; } }
|
||||
public string TraditionalVariant { get { return traditionalVariant; } set { traditionalVariant = value; } }
|
||||
public ICollection<UnicodeRadicalStrokeCount> UnicodeRadicalStrokeCounts { get { return unicodeRadicalStrokeCounts; } }
|
||||
public IList<UnicodeRadicalStrokeCount> UnicodeRadicalStrokeCounts { get { return unicodeRadicalStrokeCounts; } }
|
||||
|
||||
internal UnihanCharacterDataBuilder(int codePoint)
|
||||
{
|
||||
@@ -77,7 +77,7 @@ namespace System.Unicode.Builder
|
||||
{
|
||||
if (unicodeRadicalStrokeCounts.Count == 1) fields |= UnihanFields.UnicodeRadicalStrokeCount;
|
||||
else if (unicodeRadicalStrokeCounts.Count == 2) fields |= UnihanFields.UnicodeRadicalStrokeCountTwice;
|
||||
else fields |= UnihanFields.UnicodeRadicalStrokeCount | UnihanFields.UnicodeRadicalStrokeCountTwice;
|
||||
else fields |= UnihanFields.UnicodeRadicalStrokeCountMore;
|
||||
}
|
||||
if (Definition != null) fields |= UnihanFields.Definition;
|
||||
if (MandarinReading != null) fields |= UnihanFields.MandarinReading;
|
||||
@@ -93,6 +93,8 @@ namespace System.Unicode.Builder
|
||||
writer.Write((ushort)fields);
|
||||
|
||||
writer.WriteCodePoint(UnihanCharacterData.PackCodePoint(codePoint));
|
||||
if ((fields & UnihanFields.OtherNumeric) != 0) writer.Write(numericValue);
|
||||
|
||||
if ((fields & UnihanFields.UnicodeRadicalStrokeCountMore) != 0)
|
||||
{
|
||||
if ((fields & (UnihanFields.UnicodeRadicalStrokeCountMore)) == UnihanFields.UnicodeRadicalStrokeCountMore)
|
||||
@@ -104,7 +106,7 @@ namespace System.Unicode.Builder
|
||||
writer.Write((byte)(radicalStrokeCount.StrokeCount | (radicalStrokeCount.IsSimplified ? 0x80 : 0)));
|
||||
}
|
||||
}
|
||||
if ((fields & UnihanFields.OtherNumeric) != 0) writer.Write(numericValue);
|
||||
|
||||
if ((fields & UnihanFields.Definition) != 0) writer.Write(Definition);
|
||||
if ((fields & UnihanFields.MandarinReading) != 0) writer.Write(MandarinReading);
|
||||
if ((fields & UnihanFields.CantoneseReading) != 0) writer.Write(CantoneseReading);
|
||||
|
||||
@@ -153,6 +153,47 @@ namespace UnicodeInformation.Tests
|
||||
Assert.AreEqual("Miscellaneous Symbols and Pictographs", UnicodeInfo.GetBlockName(0x1F574));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RadicalStrokeCountTest()
|
||||
{
|
||||
var char5E7A = UnicodeInfo.GetCharInfo(0x5E7A);
|
||||
|
||||
Assert.AreNotEqual(0, char5E7A.UnicodeRadicalStrokeCounts);
|
||||
Assert.AreEqual(false, char5E7A.UnicodeRadicalStrokeCounts[0].IsSimplified);
|
||||
Assert.AreEqual(char5E7A.UnicodeRadicalStrokeCounts[0].Radical, 52);
|
||||
Assert.AreEqual(char5E7A.UnicodeRadicalStrokeCounts[0].StrokeCount, 0);
|
||||
|
||||
var char2A6D6 = UnicodeInfo.GetCharInfo(0x2A6D6);
|
||||
|
||||
Assert.AreNotEqual(0, char2A6D6.UnicodeRadicalStrokeCounts);
|
||||
Assert.AreEqual(false, char2A6D6.UnicodeRadicalStrokeCounts[0].IsSimplified);
|
||||
Assert.AreEqual(char2A6D6.UnicodeRadicalStrokeCounts[0].Radical, 214);
|
||||
Assert.AreEqual(char2A6D6.UnicodeRadicalStrokeCounts[0].StrokeCount, 20);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RadicalInfoTest()
|
||||
{
|
||||
var radical1 = UnicodeInfo.GetCjkRadicalInfo(1);
|
||||
|
||||
Assert.AreEqual(false, radical1.HasSimplifiedForm);
|
||||
Assert.AreEqual('\u2F00', radical1.TraditionalRadicalCodePoint);
|
||||
Assert.AreEqual('\u4E00', radical1.TraditionalCharacterCodePoint);
|
||||
Assert.AreEqual('\u2F00', radical1.SimplifiedRadicalCodePoint);
|
||||
Assert.AreEqual('\u4E00', radical1.SimplifiedCharacterCodePoint);
|
||||
|
||||
var radical214 = UnicodeInfo.GetCjkRadicalInfo(214);
|
||||
|
||||
Assert.AreEqual(false, radical214.HasSimplifiedForm);
|
||||
Assert.AreEqual('\u2FD5', radical214.TraditionalRadicalCodePoint);
|
||||
Assert.AreEqual('\u9FA0', radical214.TraditionalCharacterCodePoint);
|
||||
Assert.AreEqual('\u2FD5', radical214.SimplifiedRadicalCodePoint);
|
||||
Assert.AreEqual('\u9FA0', radical214.SimplifiedCharacterCodePoint);
|
||||
|
||||
AssertEx.ThrowsExactly<IndexOutOfRangeException>(() => UnicodeInfo.GetCjkRadicalInfo(0), nameof(UnicodeInfo.GetCjkRadicalInfo));
|
||||
AssertEx.ThrowsExactly<IndexOutOfRangeException>(() => UnicodeInfo.GetCjkRadicalInfo(215), nameof(UnicodeInfo.GetCjkRadicalInfo));
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
[TestMethod]
|
||||
public void UnihanCodePointPackingTest()
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace System.Unicode
|
||||
{
|
||||
internal struct CjkRadicalData
|
||||
{
|
||||
public readonly char TraditionalRadicalCodePoint;
|
||||
public readonly char TraditionalCharacterCodePoint;
|
||||
public readonly char SimplifiedRadicalCodePoint;
|
||||
public readonly char SimplifiedCharacterCodePoint;
|
||||
|
||||
internal CjkRadicalData(char radicalCodePoint, char characterCodePoint)
|
||||
{
|
||||
TraditionalRadicalCodePoint = radicalCodePoint;
|
||||
TraditionalCharacterCodePoint = characterCodePoint;
|
||||
SimplifiedRadicalCodePoint = radicalCodePoint;
|
||||
SimplifiedCharacterCodePoint = characterCodePoint;
|
||||
}
|
||||
|
||||
internal CjkRadicalData(char traditionalRadicalCodePoint, char traditionalCharacterCodePoint, char simplifiedRadicalCodePoint, char simplifiedCharacterCodePoint)
|
||||
{
|
||||
TraditionalRadicalCodePoint = traditionalRadicalCodePoint;
|
||||
TraditionalCharacterCodePoint = traditionalCharacterCodePoint;
|
||||
SimplifiedRadicalCodePoint = simplifiedCharacterCodePoint;
|
||||
SimplifiedCharacterCodePoint = simplifiedCharacterCodePoint;
|
||||
}
|
||||
|
||||
public bool HasSimplifiedForm { get { return SimplifiedRadicalCodePoint != TraditionalRadicalCodePoint || SimplifiedCharacterCodePoint != TraditionalCharacterCodePoint; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace System.Unicode
|
||||
{
|
||||
public struct CjkRadicalInfo
|
||||
{
|
||||
private readonly byte radicalIndex;
|
||||
private readonly CjkRadicalData radicalData;
|
||||
|
||||
public byte RadicalIndex { get { return radicalIndex; } }
|
||||
|
||||
public char TraditionalRadicalCodePoint { get { return radicalData.TraditionalRadicalCodePoint; } }
|
||||
public char TraditionalCharacterCodePoint { get { return radicalData.TraditionalCharacterCodePoint; } }
|
||||
public char SimplifiedRadicalCodePoint { get { return radicalData.SimplifiedRadicalCodePoint; } }
|
||||
public char SimplifiedCharacterCodePoint { get { return radicalData.SimplifiedCharacterCodePoint; } }
|
||||
|
||||
public bool HasSimplifiedForm { get { return radicalData.HasSimplifiedForm; } }
|
||||
|
||||
internal CjkRadicalInfo(byte radicalIndex, CjkRadicalData radicalData)
|
||||
{
|
||||
this.radicalIndex = radicalIndex;
|
||||
this.radicalData = radicalData;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,17 +18,18 @@ namespace System.Unicode
|
||||
private static readonly UnicodeCharacterData[] unicodeCharacterData;
|
||||
private static readonly UnihanCharacterData[] unihanCharacterData;
|
||||
private static readonly UnicodeBlock[] blocks;
|
||||
private static readonly CjkRadicalData[] radicals;
|
||||
private static readonly int maxContiguousIndex;
|
||||
|
||||
static UnicodeInfo()
|
||||
{
|
||||
using (var stream = new DeflateStream(typeof(UnicodeInfo).GetTypeInfo().Assembly.GetManifestResourceStream("ucd.dat"), CompressionMode.Decompress, false))
|
||||
{
|
||||
ReadFromStream(stream, out unicodeVersion, out unicodeCharacterData, out unihanCharacterData, out blocks, out maxContiguousIndex);
|
||||
ReadFromStream(stream, out unicodeVersion, out unicodeCharacterData, out unihanCharacterData, out radicals, out blocks, out maxContiguousIndex);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ReadFromStream(Stream stream, out Version unicodeVersion, out UnicodeCharacterData[] unicodeCharacterData, out UnihanCharacterData[] unihanCharacterData, out UnicodeBlock[] blocks, out int maxContiguousIndex)
|
||||
internal static void ReadFromStream(Stream stream, out Version unicodeVersion, out UnicodeCharacterData[] unicodeCharacterData, out UnihanCharacterData[] unihanCharacterData, out CjkRadicalData[] radicals, out UnicodeBlock[] blocks, out int maxContiguousIndex)
|
||||
{
|
||||
using (var reader = new BinaryReader(stream, Encoding.UTF8))
|
||||
{
|
||||
@@ -73,6 +74,13 @@ namespace System.Unicode
|
||||
blockEntries[i] = ReadBlockEntry(reader);
|
||||
}
|
||||
|
||||
var cjkRadicalEntries = new CjkRadicalData[reader.ReadByte()];
|
||||
|
||||
for (i = 0; i < cjkRadicalEntries.Length; ++i)
|
||||
{
|
||||
cjkRadicalEntries[i] = ReadCjkRadicalInfo(reader);
|
||||
}
|
||||
|
||||
var unihanCharacterDataEntries = new UnihanCharacterData[ReadCodePoint(reader)];
|
||||
|
||||
for (i = 0; i < unihanCharacterDataEntries.Length; ++i)
|
||||
@@ -83,6 +91,7 @@ namespace System.Unicode
|
||||
unicodeVersion = fileUnicodeVersion;
|
||||
unicodeCharacterData = unicodeCharacterDataEntries;
|
||||
unihanCharacterData = unihanCharacterDataEntries;
|
||||
radicals = cjkRadicalEntries;
|
||||
blocks = blockEntries;
|
||||
}
|
||||
}
|
||||
@@ -227,6 +236,17 @@ namespace System.Unicode
|
||||
);
|
||||
}
|
||||
|
||||
private static CjkRadicalData ReadCjkRadicalInfo(BinaryReader reader)
|
||||
{
|
||||
char tr;
|
||||
char tc;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
private static UnicodeBlock ReadBlockEntry(BinaryReader reader)
|
||||
{
|
||||
return new UnicodeBlock(new UnicodeCharacterRange(ReadCodePoint(reader), ReadCodePoint(reader)), reader.ReadString());
|
||||
@@ -302,7 +322,7 @@ namespace System.Unicode
|
||||
int minIndex;
|
||||
int maxIndex;
|
||||
|
||||
if (unihanCharacterData.Length == 0 || codePoint < unihanCharacterData[minIndex = 0].CodePoint || codePoint > unihanCharacterData[maxIndex = unicodeCharacterData.Length - 1].CodePoint)
|
||||
if (unihanCharacterData.Length == 0 || codePoint < unihanCharacterData[minIndex = 0].CodePoint || codePoint > unihanCharacterData[maxIndex = unihanCharacterData.Length - 1].CodePoint)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -340,6 +360,10 @@ namespace System.Unicode
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>Gets the name of the Unicode block containing the character.</summary>
|
||||
/// <remarks>If the character has not been assigned to a block, the value of <see cref="DefaultBlock"/> will be returned.</remarks>
|
||||
/// <param name="codePoint">The Unicode code point whose block should be retrieved.</param>
|
||||
/// <returns>The name of the block the code point was assigned to.</returns>
|
||||
public static string GetBlockName(int codePoint)
|
||||
{
|
||||
int i = FindBlockIndex(codePoint);
|
||||
@@ -347,11 +371,43 @@ namespace System.Unicode
|
||||
return i >= 0 ? blocks[i].Name : DefaultBlock;
|
||||
}
|
||||
|
||||
/// <summary>Gets Unicode information on the specified code point.</summary>
|
||||
/// <remarks>
|
||||
/// This method will consolidate the data from a few different sources.
|
||||
/// There are more efficient way of retrieving the data for some properties if only one of those is needed at a time:
|
||||
/// <list type="bullet">
|
||||
/// <listheader>
|
||||
/// <term>Property</term>
|
||||
/// <description>Method</description>
|
||||
/// </listheader>
|
||||
/// <item>
|
||||
/// <term>Name</term>
|
||||
/// <description><see cref="GetName(int)"/></description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>Category</term>
|
||||
/// <description><see cref="GetCategory(int)"/></description>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>Block</term>
|
||||
/// <description><see cref="GetBlockName(int)"/></description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
/// <param name="codePoint">The Unicode code point for which the data must be retrieved.</param>
|
||||
/// <returns>The name of the code point, if defined; <see langword="null"/> otherwise.</returns>
|
||||
public static UnicodeCharInfo GetCharInfo(int codePoint)
|
||||
{
|
||||
return new UnicodeCharInfo(codePoint, FindUnicodeCodePoint(codePoint), FindUnihanCodePoint(codePoint), GetBlockName(codePoint));
|
||||
}
|
||||
|
||||
/// <summary>Gets the category of the specified code point.</summary>
|
||||
/// <remarks>
|
||||
/// The name referred to is the unicode General_Category property.
|
||||
/// If you only need the category of a character, calling this method is faster than calling <see cref="GetCharInfo(int)"/> and retrieving <see cref="UnicodeCharInfo.Category"/>, because there is less information to lookup.
|
||||
/// </remarks>
|
||||
/// <param name="codePoint">The Unicode code point for which the category must be retrieved.</param>
|
||||
/// <returns>The category of the code point.</returns>
|
||||
public static UnicodeCategory GetCategory(int codePoint)
|
||||
{
|
||||
var charData = FindUnicodeCodePoint(codePoint);
|
||||
@@ -359,6 +415,9 @@ namespace System.Unicode
|
||||
return charData != null ? charData.Category : UnicodeCategory.OtherNotAssigned;
|
||||
}
|
||||
|
||||
/// <summary>Gets a display text for the specified code point.</summary>
|
||||
/// <param name="charInfo">The information for the code point.</param>
|
||||
/// <returns>A display text for the code point, which may be the representation of the code point itself.</returns>
|
||||
public static string GetDisplayText(UnicodeCharInfo charInfo)
|
||||
{
|
||||
if (charInfo.CodePoint <= 0x0020) return ((char)(0x2400 + charInfo.CodePoint)).ToString();
|
||||
@@ -366,6 +425,9 @@ namespace System.Unicode
|
||||
else return char.ConvertFromUtf32(charInfo.CodePoint);
|
||||
}
|
||||
|
||||
/// <summary>Gets a display text for the specified code point.</summary>
|
||||
/// <param name="codePoint">The Unicode code point, for which a display text should be returned.</param>
|
||||
/// <returns>A display text for the code point, which may be the representation of the code point itself.</returns>
|
||||
public static string GetDisplayText(int codePoint)
|
||||
{
|
||||
if (codePoint <= 0x0020) return ((char)(0x2400 + codePoint)).ToString();
|
||||
@@ -373,6 +435,13 @@ namespace System.Unicode
|
||||
else return char.ConvertFromUtf32(codePoint);
|
||||
}
|
||||
|
||||
/// <summary>Gets the name of the specified code point.</summary>
|
||||
/// <remarks>
|
||||
/// The name referred to is the unicode Name property.
|
||||
/// If you only need the name of a character, calling this method is faster than calling <see cref="GetCharInfo(int)"/> and retrieving <see cref="UnicodeCharInfo.Name"/>, because there is less information to lookup.
|
||||
/// </remarks>
|
||||
/// <param name="codePoint">The Unicode code point for which the name must be retrieved.</param>
|
||||
/// <returns>The name of the code point, if defined; <see langword="null"/> otherwise.</returns>
|
||||
public static string GetName(int codePoint)
|
||||
{
|
||||
if (HangulInfo.IsHangul(codePoint)) return HangulInfo.GetHangulName((char)codePoint);
|
||||
@@ -387,6 +456,22 @@ namespace System.Unicode
|
||||
else return null;
|
||||
}
|
||||
|
||||
/// <summary>Returns information for a CJK radical.</summary>
|
||||
/// <param name="radicalIndex">The index of the radical. Must be between 1 and <see cref="CjkRadicalCount"/>.</param>
|
||||
/// <returns>Information on the specified radical.</returns>
|
||||
/// <exception cref="IndexOutOfRangeException">The <paramref name="radicalIndex"/> parameter is out of range.</exception>
|
||||
public static CjkRadicalInfo GetCjkRadicalInfo(int radicalIndex)
|
||||
{
|
||||
return new CjkRadicalInfo(checked((byte)radicalIndex), radicals[radicalIndex - 1]);
|
||||
}
|
||||
|
||||
/// <summary>Returns the number of CJK radicals in the Unicode data.</summary>
|
||||
/// <remarks>This value will be 214 for the foreseeable future.</remarks>
|
||||
public static int CjkRadicalCount { get { return radicals.Length; } }
|
||||
|
||||
/// <summary>Gets all the blocks defined in the Unicode data.</summary>
|
||||
/// <remarks><see cref="DefaultBlock"/> is not the name of a block, but only a value indicating the abscence of block information for a given code point.</remarks>
|
||||
/// <returns>An array containing an entry for every block defined in the Unicode data.</returns>
|
||||
public static UnicodeBlock[] GetBlocks()
|
||||
{
|
||||
return (UnicodeBlock[])blocks.Clone();
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -40,6 +42,8 @@
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DocumentationFile>
|
||||
</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
@@ -59,6 +63,8 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BidirectionalClass.cs" />
|
||||
<Compile Include="CjkRadicalData.cs" />
|
||||
<Compile Include="CjkRadicalInfo.cs" />
|
||||
<Compile Include="CompatibilityFormattingTag.cs" />
|
||||
<Compile Include="ContributoryProperties.cs" />
|
||||
<Compile Include="CanonicalCombiningClass.cs" />
|
||||
|
||||
@@ -22,13 +22,12 @@ namespace System.Unicode
|
||||
internal UnicodeRadicalStrokeCount(byte radical, byte strokeCount, bool isSimplified)
|
||||
{
|
||||
this.radical = radical;
|
||||
if (isSimplified) strokeCount |= 0x80;
|
||||
this.strokeCount = strokeCount;
|
||||
|
||||
if (isSimplified) this.strokeCount |= 0x80;
|
||||
}
|
||||
|
||||
public byte Radical { get { return radical; } }
|
||||
public byte StrokeCount { get { return strokeCount; } }
|
||||
public byte StrokeCount { get { return (byte)(strokeCount & 0x7F); } }
|
||||
public bool IsSimplified { get { return (strokeCount & 0x80) != 0; } }
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user