在 C# windows.Form 中使用的自定义 .ttf 字体
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/544590/
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
Custom .ttf fonts to use in C# windows.Form
提问by kthakore
How do I use a custom .tff font file I have with my current windows.forms application? I read some where that I use it as an embedded resource, but how do I set it the System.Drawing.Font type?
如何在当前 windows.forms 应用程序中使用自定义 .tff 字体文件?我读了一些我将它用作嵌入式资源的地方,但是如何将其设置为 System.Drawing.Font 类型?
采纳答案by Ash
This article: How to embed a true type fontshows how to do what you ask in .NET.
这篇文章:How to embed a true type font展示了如何在 .NET 中执行您的要求。
How to embed a True Type font
如何嵌入 True Type 字体
Some applications, for reasons of esthetics or a required visual style, will embed certain uncommon fonts so that they are always there when needed regardless of whether the font is actually installed on the destination system.
The secret to this is twofold. First the font needs to be placed in the resources by adding it to the solution and marking it as an embedded resource. Secondly, at runtime, the font is loaded via a stream and stored in a PrivateFontCollection object for later use.
This example uses a font which is unlikely to be installed on your system. Alpha Dance is a free True Type font that is available from the Free Fonts Collection. This font was embedded into the application by adding it to the solution and selecting the "embedded resource" build action in the properties.
出于美观或所需视觉风格的原因,某些应用程序将嵌入某些不常见的字体,以便在需要时它们始终存在,无论该字体是否实际安装在目标系统上。
这样做的秘诀是双重的。首先,需要通过将字体添加到解决方案并将其标记为嵌入资源来将字体放置在资源中。其次,在运行时,字体通过流加载并存储在 PrivateFontCollection 对象中供以后使用。
本示例使用的字体不太可能安装在您的系统上。Alpha Dance 是一种免费的 True Type 字体,可从 Free Fonts Collection 中获得。通过将其添加到解决方案并在属性中选择“嵌入资源”构建操作,将此字体嵌入到应用程序中。
Once the file has been successfully included in the resources you need to provide a PrivateFontCollection object in which to store it and a method by which it's loaded into the collection. The best place to do this is probably the form load override or event handler. The following listing shows the process. Note how the AddMemoryFont method is used. It requires a pointer to the memory in which the font is saved as an array of bytes. In C# we can use the unsafe keyword for convienience but VB must use the capabilities of the Marshal classes unmanaged memory handling. The latter option is of course open to C# programmers who just don't like the unsafe keyword. PrivateFontCollection pfc = new PrivateFontCollection();
一旦文件成功包含在资源中,您需要提供一个 PrivateFontCollection 对象来存储它,以及一个将它加载到集合中的方法。执行此操作的最佳位置可能是表单加载覆盖或事件处理程序。以下清单显示了该过程。请注意如何使用 AddMemoryFont 方法。它需要一个指向将字体保存为字节数组的内存的指针。在 C# 中,为了方便起见,我们可以使用 unsafe 关键字,但 VB 必须使用 Marshal 类的非托管内存处理功能。后一种选择当然对不喜欢 unsafe 关键字的 C# 程序员开放。PrivateFontCollection pfc = new PrivateFontCollection();
private void Form1_Load(object sender, System.EventArgs e)
{
Stream fontStream = this.GetType().Assembly.GetManifestResourceStream("embedfont.Alphd___.ttf");
byte[] fontdata = new byte[fontStream.Length];
fontStream.Read(fontdata,0,(int)fontStream.Length);
fontStream.Close();
unsafe
{
fixed(byte * pFontData = fontdata)
{
pfc.AddMemoryFont((System.IntPtr)pFontData,fontdata.Length);
}
}
}
Fonts may have only certain styles which are available and unfortunately, selecting a font style that doesn't exist will throw an exception. To overcome this the font can be interrogated to see which styles are available and only those provided by the font can be used. The following listing demonstrates how the Alpha Dance font is used by checking the available font styles and showing all those that exist. Note that the underline and strikethrough styles are pseudo styles constructed by the font rendering engine and are not actually provided in glyph form.
字体可能只有某些可用的样式,不幸的是,选择不存在的字体样式将引发异常。为了克服这个问题,可以询问字体以查看哪些样式可用,并且只能使用字体提供的样式。下面的清单通过检查可用的字体样式并显示所有存在的字体样式来演示如何使用 Alpha Dance 字体。请注意,下划线和删除线样式是由字体渲染引擎构建的伪样式,实际上并非以字形形式提供。
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
bool bold=false;
bool regular=false;
bool italic=false;
e.Graphics.PageUnit=GraphicsUnit.Point;
SolidBrush b = new SolidBrush(Color.Black);
float y=5;
System.Drawing.Font fn;
foreach(FontFamily ff in pfc.Families)
{
if(ff.IsStyleAvailable(FontStyle.Regular))
{
regular=true;
fn=new Font(ff,18,FontStyle.Regular);
e.Graphics.DrawString(fn.Name,fn,b,5,y,StringFormat.GenericTypographic);
fn.Dispose();
y+=20;
}
if(ff.IsStyleAvailable(FontStyle.Bold))
{
bold=true;
fn=new Font(ff,18,FontStyle.Bold);
e.Graphics.DrawString(fn.Name,fn,b,5,y,StringFormat.GenericTypographic);
fn.Dispose();
y+=20;
}
if(ff.IsStyleAvailable(FontStyle.Italic))
{
italic=true;
fn=new Font(ff,18,FontStyle.Italic);
e.Graphics.DrawString(fn.Name,fn,b,5,y,StringFormat.GenericTypographic);
fn.Dispose();
y+=20;
}
if(bold && italic)
{
fn=new Font(ff,18,FontStyle.Bold | FontStyle.Italic);
e.Graphics.DrawString(fn.Name,fn,b,5,y,StringFormat.GenericTypographic);
fn.Dispose();
y+=20;
}
fn=new Font(ff,18,FontStyle.Underline);
e.Graphics.DrawString(fn.Name,fn,b,5,y,StringFormat.GenericTypographic);
fn.Dispose();
y+=20;
fn=new Font(ff,18,FontStyle.Strikeout);
e.Graphics.DrawString(fn.Name,fn,b,5,y,StringFormat.GenericTypographic);
fn.Dispose();
}
b.Dispose();
}
Figure 2 shows the application in action.
图 2 显示了运行中的应用程序。
See the Form1_Paint event handler, it shows specifically how to set the System.Drawing.Font type. It is based on using the System.Drawing.Text.PrivateFontCollection class.
请参阅 Form1_Paint 事件处理程序,它具体显示了如何设置 System.Drawing.Font 类型。它基于使用 System.Drawing.Text.PrivateFontCollection 类。
Hope this helps.
希望这可以帮助。
回答by Thomas
Use the AddFontResourceExAPI function through p/invoke, passing FR_PRIVATE to prevent installing a global font. Then you should be able to pass the font name to the Font constructor as usual.
通过 p/invoke使用AddFontResourceExAPI 函数,传递 FR_PRIVATE 以防止安装全局字体。然后您应该能够像往常一样将字体名称传递给 Font 构造函数。
Edit: If you use the PrivateFontCollectionand load the font from an external file, you don't even need this. If you load the font from an embedded resource, use Ash's solution.
编辑:如果您使用PrivateFontCollection并从外部文件加载字体,则甚至不需要它。如果从嵌入的资源加载字体,请使用 Ash 的解决方案。
回答by Alexander Prokofyev
You might find useful a MSDN article How to: Create a Private Font Collection.
您可能会发现 MSDN 文章How to: Create a Private Font Collection很有用。