public void CreatePDF(Stream stream) { var doc = new GcPdfDocument(); var font = StandardFonts.Times; var fontSize = 12; // 1/2" margins all around (72 dpi is the default resolution used by GcPdf): var margin = 72 / 2; var pageWidth = doc.PageSize.Width; var pageHeight = doc.PageSize.Height; var cW = pageWidth - margin * 2; // Text format for the chapter titles: var tlCaption = new TextLayout(72); tlCaption.DefaultFormat.Font = font; tlCaption.DefaultFormat.FontSize = fontSize + 4; tlCaption.DefaultFormat.Underline = true; tlCaption.MaxWidth = pageWidth; tlCaption.MaxHeight = pageHeight; tlCaption.MarginLeft = tlCaption.MarginTop = tlCaption.MarginRight = tlCaption.MarginBottom = margin; tlCaption.TextAlignment = TextAlignment.Center; // Height of chapter caption (use a const for simplicity): const float captionH = 24; // Text layout for main document body (default GcPdf resolution is 72dpi): var tl = new TextLayout(72); tl.DefaultFormat.Font = font; tl.DefaultFormat.FontSize = fontSize; tl.FirstLineIndent = 72 / 2; tl.MaxWidth = pageWidth; tl.MaxHeight = pageHeight; tl.MarginLeft = tl.MarginRight = tl.MarginBottom = margin; tl.MarginTop = margin + captionH; tl.ColumnWidth = cW * 0.3f; tl.TextAlignment = TextAlignment.Justified; tl.AlignmentDelayToSplit = true; // Array of PageSplitArea's which control additional columns (1st column is controlled by // the 'main' TextLayout, for each additional one a PageSplitArea must be provided - // it will create and return a TextLayout that can then be used to render the column): var psas = new PageSplitArea[] { new PageSplitArea(tl) { MarginLeft = tl.MarginLeft + (cW * 0.35f) }, new PageSplitArea(tl) { ColumnWidth = -cW * 0.3f } }; // Split options to control splitting text between pages: TextSplitOptions tso = new TextSplitOptions(tl) { RestMarginTop = margin, MinLinesInFirstParagraph = 2, MinLinesInLastParagraph = 2 }; // Generate a number of "chapters", provide outline entry for each: const int NChapters = 20; doc.Pages.Add(); for (int i = 0; i < NChapters; ++i) { // Print chapter header across all columns: string chapter = $"Chapter {i + 1}"; tlCaption.Clear(); tlCaption.Append(chapter); tlCaption.PerformLayout(true); doc.Pages.Last.Graphics.DrawTextLayout(tlCaption, PointF.Empty); // Add outline node for the chapter: doc.Outlines.Add(new OutlineNode(chapter, new DestinationFitV(doc.Pages.Count - 1, null))); // // Clear last chapter's text and add new chapter: tl.FirstLineIsStartOfParagraph = true; tl.LastLineIsEndOfParagraph = true; tl.Clear(); tl.Append(Common.Util.LoremIpsum(5, 7, 9, 15, 25)); tl.PerformLayout(true); // Variable to hold last chapter end's bottom coord: float contentBottom = 0f; // Print the chapter: var tls = new TextLayoutSplitter(tl); while (true) { var tlCol0 = tls.SplitAndBalance(psas, tso); var g = doc.Pages.Last.Graphics; g.DrawTextLayout(tlCol0, PointF.Empty); g.DrawTextLayout(psas[0].TextLayout, PointF.Empty); g.DrawTextLayout(psas[1].TextLayout, PointF.Empty); if (tls.SplitResult != SplitResult.Split) { // End of chapter, find out how much height left on page for next chapter: contentBottom = tl.ContentY + tl.ContentHeight; contentBottom = Math.Max(contentBottom, psas[0].TextLayout.ContentRectangle.Bottom); contentBottom = Math.Max(contentBottom, psas[1].TextLayout.ContentRectangle.Bottom); // Done printing chapter: break; } // Continue printing chapter on new page: psas[0].MarginTop = psas[1].MarginTop = margin; doc.Pages.Add(); } // Next chapter - find out if we have enough space left on current page to start new chapter: if (contentBottom + captionH < pageHeight * 0.8f) { // Start new chapter on current page: contentBottom += pageHeight * 0.05f; tlCaption.MarginTop = contentBottom; tl.MarginTop = psas[0].MarginTop = psas[1].MarginTop = contentBottom + captionH; } else if (i < NChapters - 1) { // Start new chapter on new page: tlCaption.MarginTop = margin; tl.MarginTop = psas[0].MarginTop = psas[1].MarginTop = margin + captionH; doc.Pages.Add(); } } // Done: doc.Save(stream); }
public int CreatePDF(Stream stream) { // Number of pages to generate: const int N = Common.Util.LargeDocumentIterations; var start = DateTime.Now; var doc = new GcPdfDocument(); // Prep a TextLayout to hold/format the text: var tl = new TextLayout(72) { MaxWidth = doc.PageSize.Width, MaxHeight = doc.PageSize.Height, MarginAll = 72, FirstLineIndent = 36, }; tl.DefaultFormat.Font = StandardFonts.Times; tl.DefaultFormat.FontSize = 12; // Generate the document: for (int paraIdx = 0; paraIdx < N; ++paraIdx) { tl.AppendLine(Common.Util.LoremIpsum(1)); } // Split and render TextLayout as shown in the PaginatedText sample: TextSplitOptions tso = new TextSplitOptions(tl) { MinLinesInFirstParagraph = 2, MinLinesInLastParagraph = 2, }; tl.PerformLayout(true); // The loop splitting and rendering the layout: var tls = new TextLayoutSplitter(tl); for (var tlPage = tls.Split(tso); tlPage != null; tlPage = tls.Split(tso)) { doc.NewPage().Graphics.DrawTextLayout(tlPage, PointF.Empty); } tl.Clear(); // Insert a title page (cannot be done if using StartDoc/EndDoc): tl.FirstLineIndent = 0; var fnt = Font.FromFile(Path.Combine("Resources", "Fonts", "yumin.ttf")); var tf0 = new TextFormat() { FontSize = 24, FontBold = true, Font = fnt }; tl.Append(string.Format("Large Document\n{0} Pages of Lorem Ipsum\n\n", N), tf0); var tf1 = new TextFormat(tf0) { FontSize = 14, FontItalic = true }; tl.Append(string.Format("Generated on {0} in {1:m\\m\\ s\\s\\ fff\\m\\s}.", DateTime.Now, DateTime.Now - start), tf1); tl.TextAlignment = TextAlignment.Center; tl.PerformLayout(true); doc.Pages.Insert(0).Graphics.DrawTextLayout(tl, PointF.Empty); // Done: doc.Save(stream); return(doc.Pages.Count); }