你的位置:首页 > ASP.net教程

[ASP.net教程]03、矢量图形查询工具(Symbol Unicode)


  

   目前的软件开发中,很多地方都使用到了矢量图标,在 Metro app 的开发中,可以使用 Windows

系统图标(02、Universal app 中按钮图标使用 ),包括 Segoe UI Symbol、Segoe MDL2 Assets(Windows10 新添加)、

Segoe UI Emoji 等。

  不过在开发中,遇到了一个问题,就是系统自带的 “字符映射表” 中很多图标太小了,又不能调整大小

,不方便浏览,于是自己动手写了一个矢量图形的 Unicode 查询工具(使用 WPF 写的),涉及到了 Unicode

转码的一些技术。

 

系统自带的 “字符映射表” :

 

1、"矢量图形查询工具" 运行效果:

  1)主窗口:

 

  2) 可以同时打开 Segoe UI Emoji  窗口:

 

Segoe UI Symbol 窗口:

 

Segoe MDL2 Assets 窗口:

 

 

2、不同编码,占用的字节关系:

  1)ASCII码:一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。

   UTF-8编码:一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。

   Unicode编码:一个英文等于两个字节,一个中文(含繁体)等于两个字节。

     符号:英文标点占一个字节,中文标点占两个字节。举例:英文句号“.”占1个字节的大小,中文句号“。”占2个字节的大小。

 

  2)示例:在代码和

 <Label Content="示例:" Grid.Row="5"/> <StackPanel Orientation="Horizontal" Grid.Row="5" Grid.Column="1">   <!--将字符的 Unicode 的写在 -->   <TextBlock FontFamily="Segoe UI Symbol" Text="&#xE189;"/>     <!--在 C# 页面中,用代码赋值-->   <TextBlock FontFamily="Segoe UI Symbol" x:Name="txtSample" Margin="30,0,0,0"/> </StackPanel>

 

   在 C# 代码中(与 C++ 表示方式相同),unicode 书写的格式为以 '\u' 开头(注意 u 为小写),后面是大于4位的 十六进制数,格式需要正确:

 txtSample.Text = "\uE189";

 

   显示效果:

 

 

   如果格式不对,不会通过编译:

 

 

 3、遍历当前 Windows系统上安装的所有字体:

  1)首页 MainWindow.xaml 中的代码:

  <Label Content="所有字体:" Grid.Row="1"/>  <ComboBox x:Name="fullFamily" Grid.Row="1" Grid.Column="1">    <ComboBox.ItemsPanel>      <ItemsPanelTemplate>        <VirtualizingStackPanel/>      </ItemsPanelTemplate>    </ComboBox.ItemsPanel>    <ComboBox.ItemTemplate>      <DataTemplate>        <TextBlock Text="{Binding}" Margin="30,5,0,0" Background="Transparent"/>      </DataTemplate>    </ComboBox.ItemTemplate>  </ComboBox>  <Label Content="打开查询窗口:" Grid.Row="3"/>  <ListBox x:Name="listBox" Grid.Row="3" Grid.Column="1">    <ListBox.ItemTemplate>      <DataTemplate>        <TextBlock Text="{Binding}" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown" Margin="30,5,0,0" Background="Transparent"/>      </DataTemplate>    </ListBox.ItemTemplate>  </ListBox>

 

   2)C# 页面代码:

private void MainWindow_Loaded(object sender, RoutedEventArgs e){  FontFamilyMapCollection ffCollection;  // 遍历当前系统上的所有字体。参考 MSDN:  // https://msdn.microsoft.com/zh-cn/library/system.windows.media.fontfamily.aspx  foreach (FontFamily fontFamily in Fonts.SystemFontFamilies)  {
// 这里把 “图标字体”显示到 ListBox 中,“所有字体” 显示到 ComboBox 中 if (fontFamily.Source == "Segoe UI Symbol" || fontFamily.Source == "Segoe MDL2 Assets" || fontFamily.Source == "Segoe UI Emoji") { ffCollection = fontFamily.FamilyMaps; listBox.Items.Add(fontFamily.Source); } fullFamily.Items.Add(fontFamily.Source); }}// 选中相应 “图标字体” 后,跳转到 “查看窗口”private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){ string fontName = (sender as TextBlock).Text; SymbolWindow sw = new SymbolWindow(); // 使用静态属性,作为参数传递 SymbolWindow.CurrentFontFamily = new FontFamily(fontName); // 选中的字体 sw.Show();}

 

 4、浏览窗口:

  1)SymbolWindow.xaml 文件 ,窗口的 x:Name 设置为 myWindow :

