标签不使用自定义字体

时间:2013-12-14 03:19:34

标签: c# .net winforms fonts

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

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字体。最重要的是,我知道字体已正确加载,因为表单绘制正确。按照这个逻辑,我正在正确地改变字体,我正在正确加载字体,所以它应该可以工作。

1 个答案:

答案 0 :(得分:0)

您需要将UseCompatibleTextRendering设置为true才能使用不属于Windows字体库的本地加载字体。

Label有2个渲染路径,第一个(默认)是使用GDI渲染,它不能使用Font对象,需要将其转换为内部格式并期望实际字体进入Windows库。

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

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