0

经过多次试验和错误,我终于让我的应用程序在开发机器以外的机器上使用自定义字体,但是,我不确定我已经开始使用的两种方法中的哪一种是首选的做事方式。

将字体作为资源嵌入并使用Assembly.GetManifestResourceStream()将字体文件数据推送到非托管内存中并将其添加到PrivateFontCollection使用中AddMemoryFont(),如下所示:

(删除所有错误处理和多余代码)

Imports System.Runtime.InteropServices
Imports System.Drawing.Text

Public Class FormExample

    Private ReadOnly pfc As New PrivateFontCollection
    Private f As Font
    Private ReadOnly Bytes() As Byte = GetFontData(Reflection.Assembly.GetExecutingAssembly, "MyFont.ttf")
    Private ReadOnly fontPtr As IntPtr = Marshal.AllocCoTaskMem(Me.Bytes.Length)

    Private Sub FormExample_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Marshal.Copy(Me.Bytes, 0, Me.fontPtr, Me.Bytes.Length)
        Me.pfc.AddMemoryFont(Me.fontPtr, Me.Bytes.Length)
        Me.f = New Font(Me.pfc.Families(0), 14, FontStyle.Regular)
        'Iterate through forms controls and set font where valid
        SetFormsCustomFont(Me, Me.f)
    End Sub

    Private Sub FormExample_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
        Marshal.FreeCoTaskMem(Me.fontPtr)
        Me.pfc.Dispose()
    End Sub

    Private Function GetFontData(Asm As Assembly, Name As String) As Byte()
        Using Stream As Stream = Asm.GetManifestResourceStream(Name)
            Dim Buffer() As Byte = New Byte(CInt(Stream.Length - 1)) {}
            Stream.Read(Buffer, 0, CInt(Stream.Length))
            Return Buffer
        End Using
    End Function

End Class

或者通过简单地将字体包含在应用程序中,而不是将其作为资源嵌入并使用PrivateFontCollection.AddFontFile()

Public Class FormExample2

    Private ReadOnly pfc As New PrivateFontCollection
    Private f As Font

    Private Sub FormExample2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim fontFile As String = ".\Path\To\MyFont.ttf"
        Me.pfc.AddFontFile(fontFile)
        Me.f = New Font(Me.pfc.Families(0), 14)
        'Iterate through forms controls and set font where valid
        SetFormsCustomFont(Me, Me.f)
    End Sub

    Private Sub FormExample2_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
        Me.pfc.Dispose()
    End Sub

End Class

在这两种方法中,字体集合都需要在表单的整个生命周期中保留,并且我必须重复代码并为应用程序中的每个表单设置字体对象,这样我就不会践踏非托管内存。

除了第二种方法允许用户访问您的字体文件这一事实之外,第一种方法还有其他好处吗?

或者,是否有另一种我不知道的首选方法?

4

0 回答 0