当前位置: 代码迷 >> 综合 >> 打印系统开发(63)——C# 实现虚拟打印机 HP Color LaserJet 4500 (2) True Type Font字体显示
  详细解决方案

打印系统开发(63)——C# 实现虚拟打印机 HP Color LaserJet 4500 (2) True Type Font字体显示

热度:35   发布时间:2023-10-01 12:58:59.0

本来打算酸所有的PCL HPGL/2的都贴出来.后来发现这里重要的字体显示 TTF的数据显示就2000多行 10来个类了.所以把这个独立出来.另外我增加了一些字符对应和轮廓显示的方法.有兴趣的朋友可以单独去使用.

效果图

打印系统开发(63)——C# 实现虚拟打印机 HP Color LaserJet 4500 (2) True Type Font字体显示

使用代码

    private Zgke.MyImage.ImageFile.ImageTTF m_TTF = new ImageTTF(@"C:/Windows/Fonts/FZYTK.TTF");private void Form2_Load(object sender, EventArgs e){m_TTF.FillDraw = false;m_TTF.Brush = Brushes.Red;}private void button1_Click(object sender, EventArgs e){if (textBox1.Text.Length > 0) pictureBox1.Image = m_TTF[textBox1.Text[0]];}

下面是我们在虚拟打印机里使用的方法 以后贴PCL HPGL时候不会在贴这个类.只要是ImageTTF的就是这个了.

        /// <summary>///暴露一个方法这个方法用来在PCL文件显示里使用      /// </summary>public void LoadImage(){//字符数据string _TextFontBytes = "000200010000007F00C0001B001F0000373727373737273737373707373737073707270737072707273727073737372708151C051B0A1C041C150E1416140E141D051C0A1D041E140E14161419160A170041000F0020000F0041004100410041000F0020000F00410041004150002000";byte[] _Bytes = new byte[_TextFontBytes.Length / 2];for (int i = 0; i != _Bytes.Length; i++){_Bytes[i] = Convert.ToByte(_TextFontBytes.Substring(i * 2, 2), 16);}//方法pictureBox1.Image = m_TTF.GetImageOfBytes(_Bytes);}

