vb.net 载入私有字体、私有字符集
在.NET中载入一个独立的字体文件其实很容易,但如果你想将这个字体文件内嵌到程序之中,则会不可避免地碰到控件字符绘图的深坑。
那么该如何避免这些坑呢?
直接从文件载入字体
方便,直接,不需要系统安装过该字体
可直接应用到GDI+或者控件当中
载入内存字体
内存字体的载入方法,就复杂一点,要用
并且如果控件要使用内存字体,还需要设置它的
载入内嵌程序集资源
将字体文件复制到工程内,设置文件属性【生成操作】为【嵌入的资源】
其中 WindowsApplication1 为程序的根命名空间,请自己修改
另外,如果采用Sub Main方式执行程序的话,可以在运行窗体之前,使用
那么该如何避免这些坑呢?
直接从文件载入字体
方便,直接,不需要系统安装过该字体
可直接应用到GDI+或者控件当中
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim fontpath As String = "G:\fonts\田氏圆笔刷体繁.ttf"
Dim g As Graphics = Me.CreateGraphics
Dim PFC As New Drawing.Text.PrivateFontCollection() '私有字符集和
PFC.AddFontFile(fontpath) '载入一个字符文件
'…………
Dim FFS() As FontFamily = PFC.Families
'Dim FName As String = FFS(0).Name '无用代码
Dim F As New Font(FFS(0), 16) '创建字符实例
Dim B As New SolidBrush(Color.Blue) '字体颜色
Dim P As New PointF(10, 10) '字符位置
g.DrawString("This is MyText!!! " & vbCrLf & "我的私有字体!!!", F, B, P)
Button1.Font = New Font(F, FontStyle.Regular)
End Sub
载入内存字体
内存字体的载入方法,就复杂一点,要用
Marshal.Copy
将数据写入一个内存指针 并且如果控件要使用内存字体,还需要设置它的
UseCompatibleTextRendering
属性Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
' 用数据加载字体,这里可以用各种方法来加载数据,比如从文件、程序集、或者其他方式
Dim fontpath As String = "G:\fonts\田氏圆笔刷体繁.ttf"
Dim fontbytes As Byte() = IO.File.ReadAllBytes(fontpath)
' 将数据拷入内存指针
Dim fontPtr As IntPtr = Runtime.InteropServices.Marshal.AllocCoTaskMem(fontbytes.Length)
Runtime.InteropServices.Marshal.Copy(fontbytes, 0, fontPtr, fontbytes.Length)
Dim g As Graphics = Me.CreateGraphics
Dim PFC As New Drawing.Text.PrivateFontCollection() '私有字符集和
' 载入一个内存字符数据
PFC.AddMemoryFont(fontPtr, fontbytes.Length)
Runtime.InteropServices.Marshal.FreeCoTaskMem(fontPtr) '记得释放内存
'…………
Dim FFS() As FontFamily = PFC.Families
'Dim FName As String = FFS(0).Name '无用代码
Dim F As New Font(FFS(0), 16) '创建字符实例
Dim B As New SolidBrush(Color.Blue) '字体颜色
Dim P As New PointF(10, 10) '字符位置
g.DrawString("This is MyText!!! " & vbCrLf & "我的私有字体!!!", F, B, P)
' 注意!!!!!要想控件使用内存字符
' 一定要将控件的 UseCompatibleTextRendering 属性设为True
Button2.UseCompatibleTextRendering = True
Button2.Font = New Font(F, FontStyle.Regular)
End Sub
载入内嵌程序集资源
将字体文件复制到工程内,设置文件属性【生成操作】为【嵌入的资源】
其中 WindowsApplication1 为程序的根命名空间,请自己修改
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim fontAName As String = "WindowsApplication1.田氏圆笔刷体繁.ttf"
Dim fontStream As IO.Stream = Reflection.Assembly.GetEntryAssembly.GetManifestResourceStream(fontAName)
'Dim fontStream As IO.Stream = Me.GetType.Assembly.GetManifestResourceStream(fontAName)
Dim fontbytes(fontStream.Length - 1) As Byte
fontStream.Read(fontbytes, 0, fontStream.Length)
fontStream.Close()
Dim fontPtr As IntPtr = Runtime.InteropServices.Marshal.AllocCoTaskMem(fontbytes.Length)
Runtime.InteropServices.Marshal.Copy(fontbytes, 0, fontPtr, fontbytes.Length)
Dim g As Graphics = Me.CreateGraphics
Dim PFC As New Drawing.Text.PrivateFontCollection() '私有字符集和
' 载入一个内存字符数据
PFC.AddMemoryFont(fontPtr, fontbytes.Length)
Runtime.InteropServices.Marshal.FreeCoTaskMem(fontPtr) '记得释放内存
'…………
Dim FFS() As FontFamily = PFC.Families
'Dim FName As String = FFS(0).Name '无用代码
Dim F As New Font(FFS(0), 16) '创建字符实例
Dim B As New SolidBrush(Color.Blue) '字体颜色
Dim P As New PointF(10, 10) '字符位置
g.DrawString("This is MyText!!! " & vbCrLf & "我的私有字体!!!", F, B, P)
Button3.UseCompatibleTextRendering = True
Button3.Font = F
End Sub
另外,如果采用Sub Main方式执行程序的话,可以在运行窗体之前,使用
Application.SetCompatibleTextRenderingDefault(True)
这个方法,来默认程序内控件的绘制行为,就不用为每个控件指定 UseCompatibleTextRendering
属性了。Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(True)
Application.Run(Form1)
End Sub
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。