【发布时间】:2023-04-09 03:42:01
【问题描述】:
如何在VB.net/C#中为独立应用[桌面应用]直接使用资源字体而不在本地文件系统中保存字体?
【问题讨论】:
-
@SamSol:没有 CS.NET 这样的东西。你从哪里听说过这个?该语言只是“C#”。
标签: c# vb.net winforms fonts resources
如何在VB.net/C#中为独立应用[桌面应用]直接使用资源字体而不在本地文件系统中保存字体?
【问题讨论】:
标签: c# vb.net winforms fonts resources
这是可能的,您需要使用 PrivateFontCollection.AddMemoryFont() 方法。例如,我添加了一个名为“test.ttf”的字体文件作为资源并像这样使用它:
using System.Drawing.Text;
using System.Runtime.InteropServices;
...
public partial class Form1 : Form {
private static PrivateFontCollection myFonts;
private static IntPtr fontBuffer;
public Form1() {
InitializeComponent();
if (myFonts == null) {
myFonts = new PrivateFontCollection();
byte[] font = Properties.Resources.test;
fontBuffer = Marshal.AllocCoTaskMem(font.Length);
Marshal.Copy(font, 0, fontBuffer, font.Length);
myFonts.AddMemoryFont(fontBuffer, font.Length);
}
}
protected override void OnPaint(PaintEventArgs e) {
FontFamily fam = myFonts.Families[0];
using (Font fnt = new Font(fam, 16)) {
TextRenderer.DrawText(e.Graphics, "Private font", fnt, Point.Empty, Color.Black);
//e.Graphics.DrawString("Private font", fnt, Brushes.Black, 0, 0);
}
}
}
请注意fontBuffer 变量是有意静态的。使用 AddMemoryFont() 时内存管理很困难,只要字体可以使用且 PrivateFontCollection 尚未释放,内存就需要保持有效。如果您没有该保证,请务必不要调用 Marshal.FreeCoTaskMem(),这是一个非常常见的错误,导致很难诊断文本损坏。只有在幸运时才会收到 AccessViolationException。简单的解决方案是让它在程序的生命周期内保持有效。
【讨论】:
AddFontMemResourceEx...也许是因为PrivateFontCollection.AddMemoryFont() 期望字体在系统内存中。我还想知道这是否与我正在更改文本框的字体这一事实有关,而不是与字体显式渲染有关。 (但使用 PrivateFontCollection.AddFontFile() 在没有 PInvoke 功能的情况下仍然有效)。
您是在谈论使用应用程序包装字体吗?如是。 看看这个: http://msdn.microsoft.com/en-us/library/ms753303.aspx
【讨论】: