我正在使用以下代码加载嵌入字体:
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字体。最重要的是,我知道字体已正确加载,因为表单绘制正确。按照这个逻辑,我正在正确地改变字体,我正在正确加载字体,所以它应该可以工作。
答案 0 :(得分:0)
您需要将UseCompatibleTextRendering
设置为true才能使用不属于Windows字体库的本地加载字体。
Label
有2个渲染路径,第一个(默认)是使用GDI渲染,它不能使用Font
对象,需要将其转换为内部格式并期望实际字体进入Windows库。
当UseCompatibleTextRendering
为真时使用的第二个路径是使用GDI +,看起来很像你的绘制方法,使用Graphics.DrawString
方法并传入分配给标签的Font
。
您还可以使用Application.SetCompatibleTextRenderingDefault
全局设置设置,而不是在每个控件上设置。{{3}}默认情况下使用WinForms应用程序创建的Program.cs中已存在。