如何:创建专用的字体集合

PrivateFontCollection 类继承自 FontCollection 抽象基类。 可以使用对象 PrivateFontCollection 来维护一组专门用于应用程序的字体。 专用字体集合可以包括已安装的系统字体以及尚未在计算机上安装的字体。 若要将字体文件添加到专用字体集合,请调用 AddFontFile 对象的 PrivateFontCollection 方法。

Families 对象的 PrivateFontCollection 属性包含 FontFamily 对象组成的一个数组。

专用字体集合中的字体系列数量不一定与已添加到集合中的字体文件数量相同。 例如,假设将文件 ArialBd.tff、Times.tff 和 TimesBd.tff 添加到集合中。 由于 Times.tff 和 TimesBd.tff 属于同一个系列,因此集合中将会有三个文件但只有两个系列。

示例:

以下示例将以下三个字体文件添加到 PrivateFontCollection 对象:

  • C:\systemroot\Fonts\Arial.tff(Arial,常规)

  • C:\systemroot\Fonts\CourBI.tff(Courier New,粗斜体)

  • C:\systemroot\Fonts\TimesBd.tff(Times New Roman,粗体)

代码从 FontFamily 对象的 Families 属性中检索一组 PrivateFontCollection 对象。

对于集合中的每个 FontFamily 对象,代码会调用 IsStyleAvailable 方法来确定各种样式是否(常规、粗体、斜体、粗斜体、下划线和删除线)可用。 传递给 IsStyleAvailable 方法的参数是 FontStyle 枚举的成员。

如果给定的系列/样式组合可用,则会使用该系列和样式构造 Font 对象。 传递给 Font 构造函数的第一个参数是字体系列名称(不像 FontFamily 构造函数的其他变体那样是 Font 对象)。 构造 Font 对象后,将其传递给 DrawString 类的 Graphics 方法以显示系列名称以及样式名称。

以下代码的输出类似于下图所示的输出:

显示各种字体文本的屏幕截图。

Arial.tff(在以下代码示例中被添加到专用字体集合中)是 Arial 常规样式的字体文件。 但是请注意,程序输出还会显示除常规 Arial 字体系列以外的几种可用样式。 这是因为 GDI+ 可以模拟常规样式中的粗体、斜体和粗体斜体样式。 GDI+ 还可以从常规样式生成下划线和删除线。

同样,GDI+ 可以从粗体样式或斜体样式模拟粗斜体样式。 程序输出显示,即使 TimesBd.tff(Times New Roman,粗体)是集合中唯一的 Times 文件,粗斜体样式也可用于 Times 系列。

// Helper function to print text in a font and style
private float DrawFont(Graphics graphicsObj,
                       FontFamily family,
                       FontStyle style,
                       SolidBrush colorBrush,
                       PointF ___location,
                       string styleName)
{
    // The string to print, which contains the family name and style
    string familyNameAndStyle = $"{family.Name} {styleName}";

    // Create the font object
    using (Font fontObject = new Font(family, 16, style, GraphicsUnit.Pixel))
    {
        // Draw the string
        graphicsObj.DrawString(familyNameAndStyle, fontObject, colorBrush, ___location);

        // Return the height of the font
        return fontObject.Height;
    }
}

