如何在 C# 应用程序中嵌入字体?(使用 Visual Studio 2005)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/727053/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I Embed a font with my C# application? (using Visual Studio 2005)
提问by Gary Willoughby
What is the best way to embed a truetype font within the application i'm developing? Basically i want to make sure a particular font is available to my application when installed on another machine. I have the *.ttf font file and just need a way of embedding it or automatically installing it when the application is run.
在我正在开发的应用程序中嵌入 truetype 字体的最佳方法是什么?基本上,我想确保在另一台机器上安装时,我的应用程序可以使用特定的字体。我有 *.ttf 字体文件,只需要一种嵌入它或在应用程序运行时自动安装它的方法。
Do i need to set the installation program to install the font during installation or can i dynamically load the font during runtime of the application? In fact both would be nice to know.
我是否需要在安装过程中设置安装程序来安装字体,还是可以在应用程序运行时动态加载字体?事实上,两者都会很高兴知道。
The application is being developed in C# using .NET 2.0.
该应用程序是使用 .NET 2.0 用 C# 开发的。
采纳答案by dommer
This blog postshould help you.
这篇博文应该对你有所帮助。
Basically you add the font as an embedded resource then load it into a PrivateFontCollectionobject.
基本上,您将字体添加为嵌入资源,然后将其加载到PrivateFontCollection对象中。
回答by Gary Willoughby
Its easier than this seems; you can embed the font as a resource in your app and access it as a strongly-typed property within the Properties namespace of your app. But the given link should be a good starting point.
它看起来比这更容易;您可以将字体作为资源嵌入到您的应用程序中,并在您的应用程序的 Properties 命名空间中将其作为强类型属性进行访问。但是给定的链接应该是一个很好的起点。
For the VB-disabled:
对于 VB 禁用:
Add the font as a resource in your application.Call the resource MyFontLol. You can access this resource (as a byte array) from Properties.Resources.MyFontLol.
将字体作为资源添加到您的应用程序中。调用资源 MyFontLol。您可以从 Properties.Resources.MyFontLol 访问此资源(作为字节数组)。
I haven't tested the following, but it appears to be workable:
我还没有测试以下内容,但它似乎是可行的:
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
}
}
One last note. The PFC stores the font as a GDI+ font. These aren't compatible with some forms controls. From the docs:
最后一点。PFC 将字体存储为 GDI+ 字体。这些与某些表单控件不兼容。从文档:
To use the memory font, text on a control must be rendered with GDI+. Use the SetCompatibleTextRenderingDefaultmethod, passing true, to set GDI+ rendering on the application, or on individual controls by setting the control's UseCompatibleTextRenderingproperty to true. Some controls cannot be rendered with GDI+.
若要使用内存字体,控件上的文本必须使用 GDI+ 呈现。使用 SetCompatibleTextRenderingDefault方法,传递 true,通过将控件的UseCompatibleTextRendering属性设置为 true,在应用程序或单个控件上设置 GDI+ 呈现。某些控件无法使用 GDI+ 呈现。
回答by Chris Doggett
Here's Will's answer, translated to C# (untested):
这是 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);
}
along with their Paint() method:
连同他们的 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);
}
}
}
}
回答by Crash893
it might not be the best way but couldn't you just include the font with your resources and then copy it to the font's folder on the windows dir?
它可能不是最好的方法,但您不能只将字体包含在您的资源中,然后将其复制到 Windows 目录上的字体文件夹中吗?