如何在我正在开发的应用程序中嵌入TrueType字体是最佳方式?基本上,当安装在另一台计算机上时,我希望确保特定字体可供我的应用程序使用。我有*.ttf字体文件,只需要一种将其嵌入或在运行应用程序时自动安装的方法。
我需要设置安装程序在安装期间安装字体,还是可以在应用程序运行时动态加载字体?实际上两种方式都不错。
该应用程序是使用.NET 2.0中的C#开发的。
这篇博客文章可以帮助你。
基本上,你需要将字体作为嵌入式资源添加,然后将其加载到一个PrivateFontCollection对象中。
这里是 Will 的答案,翻译成 C#(未经测试):
PrivateFontCollection pfc = new PrivateFontCollection();
using (Stream fontStream = GetType().Assembly.GetManifestResourceStream("Alphd___.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() 方法一起:
protected void Form1_Paint(object sender, PaintEventArgs e)
{
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);
}
}
}
}
这比看起来要容易得多;您可以将字体作为资源嵌入到应用程序中,并在应用程序的属性命名空间中访问它作为强类型属性。但是,给定的链接应该是一个很好的起点。
对于禁用VB的用户:
将字体作为应用程序资源添加。 将资源命名为MyFontLol。 您可以通过Properties.Resources.MyFontLol访问此资源(作为字节数组)。
我尚未测试以下内容,但似乎可行:
public void LoadMyFontLolKThx()
{
// get our font and wrap it in a memory stream
byte[] myFont = Properties.Resources.MyFontLol;
using (var ms = new MemoryStream(myFont))
{
// used to store our font and make it available in our app
PrivateFontCollection pfc = new PrivateFontCollection();
// The next call requires a pointer to our memory font
// I'm doing it this way; not sure what best practice is
GCHandle handle = GCHandle.Alloc(ms, GCHandleType.Pinned);
// If Length > int.MaxValue this will throw
checked
{
pfc.AddMemoryFont(
handle.AddrOfPinnedObject(), (int)ms.Length);
}
var font = new Font(pfc.Families[0],12);
// use your font here
}
}
最后一点。PFC将字体存储为GDI+字体。这些与某些表单控件不兼容。从文档中可以看出:
要使用内存字体,必须使用GDI+渲染控件上的文本。使用SetCompatibleTextRenderingDefault方法,并传递true,在应用程序上设置GDI+渲染,或通过将控件的UseCompatibleTextRendering属性设置为true,在单个控件上设置。有些控件无法使用GDI+进行渲染。
这可能不是最好的方法,但你可以将字体与资源一起包含,然后将其复制到Windows目录中的字体文件夹中,这样行吗?