本来打算酸所有的PCL HPGL/2的都贴出来.后来发现这里重要的字体显示 TTF的数据显示就2000多行 10来个类了.所以把这个独立出来.另外我增加了一些字符对应和轮廓显示的方法.有兴趣的朋友可以单独去使用.
效果图
使用代码
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;
#endregion
public 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
}
}