NumberedList.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 中将文本段落呈现为编号列表。
// 本示例中渲染文本页面的方法取自PaginatedText
// 样本。另请参见TextRendering。
public class NumberedList
{
// 封装示例中使用的页面布局常量:
private struct Layout
{
public static float Margin => 72;
public static float ListOffset => 24;
};
// 在 TextLayout 中的所有段落前面添加数字的实用方法。
private void AddBullets(GcGraphics g, PointF pt, TextLayout tl, ref int itemNo)
{
var tlBullet = g.CreateTextLayout();
tlBullet.DefaultFormat.Font = StandardFonts.Times;
tlBullet.DefaultFormat.FontSize = 12;
foreach (var line in tl.Lines)
{
if (line.FirstLineInParagraph)
{
tlBullet.Clear();
tlBullet.Append($"{itemNo++})");
tlBullet.PerformLayout(true);
g.DrawTextLayout(tlBullet, new PointF(pt.X, pt.Y + line.Position + line.LineGap));
}
}
}
// 主要入口点:
public int CreatePDF(Stream stream)
{
var doc = new GcPdfDocument();
var ip = new PointF(Layout.Margin, Layout.Margin);
// 使用 TextLayout.MarginLeft 为列表编号/项目符号保留空间:
var tl = new TextLayout(72)
{
MaxWidth = doc.PageSize.Width - Layout.Margin * 2,
MaxHeight = doc.PageSize.Height - Layout.Margin * 2,
ParagraphSpacing = 8,
MarginLeft = Layout.ListOffset,
};
tl.DefaultFormat.Font = StandardFonts.Times;
// 添加 20 段文本,这些文本将呈现为 20 个项目的编号列表:
tl.Append(Common.Util.LoremIpsum(20, 1, 6));
// 执行布局:
tl.PerformLayout(true);
// 使用分割选项来提供寡妇/孤儿控制:
var to = new TextSplitOptions(tl);
to.MinLinesInFirstParagraph = 2;
to.MinLinesInLastParagraph = 2;
// 在循环中,分割并渲染文本(参见PaginatedText),
// 并添加列表编号:
int itemNo = 1;
while (true)
{
// 'rest' 将接受不适合的文本:
var splitResult = tl.Split(to, out TextLayout rest);
var g = doc.Pages.Add().Graphics;
g.DrawTextLayout(tl, ip);
AddBullets(g, ip, tl, ref itemNo);
if (splitResult != SplitResult.Split)
break;
tl = rest;
}
// 完毕:
doc.Save(stream);
return doc.Pages.Count;
}
}
}