【发布时间】:2010-10-18 03:26:18
【问题描述】:
在我正在开发的应用程序中嵌入 truetype 字体的最佳方式是什么?基本上我想确保在另一台机器上安装时我的应用程序可以使用特定的字体。我有 *.ttf 字体文件,只需要一种嵌入方式或在应用程序运行时自动安装它。
我需要在安装过程中设置安装程序来安装字体还是可以在应用程序运行时动态加载字体?事实上,两者都很高兴知道。
应用程序正在使用 .NET 2.0 在 C# 中开发。
【问题讨论】:
在我正在开发的应用程序中嵌入 truetype 字体的最佳方式是什么?基本上我想确保在另一台机器上安装时我的应用程序可以使用特定的字体。我有 *.ttf 字体文件,只需要一种嵌入方式或在应用程序运行时自动安装它。
我需要在安装过程中设置安装程序来安装字体还是可以在应用程序运行时动态加载字体?事实上,两者都很高兴知道。
应用程序正在使用 .NET 2.0 在 C# 中开发。
【问题讨论】:
看起来比这更容易;您可以将字体作为资源嵌入到您的应用中,并在应用的 Properties 命名空间中将其作为强类型属性进行访问。但是给定的链接应该是一个很好的起点。
对于禁用 VB 的用户:
Add the font as a resource in your application. 调用资源 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 属性为真。有些控件不能 用 GDI+ 渲染。
【讨论】:
这个blog post 应该可以帮到你。
基本上,您将字体添加为嵌入式资源,然后将其加载到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);
}
}
}
}
【讨论】:
这可能不是最好的方法,但你不能在资源中包含字体,然后将其复制到 windows 目录上的字体文件夹吗?
【讨论】: