TextRendering.vb
'' 完毕:
Imports System.IO
Imports System.Drawing
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Drawing

'' 此示例演示了在 GcDocs.Pdf 中渲染文本的基础知识。
'' 两种主要方法是:
'' - 使用 MeasureString/DrawString 对,或者
'' - 直接使用TextLayout。
'' 虽然第一种方法在简单情况下可能更容易,
'' 第二种方法(使用 TextLayout)更强大
'' 一般来说,会产生更好的性能。
'' 请阅读下面代码中的注释以了解更多详细信息。
'' 另请参阅CharacterFormattingPaginatedTextParagraphAlign、
'' ParagraphFormattingTextAlign。
Public Class TextRendering
    Function CreatePDF(ByVal stream As Stream) As Integer
        Dim doc = New GcPdfDocument()
        Dim page = doc.NewPage()
        Dim g = page.Graphics
        '' 默认情况下,GcDocs.Pdf 使用 72dpi:
        Const Inch = 72.0F

        '' TextFormat 类在所有 GcDocs.Pdf 文本渲染中使用来指定
        '' 字体和其他字符格式:
        Dim tf = New TextFormat() With {.Font = StandardFonts.Times, .FontSize = 12}

        '' 1.
        '' 在页面上的任意位置呈现短字符串的最简单方法,
        '' 当您 100% 确定字符串适合可用空间时,
        '' 是使用 GcGraphics.DrawString() 重载接受点
        '' 在哪里绘制字符串:
        g.DrawString("1.测试串。", tf, New PointF(Inch, Inch))

        '' 2.
        '' 另一种重载采用矩形,加上对齐和换行
        '' 选项,也可用并提供更多的灵活性。
        '' 参数为:
        '' - 文本字符串;
        '' - 文本格式;
        '' - 布局矩形;
        '' -(可选)文本对齐方式(默认为前导,LTR 语言为左对齐);
        '' -(可选)段落对齐方式(默认为near、top,为从上到下的流程);
        '' -(可选)自动换行(默认为true):
        g.DrawString("2. 更长的测试字符串,可能需要比分配的更多的字符串" +
            "",
            tf,
            New RectangleF(Inch, Inch * 2, Inch * 4, Inch),
            TextAlignment.Leading,
            ParagraphAlignment.Near,
            True)

        '' 3.
        '' 作为 DrawString 的补充,可以使用 MeasureString() 方法
        '' (具有几种不同的重载),并且可以与
        '' 当需要对文本布局进行更多控制时使用 DrawString:
        Dim tstr3 = "3. 测试字符串以演示 MeasureString() 与 DrawString() 的使用。"

        Dim layoutSize = New SizeF(Inch * 3, Inch * 0.8F) '' available size
        Dim fitCharCount As Integer
        Dim s = g.MeasureString(tstr3, tf, layoutSize, fitCharCount)
        '' 将传入的尺寸显示为红色,测量的尺寸显示为蓝色,
        '' 并在返回的大小范围内绘制字符串作为边界:
        Dim pt = New PointF(Inch, Inch * 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)。
        Dim tl = g.CreateTextLayout()
        '' 要添加文本,请使用 Append() 或 AppendLine() 方法:
        tl.Append("4. 第一个测试字符串添加到 TextLayout。", tf)
        tl.Append("第二个测试字符串添加到 TextLayout,继续同一段落。", tf)
        tl.AppendLine() '' Add a line break, effectively starting a new paragraph
        tl.Append("第三个测试字符串添加到 TextLayout,一个新段落。", tf)
        tl.Append("第四个测试字符串,具有不同的字符格式。",
            New TextFormat(tf) With {.Font = StandardFonts.TimesBoldItalic, .ForeColor = Color.DarkSeaGreen})
        '' 无需显式 TextFormat 即可将文本添加到 TextLayout:
        tl.Append("第五个测试字符串,使用 TextLayout 的默认格式。")
        '' ...但在这种情况下,至少必须在
        '' TextLayout的DefaultFormat,否则PerformLayout(如下)将会失败:
        tl.DefaultFormat.Font = StandardFonts.TimesItalic

        '' 指定布局,例如最大可用大小等。
        '' 这里我们只提供最大宽度,但还可以设置更多参数:
        tl.MaxWidth = page.Size.Width - Inch * 2
        '' 段落格式也可以设置,这里我们设置首行偏移量,
        '' 段落间距和行间距:
        tl.FirstLineIndent = Inch * 0.5F
        tl.ParagraphSpacing = Inch * 0.05F
        tl.LineSpacingScaleFactor = 0.8F

        '' 添加所有文本并指定布局选项后,
        '' TextLayout 需要计算渲染所需的字形
        '' 文本,并进行布局。这可以通过
        '' 单次调用:
        tl.PerformLayout(True)

        '' 现在我们可以在页面上绘制它:
        pt = New PointF(Inch, Inch * 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(Inch, Inch * 5))
        ''
        '' 完毕:
        doc.Save(stream)
        Return doc.Pages.Count
    End Function
End Class