TextRendering.cs
// 完毕:
using System;
using System.IO;
using System.Drawing;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Drawing;
namespace DsPdfWeb.Demos.Basics
{
// 此示例演示了在 GcDocs.Pdf 中渲染文本的基础知识。
// 两种主要方法是:
// - 使用 MeasureString/DrawString 对,或者
// - 直接使用TextLayout。
// 虽然第一种方法在简单情况下可能更容易,
// 第二种方法(使用 TextLayout)更强大
// 一般来说,会产生更好的性能。
// 请阅读下面代码中的注释以了解更多详细信息。
// 另请参阅CharacterFormatting、PaginatedText、ParagraphAlign、
// ParagraphFormatting、TextAlign。
public class TextRendering
{
public int CreatePDF(Stream stream)
{
var doc = new GcPdfDocument();
var page = doc.NewPage();
var g = page.Graphics;
// 默认情况下,GcDocs.Pdf 使用 72dpi:
const float In = 72;
// TextFormat 类在所有 GcDocs.Pdf 文本渲染中使用来指定
// 字体和其他字符格式:
var tf = new TextFormat() { Font = StandardFonts.Times, FontSize = 12 };
// 1.
// 在页面上的任意位置呈现短字符串的最简单方法,
// 当您 100% 确定字符串适合可用空间时,
// 是使用 GcGraphics.DrawString() 重载接受点
// 在哪里绘制字符串:
g.DrawString("1.测试串。",
tf, new PointF(In, In));
// 2.
// 另一种重载采用矩形,加上对齐和换行
// 选项,也可用并提供更多的灵活性。
// 参数为:
// - 文本字符串;
// - 文本格式;
// - 布局矩形;
// -(可选)文本对齐方式(默认为前导,LTR 语言为左对齐);
// -(可选)段落对齐方式(默认为near、top,为从上到下的流程);
// -(可选)自动换行(默认为true):
g.DrawString("2. 更长的测试字符串,可能需要比分配的更多的字符串" +
"",
tf,
new RectangleF(In, In * 2, In * 4, In),
TextAlignment.Leading,
ParagraphAlignment.Near,
true);
// 3.
// 作为 DrawString 的补充,可以使用 MeasureString() 方法
// (具有几种不同的重载),并且可以与
// 当需要对文本布局进行更多控制时使用 DrawString:
string tstr3 = "3. 测试字符串以演示 MeasureString() 与 DrawString() 的使用。";
// 可用布局尺寸:
SizeF layoutSize = new SizeF(In * 3, In * 0.8f);
SizeF s = g.MeasureString(tstr3, tf, layoutSize, out int fitCharCount);
// 将传入的尺寸显示为红色,测量的尺寸显示为蓝色,
// 并在返回的大小范围内绘制字符串作为边界:
PointF pt = new PointF(In, In * 3);
g.DrawRectangle(new RectangleF(pt, layoutSize), Color.Red);
g.DrawRectangle(new RectangleF(pt, s), Color.Blue);
g.DrawString(tstr3, tf, new RectangleF(pt, s));
// 4.
// 一种更强大、性能更好的文本渲染方式
// 就是使用TextLayout。 (无论如何,TextLayout 都会被 DrawString/MeasureString 使用,
// 所以当你直接使用TextLayout时,基本上你的工作量就减半了。)
// TextLayout 实例表示一个或多个文本段落,其中
// 相同的段落格式(字符格式可能不同,
// 参见MultiFormattedText)。
var tl = g.CreateTextLayout();
// 要添加文本,请使用 Append() 或 AppendLine() 方法:
tl.Append("4. 第一个测试字符串添加到 TextLayout。", tf);
tl.Append("第二个测试字符串添加到 TextLayout,继续同一段落。", tf);
// 添加换行符,有效地开始一个新段落:
tl.AppendLine();
tl.Append("第三个测试字符串添加到 TextLayout,一个新段落。", tf);
tl.Append("第四个测试字符串,具有不同的字符格式。",
new TextFormat(tf) { Font = StandardFonts.TimesBoldItalic, ForeColor = Color.DarkSeaGreen, });
// 无需显式 TextFormat 即可将文本添加到 TextLayout:
tl.Append("第五个测试字符串,使用 TextLayout 的默认格式。");
// ...但在这种情况下,至少必须在
// TextLayout的DefaultFormat,否则PerformLayout(如下)将会失败:
tl.DefaultFormat.Font = StandardFonts.TimesItalic;
// 指定布局,例如最大可用大小等。
// 这里我们只提供最大宽度,但还可以设置更多参数:
tl.MaxWidth = page.Size.Width - In * 2;
// 段落格式也可以设置,这里我们设置首行偏移量,
// 段落间距和行间距:
tl.FirstLineIndent = In * 0.5f;
tl.ParagraphSpacing = In * 0.05f;
tl.LineSpacingScaleFactor = 0.8f;
// 添加所有文本并指定布局选项后,
// TextLayout 需要计算渲染所需的字形
// 文本,并进行布局。这可以通过
// 单次调用:
tl.PerformLayout(true);
// 现在我们可以在页面上绘制它:
pt = new PointF(In, In * 4);
g.DrawTextLayout(tl, pt);
// TextLayout 提供有关文本的信息,包括测量的边界
// 以及更多。这里我们用橙红色绘制边界框:
g.DrawRectangle(new RectangleF(pt, tl.ContentRectangle.Size), Color.OrangeRed);
// 5.
// TextLayout 可以重复使用来绘制不同的段落,这很有用
// 当您需要呈现具有相同段落格式的不同文本时。
// Clear() 调用会删除文本但保留段落格式:
tl.Clear();
tl.Append("5. 这是使用相同 TextLayout 重新呈现的文本。");
tl.Append("添加到 TextLayout 的更多文本被重复使用,继续同一段落。", tf);
tl.Append("最后,添加了一些更多的文字。", tf);
// 计算字形并执行布局所需的调用:
tl.PerformLayout(true);
// 渲染文本:
g.DrawTextLayout(tl, new PointF(In, In * 5));
// 完毕:
doc.Save(stream);
return doc.Pages.Count;
}
}
}