// The OnPaint method of a form, which provides the graphics object
protected override void OnPaint(PaintEventArgs e)
{
    PointF ___location = new PointF(10, 0);
    SolidBrush solidBrush = new SolidBrush(Color.Black);

    FontFamily[] fontFamilies;
    PrivateFontCollection privateFontCollection = new PrivateFontCollection(); // Dispose later

    // Add three font files to the private collection.
    privateFontCollection.AddFontFile(System.Environment.ExpandEnvironmentVariables("%systemroot%\\Fonts\\Arial.ttf"));
    privateFontCollection.AddFontFile(System.Environment.ExpandEnvironmentVariables("%systemroot%\\Fonts\\CourBI.ttf"));
    privateFontCollection.AddFontFile(System.Environment.ExpandEnvironmentVariables("%systemroot%\\Fonts\\TimesBD.ttf"));

    // Get the array of FontFamily objects.
    fontFamilies = privateFontCollection.Families;

    // Process each font in the collection
    for (int i = 0; i < fontFamilies.Length; i++)
    {
        // Draw the font in every style

        // Regular
        if (fontFamilies[i].IsStyleAvailable(FontStyle.Regular))
            ___location.Y += DrawFont(e.Graphics, fontFamilies[i], FontStyle.Regular, solidBrush, ___location, "Regular");

        // Bold
        if (fontFamilies[i].IsStyleAvailable(FontStyle.Bold))
            ___location.Y += DrawFont(e.Graphics, fontFamilies[i], FontStyle.Bold, solidBrush, ___location, "Bold");

        // Italic
        if (fontFamilies[i].IsStyleAvailable(FontStyle.Italic))
            ___location.Y += DrawFont(e.Graphics, fontFamilies[i], FontStyle.Italic, solidBrush, ___location, "Italic");

        // Bold and Italic
        if (fontFamilies[i].IsStyleAvailable(FontStyle.Bold) &&
            fontFamilies[i].IsStyleAvailable(FontStyle.Italic))
            ___location.Y += DrawFont(e.Graphics, fontFamilies[i], FontStyle.Bold | FontStyle.Italic, solidBrush, ___location, "BoldItalic");

        // Underline
        if (fontFamilies[i].IsStyleAvailable(FontStyle.Underline))
            ___location.Y += DrawFont(e.Graphics, fontFamilies[i], FontStyle.Underline, solidBrush, ___location, "Underline");

        // Strikeout
        if (fontFamilies[i].IsStyleAvailable(FontStyle.Strikeout))
            ___location.Y += DrawFont(e.Graphics, fontFamilies[i], FontStyle.Strikeout, solidBrush, ___location, "Strikeout");

        // Extra space between font families
        ___location.Y += 10;
    }

    privateFontCollection.Dispose();
}
' Helper function to print text in a font and style
Private Function DrawFont(graphicsObj As Graphics,
                          family As FontFamily,
                          style As FontStyle,
                          colorBrush As SolidBrush,
                          ___location As PointF,
                          styleName As String) As Single

    ' The string to print, which contains the family name and style
    Dim familyNameAndStyle As String = $"{family.Name} {styleName}"

    ' Create the font object
    Using fontObject As New Font(family, 16, style, GraphicsUnit.Pixel)

        ' Draw the string
        graphicsObj.DrawString(familyNameAndStyle, fontObject, colorBrush, ___location)

        ' Return the height of the font
        Return fontObject.Height

    End Using

End Function

' The OnPaint method of a form, which provides the graphics object
Protected Overrides Sub OnPaint(e As PaintEventArgs)

    Dim ___location As New PointF(10, 0)
    Dim solidBrush As New SolidBrush(Color.Black)

    Dim fontFamilies() As FontFamily
    Dim privateFontCollection As New PrivateFontCollection() ' Dispose later

    ' Add three font files to the private collection.
    privateFontCollection.AddFontFile(System.Environment.ExpandEnvironmentVariables("%systemroot%\Fonts\Arial.ttf"))
    privateFontCollection.AddFontFile(System.Environment.ExpandEnvironmentVariables("%systemroot%\Fonts\CourBI.ttf"))
    privateFontCollection.AddFontFile(System.Environment.ExpandEnvironmentVariables("%systemroot%\Fonts\TimesBD.ttf"))

    ' Get the array of FontFamily objects.
    fontFamilies = privateFontCollection.Families

    ' Process each font in the collection
    For i = 0 To fontFamilies.Length - 1

        ' Draw the font in every style

        ' Regular
        If fontFamilies(i).IsStyleAvailable(FontStyle.Regular) Then
            ___location.Y += DrawFont(e.Graphics, fontFamilies(i), FontStyle.Regular, solidBrush, ___location, "Regular")
        End If

        ' Bold
        If fontFamilies(i).IsStyleAvailable(FontStyle.Bold) Then
            ___location.Y += DrawFont(e.Graphics, fontFamilies(i), FontStyle.Bold, solidBrush, ___location, "Bold")
        End If

        ' Italic
        If fontFamilies(i).IsStyleAvailable(FontStyle.Italic) Then
            ___location.Y += DrawFont(e.Graphics, fontFamilies(i), FontStyle.Italic, solidBrush, ___location, "Italic")
        End If

        ' Bold and Italic
        If fontFamilies(i).IsStyleAvailable(FontStyle.Italic) And
           fontFamilies(i).IsStyleAvailable(FontStyle.Italic) Then
            ___location.Y += DrawFont(e.Graphics, fontFamilies(i), FontStyle.Bold Or FontStyle.Italic, solidBrush, ___location, "BoldItalic")
        End If

        ' Underline
        If fontFamilies(i).IsStyleAvailable(FontStyle.Underline) Then
            ___location.Y += DrawFont(e.Graphics, fontFamilies(i), FontStyle.Underline, solidBrush, ___location, "Underline")
        End If

        ' Strikeout
        If fontFamilies(i).IsStyleAvailable(FontStyle.Strikeout) Then
            ___location.Y += DrawFont(e.Graphics, fontFamilies(i), FontStyle.Strikeout, solidBrush, ___location, "Strikeout")
        End If

        ' Extra space between font families
        ___location.Y += 10

    Next

    privateFontCollection.Dispose()

End Sub

编译代码

前面的示例专用于 Windows 窗体,它需要 PaintEventArgse,这是 PaintEventHandler 的参数。

另请参阅