<ListView x:Name="listBox" ItemTemplate="{StaticResource template}">  <ListView.ItemsPanel>    <ItemsPanelTemplate>      <!--Items 面板的宽度与窗口宽度绑定,根据窗口改变排列。防止显示为单行-->      <WrapPanel Orientation="Horizontal" Width="{Binding ActualWidth,ElementName=myWindow}"/>    </ItemsPanelTemplate>  </ListView.ItemsPanel></ListView>

 

   2)在  this.Loaded 事件中,调用 FontItem.EnumeratorFontFamily(CurrentFontFamily) 静态方法,把相关字体中

    包含的所有 Unicode 编码转换为相应的 字符:

 /// <summary> /// 作为从 MainWindow.xaml 传递来的参数 /// </summary> public static FontFamily CurrentFontFamily; private void Segoe_UI_Symbol_Loaded(object sender, RoutedEventArgs e) {   // FontFamily ff = new FontFamily("Segoe MDL2 Assets");   if (CurrentFontFamily != null)   {     this.FontFamily = CurrentFontFamily;     this.Title = " 当前字体 : " + CurrentFontFamily.Source;     listBox.ItemsSource = FontItem.EnumeratorFontFamily(CurrentFontFamily);   } }

 

 

 5、FontItem 类定义,用来显示绑定和 Unicode 的转码:

  1)把十六进制 unicode 转换为 byte 数组,再调用 Encoding.Unicode.GetChars(array); 方法,转换为

相应字符:

 // Unicode 转换为 “符号” 字符表示 // 例如,0xE189 转换为 byte[]{ 137, 225 } byte[] bytes = new byte[] {  (byte) Key,  (byte) (Key >> 8) }; string Character = ByteToString(bytes);

 

 // 把二进制数转换成字符 public static string ByteToString(byte[] array) {   var enc = Encoding.Unicode;   var chars = enc.GetChars(array);   return new string(chars); }

   

   FontItem.cs 文件 全部代码:

 class FontItem  {    public string key { set; get; }    public string value { get; set; }    public string font { set; get; }        public static List<FontItem> EnumeratorFontFamily(FontFamily family)    {      Dictionary<int, FontItem> fonts = new Dictionary<int, FontItem>();      var typefaces = family.GetTypefaces();      foreach (Typeface typeface in typefaces)      {        // 对应字体文件中包含的物理字体        GlyphTypeface glyph;        typeface.TryGetGlyphTypeface(out glyph);        // 根据字体“CMAP”表的定义获取 Unicode 码位与标志符号索引之间的名义映射。         IDictionary<int, ushort> characterMap = glyph.CharacterToGlyphMap;        foreach (KeyValuePair<int, ushort> kvp in characterMap)        {          // Console.WriteLine(String.Format("{0}:{1}", kvp.Key, kvp.Value));          int Key = kvp.Key; // 没有用到 kvp.Value          // 如果大于 0xffff(为空字符,显示为小方框),则跳出循环          if (Key > 0xffff) // 0 ~ 65535          {            break;          }                    // 方法 1: Unicode 转换为 “符号” 字符表示          // 例如,0xE189 转换为 byte[]{ 137, 225 }          byte[] bytes = new byte[]           {            (byte) Key,            (byte) (Key >> 8)           };                    string Character = ByteToString(bytes);          // 方法 2:Unicode 转换为 “符号” 字符          //    可以用来转换 Key= 65535 以下的 Unicode,如果大于 65535,则会抛出:          //    “ System.OverflowException:值对于字符太大或太小” 的异常          // char c = Convert.ToChar(Key);          // string Character = c.ToString();          // 过滤掉空字符          if (!string.IsNullOrEmpty(Character) &&            !string.IsNullOrWhiteSpace(Character) &&            !fonts.Keys.Contains(Key)// 去掉重复的            )          {            fonts.Add(Key, new FontItem { key = Key.ToString("X4"), font = Character });          }        }      }      return fonts.Values.ToList();    }        // 把二进制数转换成字符    public static string ByteToString(byte[] array)    {      var enc = Encoding.Unicode;      var chars = enc.GetChars(array);      return new string(chars);    }  }

View Code

 

 

工具直接下载 (基于 .net framework 4.5)

源代码下载

 

 

 

参考及相关阅读:

How to: Enumerate Installed Fonts

字体文件中包含的字符判断

百度百科:Unicode