WinForms
当您使用 WinForms 时,几乎不可能进行正确的类型设置,是的,几乎所有事情都必须手动完成。这有几个原因:
- 你没有得到详细的字形信息
- 文本测量非常不准确,无论是 GDI+ 还是基于 GDI 的版本。
Windows 演示基础
如果您使用 WPF,这是完全不同的事情,因为您可以获得有关每个字形的详细几何信息。
但是,您可以将两者交错,有点乱,但可能。虽然,我不推荐它,因为图形和位图不能直接互换,这会导致性能下降。
如果您想查看需要将其导入System.Windows.Media
项目以访问 WPF 的字体和字形功能的可能性。
您还将遇到其他一些挑战:
- WinForm 和 WPF 之间的字体列表并不相同(使用 WPF 的字体和字体类型更多)。
- 您不能只使用 WPF 字形并将其绘制到 WinForm 位图。
- 正如预期的那样,字形中的值是 in
em
因此需要根据点大小将它们转换为像素。
但是,您可以获得以下(不限于)信息:
所有详细信息(此处无法列出):http:
//msdn.microsoft.com/en-us/library/system.windows.media.glyphtypeface.aspx
结论
但是,如果您坚持使用 GDI+ 和 WinForms,您可以采取的最佳方法可能是使用基于 GDI 的TextMetrics类。
在任何情况下,您都会遇到可能的填充问题,您无法设置字符间距等。
您必须使用 top + ascent 计算每种字体和大小的基线:
FontFamily ff = myFont.FontFamily;
float lineSpace = ff.GetLineSpacing(myFont.Style);
float ascent = ff.GetCellAscent(myFont.Style);
float baseline = myFont.GetHeight(ev.Graphics) * ascent / lineSpace;
PointF renderPt = new PointF(pt.X, pt.Y - baseline));
ev.Graphics.DrawString("My baselined text", myFont, textBrush, renderPt);
我不知道有任何第三方库可以在 WinForm 环境中做到这一点,我相信出于这里提到的原因以及它会带来的痛苦。
总之,我只能建议您查看 Windows Presentation Foundation/WPF 以获得更好的基础来实现正确的类型设置,因为您将为此使用 WinForms 陷入许多妥协(我制作了一个字体查看器,我在遇到 WPF,因为我想显示字形和有关它的详细信息,包括黑盒等 - 这已经够痛苦了)。
更新:
WebBrowser 作为排版引擎
一种可能的解决方法是使用 WebBrowser 控件进行设置。这不是真正的 hack,而是有点 hack-ish,因为它最初对用户计算机上的 IE 浏览器建立了不必要的依赖。
但是,当涉及到类型设置时,这会变得很灵活,因为您对文本具有与任何 HTML 页面相同的简单控件。
要获得结果,请附加带有文本样式和属性的 HTML。您甚至可以将它与图像等结合起来(显然)。
例如,该控件可以位于用户不可见的另一个隐藏表单上。
在表单上放入 WebControl 或手动创建它后,只需一步即可完成 HTML 设置:
WebBrowser1.DocumentText = "<span style='font-size:24px;'>Type-setting</span> <span style='font-family:sans-serif;font-size:18px;font-style:italic;'>using the browser component.</span>";
下一步是将您呈现为 HTML 的内容作为图像抓取,可以这样做:
using mshtml;
using System.Drawing;
using System.Runtime.InteropServices;
[ComImport, InterfaceType((short)1), Guid("3050F669-98B5-11CF-BB82-00AA00BDCE0B")]
private interface IHTMLElementRenderFixed
{
void DrawToDC(IntPtr hdc);
void SetDocumentPrinter(string bstrPrinterName, IntPtr hdc);
}
public Bitmap GetImage(string id)
{
HtmlElement e = webBrowser1.Document.GetElementById(id);
IHTMLImgElement img = (IHTMLImgElement)e.DomElement;
IHTMLElementRenderFixed render = (IHTMLElementRenderFixed)img;
Bitmap bmp = new Bitmap(e.OffsetRectangle.Width, e.OffsetRectangle.Height);
Graphics g = Graphics.FromImage(bmp);
IntPtr hdc = g.GetHdc();
render.DrawToDC(hdc);
g.ReleaseHdc(hdc);
return bmp;
}
来自:从 WebBrowser 控件保存图像
现在您可以将位图放到您的普通页面上。..或者直接在表单上使用控件,减少交互能力(如果没有,右键菜单很容易成为问题)。
不知道它的确切用途,这可能是也可能不是合适的解决方案,但它提供了一些强大的选项,并且可以代替第三方解决方案。
成分
从高处和低处看,这个区域似乎没有那么多针对性。我可以找到一个接近的组件,但模式仍在继续:一个将用大锤击中钉子。它最终与 WebBrowser 解决方法属于同一类别。
这个组件实际上是一个成熟的编辑器,但是通过禁用它的大部分,它可能可以用来简单地显示格式化的文本/图形,并且手头有类型设置:
http://www.textcontrol.com/en_US/products/dotnet/overview/
另一种可能性是使用 PDF 组件设置内容并使用组件将 PDF 呈现为图形(商业):
http
://www.dynamicpdf.com/Generate-PDF-.NET.aspx http://www .dynamicpdf.com/Rasterizer-PDF-.NET.aspx
非商业:
http ://www.pdfsharp.net/?AspxAutoDetectCookieSupport=1
使用 GhostScript 获取图像: http:
//www.codeproject.com/Articles/32274/How-To-Convert-PDF-to-Image-Using-Ghostscript-API
显而易见的静态替代方案
..也许还有软木,但无论如何我都会把它包括在内,因为简单有时效果最好 -
如果能够动态创建这些页面不是绝对要求,则在 Illustrator/Photoshop/inDesign 等中生成所有文本和图形,并将结果保存为要显示的图像。