.net 带有gdi+的PrivateFontCollection有时在WIndows 8或更高版本中使用错误的FontStyle

.net 带有gdi+的PrivateFontCollection有时在WIndows 8或更高版本中使用错误的FontStyle,.net,fonts,gdi+,system.drawing,privatefontcollection,.net,Fonts,Gdi+,System.drawing,Privatefontcollection,如果您有一个从PrivateFontCollection创建的字体,并尝试使用GDI+绘制字符串,它有时会使用错误的FontStyle 我在从内存加载到PrivateFontCollection的字体和从文件加载到PrivateFontCollection的字体中都观察到了这一点 在下面的示例中,我从文件中加载字体。我把它们都放在一个叫做字体的文件夹里。如果我们能像下面那样装载它们 private void loadFontsIntoPrivateCollection() {

如果您有一个从PrivateFontCollection创建的字体,并尝试使用GDI+绘制字符串,它有时会使用错误的FontStyle

我在从内存加载到PrivateFontCollection的字体和从文件加载到PrivateFontCollection的字体中都观察到了这一点

在下面的示例中,我从文件中加载字体。我把它们都放在一个叫做字体的文件夹里。如果我们能像下面那样装载它们

    private void loadFontsIntoPrivateCollection()
    {
        _privateFontCollection = new PrivateFontCollection();
        _families = new Dictionary<string, FontFamily>();

        var files = Directory.GetFiles("Fonts");
        foreach (var file in files)
            _privateFontCollection.AddFontFile(file);

        foreach (var fontFamily in _privateFontCollection.Families)
        {
            _families.Add(fontFamily.Name, fontFamily);
            comboBox1.Items.Add(fontFamily.Name);
        }

        comboBox1.Text = "Californian FB";
    }
然后,在大多数情况下,字符串将以FontStyle.Regular对应的字体绘制。我注意到,如果您注意先加载常规字体,那么FontFamily将伪造除FontStyle.Regular之外的任何FontStyle。不管您是否已将它们加载到PrivateFontCollection中

以下是我在中看到的一些字体

虞哥特式 加州餐饮 双峰 吉尔圣山酒店 柏林圣FB酒店 布朗 传统阿拉伯语 在graphicsPath上执行Graphics.DrawString和AddString时,我会看到这种行为。使用TextRenderer.DrawText将正确绘制字体

您应该能够在Windows 8或10中轻松地重新创建此行为,只需使用PrivateFontCollection的示例代码即可


根据我与微软就这一行为的通信,他们认为这是gdi+的问题。

我们注意到,如果您只将一个FontStyle加载到PrivateFontCollection中,它将始终使用该FontStyle

我们所做的是包装PrivateFontCollection和FontFamily类,因此当我们将字体从文件加载到PrivateFontCollection中时,它实际上会将其添加到4个PrivateFontCollections中的一个,具体取决于字体文件的字体样式

然后,我们通过调用我们自己的FontFamily类来创建字体,该类具有从相应的PrivateFontCollection中选择字体的逻辑。

我已将此问题发布在
    private void panelTextArea_Paint(object sender, PaintEventArgs e)
    {
        var familyToUse = _families[comboBox1.Text];
        var fontToUse = new Font(familyToUse, 28, _styleToUse, GraphicsUnit.World);
        e.Graphics.DrawString(textBox1.Text, fontToUse, Brushes.Black, panelTextArea.ClientRectangle);
    }