UWP原生控件通过FontFamily加载网络自定义字体

今天突然做的一个第三方UWP的某些页面加载不出来了,一检查发现是爬网得到的html格式变了,本来想着只是调整下正则表达式的事情,结果仔细一看,发现它把里面的文字全部改成了Unicode编码的形式(这种),然后套了一个自定义的字体去显示,这样的话,用其他字体显示出来,就是乱码了。

这种情况以前也遇到过,不过是10个数字做成这样,当时一开始是想着做一个编码对应表,结果发现字体与编码都是随机生成的,就放弃了,后来是用WebView,把html和字体样式写进去加载。

但是用WebView的方式,用于这种大段的文字,却是不太好,性能差、体验也差,我就想能不能通过原生控件自身来加载网络字体。经过多方搜索,在一个人写的博客文章中,看到了曙光。链接:https://blog.mzikmund.com/2017/01/using-custom-fonts-in-cs-uwp-apps/

根据博客文章里面的写法,我把html里面的字体文件下载下来,放到UWP的Assets文件夹下,然后在TextBlock的Text中写入对应的html,发现可以解析。不过由于字体文件和html编码都是服务器那边随机生成的,而UWP程序在运行时是没有权限修改Assets等资源目录的,所以Assets文件夹下的字体能加载并不代表完全获得了成功。继续尝试,试了文件的绝对路径、http链接,都不行。一边继续在网上搜索,一边准备放弃了,改走WebView路线,最终,还是在MSDN上发现了办法。链接:https://docs.microsoft.com/en-us/uwp/api/Windows.UI.Xaml.Media.FontFamily?view=winrt-19041

MSDN里面写了可以用URI,我就试了一下ms-appx协议,发现可以正常加载Assets文件夹下的字体,就再尝试了一下ms-appdata协议,发现可以用来加载UWP的local、temp、roaming里面字体文件,这下就满足了我的要求了。

具体的用法及注意事项如下:

写法在C#和XAML里面都一致:

TextBlock1.FontFamily = "ms-appdata:///temp/24866d64-cfad-4bd2-838f-ea863f60d3dd.ttf#FontName";

这里面有几个注意事项:

1、字体文件的类型只支持ttf和otf,不支持woff2和eot等

2、fontName,需要用上面那个博文里面提到的dp4 Font Viewer软件去查看,对应里面的Full font name属性,而不是css里面写的那个family-name,但有时可能需要将Full font name最后的Regular删掉才行

3、这里的temp目录,对应的是Windows.Storage.ApplicationData.Current.TemporaryFolder.Path,而不是Path.GetTempPath()的那个临时文件夹,我因为搞错了这个,导致一度差点放弃继续尝试解决这个问题

4、在C#代码中对Text赋值时,需先将⭧形式的编码进行Html解码后再赋值,否则就会直接显示出&#这样的编码

5、如果URI中存在特殊字符,如空格、#等,先使用URL编码

另外,由于字体文件存在一个被占用的问题,每次最好用随机的文件名去保存,否则会引发异常,导致应用闪退。

那个博文的最后,写了UWP应该支持DirectWrite fonts,不过我看了那个Sample的代码,并没有找到什么解决方案,直接写http的链接也不行,不知道是不是真的可以。

你可能感兴趣的:(UWP,编程经验,c#,uwp)