标签未使用自定义字体

本文关键字:字体 自定义 未使用 标签 | 更新日期: 2024-09-20 20:38:52

我正在使用以下代码加载嵌入字体:

PrivateFontCollection pfc = new PrivateFontCollection(); //declared outside this function
using (Stream fontStream = GetType().Assembly.GetManifestResourceStream("NucWar.BSOD_Font.ttf"))
{
    if (null == fontStream)
    {
        return;
    }
    int fontStreamLength = (int)fontStream.Length;
    IntPtr data = Marshal.AllocCoTaskMem(fontStreamLength);
    byte[] fontData = new byte[fontStreamLength];
    fontStream.Read(fontData, 0, fontStreamLength);
    Marshal.Copy(fontData, 0, data, fontStreamLength);
    pfc.AddMemoryFont(data, fontStreamLength);
    Marshal.FreeCoTaskMem(data);
}

这很好用。如果我在最后抛出一个断点,我可以看到字体已成功加载。如果我连接Paint事件,并使用它:

bool bold = false;
bool italic = false;
e.Graphics.PageUnit = GraphicsUnit.Point;
using (SolidBrush b = new SolidBrush(Color.Black))
{
    int y = 5;
    foreach (FontFamily fontFamily in pfc.Families)
    {
        if (fontFamily.IsStyleAvailable(FontStyle.Regular))
        {
            using (Font font = new Font(fontFamily, 32, FontStyle.Regular))
            {
                e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
            }
            y += 40;
        }
        if (fontFamily.IsStyleAvailable(FontStyle.Bold))
        {
            bold = true;
            using (Font font = new Font(fontFamily, 32, FontStyle.Bold))
            {
                e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
            }
            y += 40;
        }
        if (fontFamily.IsStyleAvailable(FontStyle.Italic))
        {
            italic = true;
            using (Font font = new Font(fontFamily, 32, FontStyle.Italic))
            {
                e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
            }
            y += 40;
        }
        if (bold && italic)
        {
            using (Font font = new Font(fontFamily, 32, FontStyle.Bold | FontStyle.Italic))
            {
                e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
            }
            y += 40;
        }
        using (Font font = new Font(fontFamily, 32, FontStyle.Underline))
        {
            e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
            y += 40;
        }
        using (Font font = new Font(fontFamily, 32, FontStyle.Strikeout))
        {
            e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
        }
    }
}

这也很好用,字体在表单上绘制了 5 次。

所以我在使用这个函数时发现它非常混乱:

//Yes, pts is a valid size. eg 16, 20, 22, 30
private void AdjustFontSize(float pts)
{
    int count = 0;
    //_yPos is a dict<string, int> that contains the Name of each Label control, and its original Y position
    // Therefore, Keys contains the Name prop of each label
    foreach (var lbl in _yPos.Keys)                                 
    {
        var con = Controls[lbl] as Label; //Current label
        FontFamily f = pfc.Families[0]; //Get the font out of pfc. Debugging confirms that f is not null and has a font in it.
        //Why this no work? It works fine if I use a built in font, like "Times"
        con.Font = new Font(f, pts, FontStyle.Regular); 
        //Messing with the location prop, still working on it. Probably not important
        con.Location = new Point(con.Location.X, (int) (_yPos[lbl] + Math.Pow(1.15, (int) pts)*count++)); 
    }
}

标签字体更改为 Arial,而不是我想要的字体。真正困扰我的是,如果我将con.Font = ...更改为使用"Times"而不是f它会正确更改为 Times 字体。最重要的是,我知道字体已正确加载,因为表单绘制正确。按照这个逻辑,我正在正确更改字体,并且我正在正确加载字体,因此它应该可以工作。

标签未使用自定义字体

您需要

UseCompatibleTextRendering设置为 true 才能使用本地加载的字体,该字体不是 Windows 字体库的一部分。

Label有 2 个呈现路径,第一个(也是默认(是使用 GDI 呈现,它不能使用 Font 对象,需要将其转换为内部格式,并期望实际字体位于 Windows 库中。

UseCompatibleTextRendering为 true 时使用的第二条路径是使用 GDI+,通过使用 Graphics.DrawString 方法并传入分配给标签的Font,看起来很像绘制方法。

您还可以使用程序中已存在的Application.SetCompatibleTextRenderingDefault全局设置设置.cs而不是在每个控件上设置,该程序默认使用 WinForms 应用程序创建。