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)示例:在代码和 xml 中表示 unicode:

 <Label Content="示例:" Grid.Row="5"/>
 <StackPanel Orientation="Horizontal" Grid.Row="5" Grid.Column="1">
     <!--将字符的 Unicode 的写在 xml 文件中时,需要使用转码格式-->
     <TextBlock FontFamily="Segoe UI Symbol" Text=""/>

     <!--在 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);
        }
    }

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

源代码下载

参考及相关阅读:

How to: Enumerate Installed Fonts

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

百度百科:Unicode

时间: 2024-10-12 14:16:04

03、矢量图形查询工具(Symbol Unicode)的相关文章

Linux命令(37):dig命令-域名查询工具

dig命令 功能说明 dig和nslookup一样,也是域名查询工具,用来测试域名系统是否正常工作.这二个命令都在bind-utils包下,dig用起来比nslookup方便.用法如下: dig [参数] [选项] 常用参数 选项 说明 @server 如果不想以/etc/resolv.conf来作为dns主机,则可以在此填入其他的IP -t(type) 指定查询类型 -x 逆向查询 +short 提供一个简短的回复,默认是长的 示例                     域名解析为IP地址

Linux命令(38):host命令-域名查询工具

host命令 功能说明 host命令是常用的域名查询工具,和nslookup.dig功能基本相同,用法如下: host [参数] [选项] 常用参数 选项 说明 -a 查询DNS详细信息相当于-v -t -c(type) 指定查询类型,默认为IN -r 禁用递归处理 -t(type) 指定查询类型 包括a.all.mx.ns  示例                     查询jd.com信息 [[email protected] ~]# host jd.com jd.com has addre

Python3实现火车票查询工具

Python 实现火车票查询工具 一. 实验介绍 通过python3实现一个简单的命令行版本的火车票查询工具,用实际中的例子会更感兴趣,不管怎么样,既练习了又可以自己使用. 1.  知识点: Python 基础知识的综合运用 docopt, requests, colorama, prettytable 库的使用 setuptools 的使用 2. 效果截图: 二. 接口设计 接口我们就按照12306官网的查询格式如下:   程序名: pickets 查询方式: 程序名 出发地 目的地 出发日

【T-SQL基础】03.子查询

本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础]02.联接查询 [T-SQL基础]03.子查询 [T-SQL基础]04.表表达式 [T-SQL基础]05.集合运算 [T-SQL基础]06.透视.逆透视.分组集 [T-SQL基础]07.数据修改 [T-SQL基础]08.事务和并发 [T-SQL基础]09.可编程对象 ----------------------------------------------------

微信小程序+OLAMI(欧拉蜜)自然语言API接口制作智能查询工具--快递、聊天、日历等

微信小程序最近比较热门,再加上自然语义理解也越来越被人关注,于是我想赶赶潮流,做一个小程序试试.想来想去快递查询应该是一种比较普遍的需求. 如果你也在通过自然语言接口做点什么,希望我的这篇博客能帮到你.我建了一个QQ群656580961,感兴趣的朋友可以加入互通有无.或者你也可以直接下载代码试一试. 用微信扫描下面的二维码可以直接测试小程序 也可以通过关注下面的公众号,点解工具使用小程序 ----------------功能介绍: 我的小程序名字叫"智能生活宝"------------

java 数据库查询工具类.

import java.util.List;import java.util.Map; /** * 数据库查询工具类. * */public class QueryTool {        /**     * Checks if is condition.     *     * @param obj the obj     * @return true, if is condition     */    public static boolean isCondition(Object ob

基于nodejs的DNS查询工具

开始这个实例之前,我们简单谈一下Node.js吧,Node.js是一个由JavaScript书写而成的强大Web开发框架,它让开发强壮的.伸缩性良好的服务器端Web应用变得更加简单.容易.这种技术诞生于09年末,在一个JavaScript大会上宣布,当时这项在服务器端运行JavaScript技术让所有参会者惊奇,当时这位提出者给出了一个“hello world”的程序. 1 var http = require('http'); 2 var server = http.createServer(

dig 常用的域名查询工具

dig 命令是常用的域名查询工具,可以用来测试域名系统工作是否正常. 语法: dig (选项) (参数) 选项: @<服务器地址>: 指定进行域名解析的域名服务器: -b: 当主机具有多个IP地址,指定使用本机的哪个IP地址向域名服务器发送域名查询请求: -f<文件名称>: 指定dig以批处理的方式运行,指定的文件中保存着需要批处理查询的DNS任务信息: -P: 指定域名服务器所使用端口号: -t<类型>: 指定要查询的DNS数据类型: -x: 执行逆向域名查询: -4

12306火车票查询工具

使用Python实现的火车票查询工具: Usage: ticket.py [-gdtzk] <from> <to> <date> Options: -h,--help 帮助信息 -a 所有 -g 高铁 -d 动车 -t 特快 -z 直达 -k 快速 Demo: ticket.py shenzhen beijing 20161001 -g 1 #!/usr/bin/env python 2 #coding:utf-8 3 import urllib2,re,json 4