偶遇需要再 WPF中加载Fnt字体,此做。。。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Helper.JilyImage; namespace Helper.JilyData
{ public class FntInfo
{ public FileInfo FntFileInfo { get; set; } /// <summary> 字体名称 </summary>
public string Name { get; set; } /// <summary> 大小为32像素 </summary>
public int Size { get; set; } /// <summary> 加粗 </summary>
public bool Bold { get; set; } /// <summary> 斜体 </summary>
public bool Italic { get; set; } /// <summary> 编码字符集,没有填写值即使用默认 </summary>
public string Charset { get; set; } /// <summary> 使用Unicode </summary>
public bool Unicode { get; set; } /// <summary> 纵向缩放百分比 </summary>
public double StretchH { get; set; } /// <summary> 开启平滑 </summary>
public bool Smooth { get; set; } /// <summary> 开启抗锯齿 </summary>
public bool Aa { get; set; } /// <summary> 内边距,文字与边框的空隙 </summary>
public FntPadding Padding { get; set; } /// <summary> 外边距,就是相临边缘的距离 </summary>
public FntPadding Spacing { get; set; } public FntCommon Common { get; set; } /// <summary> 此种字体共用到图数 </summary>
public List<FntPage> Pages { get; set; } public List<FntChar> Chars { get; set; } public List<FntKerning> Kernings { get; set; } public Rect Bounds { get; private set; } private FntInfo()
{
this.Common = new FntCommon();
this.Pages = new List<FntPage>();
this.Chars = new List<FntChar>();
this.Kernings = new List<FntKerning>();
} public FntInfo(string fntpath, Encoding encoding = null)
: this()
{
this.FntFileInfo = new FileInfo(fntpath);
if (this.FntFileInfo.Exists)
{
var fntlines = File.ReadAllLines(this.FntFileInfo.FullName, encoding ?? Encoding.Default);
foreach (var item in fntlines)
{
if (item.StartsWith("info"))
{
DecodeInfo(item);
}
else if (item.StartsWith("common"))
{
DecodeCommon(item);
}
else if (item.StartsWith("page"))
{
DecodePage(item);
}
else if (item.StartsWith("char") && !item.StartsWith("chars"))
{
DecodeChar(item);
}
else if (item.StartsWith("kerning") && !item.StartsWith("kernings"))
{
DecodeKerning(item);
}
}
}
} private void DecodeInfo(string str)
{
this.Name = GetValueAfterTittle(str, "face=\"", '"');
this.Size = int.Parse(GetValueAfterTittle(str, "size="));
this.Bold = int.Parse(GetValueAfterTittle(str, "bold=")) != ;
this.Italic = int.Parse(GetValueAfterTittle(str, "italic=")) != ;
this.Charset = GetValueAfterTittle(str, "charset=\"", '"');
this.Unicode = int.Parse(GetValueAfterTittle(str, "unicode=")) != ;
this.StretchH = int.Parse(GetValueAfterTittle(str, "stretchH="));
this.Smooth = int.Parse(GetValueAfterTittle(str, "smooth=")) != ;
this.Aa = int.Parse(GetValueAfterTittle(str, "aa=")) != ;
this.Padding = new FntPadding(GetValueAfterTittle(str, "padding="));
this.Spacing = new FntPadding(GetValueAfterTittle(str, "spacing="));
} private void DecodeCommon(string str)
{
this.Common.LineHeight = int.Parse(GetValueAfterTittle(str, "lineHeight="));
this.Common.Base = int.Parse(GetValueAfterTittle(str, "base="));
this.Common.ScaleW = int.Parse(GetValueAfterTittle(str, "scaleW="));
this.Common.ScaleH = int.Parse(GetValueAfterTittle(str, "scaleH="));
this.Common.Packed = int.Parse(GetValueAfterTittle(str, "lineHeight=")) != ;
} private void DecodePage(string str)
{
var page = new FntPage();
page.Id = int.Parse(GetValueAfterTittle(str, "id="));
page.FilePath = GetValueAfterTittle(str, "file=\"", '"');
page.RealPath = this.FntFileInfo.DirectoryName + "\\" + page.FilePath;
this.Pages.Add(page);
} private void DecodeChar(string str)
{
var fntchar = new FntChar();
fntchar.Id = int.Parse(GetValueAfterTittle(str, "id="));
fntchar.X = int.Parse(GetValueAfterTittle(str, "x="));
fntchar.Y = int.Parse(GetValueAfterTittle(str, "y="));
fntchar.Width = int.Parse(GetValueAfterTittle(str, "width="));
fntchar.Height = int.Parse(GetValueAfterTittle(str, "height="));
fntchar.Xoffset = int.Parse(GetValueAfterTittle(str, "xoffset="));
fntchar.Yoffset = int.Parse(GetValueAfterTittle(str, "yoffset="));
fntchar.Xadvance = int.Parse(GetValueAfterTittle(str, "xadvance="));
fntchar.Page = int.Parse(GetValueAfterTittle(str, "page="));
fntchar.Chnl = int.Parse(GetValueAfterTittle(str, "chnl=")); fntchar.InitData(this); this.Chars.Add(fntchar);
} private void DecodeKerning(string str)
{
var kerning = new FntKerning();
kerning.First = int.Parse(GetValueAfterTittle(str, "first="));
kerning.Second = int.Parse(GetValueAfterTittle(str, "second="));
kerning.Amount = int.Parse(GetValueAfterTittle(str, "amount="));
this.Kernings.Add(kerning);
} public ImageSource GetStrImage(string text)
{
//1 移除不在范围内的字符
List<char> chars = new List<char>();
foreach (var item in text)
{
if (this.Chars.FirstOrDefault(fc => fc.Id == (int)item) != null)
{
chars.Add(item);
}
} int viewwidth = ;
int viewheight = ;
int count = chars.Count - ;
for (int i = ; i <= count; i++)
{
char item = chars[i];
var c = this.Chars.FirstOrDefault(fc => fc.Id == (int)item);
if (c != null)
{
//设置宽高,用最大高度
viewheight = (c.Height + c.Yoffset) > viewheight ? (c.Height + c.Yoffset) : viewheight;
viewwidth += (c.Xadvance); if (i != )
{
var kerning = this.Kernings.FirstOrDefault(k => k.First == (int)item && k.Second == (int)chars[i - ]);
if (kerning != null)
{
//补齐长度,在存在偏移的时候,偏移量也计算在总长度
viewwidth += kerning.Amount;
}
}
}
} int currentxoffset = ;
var img = new Bitmap(viewwidth, viewheight);
using (var g = Graphics.FromImage(img))
{
for (int i = ; i <= count; i++)
{
char item = chars[i];
var c = this.Chars.FirstOrDefault(fc => fc.Id == (int)item);
if (c != null)
{
var xposition = currentxoffset + c.Xoffset;
int yposition = c.Yoffset; if (i != )
{
//前后两个字符进行偏移
var kerning = this.Kernings.FirstOrDefault(k => k.First == (int)item && k.Second == (int)chars[i - ]);
if (kerning != null)
{
//确定位置,和前一个相比,加上需要偏移的位置
xposition += kerning.Amount;
}
}
//当显示文字为空格 char 32 时不需要绘制
if (c.Data != null)
{
g.DrawImage(c.Data, xposition, yposition, c.Width, c.Height);
}
//叠加当前绘制过的长度
currentxoffset += (c.Xadvance);
}
}
} Bounds = new Rect(, , viewwidth, viewheight); return img.ConvertImageSource();
} private string GetValueAfterTittle(string s, string tittle, char endwith = ' ')
{
//补齐一个空格,用来判断最后的字符
var str = s + " ";
if (!string.IsNullOrWhiteSpace(str))
{
int firstindex = str.IndexOf(tittle) + tittle.Length;
int lastindex = str.IndexOf(endwith, firstindex);
if (firstindex != - && lastindex != -)
{
return new string(str.Skip(firstindex).Take(lastindex - firstindex).ToArray());
}
}
return "";
} } public class FntCommon
{
/// <summary> 行高,如果遇到换行符时,绘制字的位置坐标的Y值在换行后增加的像素值 </summary>
public int LineHeight { get; set; } /// <summary> 字的基本大小 </summary>
public int Base { get; set; } /// <summary> 图片宽 </summary>
public int ScaleW { get; set; } /// <summary>
/// 图片高
/// </summary>
public int ScaleH { get; set; } //没搞明白什么用
//alphaChnl = int.Parse(GetValueAfterTittle(str, "alphaChnl="));
//redChnl = int.Parse(GetValueAfterTittle(str, "redChnl="));
//greenChnl = int.Parse(GetValueAfterTittle(str, "greenChnl="));
//blueChnl = int.Parse(GetValueAfterTittle(str, "blueChnl=")); /// <summary> 图片压缩 </summary>
public bool Packed { get; set; } public FntCommon()
{ }
} public class FntPage
{
/// <summary> 当前页数 </summary>
public int Id { get; set; } /// <summary> 图片相对fnt文件的路径 </summary>
public string FilePath { get; set; } private string realPath;
public string RealPath
{
get { return realPath; }
set
{
realPath = value;
FntImage = BitmapHelper.GetBitmap(realPath);
}
} public Bitmap FntImage { get; private set; } } public class FntChar
{ /// <summary> 文字的 ID </summary>
public int Id { get; set; } /// <summary> 所在图片的X </summary>
public int X { get; set; }
/// <summary> 所在图片的Y </summary>
public int Y { get; set; } /// <summary> 宽 </summary>
public int Width { get; set; }
/// <summary> 高 </summary>
public int Height { get; set; } /// <summary> 像素偏移X </summary>
public int Xoffset { get; set; }
/// <summary> 像素偏移Y </summary>
public int Yoffset { get; set; } /// <summary> 绘制完后相应位置的x往后移 ... 像素再画下一个字 </summary>
public int Xadvance { get; set; } /// <summary> 所在图片页 </summary>
public int Page { get; set; } /// <summary> 未知 </summary>
public int Chnl { get; set; } public Bitmap Data { get; private set; } static int count = ;
public void InitData(FntInfo fntinfo)
{
count++;
var page = fntinfo.Pages.FirstOrDefault(i => i.Id == this.Page); if (page != null)
{
var rect = new Rectangle(this.X, this.Y, this.Width, this.Height);
if (Rectangle.Empty != rect && !(this.Width == && this.Height == ))
{
this.Data = page.FntImage.Clone(rect, page.FntImage.PixelFormat);
}
}
} public override string ToString()
{
return ((char)this.Id).ToString();
}
} public class FntKerning
{
/// <summary> 位移的前字符 </summary>
public int First { get; set; } /// <summary> 位移的后字符 </summary>
public int Second { get; set; } /// <summary> X右移位置,正为右 </summary>
public int Amount { get; set; } } public struct FntPadding
{
public int V1 { get; set; }
public int V2 { get; set; }
public int V3 { get; set; }
public int V4 { get; set; } public FntPadding(int v1, int v2, int v3, int v4)
: this()
{
this.V1 = v1;
this.V2 = v2;
this.V3 = v3;
this.V4 = v4;
} public FntPadding(string value)
: this()
{
var values = value.Split(',');
if (values.Length == )
{
this.V1 = int.Parse(values[]);
this.V2 = int.Parse(values[]);
this.V3 = int.Parse(values[]);
this.V4 = int.Parse(values[]);
}
else if (value.Length == )
{
this.V1 = int.Parse(values[]);
this.V2 = int.Parse(values[]);
this.V3 = int.Parse(values[]);
this.V4 = int.Parse(values[]);
}
}
}
}

