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

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

MDL : microsoft design language)、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 >> )
}; 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 >> )
}; 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

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

  1. C# Winform实现手机号码归属地查询工具

    摘要:本文介绍使用C#开发基于Winform的手机号码归属地查询工具,并提供详细的示例代码供参考. 一.需求描述 输入正确的手机号码,查询该号码的归属地和其他相关信息. 二.需求分析 1.实现手机号码 ...

  2. Python3实现火车票查询工具

    Python 实现火车票查询工具 一. 实验介绍 通过python3实现一个简单的命令行版本的火车票查询工具,用实际中的例子会更感兴趣,不管怎么样,既练习了又可以自己使用. 1.  知识点: Pyth ...

  3. 域名解析服务查询工具dnstracer

    域名解析服务查询工具dnstracer   在访问网站过程中,当用户输入网址后,通常是先解析域名,获取该网站的IP地址.然后,根据IP地址访问对应的网站服务器.所以,域名解析服务器保证域名指向正确的网 ...

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

    以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化. 本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 ...

  5. dig 常用的域名查询工具

    dig 命令是常用的域名查询工具,可以用来测试域名系统工作是否正常. 语法: dig (选项) (参数) 选项: @<服务器地址>: 指定进行域名解析的域名服务器: -b: 当主机具有多个 ...

  6. 第三方br查询工具害人不浅

    第三方br查询工具害人不浅,查询的时候会大批量调用百度的数据库,为什么说是大批量查询呢? 首先是自己查询,心急的站长恨不得下一次刷新br时数值会有所提高,不是那么急的也会一天查一次或几天一次,记录网站 ...

  7. 强大的数据库查询工具Database.NET 9.4.5018.42

    原文:强大的数据库查询工具Database.NET 9.4.5018.42 强大的数据库查询工具Database.NET 9.4.5018.42 两个工具的下载地址,两个软件都是绿色免安装的,直接双击 ...

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

    微信小程序最近比较热门,再加上自然语义理解也越来越被人关注,于是我想赶赶潮流,做一个小程序试试.想来想去快递查询应该是一种比较普遍的需求. 如果你也在通过自然语言接口做点什么,希望我的这篇博客能帮到你 ...

  9. Python 实现火车票查询工具

    注意:由于 12306 的接口经常变化,课程内容可能很快过期,如果遇到接口问题,需要根据最新的接口对代码进行适当修改才可以完成实验. 一.实验简介 当你想查询一下火车票信息的时候,你还在上 12306 ...

随机推荐

  1. iOS开源项目:JSONKit

    一个Json解析库,其特点是代码简单,只有一个.h和.m文件. https://github.com/johnezang/JSONKit JSON(JavaScript Object Notation ...

  2. Storm和Spark Streaming框架对比(转)

    原文链接:Storm和Spark Streaming框架对比 Storm和Spark Streaming两个都是分布式流处理的开源框架.但是这两者之间的区别还是很大的,正如你将要在下文看到的. 处理模 ...

  3. java 中 SVN 设置所有文件及子目录 needs-lock, svn 提交时自动设置 needs-lock, 及版本不一致问题

    摘自: http://my.oschina.net/zhangzhihao/blog/72177 设置后的效果:文件会自动带上svn:needs-lock属性,默认是只读的要签出才能修改以防止修改完后 ...

  4. vmware 传输(vmdb)错误-32:pipe:read failed 解决方法

    摘自: http://www.myzhenai.com.cn/post/1088.html 传输(vmdb)错误-32:pipe:read failed 解决方法   原创内容,转载请注明出处:htt ...

  5. win8.1安装开发工具 vs2015 Visual Studio 2015 Preview Downloads

    1.首先全新安装win8.1 略 破解激活.... 2.安装Visual Studio 2015 Visual Studio 2015 是免费的,不存在破解版本, 如果安装过程中存在问题,建议先把本文 ...

  6. iOS 检查app版本更新操作

    iOS 检查app版本更新操作 1:获取本地安装的版本信息: [NSString stringWithFormat:@"Version %@ (%@)", [[[NSBundle ...

  7. Python 中的几种复制文件的用法

    1. os.system Python code import os import tempfile filename1 = tempfile.mktemp (".txt") #产 ...

  8. TP框架中field查询字段

    TP框架中field查询字段 不是fields 也不是files !!!! 不是fields 也不是files !!!! 不是fields 也不是files !!!! 不是fields 也不是file ...

  9. [Exception JavaWeb 1] - javax.el.PropertyNotFoundException: Property 'id' not found on ..........

    好久不写Web应用了,今天碰到这个问题的时候,还一时半会没反应过来.实体类在jsp无法找对应的值. 最后发现是实体bean的属性的开头字母不能与次字母不能大写+小写或小写+大写,最后改成小写+小写就好 ...

  10. 错误:因为相同类型的其他实体已具有相同的主键值。在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 解决方法

    在更新一个实体类的时候可能会有预先有一次查询或者其它操作,我们这样用目的是为了与提交的数据做一个比较之类的东西,如果先查询再对此类进行SaveChanges就会出错. 我们只要用AsNoTrackin ...