下面是全部代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Imaging;
using System.Drawing;namespace Zgke.MyImage.ImageFile
{/// <summary>/// True Type Format 文件获取结构/// qq:116149/// zgke@sina.com/// </summary>public class ImageTTF{/// <summary>/// 文件信息 /// </summary>private byte[] m_FileBytes = null;/// <summary>/// 表格数量/// </summary>private ushort m_NumTables = 0;/// <summary>/// 描述表的大小/// </summary>private ushort m_SearchRange = 0;/// <summary>/// 未知/// </summary>private ushort m_EntrySelector = 0;/// <summary>/// 未知/// </summary>private ushort m_RangeShift = 0;/// <summary>/// 显示的大小/// </summary>private float m_Zoom = 1f;/// <summary>/// 前景色/// </summary>private Brush m_Brush = new SolidBrush(Color.Black);#region 子表结构private TableDSIG Table_DSIG = null;private TableOS2 Table_OS2 = null;private TableVDMX Table_VDMX = null;private TableCMAP Table_CMAP = null;private TableCVT Table_CVT = null;private TableFPGM Table_FPGM = null;private TableGASP Table_GASP = null;private TableGLYF Table_GLYF = null;private TableHEAD Table_HEAD = null;private TableHHEA Table_HHEA = null;private TableHMTX Table_HMTX = null;private TableLOCA Table_LOCA = null;private TableMAXP Table_MAXP = null;private TableNAME Table_NAME = null;private TablePOST Table_Post = null;private TablePREP Table_PREP = null;private TableLTSH Table_LTSH = null;private TableHDMX Table_HDMX = null;private TableGSUB Table_GSUB = null;private TableVHEA Table_VHEA = null;private TableVMTX Table_VMTX = null;#endregionpublic ImageTTF(string p_FileName){m_FileBytes = System.IO.File.ReadAllBytes(p_FileName);LoadTTF();}public ImageTTF(byte[] p_FileBytes){m_FileBytes = p_FileBytes;LoadTTF();}       #region 属性/// <summary>/// 根据CHAR类型获取图形/// </summary>/// <param name="p_Char"></param>/// <returns></returns>public Image this[char p_Char]{get{int _LocaIndex = Table_CMAP.CharToLocaIndex(p_Char, Table_HEAD);if (_LocaIndex == -1) _LocaIndex = 0;int _GlyfIndex = Table_LOCA.GetAddressOfIndex(_LocaIndex);if (_GlyfIndex == -1) return null;Image _Image = Table_GLYF.LoadImage(_GlyfIndex, m_Zoom, m_Brush);((int[])_Image.Tag)[4] = Table_HMTX.GetAdvanceWidthOfIndex(_LocaIndex);return _Image;}}/// <summary>/// 根据USHORT类型获取图形/// </summary>/// <param name="p_Char"></param>/// <returns></returns>public Image this[ushort p_Short]{get{return this[(char)p_Short];}}/// <summary>/// 问题字符获取图形。。(回异常的)/// </summary>/// <param name="p_Bytes"></param>/// <returns></returns>public Image GetImageOfBytes(byte[] p_Bytes){return Table_GLYF.LoadImage(p_Bytes, m_Zoom, m_Brush);}/// <summary>/// 返回字符基本宽/// </summary>/// <param name="p_Char"></param>/// <returns></returns>public int GetAdvanceWidthOfChar(char p_Char){int _LocaIndex = Table_CMAP.CharToLocaIndex(p_Char, Table_HEAD);if (_LocaIndex == -1) _LocaIndex = 0;return Table_HMTX.GetAdvanceWidthOfIndex(_LocaIndex); }/// <summary>/// 返回字符基本宽/// </summary>/// <param name="p_Char"></param>/// <returns></returns>public int GetAdvanceWidthOfGrlyID(ushort p_GrlyID){return Table_HMTX.GetAdvanceWidthOfIndex(p_GrlyID);}/// <summary>/// 显示的大小/// </summary>public float ImageZoom { get { return m_Zoom; } set { m_Zoom = value; } }/// <summary>/// 是否填充绘制/// </summary>public bool FillDraw { get { return Table_GLYF.FillDraw; } set { Table_GLYF.FillDraw = value; } }/// <summary>/// 设置纹理色/// </summary>public Brush Brush { get { return m_Brush; } set { m_Brush = value; } }#endregion/// <summary>/// 开始获取数据/// </summary>private void LoadTTF(){LoadData();}/// <summary>/// 获取数据表/// </summary>private void LoadData(){m_NumTables = (ushort)(m_FileBytes[4] << 8 | m_FileBytes[5]);m_SearchRange = (ushort)(m_FileBytes[6] << 8 | m_FileBytes[7]);m_EntrySelector = (ushort)(m_FileBytes[8] << 8 | m_FileBytes[9]);m_RangeShift = (ushort)(m_FileBytes[10] << 8 | m_FileBytes[11]);int _ReadIndex = 12;string _TableName = "";uint _CheckSum = 0;uint _Offset = 0;uint _Length = 0;for (int i = 0; i != m_NumTables; i++){_TableName = Encoding.ASCII.GetString(m_FileBytes, _ReadIndex, 4);_ReadIndex += 4;_CheckSum = (uint)(m_FileBytes[_ReadIndex] << 32 | m_FileBytes[_ReadIndex + 1] << 16 | m_FileBytes[_ReadIndex + 2] << 8 | m_FileBytes[_ReadIndex + 3]);_ReadIndex += 4;_Offset = (uint)(m_FileBytes[_ReadIndex] << 32 | m_FileBytes[_ReadIndex + 1] << 16 | m_FileBytes[_ReadIndex + 2] << 8 | m_FileBytes[_ReadIndex + 3]);_ReadIndex += 4;_Length = (uint)(m_FileBytes[_ReadIndex] << 32 | m_FileBytes[_ReadIndex + 1] << 16 | m_FileBytes[_ReadIndex + 2] << 8 | m_FileBytes[_ReadIndex + 3]);_ReadIndex += 4;byte[] _DataValue = new byte[_Length];Array.Copy(m_FileBytes, _Offset, _DataValue, 0, _DataValue.Length);switch (_TableName){case "DSIG":Table_DSIG = new TableDSIG(_DataValue, _CheckSum, _Offset);break;case "OS/2":Table_OS2 = new TableOS2(_DataValue, _CheckSum, _Offset);break;case "VDMX":Table_VDMX = new TableVDMX(_DataValue, _CheckSum, _Offset);break;case "cmap":Table_CMAP = new TableCMAP(_DataValue, _CheckSum, _Offset);break;case "cvt ":Table_CVT = new TableCVT(_DataValue, _CheckSum, _Offset);break;case "fpgm":Table_FPGM = new TableFPGM(_DataValue, _CheckSum, _Offset);break;case "gasp":Table_GASP = new TableGASP(_DataValue, _CheckSum, _Offset);break;case "glyf":Table_GLYF = new TableGLYF(_DataValue, _CheckSum, _Offset);break;case "head":Table_HEAD = new TableHEAD(_DataValue, _CheckSum, _Offset);break;case "hhea":Table_HHEA = new TableHHEA(_DataValue, _CheckSum, _Offset);break;case "hmtx":Table_HMTX = new TableHMTX(_DataValue, _CheckSum, _Offset);break;case "loca":Table_LOCA = new TableLOCA(_DataValue, _CheckSum, _Offset);break;case "maxp":Table_MAXP = new TableMAXP(_DataValue, _CheckSum, _Offset);break;case "name":Table_NAME = new TableNAME(_DataValue, _CheckSum, _Offset);break;case "post":Table_Post = new TablePOST(_DataValue, _CheckSum, _Offset);break;case "prep":Table_PREP = new TablePREP(_DataValue, _CheckSum, _Offset);break;case "LTSH":Table_LTSH = new TableLTSH(_DataValue, _CheckSum, _Offset);break;case "hdmx":Table_HDMX = new TableHDMX(_DataValue, _CheckSum, _Offset);break;case "GSUB":Table_GSUB = new TableGSUB(_DataValue, _CheckSum, _Offset);break;case "vhea":Table_VHEA = new TableVHEA(_DataValue, _CheckSum, _Offset);break;case "vmtx":Table_VMTX = new TableVMTX(_DataValue, _CheckSum, _Offset);break;case "gdir":break;default:break;//throw new Exception("未实现[" + _TableName + "]");}}if (Table_LOCA != null){Table_LOCA.GetAddress(Table_HEAD, Table_MAXP);Table_GLYF.m_Address = Table_LOCA.m_Address;}if (Table_GLYF == null) Table_GLYF = new TableGLYF(new byte[0], 0, 0);}#region 类/// <summary>/// 基类/// </summary>private class TableBase{/// <summary>/// 表名称/// </summary>protected string m_Tag = "";/// <summary>/// 验效/// </summary>protected uint m_CheckSum = 0;/// <summary>/// 开始位置/// </summary>protected uint m_Offset = 0;/// <summary>/// 长度/// </summary>protected uint m_Length = 0;/// <summary>/// 基本数据/// </summary>protected byte[] m_DataBytes = null;}/// <summary>/// 数字签名表/// </summary>private class TableDSIG : TableBase{public TableDSIG(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "DSIG";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}}/// <summary>/// OS/2系统用的度量/// </summary>private class TableOS2 : TableBase{public TableOS2(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "OS/2";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}/// <summary>/// 版本号 为0x0001/// </summary>public ushort Version { get { return (ushort)(m_DataBytes[0] << 8 | m_DataBytes[1]); } }/// <summary>/// 平均字符宽度/// </summary>public ushort AvgCharWidth { get { return (ushort)(m_DataBytes[2] << 8 | m_DataBytes[3]); } }/// <summary>/// 指示重量 加粗/// </summary>public ushort WeightClass { get { return (ushort)(m_DataBytes[4] << 8 | m_DataBytes[5]); } }/// <summary>/// 指示从正常的宽高比/// </summary>public ushort WidthClass { get { return (ushort)(m_DataBytes[6] << 8 | m_DataBytes[7]); } }/// <summary>/// 显示字体嵌入字体的许可权  0x8 可编辑嵌入  0x4 预览及打印嵌入  02 不是嵌入字体/// </summary>public short Type { get { return (short)(m_DataBytes[8] << 8 | m_DataBytes[9]); } }/// <summary>/// X计算单位/// </summary>public short SubscriptXSize { get { return (short)(m_DataBytes[10] << 8 | m_DataBytes[11]); } }/// <summary>/// Y计算单位/// </summary>public short SubscriptYSize { get { return (short)(m_DataBytes[12] << 8 | m_DataBytes[13]); } }/// <summary>/// X水平偏移/// </summary>public short SubscriptXOffset { get { return (short)(m_DataBytes[14] << 8 | m_DataBytes[15]); } }/// <summary>/// Y水平偏移/// </summary>public short SubscriptYOffset { get { return (short)(m_DataBytes[16] << 8 | m_DataBytes[17]); } }/// <summary>/// X计算单位/// </summary>public short SuperscriptXSize { get { return (short)(m_DataBytes[18] << 8 | m_DataBytes[19]); } }/// <summary>/// Y计算单位/// </summary>public short SuperscriptYSize { get { return (short)(m_DataBytes[20] << 8 | m_DataBytes[21]); } }/// <summary>/// X水平偏移/// </summary>public short SuperscriptXOffset { get { return (short)(m_DataBytes[22] << 8 | m_DataBytes[23]); } }/// <summary>/// Y水平偏移/// </summary>public short SuperscriptYOffset { get { return (short)(m_DataBytes[24] << 8 | m_DataBytes[25]); } }/// <summary>/// 宽度这重量/// </summary>public short StrikeoutSize { get { return (short)(m_DataBytes[26] << 8 | m_DataBytes[27]); } }/// <summary>/// 重量位置/// </summary>public short StrikeoutPosition { get { return (short)(m_DataBytes[28] << 8 | m_DataBytes[29]); } }/// <summary>/// 字体样式/// </summary>public short FamilyClass { get { return (short)(m_DataBytes[30] << 8 | m_DataBytes[31]); } }/// <summary>///  0= Any 1 = No Fit 2= Text and Display 3= Script  4= Decorative  5= Pictorial/// </summary>public byte PanoseFamilyType { get { return m_DataBytes[32]; } }/// <summary>/// /// </summary>public byte PanoseSerifStyle { get { return m_DataBytes[33]; } }/// <summary>/// /// </summary>public byte PanoseWeight { get { return m_DataBytes[34]; } }/// <summary>/// /// </summary>public byte PanoseProportion { get { return m_DataBytes[35]; } }/// <summary>/// /// </summary>public byte PanoseContrast { get { return m_DataBytes[36]; } }/// <summary>/// /// </summary>public byte PanoseStrokeVariation { get { return m_DataBytes[37]; } }/// <summary>/// /// </summary>public byte PanoseArmStyle { get { return m_DataBytes[38]; } }/// <summary>/// /// </summary>public byte PanoseLetterform { get { return m_DataBytes[39]; } }/// <summary>/// /// </summary>public byte PanoseMidline { get { return m_DataBytes[40]; } }/// <summary>/// /// </summary>public byte PanoseXHeight { get { return m_DataBytes[41]; } }/// <summary>/// 字符范围1/// </summary>public uint UnicodeRange1 { get { return (uint)(m_DataBytes[42] << 24 | m_DataBytes[43] << 16 | m_DataBytes[44] << 8 | m_DataBytes[45]); } }/// <summary>/// 字符范围2/// </summary>public uint UnicodeRange2 { get { return (uint)(m_DataBytes[46] << 24 | m_DataBytes[47] << 16 | m_DataBytes[48] << 8 | m_DataBytes[49]); } }/// <summary>/// 字符范围3/// </summary>public uint UnicodeRange3 { get { return (uint)(m_DataBytes[50] << 24 | m_DataBytes[51] << 16 | m_DataBytes[52] << 8 | m_DataBytes[53]); } }/// <summary>/// 字符范围4/// </summary>public uint UnicodeRange4 { get { return (uint)(m_DataBytes[54] << 24 | m_DataBytes[55] << 16 | m_DataBytes[56] << 8 | m_DataBytes[57]); } }/// <summary>/// 标识符/// </summary>public string VendID { get { return Encoding.ASCII.GetString(m_DataBytes, 58, 4); } }/// <summary>/// 字体形态的性质/// </summary>public ushort Selection { get { return (ushort)(m_DataBytes[62] << 8 | m_DataBytes[63]); } }/// <summary>/// 最低的Unicode/// </summary>public ushort FirstCharIndex { get { return (ushort)(m_DataBytes[64] << 8 | m_DataBytes[65]); } }/// <summary>/// 最高的Unicode/// </summary>public ushort LastCharIndex { get { return (ushort)(m_DataBytes[66] << 8 | m_DataBytes[67]); } }/// <summary>/// 苹果公司/// </summary>public ushort TypoAscender { get { return (ushort)(m_DataBytes[68] << 8 | m_DataBytes[69]); } }/// <summary>/// 苹果公司/// </summary>public ushort TypoDescender { get { return (ushort)(m_DataBytes[70] << 8 | m_DataBytes[71]); } }/// <summary>/// 苹果公司/// </summary>public ushort TypoLineGap { get { return (ushort)(m_DataBytes[72] << 8 | m_DataBytes[73]); } }/// <summary>/// 苹果公司/// </summary>public ushort WinAscent { get { return (ushort)(m_DataBytes[74] << 8 | m_DataBytes[75]); } }/// <summary>/// 苹果公司/// </summary>public ushort WinDescent { get { return (ushort)(m_DataBytes[76] << 8 | m_DataBytes[77]); } }/// <summary>/// 代码页的字符范围/// </summary>public uint CodePageRange1 { get { return (uint)(m_DataBytes[78] << 24 | m_DataBytes[79] << 16 | m_DataBytes[80] << 8 | m_DataBytes[81]); } }/// <summary>/// 代码页的字符范围/// </summary>public uint CodePageRange2 { get { return (uint)(m_DataBytes[82] << 24 | m_DataBytes[83] << 16 | m_DataBytes[84] << 8 | m_DataBytes[85]); } }}/// <summary>/// 设备垂直度量/// </summary>private class TableVDMX : TableBase{public TableVDMX(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "VDMX";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}}/// <summary>/// 代码映射表/// </summary>private class TableCMAP : TableBase{public TableCMAP(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "cmap";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;LoadCMAP();}/// <summary>/// 代码影射表/// </summary>private IList<CmapFollowed> m_CmapFollowed = new List<CmapFollowed>();/// <summary>/// 获取CMAP数据基本信息/// </summary>public void LoadCMAP(){for (int i = 0; i != Number; i++){m_CmapFollowed.Add(new CmapFollowed(m_DataBytes, (uint)((i * 8) + 4)));}}/// <summary>/// 版本号 为0x0001/// </summary>public ushort Version { get { return (ushort)(m_DataBytes[0] << 8 | m_DataBytes[1]); } }/// <summary>/// 字表个数/// </summary>public ushort Number { get { return (ushort)(m_DataBytes[2] << 8 | m_DataBytes[3]); } }/// <summary>/// 根据字符获取所在位置的索引/// </summary>/// <param name="p_Char"></param>/// <returns></returns>public int CharToLocaIndex(char p_Char, TableHEAD p_Head){for (int i = 0; i != m_CmapFollowed.Count; i++){  ushort _Value = (ushort)p_Char;if (m_CmapFollowed[i].Platform == 3){switch (m_CmapFollowed[i].EncodingID){case 0:_Value |= 0xF000;break;   case 1:break;default:throw new Exception("未实现编码方式[CMAP]");}int _LocaIndex = m_CmapFollowed[i].GetLocaIndex(_Value, p_Head, (ushort)p_Char);if (_LocaIndex != -1) return _LocaIndex;}}return -1;}/// <summary>///  子表类/// </summary>private class CmapFollowed{/// <summary>/// 平台代码/// </summary>private ushort m_Platform = 0;/// <summary>/// 译码体系代码/// </summary>private ushort m_EncodingID = 0;/// <summary>/// 此子表位置偏移(从 cmap 表头开始)/// </summary>private uint m_TableOffset = 0;/// <summary>/// 格式信息/// </summary>private FormatBase m_Format = null;public CmapFollowed(byte[] p_DataBytes, uint p_Index){uint _ReadIndex = p_Index;m_Platform = (ushort)(p_DataBytes[_ReadIndex] << 8 | p_DataBytes[_ReadIndex + 1]);_ReadIndex += 2;m_EncodingID = (ushort)(p_DataBytes[_ReadIndex] << 8 | p_DataBytes[_ReadIndex + 1]);_ReadIndex += 2;m_TableOffset = (uint)(p_DataBytes[_ReadIndex] << 24 | p_DataBytes[_ReadIndex + 1] << 16 | p_DataBytes[_ReadIndex + 2] << 8 | p_DataBytes[_ReadIndex + 3]);_ReadIndex = m_TableOffset;m_Format = GetFormat(p_DataBytes, _ReadIndex);}/// <summary>/// 根据char代用 FormatBase获取Loca用的index/// </summary>/// <param name="p_Char"></param>/// <returns></returns>public int GetLocaIndex(ushort p_Char, TableHEAD p_Head, ushort p_CharValue){return m_Format.GetLocaIndex(p_Char, p_Head, p_CharValue);}/// <summary>/// 根据FORMAT获取对应的结构/// </summary>/// <param name="p_DataBytes"></param>/// <param name="p_Index"></param>/// <returns></returns>private FormatBase GetFormat(byte[] p_DataBytes, uint p_Index){switch ((ushort)(p_DataBytes[p_Index] << 8 | p_DataBytes[p_Index + 1])){case 0:return new Format0(p_DataBytes, p_Index);case 4:return new Format4(p_DataBytes, p_Index);default:throw new Exception("CMAP表里的Format[" + p_DataBytes[p_Index + 1].ToString() + "]未定义");}}/// <summary>/// 编码格式/// </summary>public ushort Platform { get { return m_Platform; } }/// <summary>/// 编码格式/// </summary>public ushort EncodingID { get { return m_EncodingID; } }private class FormatBase{/// <summary>/// 格式/// </summary>protected ushort m_FormatType = 0;/// <summary>/// 长度/// </summary>protected ushort m_Length = 0;/// <summary>/// 版本/// </summary>protected ushort m_Version = 0;public virtual int GetLocaIndex(ushort p_Char, TableHEAD p_Head, ushort p_CharValue){return -1;}}/// <summary>/// 数据结构0/// </summary>private class Format0 : FormatBase{public Format0(byte[] p_DataBytes, uint p_ReadIndex){uint _ReadIndex = p_ReadIndex;m_FormatType = (ushort)(p_DataBytes[_ReadIndex] << 8 | p_DataBytes[_ReadIndex + 1]);_ReadIndex += 2;m_Length = (ushort)(p_DataBytes[_ReadIndex] << 8 | p_DataBytes[_ReadIndex + 1]);_ReadIndex += 2;m_Version = (ushort)(p_DataBytes[_ReadIndex] << 8 | p_DataBytes[_ReadIndex + 1]);_ReadIndex += 2;m_Bytes = new byte[m_Length - 6];for (int i = 0; i != m_Bytes.Length; i++){m_Bytes[i] = p_DataBytes[_ReadIndex];_ReadIndex++;}}/// <summary>/// 根据字符查询位置索引/// </summary>/// <param name="p_Char"></param>/// <returns></returns>public override int GetLocaIndex(ushort p_Char, TableHEAD p_Head, ushort p_CharValue){if ((ushort)p_Char > 255) return -1;return (int)m_Bytes[(int)p_Char];}private byte[] m_Bytes = null;}/// <summary>/// 数据结构4/// </summary>private class Format4 : FormatBase{/// <summary>/// 分段数目/// </summary>private ushort m_SegCountX2 = 0;/// <summary>/// 快速查找范围/// </summary>private ushort m_SearchRange = 0;/// <summary>/// 人口值范围/// </summary>private ushort m_EntrySelector = 0;/// <summary>/// 偏移谓整/// </summary>private ushort m_RangeShift = 0;/// <summary>/// /// </summary>private ushort[] m_EndCount = new ushort[0];/// <summary>/// /// </summary>private ushort m_ReservedPad = 0;/// <summary>/// /// </summary>private ushort[] m_StartCount = new ushort[0];/// <summary>/// 每段的调整量/// </summary>private ushort[] m_IdDelta = new ushort[0];/// <summary>/// 对应到子表的字节偏移量/// </summary>private ushort[] m_IdRangeOffset = new ushort[0];/// <summary>/// 变长的文字序号数组/// </summary>private ushort[] m_GlyphIdArray = new ushort[0];/// <summary>/// 读取到位置/// </summary>private uint m_ReadIndex = 0;/// <summary>/// m_GlyphidArray开始位置/// </summary>private uint m_GlyphidArrayStart = 0;/// <summary>/// m_IdRangeOffset对应的位置/// </summary>private uint[] m_IdRangeOffsetIndex = new uint[0];public Format4(byte[] p_DataBytes, uint p_ReadIndex){m_ReadIndex = p_ReadIndex;m_FormatType = (ushort)(p_DataBytes[m_ReadIndex] << 8 | p_DataBytes[m_ReadIndex + 1]);m_ReadIndex += 2;m_Length = (ushort)(p_DataBytes[m_ReadIndex] << 8 | p_DataBytes[m_ReadIndex + 1]);m_ReadIndex += 2;m_Version = (ushort)(p_DataBytes[m_ReadIndex] << 8 | p_DataBytes[m_ReadIndex + 1]);m_ReadIndex += 2;m_SegCountX2 = (ushort)(p_DataBytes[m_ReadIndex] << 8 | p_DataBytes[m_ReadIndex + 1]);m_ReadIndex += 2;m_SearchRange = (ushort)(p_DataBytes[m_ReadIndex] << 8 | p_DataBytes[m_ReadIndex + 1]);m_ReadIndex += 2;m_EntrySelector = (ushort)(p_DataBytes[m_ReadIndex] << 8 | p_DataBytes[m_ReadIndex + 1]);m_ReadIndex += 2;m_RangeShift = (ushort)(p_DataBytes[m_ReadIndex] << 8 | p_DataBytes[m_ReadIndex + 1]);m_ReadIndex += 2;int _CountUshort = m_SegCountX2 / 2;m_EndCount = new ushort[_CountUshort];m_ReservedPad = (ushort)(p_DataBytes[m_ReadIndex + m_SegCountX2] << 8 | p_DataBytes[m_ReadIndex + m_SegCountX2 + 1]);m_StartCount = new ushort[_CountUshort];m_IdDelta = new ushort[_CountUshort];m_IdRangeOffset = new ushort[_CountUshort];m_IdRangeOffsetIndex = new uint[_CountUshort];for (int i = 0; i != m_SegCountX2 / 2; i++){m_EndCount[i] = (ushort)(p_DataBytes[m_ReadIndex] << 8 | p_DataBytes[m_ReadIndex + 1]);m_StartCount[i] = (ushort)(p_DataBytes[m_ReadIndex + m_SegCountX2 + 2] << 8 | p_DataBytes[m_ReadIndex + m_SegCountX2 + 3]);m_IdDelta[i] = (ushort)(p_DataBytes[m_ReadIndex + (m_SegCountX2 * 2) + 2] << 8 | p_DataBytes[m_ReadIndex + (m_SegCountX2 * 2) + 3]);m_IdRangeOffset[i] = (ushort)(p_DataBytes[m_ReadIndex + (m_SegCountX2 * 3) + 2] << 8 | p_DataBytes[m_ReadIndex + (m_SegCountX2 * 3) + 3]);m_IdRangeOffsetIndex[i] = (uint)(m_ReadIndex + (m_SegCountX2 * 3)) + 2;m_ReadIndex += 2;}m_ReadIndex += (uint)m_SegCountX2 * 3 + 2;m_GlyphidArrayStart = m_ReadIndex;int _GlyphIdCount = (int)(p_DataBytes.Length - m_ReadIndex) / 2;m_GlyphIdArray = new ushort[_GlyphIdCount];for (int i = 0; i != m_GlyphIdArray.Length; i++){m_GlyphIdArray[i] = (ushort)(p_DataBytes[m_ReadIndex] << 8 | p_DataBytes[m_ReadIndex + 1]);m_ReadIndex += 2;}}/// <summary>/// 根据字符查询位置索引/// </summary>/// <param name="p_Char"></param>/// <returns></returns>public override int GetLocaIndex(ushort p_Char, TableHEAD p_Head, ushort p_CharValue){for (int i = 0; i < m_SegCountX2 / 2; i++)//确定char_code所在的段{if (p_Char <= m_EndCount[i] && p_Char >= m_StartCount[i]){if (m_IdRangeOffset[i] == 0){return (short)p_Char + (short)m_IdDelta[i];}else{uint _StarCount = (m_IdRangeOffset[i] + m_IdRangeOffsetIndex[i]) - m_GlyphidArrayStart;return m_GlyphIdArray[_StarCount / 2 + p_Char - m_StartCount[i]];}}}return -1;}}}}/// <summary>/// 控制值表/// </summary>private class TableCVT : TableBase{public TableCVT(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "cvt ";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}}/// <summary>/// /// </summary>private class TableFPGM : TableBase{public TableFPGM(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "gpgm";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}}/// <summary>/// 并网装置和扫描转换程序/// </summary>private class TableGASP : TableBase{public TableGASP(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "gasp";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;uint _ReadIndex = 4;m_RangeMaxPPEM = new ushort[NumRanges];m_RangeGaspBehavior = new ushort[NumRanges];for (int i = 0; i != NumRanges; i++){m_RangeMaxPPEM[i] = (ushort)(m_DataBytes[(4 * i) + _ReadIndex] << 8 | m_DataBytes[(4 * i) + _ReadIndex + 1]);m_RangeGaspBehavior[i] = (ushort)(m_DataBytes[(4 * i) + _ReadIndex + 2] << 8 | m_DataBytes[(4 * i) + _ReadIndex + 2]);}}/// <summary>/// 未知/// </summary>private ushort[] m_RangeMaxPPEM = new ushort[0];/// <summary>/// 未知/// </summary>private ushort[] m_RangeGaspBehavior = new ushort[0];/// <summary>/// 版本号 为0x0001/// </summary>public ushort Version { get { return (ushort)(m_DataBytes[0] << 8 | m_DataBytes[1]); } }/// <summary>/// 字表个数/// </summary>public ushort NumRanges { get { return (ushort)(m_DataBytes[2] << 8 | m_DataBytes[3]); } }}/// <summary>/// 轮廓数据表/// </summary>private class TableGLYF : TableBase{public TableGLYF(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "glyf";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}/// <summary>/// 读取的位置/// </summary>private int m_Index = 0;/// <summary>/// 对于简单图元,numberOfContours字段中保存的是当前图元的轮廓线的数目;对于合成图元,numberOfContours字段是一个负值。/// </summary>private short NumberOfContours { get { return (short)(m_DataBytes[m_Index] << 8 | m_DataBytes[m_Index + 1]); } }/// <summary>/// 开始位置X/// </summary>private short XMin { get { return (short)(m_DataBytes[m_Index + 2] << 8 | m_DataBytes[m_Index + 3]); } }/// <summary>/// 开始位置Y/// </summary>private short YMin { get { return (short)(m_DataBytes[m_Index + 4] << 8 | m_DataBytes[m_Index + 5]); } }/// <summary>/// 宽/// </summary>private short XMax { get { return (short)(m_DataBytes[m_Index + 6] << 8 | m_DataBytes[m_Index + 7]); } }/// <summary>/// 长/// </summary>private short YMax { get { return (short)(m_DataBytes[m_Index + 8] << 8 | m_DataBytes[m_Index + 9]); } }/// <summary>/// 符合图形需要地址列表/// </summary>public List<int> m_Address = null;/// <summary>/// 线的点数量/// </summary>private ushort[] EndPtsOfContours = new ushort[0];/// <summary>/// 命令长度/// </summary>private ushort Instructionlength = 0;/// <summary>/// 命令/// </summary>private byte[] Instruction = new byte[0];/// <summary>/// 坐标读取标志位/// </summary>private byte[] Flags = new byte[0];/// <summary>/// 最终坐标组/// </summary>private Point[] m_DrawPoint = new Point[0];/// <summary>/// 获取简单图形/// </summary>/// <param name="p_ReadAddress"></param>private void GetImagePoint(){EndPtsOfContours = new ushort[NumberOfContours];int _ReadIndex = m_Index + 10;for (int i = 0; i != NumberOfContours; i++){EndPtsOfContours[i] = (ushort)(m_DataBytes[_ReadIndex] << 8 | m_DataBytes[_ReadIndex + 1]);_ReadIndex += 2;}  //获取点的数量Instructionlength = (ushort)(m_DataBytes[_ReadIndex] << 8 | m_DataBytes[_ReadIndex + 1]);   //获取命令长度Instruction = new byte[Instructionlength];_ReadIndex += 2;Array.Copy(m_DataBytes, _ReadIndex, Instruction, 0, Instruction.Length);    //获取命令_ReadIndex += Instruction.Length;GetPoint(_ReadIndex);SetPoint();}/// <summary>/// 是否填充/// </summary>private bool m_FillDraw = true;/// <summary>/// 获取图形/// </summary>/// <param name="p_ReadAddress"></param>/// <returns></returns>public Image LoadImage(int p_ReadAddress, float p_Zoom, Brush p_Brush){if (p_ReadAddress == m_DataBytes.Length) return null;m_Index = p_ReadAddress;if (NumberOfContours < 0){int _AddressIndex = m_Address.IndexOf(p_ReadAddress);if (_AddressIndex == -1) return null;int _EndIndex = 0;if (_AddressIndex + 1 == m_Address.Count){_EndIndex = m_DataBytes.Length;}else{_EndIndex = m_Address[_AddressIndex + 1];}return GetImageMultiple(p_Zoom, _EndIndex, p_Brush);}else{GetImagePoint();return GetImage(p_Zoom, p_Brush);}}/// <summary>/// 获取图形数据/// </summary>/// <param name="p_FontBytes"></param>/// <returns></returns>public Image LoadImage(byte[] p_FontBytes, float p_Zoom, Brush p_Brush){byte[] _OldBytes = m_DataBytes;m_DataBytes = p_FontBytes;m_Index = 0;if (NumberOfContours < 0){throw new Exception("PCL不知道有没有符合字体!");}else{GetImagePoint();Image _Image = GetImage(p_Zoom, p_Brush);m_DataBytes = _OldBytes;return _Image;}}/// <summary>/// 是否填充/// </summary>public bool FillDraw { get { return m_FillDraw; } set { m_FillDraw = value; } }/// <summary>/// 获取多图类型/// </summary>/// <param name="p_Size">图形大小</param>/// <returns></returns>private Image GetImageMultiple(float p_Zoom, int p_EndIndex, Brush p_Brush){if (p_Zoom <= 0) p_Zoom = 1;decimal _Width = (decimal)(XMax + XMin) * (decimal)p_Zoom;decimal _Height = (decimal)(YMax + (YMin * -1)) * (decimal)p_Zoom;short _DrawHeight = (short)(YMax + (YMin * -1));Bitmap _NewBitmap = new Bitmap((int)_Width, (int)_Height);_NewBitmap.Tag = new int[] { (short)XMin, (short)YMin, (short)XMax, (short)YMax, 0, 0 };Graphics _Graphcis = Graphics.FromImage(_NewBitmap);int _ReadIndex = m_Index + 10;while (_ReadIndex < p_EndIndex){System.Collections.BitArray _Flags = new System.Collections.BitArray(new byte[] { m_DataBytes[_ReadIndex + 1], m_DataBytes[_ReadIndex] });_ReadIndex += 2;ushort _LocaIndex = (ushort)(m_DataBytes[_ReadIndex] << 8 | m_DataBytes[_ReadIndex + 1]);_ReadIndex += 2;if (_LocaIndex >= m_Address.Count) break;Image _GraoupImage = LoadImage(m_Address[_LocaIndex], p_Zoom, p_Brush);short _Argument1 = 0;short _Argument2 = 1;decimal _ScaleX = 0;decimal _ScaleY = 0;decimal _MScale01 = 0;decimal _MScale10 = 0;if (!_Flags[0]){_Argument1 = m_DataBytes[_ReadIndex];_Argument2 = m_DataBytes[_ReadIndex + 1];_ReadIndex += 2;}else{_Argument1 = (short)(m_DataBytes[_ReadIndex] << 8 | m_DataBytes[_ReadIndex + 1]);_ReadIndex += 2;_Argument2 = (short)(m_DataBytes[_ReadIndex] << 8 | m_DataBytes[_ReadIndex + 1]);_ReadIndex += 2;}if (_Flags[3]){_ScaleX = F2Dot14ToDecimal(m_DataBytes, _ReadIndex);_ScaleY = _ScaleX;_ReadIndex += 2;}if (_Flags[6]){_ScaleX = F2Dot14ToDecimal(m_DataBytes, _ReadIndex);_ReadIndex += 2;_ScaleY = F2Dot14ToDecimal(m_DataBytes, _ReadIndex);_ReadIndex += 2;}if (_Flags[7]){_ScaleX = F2Dot14ToDecimal(m_DataBytes, _ReadIndex);_ReadIndex += 2;_MScale01 = F2Dot14ToDecimal(m_DataBytes, _ReadIndex);_ReadIndex += 2;_MScale10 = F2Dot14ToDecimal(m_DataBytes, _ReadIndex);_ReadIndex += 2;_ScaleY = F2Dot14ToDecimal(m_DataBytes, _ReadIndex);_ReadIndex += 2;if (_MScale01 >= 0 && _MScale10 >= 0) _Argument1 += (short)(((Rectangle)_GraoupImage.Tag).Height);if (_MScale01 <= 0 && _MScale10 <= 0) _Argument1 += (short)-(((Rectangle)_GraoupImage.Tag).Height);if (_MScale01 >= 0 && _MScale10 <= 0) _Argument1 += (short)-(((Rectangle)_GraoupImage.Tag).Height);if (_MScale01 <= 0 && _MScale10 >= 0) _Argument1 += (short)(((Rectangle)_GraoupImage.Tag).Height);_MScale01 *= -1;_MScale10 *= -1;_Argument2 = (short)(_DrawHeight - _Argument2);}_ReadIndex += 2;float _X = (float)_Argument1 * p_Zoom;float _Y = (float)_Argument2 * p_Zoom;if (_ScaleX == 0 && _ScaleY == 0 && _MScale01==0 && _MScale10==0){_Graphcis.TranslateTransform(XMin, 0, System.Drawing.Drawing2D.MatrixOrder.Append);}else{_Graphcis.Transform = new System.Drawing.Drawing2D.Matrix((float)_ScaleX, (float)_MScale01, (float)_MScale10, (float)_ScaleY, (float)_X, (float)_Y);}_Graphcis.DrawImage(_GraoupImage, 0, 0);}_Graphcis.Dispose();return _NewBitmap;}/// <summary>/// 绘制图形(简单图形)/// </summary>/// <param name="p_Size">图形大小</param>/// <returns></returns>private Image GetImage(float p_Zoom, Brush p_Brush){if (p_Zoom <= 0) p_Zoom = 1;decimal _Width = (decimal)(XMax + (XMin * -1)) * (decimal)p_Zoom;decimal _Height = (decimal)(YMax + (YMin * -1)) * (decimal)p_Zoom;Bitmap _NewBitmap = new Bitmap((int)_Width, (int)_Height);_NewBitmap.Tag = new int[] { XMin, YMin, XMax, YMax, 0, 0 };Graphics _Graphcis = Graphics.FromImage(_NewBitmap);_Graphcis.TranslateTransform(XMin * -1, 0, System.Drawing.Drawing2D.MatrixOrder.Append);          System.Drawing.Drawing2D.GraphicsPath _Path = new System.Drawing.Drawing2D.GraphicsPath();int _ReadLineIndex = 0;List<Point> _DrawPoint = new List<Point>();foreach (ushort _DrawLine in EndPtsOfContours){decimal _StartX = (decimal)(m_DrawPoint[_ReadLineIndex].X) * (decimal)p_Zoom;decimal _StartY = (decimal)(m_DrawPoint[_ReadLineIndex].Y) * (decimal)p_Zoom;for (int i = _ReadLineIndex; i != _DrawLine + 1; i++){decimal _X = (decimal)(m_DrawPoint[_ReadLineIndex].X) * (decimal)p_Zoom;decimal _Y = (decimal)(m_DrawPoint[_ReadLineIndex].Y) * (decimal)p_Zoom;Point _LinePoint = new Point((int)_X, (int)_Y);System.Collections.BitArray _Array = new System.Collections.BitArray(new byte[] { Flags[_ReadLineIndex] });if (_Array[0]){_DrawPoint.Add(_LinePoint);DrawLine(_DrawPoint, _Path);}else{_DrawPoint.Add(_LinePoint);}_ReadLineIndex++;}_DrawPoint.Add(new Point((int)_StartX, (int)_StartY));DrawLine(_DrawPoint, _Path);_DrawPoint.Clear();_Path.StartFigure();}if (m_FillDraw){_Graphcis.FillPath(p_Brush, _Path);}else{_Graphcis.DrawPath(new Pen(p_Brush, 1), _Path);}_Graphcis.Dispose();             return _NewBitmap;}/// <summary>/// 绘制线/// </summary>/// <param name="p_Point">点集</param>/// <param name="p_Path">绘制</param>private void DrawLine(List<Point> p_Point, System.Drawing.Drawing2D.GraphicsPath p_Path){if (p_Point.Count == 0) return;Point _EndPoint = p_Point[p_Point.Count - 1];switch (p_Point.Count){case 1: return;case 2:p_Path.AddLine(p_Point[0], p_Point[1]);p_Point.RemoveAt(0);return;case 3:p_Path.AddBeziers(GetBeziersPoint(p_Point));p_Point.Clear();p_Point.Add(_EndPoint);return;default:List<Point[]> _Beziers = GetBeziersPointOfList(p_Point);for (int i = 0; i != _Beziers.Count; i++){p_Path.AddBeziers(_Beziers[i]);}p_Point.Clear();p_Point.Add(_EndPoint);return;}}/// <summary>/// 获取三阶段的Beziers/// </summary>/// <param name="p_PointList">二阶段Beziers</param>/// <returns>三阶段的Beziers</returns>private Point[] GetBeziersPoint(List<Point> p_PointList){Point[] _ReturnPointList = new Point[4];_ReturnPointList[0] = p_PointList[0];_ReturnPointList[1].X = p_PointList[0].X + 2 * (p_PointList[1].X - p_PointList[0].X) / 3;_ReturnPointList[1].Y = p_PointList[0].Y + 2 * (p_PointList[1].Y - p_PointList[0].Y) / 3;_ReturnPointList[2].X = p_PointList[1].X + 1 * (p_PointList[2].X - p_PointList[1].X) / 3;_ReturnPointList[2].Y = p_PointList[1].Y + 1 * (p_PointList[2].Y - p_PointList[1].Y) / 3;_ReturnPointList[3] = p_PointList[2];return _ReturnPointList;}/// <summary>/// 获取三阶段的Beziers/// </summary>/// <param name="p_PointList">多个不爱曲线上的点</param>/// <returns>三阶段的Beziers列表</returns>private List<Point[]> GetBeziersPointOfList(List<Point> p_PointList){List<Point[]> _ReturnListPoint = new List<Point[]>();Point[] _DrawPoint = new Point[3];int _DrawLine = 0;for (int i = 0; i != p_PointList.Count; i++){switch (_DrawLine){case 0:_DrawPoint[0] = p_PointList[i];break;case 1:_DrawPoint[1] = p_PointList[i];break;case 2:if (i == p_PointList.Count - 1){_DrawPoint[2] = p_PointList[i];}else{_DrawPoint[2].X = _DrawPoint[1].X + (p_PointList[i].X - _DrawPoint[1].X) / 2;_DrawPoint[2].Y = _DrawPoint[1].Y + (p_PointList[i].Y - _DrawPoint[1].Y) / 2;}break;}_DrawLine++;if (_DrawLine == 3){_DrawLine = 1;_ReturnListPoint.Add(GetBeziersPoint(new List<Point>(_DrawPoint)));_DrawPoint[0] = _DrawPoint[2];i--;}}return _ReturnListPoint;}/// <summary>/// F2DOT14结构的符点数转换为 decimal/// </summary>/// <param name="p_Bytes">字节</param>/// <param name="p_Index">开始位置</param>/// <returns></returns>private decimal F2Dot14ToDecimal(byte[] p_Bytes, int p_Index){decimal _ReturnValue = 0;ushort _ValueBytes = (ushort)(p_Bytes[p_Index] << 8 | p_Bytes[p_Index + 1]);_ReturnValue = Math.Round((decimal)((_ValueBytes >> 14) + ((_ValueBytes & 0x3fff) / 16384.0)), 4);if ((_ValueBytes & 0x8000) == 0x8000) _ReturnValue -= 4;return _ReturnValue;}/// <summary>/// 获取坐标信息/// </summary>private void GetPoint(int p_ReadIndex){Flags = new byte[EndPtsOfContours[EndPtsOfContours.Length - 1] + 1];for (int i = 0; i != Flags.Length; i++)   //获取标志位{byte _FlagByte = m_DataBytes[p_ReadIndex];Flags[i] = _FlagByte;System.Collections.BitArray _Array = new System.Collections.BitArray(new byte[] { _FlagByte });if (_Array[3]){for (int z = 0; z != m_DataBytes[p_ReadIndex + 1]; z++){i++;Flags[i] = _FlagByte;}p_ReadIndex++;}p_ReadIndex++;}m_DrawPoint = new Point[Flags.Length];for (int i = 0; i != Flags.Length; i++)  //获取X{System.Collections.BitArray _Array = new System.Collections.BitArray(new byte[] { Flags[i] });if (_Array[1]){m_DrawPoint[i].X = m_DataBytes[p_ReadIndex];p_ReadIndex++;if (!_Array[4]) m_DrawPoint[i].X *= -1;}else{if (_Array[4]){m_DrawPoint[i].X = 0;}else{m_DrawPoint[i].X = (short)(m_DataBytes[p_ReadIndex] << 8 | m_DataBytes[p_ReadIndex + 1]);p_ReadIndex += 2;}}}for (int i = 0; i != Flags.Length; i++)   //获取Y{System.Collections.BitArray _Array = new System.Collections.BitArray(new byte[] { Flags[i] });if (_Array[2]){m_DrawPoint[i].Y = m_DataBytes[p_ReadIndex];p_ReadIndex++;if (!_Array[5]) m_DrawPoint[i].Y *= -1;}else{if (_Array[5]){m_DrawPoint[i].Y = 0;}else{m_DrawPoint[i].Y = (short)(m_DataBytes[p_ReadIndex] << 8 | m_DataBytes[p_ReadIndex + 1]);p_ReadIndex += 2;}}}}/// <summary>/// 设置位置/// </summary>private void SetPoint(){Point _Point = new Point();for (int i = 0; i != m_DrawPoint.Length; i++){_Point.X += m_DrawPoint[i].X;_Point.Y += m_DrawPoint[i].Y;m_DrawPoint[i].X = _Point.X;m_DrawPoint[i].Y = YMax - _Point.Y;}}}/// <summary>/// 文件头/// </summary>private class TableHEAD : TableBase{public TableHEAD(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "head";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}/// <summary>/// 版本号 为0x0001/// </summary>public uint Version { get { return (uint)(m_DataBytes[0] << 24 | m_DataBytes[1] << 16 | m_DataBytes[2] << 8 | m_DataBytes[3]); } }/// <summary>/// 制造商/// </summary>public uint FontRevision { get { return (uint)(m_DataBytes[4] << 24 | m_DataBytes[5] << 16 | m_DataBytes[6] << 8 | m_DataBytes[7]); } }/// <summary>/// 验效/// </summary>public uint CheckSumAdjustment { get { return (uint)(m_DataBytes[8] << 24 | m_DataBytes[9] << 16 | m_DataBytes[10] << 8 | m_DataBytes[11]); } }/// <summary>/// 魔数 总是  0x5f0f3cf5/// </summary>public uint MagicNumber { get { return (uint)(m_DataBytes[12] << 24 | m_DataBytes[13] << 16 | m_DataBytes[14] << 8 | m_DataBytes[15]); } }/// <summary>/// bit 0 如果设置为1则底线位于y一0处 1 如果设置为1则文字左边界点位于x0  2如果设置为1则指令执行与文字尺寸有关 3 如果设置为l则强制ppem值在内部缩放运算时为整数 4 如果设置为l则指令能够对文字宽度(advance width)进行改变 其它位 全部为0/// </summary>public ushort Flags { get { return (ushort)(m_DataBytes[16] << 8 | m_DataBytes[17]); } }/// <summary>/// 有效范围/// </summary>public ushort UnitsPerEm { get { return (ushort)(m_DataBytes[18] << 8 | m_DataBytes[19]); } }/// <summary>/// 创建日期/// </summary>public ulong Created { get { return (ulong)((uint)(m_DataBytes[20] << 24 | m_DataBytes[21] << 16 | m_DataBytes[22] << 8 | m_DataBytes[23]) << 32 | (uint)(m_DataBytes[24] << 24 | m_DataBytes[25] << 16 | m_DataBytes[26] << 8 | m_DataBytes[27])); } }/// <summary>/// 修改日期/// </summary>public ulong Modified { get { return (ulong)((uint)(m_DataBytes[28] << 24 | m_DataBytes[29] << 16 | m_DataBytes[30] << 8 | m_DataBytes[31]) << 32 | (uint)(m_DataBytes[32] << 24 | m_DataBytes[33] << 16 | m_DataBytes[34] << 8 | m_DataBytes[35])); } }/// <summary>/// 最小坐标/// </summary>public ushort XMin { get { return (ushort)(m_DataBytes[36] << 8 | m_DataBytes[37]); } }/// <summary>/// 最小坐标/// </summary>public ushort YMin { get { return (ushort)(m_DataBytes[38] << 8 | m_DataBytes[39]); } }/// <summary>/// 最大坐标/// </summary>public ushort XMax { get { return (ushort)(m_DataBytes[40] << 8 | m_DataBytes[41]); } }/// <summary>/// 最大坐标/// </summary>public ushort YMax { get { return (ushort)(m_DataBytes[42] << 8 | m_DataBytes[43]); } }/// <summary>/// 字体风格/// </summary>public ushort MacStyle { get { return (ushort)(m_DataBytes[44] << 8 | m_DataBytes[45]); } }/// <summary>/// 最小ppem 值/// </summary>public short LowestRecPPEM { get { return (short)(m_DataBytes[46] << 8 | m_DataBytes[47]); } }/// <summary>/// 字体方向/// </summary>public short FontDirectionHint { get { return (short)(m_DataBytes[48] << 8 | m_DataBytes[49]); } }/// <summary>/// loca‘表袁项数据类型(0:SHORTtl:I ONG、/// </summary>public short IndexToLocFormat { get { return (short)(m_DataBytes[50] << 8 | m_DataBytes[51]); } }/// <summary>/// /文字数据类型(0/// </summary>public short GlyphDataFormat { get { return (short)(m_DataBytes[52] << 8 | m_DataBytes[53]); } }}/// <summary>/// 横向头定义/// </summary>private class TableHHEA : TableBase{public TableHHEA(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "hhea";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}/// <summary>/// 版本号 Version = 0x00010000/// </summary>public uint Version { get { return (uint)(m_DataBytes[0] << 24 | m_DataBytes[1] << 16 | m_DataBytes[2] << 8 | m_DataBytes[3]); } }/// <summary>///上升位/// </summary>public short Ascender { get { return (short)(m_DataBytes[4] << 8 | m_DataBytes[5]); } }/// <summary>/// 下降位/// </summary>public short Descender { get { return (short)(m_DataBytes[6] << 8 | m_DataBytes[7]); } }/// <summary>/// 线距/// </summary>public short LineGap { get { return (short)(m_DataBytes[8] << 8 | m_DataBytes[9]); } }/// <summary>/// 在前进的最大的宽度值/// </summary>public ushort AdvanceWidthMax { get { return (ushort)(m_DataBytes[10] << 8 | m_DataBytes[11]); } }/// <summary>/// 左/// </summary>public ushort MinLeftSideBearing { get { return (ushort)(m_DataBytes[12] << 8 | m_DataBytes[13]); } }/// <summary>/// 右/// </summary>public ushort MinRightSideBearing { get { return (ushort)(m_DataBytes[14] << 8 | m_DataBytes[15]); } }/// <summary>/// Max(lsb + (xMax - xMin)). /// </summary>public ushort XMaxExtent { get { return (ushort)(m_DataBytes[16] << 8 | m_DataBytes[17]); } }/// <summary>/// 计算位  /// </summary>public short CaretSlopeRise { get { return (short)(m_DataBytes[18] << 8 | m_DataBytes[19]); } }/// <summary>/// 0 for vertical/// </summary>public short CaretSlopeRun { get { return (short)(m_DataBytes[20] << 8 | m_DataBytes[21]); } }/// <summary>/// 未知/// </summary>public short Reserved1 { get { return (short)(m_DataBytes[22] << 8 | m_DataBytes[23]); } }/// <summary>/// 未知/// </summary>public short Reserved2 { get { return (short)(m_DataBytes[24] << 8 | m_DataBytes[25]); } }/// <summary>/// 未知/// </summary>public short Reserved3 { get { return (short)(m_DataBytes[26] << 8 | m_DataBytes[27]); } }/// <summary>/// 未知/// </summary>public short Reserved4 { get { return (short)(m_DataBytes[28] << 8 | m_DataBytes[29]); } }/// <summary>/// 未知/// </summary>public short Reserved5 { get { return (short)(m_DataBytes[30] << 8 | m_DataBytes[31]); } }/// <summary>/// 用户定义格式/// </summary>public short MetricDataFormat { get { return (short)(m_DataBytes[32] << 8 | m_DataBytes[33]); } }/// <summary>/// 字形总数目/// </summary>public ushort NumberOfHMetrics { get { return (ushort)(m_DataBytes[34] << 8 | m_DataBytes[35]); } }}/// <summary>/// 纵向头定义/// </summary>private class TableHMTX : TableBase{public TableHMTX(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "hmtx";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}/// <summary>/// 获取最终宽/// </summary>/// <param name="p_Index"></param>/// <returns></returns>public int GetAdvanceWidthOfIndex(int p_Index){int _Address = p_Index * 4;if (_Address+4 >= m_DataBytes.Length) return -1;return (int)(m_DataBytes[_Address] << 8 | m_DataBytes[_Address + 1]);}}/// <summary>/// 地址表/// </summary>private class TableLOCA : TableBase{public TableLOCA(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "loca";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}/// <summary>/// 图形地址/// </summary>public List<int> m_Address = new List<int>();/// <summary>/// 根据文件头获取地址信息(对应TableGLYF 里的数据)/// </summary>/// <param name="p_Head"></param>/// <returns></returns>public void GetAddress(TableHEAD p_Head, TableMAXP p_Maxp){m_Address.Clear();int _Count = p_Maxp.NumGlyphs;int _NumGlyphsStart = 0;int _NumGlyphsEnd = 0;for (int i = 0; i != _Count; i++){switch (p_Head.IndexToLocFormat){case 0:_NumGlyphsStart = (int)(m_DataBytes[i * 2] << 8 | m_DataBytes[i * 2 + 1]) * 2;_NumGlyphsEnd = (int)(m_DataBytes[i * 2 + 2] << 8 | m_DataBytes[i * 2 + 3]) * 2;break;case 1:_NumGlyphsStart = (int)(m_DataBytes[i * 4] << 24 | m_DataBytes[i * 4 + 1] << 16 | m_DataBytes[i * 4 + 2] << 8 | m_DataBytes[i * 4 + 3]) * 2;_NumGlyphsEnd = (int)(m_DataBytes[i * 4 + 4] << 24 | m_DataBytes[i * 4 + 5] << 16 | m_DataBytes[i * 4 + 6] << 8 | m_DataBytes[i * 4 + 7]) * 2;break;}if (_NumGlyphsEnd == _NumGlyphsStart){m_Address.Add(-1);}else{switch(p_Head.IndexToLocFormat){case 0:m_Address.Add(_NumGlyphsStart);break;case 1:m_Address.Add(_NumGlyphsStart / 2);break;}}}}/// <summary>/// 获取地址/// </summary>/// <param name="p_Index"></param>/// <returns></returns>public int GetAddressOfIndex(int p_Index){return m_Address[p_Index];}/// <summary>/// 获取地址/// </summary>/// <param name="p_Index"></param>/// <param name="p_Head"></param>/// <returns></returns>private int GetAddressOfByte(uint p_Index, TableHEAD p_Head){uint _Index = p_Index - m_Offset;switch (p_Head.IndexToLocFormat){case 0:return (int)(m_DataBytes[_Index] << 8 | m_DataBytes[_Index + 1]) * 2;case 1:return (int)(m_DataBytes[_Index] << 24 | m_DataBytes[_Index + 1] << 16 | m_DataBytes[_Index + 2] << 8 | m_DataBytes[_Index + 3]) * 2;}return -1;}}/// <summary>/// 最大值描述表/// </summary>private class TableMAXP : TableBase{public TableMAXP(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "loca";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}/// <summary>/// 版本号 为0x0001/// </summary>public uint Version { get { return (uint)(m_DataBytes[0] << 24 | m_DataBytes[1] << 16 | m_DataBytes[2] << 8 | m_DataBytes[3]); } }/// <summary>/// 文字个数/// </summary>public ushort NumGlyphs { get { return (ushort)(m_DataBytes[4] << 8 | m_DataBytes[5]); } }/// <summary>/// 简单文字最大轮廓点数/// </summary>public ushort MaxPoints { get { return (ushort)(m_DataBytes[6] << 8 | m_DataBytes[7]); } }/// <summary>/// 简单文字最大轮廓数/// </summary>public ushort MaxContours { get { return (ushort)(m_DataBytes[8] << 8 | m_DataBytes[9]); } }/// <summary>/// 复合文字最大轮廓点数/// </summary>public ushort MaxCompositePoints { get { return (ushort)(m_DataBytes[10] << 8 | m_DataBytes[11]); } }/// <summary>/// 复合文字最大轮廓数/// </summary>public ushort MaxCompositeContours { get { return (ushort)(m_DataBytes[12] << 8 | m_DataBytes[13]); } }/// <summary>/// 指夸使用的区域个数(1或2)/// </summary>public ushort MaxZones { get { return (ushort)(m_DataBytes[14] << 8 | m_DataBytes[15]); } }/// <summary>/// z0中包吉的最太点数/// </summary>public ushort MaxTwilightPoints { get { return (ushort)(m_DataBytes[16] << 8 | m_DataBytes[17]); } }/// <summary>/// 暂存区域太小/// </summary>public ushort MaxStorage { get { return (ushort)(m_DataBytes[18] << 8 | m_DataBytes[19]); } }/// <summary>/// 最多能定义的函数个数/// </summary>public ushort MaxFunctionDefs { get { return (ushort)(m_DataBytes[20] << 8 | m_DataBytes[21]); } }/// <summary>/// 最多能定义的指令个数/// </summary>public ushort maxInstructionDefs { get { return (ushort)(m_DataBytes[22] << 8 | m_DataBytes[23]); } }/// <summary>/// 解释器堆栈的最大容量/// </summary>public ushort maxStackElements { get { return (ushort)(m_DataBytes[24] << 8 | m_DataBytes[25]); } }/// <summary>/// 文字指专描述部分的最大字节数/// </summary>public ushort maxSizeOfInstructions { get { return (ushort)(m_DataBytes[26] << 8 | m_DataBytes[27]); } }/// <summary>/// 复台文字包含的最大简单文字个数/// </summary>public ushort maxComponentElements { get { return (ushort)(m_DataBytes[28] << 8 | m_DataBytes[29]); } }/// <summary>/// 最大递归深度/// </summary>public ushort maxComponentDepth { get { return (ushort)(m_DataBytes[30] << 8 | m_DataBytes[31]); } }}/// <summary>/// 字体名称表/// </summary>private class TableNAME : TableBase{public TableNAME(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "name";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;int _ReadIndex = 6;for (int i = 0; i != NameRecordsNumb; i++){m_NameRecord.Add(new NameRecord(p_TableBytes, _ReadIndex, (NameRecordsNumb * 12) + 6));_ReadIndex += 12;}}/// <summary>/// 固定为0/// </summary>public ushort Selector { get { return (ushort)(m_DataBytes[0] << 8 | m_DataBytes[1]); } }/// <summary>/// NameRecordsName的数量/// </summary>public ushort NameRecordsNumb { get { return (ushort)(m_DataBytes[2] << 8 | m_DataBytes[3]); } }/// <summary>/// NameRecordsName结束位置/// </summary>public ushort NameRecordsEndAddress { get { return (ushort)(m_DataBytes[4] << 8 | m_DataBytes[5]); } }private IList<NameRecord> m_NameRecord = new List<NameRecord>();/// <summary>/// 名称类型/// </summary>private class NameRecord{private byte[] m_DataBytes = new byte[12];private string p_Text = "";public NameRecord(byte[] p_Bytes, int p_ReadIndex, int p_EndIndex){Array.Copy(p_Bytes, p_ReadIndex, m_DataBytes, 0, 12);Encoding _Encoding = Encoding.ASCII;if (PlatformSpecificEncoding == 1) _Encoding = Encoding.Unicode;p_Text = Encoding.ASCII.GetString(p_Bytes, p_EndIndex + StringOffset, StringLength).Replace("/0", "");}/// <summary>/// 0=Apple Unicode none 1=Macintosh  Script manager code 2=ISO  ISO encoding 3=Microsoft  Microsoft encoding /// </summary>public ushort PlatformID { get { return (ushort)(m_DataBytes[0] << 8 | m_DataBytes[1]); } }/// <summary>/// 0=未定义的字符集或索引方案  1=Unicode字元集索引计划/// </summary>public ushort PlatformSpecificEncoding { get { return (ushort)(m_DataBytes[2] << 8 | m_DataBytes[3]); } }/// <summary>/// 语种/// </summary>public ushort Language { get { return (ushort)(m_DataBytes[4] << 8 | m_DataBytes[5]); } }/// <summary>/// 0=版权声明 1=字体名称 2=字体别名  3=字体标识 4=全部字体名称 5=版本 6=Postscript名称 7=商标/// </summary>public ushort NameID { get { return (ushort)(m_DataBytes[6] << 8 | m_DataBytes[7]); } }/// <summary>/// 字符串长度/// </summary>public ushort StringLength { get { return (ushort)(m_DataBytes[8] << 8 | m_DataBytes[9]); } }/// <summary>/// 字符串地址/// </summary>public ushort StringOffset { get { return (ushort)(m_DataBytes[10] << 8 | m_DataBytes[11]); } }}}/// <summary>/// PostScript用数据/// </summary>private class TablePOST : TableBase{public TablePOST(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "name";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}}/// <summary>/// 控制值/// </summary>private class TablePREP : TableBase{public TablePREP(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "name";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}}/// <summary>/// 线发阀值/// </summary>private class TableLTSH : TableBase{public TableLTSH(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "LTSH";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}/// <summary>///版本/// </summary>public short Version { get { return (short)(m_DataBytes[0] << 8 | m_DataBytes[1]); } }/// <summary>/// 下降位/// </summary>public short NumGlyphs { get { return (short)(m_DataBytes[2] << 8 | m_DataBytes[3]); } }public byte this[int p_Index]{get { return m_DataBytes[p_Index + 4]; }}}/// <summary>/// 设备水平度量/// </summary>private class TableHDMX : TableBase{public TableHDMX(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "hdmx";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}}/// <summary>/// 标志符号替换表/// </summary>private class TableGSUB : TableBase{public TableGSUB(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "GSUB";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}}/// <summary>/// 垂直头表/// </summary>private class TableVHEA : TableBase{public TableVHEA(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "vhea";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}}/// <summary>/// 垂直度量表/// </summary>private class TableVMTX : TableBase{public TableVMTX(byte[] p_TableBytes, uint p_CheckSum, uint p_Offset){base.m_Tag = "vmtx";base.m_Length = (uint)p_TableBytes.Length;base.m_CheckSum = p_CheckSum;base.m_Offset = p_Offset;base.m_DataBytes = p_TableBytes;}}#endregion}
}

 

  相关解决方案