WPF解析Fnt字体的更多相关文章

  1. WPF解析TTF 字体

    偶遇需要自己解析 TTF 字体并显示,此做... using System; using System.Collections.Generic; using System.Drawing.Text; ...

  2. cocosstdio之字体之文本和FNT字体

    FNT字体和文本字体的作用是:导入字体资源可以使用字体资源便可以使用其资源内的字体来在程序中使用 不同的是FNT字体资源内容比较少,所以个人猜想可以在特定情况下使用: 两种字体资源对比: 赋值过程对比 ...

  3. WPF设置全局字体和字体嵌入

    原文:WPF设置全局字体和字体嵌入 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/CLeopard/article/details/40590373 ...

  4. WPF使用矢量字体图标(阿里巴巴iconfont)

    原文:WPF使用矢量字体图标(阿里巴巴iconfont) 版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/lwwl12/article/details/78 ...

  5. Wpf 获取指定字体和大小的字符的长宽

    Wpf 获取指定字体和大小的字符的长宽 运行环境:Win10 x64, NetFrameWork 4.8, 作者:乌龙哈里,日期:2019-05-09 参考: 章节: 比如一个 Consolas 字体 ...

  6. 在WPF中使用字体图标

    一.源码描述    这是一款基于WPF窗体应用程序的字体图标示例源码,    该源码简单易懂使用于初学者和实战项目应用,    感兴趣的朋友们可以下载看看哦. 二.功能介绍    1.用ICO字体代替 ...

  7. WPF中应用字体图标

    一.什么是字体图标 我们在进行GDI(图形界面)编程的过程中图标是不可少的.近些年随着网络的繁荣和移动应用的繁荣,矢量图的应用越来越火. 矢量图是一种用数学方法描述的.由一系列点和线组成的图,因此相比 ...

  8. 【WPF】添加自定义字体

    需求:在WPF项目中使用幼圆字体. 步骤: 1.首先要有幼圆TTF字体文件.在C:\Windows\Fonts目录下找,如果系统字体库中没有,就上网下一份,如这里或这里. 2.将字体文件复制到WPF项 ...

  9. 为WPF程序添加字体

    很多时候我们开发的程序可能会在多个版本的Windows上运行,比如XP.Win7.Win8. 为了程序美观,现在很多公司会使用WPF作为程序的界面设计. 跨版本的操作的操作系统往往有一些字体上的问题, ...

随机推荐

  1. 【JS Note】字符串截取

    Js中字符截取常用的三个函数:slice().substring().substr(). slice(): slice(start,[end]) 第一个参数代表开始位置,第二个参数代表结束位置的下一个 ...

  2. AspxGridView ComboBoxComlum列数据联动

    第1步: 页面放置AspxGridView控件, 设置列ComboBox1, ComboBox2列, 拟通过ComboBox1列更新联动ComboBox2列. 两个数据列均为"ComboBo ...

  3. OC Protocol----协议

    类似Java的泛型与接口的结合体,用于类型的<>中,可以多继承(按照OC的说法叫遵从某些协议) 1.定义协议 @protocol Client <NSObject> -(voi ...

  4. Android文字转语音

    虽然视觉上的反馈通常是给用户提供信息最快的方式,但这要求用户把注意力设备上.当用户不能查看设备时,则需要一些其他通信的方法.Android提供了强大的文字转语音Text-to-Speech,TTS A ...

  5. 让项目管理理论“落地”——读《IT项目经理成长手记》有感

    最近利用业余时间阅读了一本好书--<IT项目经理成长手记>(潘东.韩秋泉著).本书的两位作者是神州数码(中国本土最大的整合IT服务提供商)的高管,在书中他们介绍了神州数码在IT项目管理领域 ...

  6. 十九、android中判断sim卡状态和读取联系人资料的方法

    在写程序中,有时候可能需要获取sim卡中的一些联系人资料.在获取sim卡联系人前,我们一般会先判断sim卡状态,找到sim卡后再获取它的资料,如下代码我们可以读取sim卡中的联系人的一些信息. Pho ...

  7. jQuery异步分页插件

    学校软件工程让写课程设计(其实就是自选语言做个项目),感觉都是重复的东西就没有很认真的去写内容,更加注意写一些之前没有用过的东西. 因为一直都使用TP框架来写PHP,TP又自带分页类,想到这里就想试试 ...

  8. 【学习笔记】【C语言】位运算

    1. & 按位与 1> 功能 只有对应的两个二进位均为1时,结果位才为1,否则为0. 2> 举例: 比如9&5,其实就是1001&101=1,因此9&5=1 ...

  9. UNIX 信号基本概念

    1. 信号的基本概念 为了理解信号,先从我们最熟悉的场景说起: 用户输入命令,在Shell下启动一个前台进程. 用户按下Ctrl-C,这个键盘输入产生一个硬件中断. 如果CPU当前正在执行这个进程的代 ...

  10. HashSet 读后感

    HashSet实现Set,是一个不能重复元素的集合,内部使用HashMap实现.因此具有HashMap的特性,如不保证元素插入的顺序,线程不安全,允许null.HashSet的元素就是内部HashMa ...