示例#1
0
        public int CreatePDF(Stream stream)
        {
            // Setup:
            GcPdfDocument doc = new GcPdfDocument();
            TextLayout    tl  = new TextLayout(72)
            {
                MaxWidth  = doc.PageSize.Width,
                MaxHeight = doc.PageSize.Height,
                MarginAll = 72,
            };

            tl.DefaultFormat.FontSize = 7;
            var tfH = new TextFormat()
            {
                Font = StandardFonts.TimesBold, FontSize = 12
            };
            var tfP = new TextFormat()
            {
                Font = StandardFonts.Times, FontSize = 11
            };

            // Loop through all system fonts,
            // list Unicode ranges provided by each font:
            foreach (Font font in FontCollection.SystemFonts)
            {
                tl.AppendLine($"{font.FontFileName} [{font.FullFontName}] [{font.FontFamilyName}]", tfH);
                var shot = font.CreateFontTables(TableTag.OS2);
                tl.AppendLine(shot.GetUnicodeRanges(), tfP);
                tl.AppendLine();
            }

            // Split and render TextLayout as shown in the PaginatedText sample:
            TextSplitOptions to = new TextSplitOptions(tl)
            {
                MinLinesInFirstParagraph = 2,
                MinLinesInLastParagraph  = 2
            };

            tl.PerformLayout(true);
            while (true)
            {
                var splitResult = tl.Split(to, out TextLayout rest);
                doc.Pages.Add().Graphics.DrawTextLayout(tl, PointF.Empty);
                if (splitResult != SplitResult.Split)
                {
                    break;
                }
                tl = rest;
            }

            // Done:
            doc.Save(stream);
            return(doc.Pages.Count);
        }
示例#2
0
        public int CreatePDF(Stream stream)
        {
            using (var clouds = Image.FromFile(Path.Combine("Resources", "Images", "clouds.jpg")))
                using (var firth = Image.FromFile(Path.Combine("Resources", "Images", "firth.jpg")))
                    using (var lavender = Image.FromFile(Path.Combine("Resources", "Images", "lavender.jpg")))
                    {
                        var yumin = Font.FromFile(Path.Combine("Resources", "Fonts", "yumin.ttf"));
                        var ia    = new ImageAlign(ImageAlignHorz.Left, ImageAlignVert.Top, true, true, true, false, false);

                        var doc = new GcPdfDocument();

                        // The TextLayout that will hold and render the text:
                        var tl = new TextLayout(72);
                        tl.FirstLineIndent       = 18;
                        tl.ParagraphSpacing      = 6;
                        tl.FlowDirection         = FlowDirection.VerticalRightToLeft;
                        tl.TextAlignment         = TextAlignment.Justified;
                        tl.AlignmentDelayToSplit = true;
                        var tf = new TextFormat()
                        {
                            Font = yumin, FontSize = 12
                        };
                        // Repeat test text to fill a few pages:
                        for (int i = 0; i < 25; ++i)
                        {
                            tl.Append(text, tf);
                            tl.AppendLine();
                        }

                        // Layout text in 4 horizontal columns:
                        // (The logic/code in this sample is identical to ArabicColumns):
                        const int NCOLS  = 4;
                        var       margin = 36f;
                        var       gap    = 18f;
                        var       page   = doc.NewPage();
                        page.Landscape = true;
                        var colHeight = (page.Size.Height - margin * 2 - gap * (NCOLS - 1)) / NCOLS;
                        tl.MaxWidth     = page.Size.Width;
                        tl.MaxHeight    = page.Size.Height;
                        tl.MarginLeft   = tl.MarginRight = margin;
                        tl.MarginTop    = margin;
                        tl.MarginBottom = margin + (colHeight + gap) * (NCOLS - 1);
                        // We can specify arbitrary rectangles for the text to flow around.
                        // In this case, we add 3 areas to draw some images:
                        tl.ObjectRects = new List <ObjectRect>()
                        {
                            new ObjectRect(page.Size.Width - margin - 267, margin, 267, 200),
                            new ObjectRect(margin + 100, margin + 60, 133, 100),
                            new ObjectRect(margin, page.Size.Height - margin - 301, 200, 301),
                        };
                        // Convert object rects to image areas, adjust to provide nice looking padding:
                        var rClouds = tl.ObjectRects[0].ToRectangleF();
                        rClouds.Inflate(-4, -3);
                        var rFirth = tl.ObjectRects[1].ToRectangleF();
                        rFirth.Inflate(-4, -3);
                        var rLavender = tl.ObjectRects[2].ToRectangleF();
                        rLavender.Inflate(-4, -3);
                        page.Graphics.DrawImage(clouds, rClouds, null, ia);
                        page.Graphics.DrawImage(firth, rFirth, null, ia);
                        page.Graphics.DrawImage(lavender, rLavender, null, ia);

                        // THE call: it calculates the glyphs needed to draw the text, and lays it out:
                        tl.PerformLayout(true);

                        // Loop while there is still text to render:
                        bool done = false;
                        while (!done)
                        {
                            for (int col = 0; col < NCOLS; ++col)
                            {
                                int nextcol = (col < NCOLS - 1) ? col + 1 : 0;
                                // TextSplitOptions tell TextLayout.Split() how to layout the remaining text.
                                // In this case we advance from column to column by updating top and bottom margins:
                                var tso = new TextSplitOptions(tl)
                                {
                                    RestMarginTop    = margin + (colHeight + gap) * nextcol,
                                    RestMarginBottom = margin + (colHeight + gap) * (NCOLS - 1 - nextcol)
                                };
                                var split = tl.Split(tso, out TextLayout rest);
                                page.Graphics.DrawTextLayout(tl, PointF.Empty);
                                if (split != SplitResult.Split)
                                {
                                    done = true;
                                    break;
                                }
                                tl = rest;
                            }
                            if (!done)
                            {
                                page           = doc.NewPage();
                                page.Landscape = true;
                                // We only want to render images on the first page, so clear ObjectRect:
                                if (tl.ObjectRects != null)
                                {
                                    tl.ObjectRects = null;
                                    // We need to redo the layout, but no need to recalculate the glyphs:
                                    tl.PerformLayout(false);
                                }
                            }
                        }
                        // Done:
                        doc.Save(stream);
                        return(doc.Pages.Count);
                    }
        }
示例#3
0
        void Page1(GcPdfDocument doc)
        {
            var page = doc.Pages.Add();
            var g    = page.Graphics;
            var tl   = new TextLayout(g.Resolution)
            {
                FontCollection = _fc
            };

            var gclogo   = GetImage(Path.Combine("Resources", "ImagesBis", "gc-logo-100px.png"));
            var gclogoRc = new RectangleF(36, 0, 72 * 1.8f, 72);

            g.DrawImage(gclogo, gclogoRc, null,
                        new ImageAlign(ImageAlignHorz.Left, ImageAlignVert.Center, true, true, true, false, false), out RectangleF[] rcs);
            g.DrawLine(rcs[0].Right + 10, rcs[0].Top, rcs[0].Right + 10, rcs[0].Bottom, _darkGray, 1);

            tl.Clear();
            tl.ParagraphAlignment = ParagraphAlignment.Center;
            tl.MaxHeight          = gclogoRc.Height;
            tl.Append("Developer Solutions",
                      new TextFormat()
            {
                FontName = "open sans", FontSize = 16, ForeColor = _darkGray
            });
            tl.PerformLayout(true);
            g.DrawTextLayout(tl, new PointF(gclogoRc.Right + 20, gclogoRc.Y));

            var back       = GetImage(Path.Combine("Resources", "ImagesBis", "GCDocs-datasheet-sm.png"));
            var backRcClip = new RectangleF(0, 72, page.Size.Width, page.Size.Width - 72 * 1.75f);
            var backRc     = new RectangleF(-72, -72 * 4, page.Size.Width + 72 * 4, page.Size.Height + 72 * 4);

            g.DrawImage(back, backRc, backRcClip, ImageAlign.StretchImage);
            g.FillRectangle(new RectangleF(0, backRcClip.Bottom, page.Size.Width, page.Size.Height - backRcClip.Bottom), _lightGray);
            g.DrawLine(backRcClip.X, backRcClip.Bottom, backRcClip.Right, backRcClip.Bottom, Color.White, 1, null);
            g.DrawLine(backRcClip.X, backRcClip.Bottom + 1, backRcClip.Right, backRcClip.Bottom + 1, _darkGray, 1, null);

            var blueRc = new RectangleF(0, backRcClip.Y, page.Size.Width, 72 * 4);

            g.FillRectangle(blueRc, Color.FromArgb(220, _blue));

            blueRc.Inflate(0, -36);
            g.FillRectangle(new RectangleF(blueRc.Location, new SizeF(10, blueRc.Height)), Color.White);

            blueRc.Inflate(-36, 0);
            tl.Clear();
            tl.ParagraphAlignment = ParagraphAlignment.Near;
            tl.MaxWidth           = blueRc.Width;
            tl.MaxHeight          = blueRc.Height;
            tl.Append("NEW PRODUCT LINE",
                      new TextFormat()
            {
                FontName = "open sans semibold", FontSize = 20, ForeColor = Color.White
            });
            tl.PerformLayout(true);
            g.DrawTextLayout(tl, blueRc.Location);

            var midRc = new RectangleF(blueRc.X, blueRc.Y + tl.ContentHeight, blueRc.Width, blueRc.Height - tl.ContentHeight);

            tl.Clear();
            tl.ParagraphAlignment = ParagraphAlignment.Far;
            tl.Append(
                "Take total control of your digital documents with this NEW collection of ultra-fast, low-footprint document APIs for .NET Standard 2.0. These intuitive, extensible APIs " +
                "allow you to create, load, modify, and save Excel spreadsheets and PDF files in any .NET Standard 2.0 application",
                new TextFormat()
            {
                FontName = "open sans light", FontSize = 14, ForeColor = Color.White
            });
            tl.PerformLayout(true);
            g.DrawTextLayout(tl, blueRc.Location);

            midRc.Height -= tl.ContentHeight;
            midRc.Inflate(0, -20);

            var hex   = GetImage(Path.Combine("Resources", "ImagesBis", "gcd-hex-logo-white.png"));
            var hexRc = new RectangleF(midRc.Location, new SizeF(midRc.Height, midRc.Height));

            g.DrawImage(hex, hexRc, null, ImageAlign.StretchImage);

            tl.Clear();
            tl.ParagraphAlignment = ParagraphAlignment.Center;
            tl.MaxHeight          = midRc.Height;
            tl.Append("GrapeCity Documents",
                      new TextFormat()
            {
                FontName = "open sans semibold", FontSize = 26, ForeColor = Color.White
            });
            tl.PerformLayout(true);
            g.DrawTextLayout(tl, new PointF(midRc.X + midRc.Height + 10, midRc.Y));

            var pointRc = new RectangleF(0, backRcClip.Bottom, page.Size.Width / 2, (page.Size.Height - backRcClip.Bottom) / 2 - 12);

            tl.ParagraphAlignment = ParagraphAlignment.Near;
            tl.MaxWidth           = pointRc.Width;
            tl.MaxHeight          = pointRc.Height;
            tl.MarginLeft         = 80;
            tl.MarginTop          = 25;
            tl.MarginBottom       = 0;

            addPoint(GetImage(Path.Combine("Resources", "ImagesBis", "ico-hex-.NET.png")),
                     "Expand the reach of modern apps",
                     "With full support for .NET Standard 2.0, you can target multiple platforms, devices, and cloud with one code base.");

            pointRc.Offset(0, pointRc.Height);
            addPoint(GetImage(Path.Combine("Resources", "ImagesBis", "ico-hex-code.png")),
                     "Comprehensive, highly programmable",
                     "Do more with your Excel spreadsheets and PDFs: these APIs support Windows, Mac, Linux, and a wide variety of features for your documents.");

            pointRc.Offset(pointRc.Width, -pointRc.Height);
            tl.MarginRight = 30;
            addPoint(GetImage(Path.Combine("Resources", "ImagesBis", "ico-hex-speed.png")),
                     "High-speed, small footprint",
                     "The API architecture is designed to generate large, optimized documents, fast—while remaining lightweight and extensible.");

            pointRc.Offset(0, pointRc.Height);
            addPoint(GetImage(Path.Combine("Resources", "ImagesBis", "ico-hex-nodependences.png")),
                     "No dependencies",
                     "Generate and edit digital documents with no Acrobat or Excel dependencies.");

            g.FillRectangle(new RectangleF(0, page.Size.Height - 16, page.Size.Width, 16), _darkGray);

            drawCircle(new PointF(page.Size.Width - 160, backRcClip.Bottom - 105));

            void addPoint(IImage img, string caption, string text)
            {
                var imgRc = new RectangleF(pointRc.X + 20, pointRc.Y + tl.MarginTop, 48, 48);

                g.DrawImage(img, imgRc, null, new ImageAlign()
                {
                    AlignHorz = ImageAlignHorz.Center, AlignVert = ImageAlignVert.Center, BestFit = true
                });
                tl.Clear();
                tl.AppendLine(caption, new TextFormat()
                {
                    FontName = "open sans semibold", FontSize = 11
                });
                tl.Append(text, new TextFormat()
                {
                    FontName = "open sans light", FontSize = 11
                });
                tl.PerformLayout(true);
                if (!tl.ContentHeightFitsInBounds)
                {
                    throw new Exception("Unexpected: text overflow.");
                }
                g.DrawTextLayout(tl, pointRc.Location);
            }

            void drawCircle(PointF p)
            {
                float D     = 128;
                float angle = (float)(16 * Math.PI) / 180f;

                g.Transform =
                    Matrix3x2.CreateTranslation(-D / 2, -D / 2) *
                    Matrix3x2.CreateRotation(angle) *
                    Matrix3x2.CreateTranslation(p.X + D / 2, p.Y + D / 2);

                var r = new RectangleF(PointF.Empty, new SizeF(D, D));

                for (int i = 0; i < 3; ++i)
                {
                    g.FillEllipse(r, Color.FromArgb(30 + i * 10, _darkGray));
                    r.Inflate(-1, -1);
                }
                g.FillEllipse(r, _darkGray);
                r.Inflate(-1, -1);
                g.FillEllipse(r, Color.White);
                r.Inflate(-6, -6);
                g.FillEllipse(r, _darkGray);

                tl.Clear();
                tl.MaxHeight          = tl.MaxWidth = D;
                tl.MarginLeft         = tl.MarginRight = tl.MarginTop = tl.MarginBottom = 0;
                tl.TextAlignment      = TextAlignment.Center;
                tl.ParagraphAlignment = ParagraphAlignment.Center;
                tl.ParagraphSpacing   = -4;
                var tf = new TextFormat()
                {
                    FontName = "open sans light", FontSize = 18, ForeColor = Color.White
                };

                tl.Append("DEPLOY\nTO", tf);
                tl.Append(" AZURE\n", new TextFormat(tf)
                {
                    FontName = "open sans semibold"
                });
                tl.Append(" ");
                tl.PerformLayout(true);
                g.DrawTextLayout(tl, PointF.Empty);

                g.Transform = Matrix3x2.Identity;
            }
        }
示例#4
0
        void Page2(GcPdfDocument doc)
        {
            var page = doc.Pages.Add();
            var g    = page.Graphics;
            var tl   = new TextLayout(g.Resolution)
            {
                FontCollection = _fc
            };
            var col0X    = 36;
            var colWidth = page.Size.Width / 3 - 40;
            var colGap   = 20;
            var vgap     = 10;
            var ser1Y    = 100;
            var ser2Y    = 72 * 6;
            var h        = 45;

            List <(string caption, List <string> points)> gcpdf = new List <(string, List <string>)>()
            {
                ("Advanced Text Handling", new List <string> {
                    "Standard PDF Fonts, Truetype Fonts, Open type Fonts, WOFF Fonts, system font loading, font embedding, fallback and linked fonts, EUDC fonts",
                    "Advanced text rendering features",
                    "Special character support",
                }),
                ("Cross-Platform, Cross-Framework compatibility", new List <string>
                {
                    ".NET Standard 2.0",
                    ".NET Core 2.0",
                    ".NET Framework",
                    "Mono",
                    "Xamarin iOS",
                    "VSTO-style API"
                }),
                ("Security", new List <string>
                {
                    "Encryption and decrpyption",
                    "User and owner passwords",
                    "AllowCopyContent, AllowEditAnnotations, AllowEditContent, AllowPrint",
                    "Digital Signatures"
                }),
                ("Annotations", new List <string>
                {
                    "Figures",
                    "Comments",
                    "Text",
                    "Signatures",
                    "Stamps",
                    "Modify, extract or delete annotations from existing PDFs"
                }),
                ("Fillable Form Fields", new List <string>
                {
                    "Textbox",
                    "Checkbox",
                    "Combobox",
                    "Listbox",
                    "Radio button",
                    "Push button",
                    "Signature field",
                    "Modify, extract or delete form fields from existing PDFs"
                }),
                ("Navigation", new List <string>
                {
                    "Outlines",
                    "Hyperlinks"
                }),
                ("Additional Features", new List <string>
                {
                    "50 barcodes and properties",
                    "Create PDF/A files",
                    "Maintain document history with document properties",
                    "Generate linearized PDFs for fast web view",
                    "Full image and graphic support on all platforms",
                    "Add and delete pages",
                    "Chage page sizes",
                    "Page orientation"
                }),
            };

            List <(string caption, List <string> points)> gcexcel = new List <(string, List <string>)>()
            {
                ("Fast and Efficient", new List <string>
                {
                    "Lightweight",
                    "Optimized for processing large Excel documents quickly"
                }),
                ("Cross-Platform, Cross-Framework compatibility", new List <string>
                {
                    ".NET Standard 2.0",
                    ".NET Core 2.0",
                    ".NET Framework",
                    "Mono",
                    "Xamarin.iOS",
                    "VSTO-style API",
                }),
                ("Data Visualization", new List <string>
                {
                    "Shapes and pictures",
                    "Slicers",
                    "Sparklines",
                    "Charts",
                }),
                ("Powerful Calculation Engine", new List <string>
                {
                    "450+ Excel functions",
                    "Calculate",
                    "Query",
                    "Generate",
                    "Sorting",
                    "Filtering",
                    "Grouping",
                }),
                ("Seamless Excel Compatibility", new List <string>
                {
                    "Import and export Excel files",
                    "Export to PDF",
                    "Encrypt files",
                    "Workbooks and worksheets",
                    "Cell range operations",
                    "Pivot and Excel tables",
                    "Data validation",
                    "Annotations",
                    "Comments",
                }),
                ("Conditional Formatting Rules", new List <string>
                {
                    "Cell value",
                    "Average",
                    "Color scale",
                    "Data bar",
                    "Icon sets",
                    "Top and Bottom",
                    "Unique",
                    "Expression",
                }),
                ("Flexible Themes And Components", new List <string>
                {
                    "Customizable themes",
                    "Configurable components",
                    "Summary data",
                    "Custom styles",
                    "Embedded drawing objects",
                    "Integrated calculation engine",
                }),
            };

            addHeader(45,
                      "GrapeCity Documents for PDF",
                      "This high-speed, feature-rich PDF document API for .NET Standard 2.0 gives you total " +
                      "control of your PDF documents, with no dependencies on Adobe Acrobat.Generate, " +
                      "edit, and store feature - rich PDF documents without compromising design or features.");

            PointF ipt = new PointF(col0X, ser1Y);

            foreach (var(caption, points) in gcpdf)
            {
                var rc = addList(ipt, caption, points.ToArray());
                if (rc.Bottom < ser2Y - 120)
                {
                    ipt = new PointF(rc.X, rc.Bottom + vgap);
                }
                else
                {
                    ipt = new PointF(rc.X + colWidth + colGap, ser1Y);
                }
            }

            addHeader(ser2Y,
                      "GrapeCity Documents for Excel",
                      "Generate high-performance Excel spreadsheets with no dependencies on Excel! " +
                      "Generate, convert, calculate, format, and parse spreadsheets in any app.");

            var topY = ser2Y + h + 10;

            ipt = new PointF(col0X, topY);
            foreach (var(caption, points) in gcexcel)
            {
                var rc = addList(ipt, caption, points.ToArray());
                if (rc.Bottom < page.Size.Height - 100)
                {
                    ipt = new PointF(rc.X, rc.Bottom + vgap);
                }
                else
                {
                    ipt = new PointF(rc.X + colWidth + colGap, topY);
                }
            }

            var hdrRc = new RectangleF(28, 0, page.Size.Width - 28 * 2, 36);

            g.FillRectangle(hdrRc, _darkGray);
            var w = hdrRc.Width / 7;

            string[] hdrs  = new string[] { "Create", "Load", "Edit", "Save", "Analyze" };
            var      hdrTf = new TextFormat()
            {
                FontName = "open sans", FontSize = 12, ForeColor = Color.White
            };
            var trc = new RectangleF(hdrRc.X + w, hdrRc.Y, w, hdrRc.Height);

            for (int i = 0; i < hdrs.Length; ++i)
            {
                g.DrawString(hdrs[i], hdrTf, trc, TextAlignment.Center, ParagraphAlignment.Center, false);
                if (i < hdrs.Length - 1)
                {
                    g.DrawLine(trc.Right, trc.Top + 12, trc.Right, trc.Bottom - 12, Color.White, 1);
                }
                trc.Offset(w, 0);
            }
            var ftrRc = new RectangleF(0, page.Size.Height - 36, page.Size.Width, 36);

            g.FillRectangle(ftrRc, _darkGray);
            var ftr0 = "GrapeCity.com";
            var ftr1 = "© 2018 GrapeCity, Inc.All rights reserved.All other product and brand names are trademarks and/or registered trademarks of their respective holders.";

            ftrRc.Inflate(-col0X, -5);
            hdrTf.FontSize = 12;
            g.DrawString(ftr0, hdrTf, ftrRc, TextAlignment.Leading, ParagraphAlignment.Near, false);
            hdrTf.FontSize = 6;
            g.DrawString(ftr1, hdrTf, ftrRc, TextAlignment.Leading, ParagraphAlignment.Far, false);
            ftrRc.Inflate(0, -5);
            g.DrawImage(GetImage(Path.Combine("Resources", "ImagesBis", "logo-GC-white.png")), ftrRc, null,
                        new ImageAlign()
            {
                AlignHorz = ImageAlignHorz.Right, AlignVert = ImageAlignVert.Center, BestFit = true
            });

            void addHeader(float y, string caption, string text)
            {
                var bluerc = new RectangleF(0, y, 28, h);

                g.FillRectangle(bluerc, _blue);
                var caprc = new RectangleF(bluerc.Right, y, 72 * 2.75f, h);

                g.FillRectangle(caprc, _lightGray);
                caprc.X      = col0X;
                caprc.Width -= col0X - bluerc.Width;
                g.DrawString(caption, new TextFormat()
                {
                    FontName = "open sans semibold", FontSize = 12
                }, caprc, TextAlignment.Leading, ParagraphAlignment.Center, false);
                var textrc = new RectangleF(caprc.Right, caprc.Top, page.Size.Width - caprc.Right, caprc.Height);

                textrc.Inflate(-10, 0);
                g.DrawString(text, new TextFormat()
                {
                    FontName = "open sans light", FontSize = 9
                }, textrc, TextAlignment.Leading, ParagraphAlignment.Center, true);
            }

            RectangleF addList(PointF pt, string caption, params string[] items)
            {
                var tf = new TextFormat()
                {
                    FontName = "open sans light", FontSize = 9
                };
                var ret = new RectangleF(pt, SizeF.Empty);

                tl.Clear();
                tl.MaxWidth = colWidth;
                tl.AppendLine(caption, new TextFormat()
                {
                    FontName = "open sans", FontBold = true, FontSize = 9
                });
                tl.PerformLayout(true);
                g.DrawTextLayout(tl, pt);
                ret.Width  = tl.ContentWidth;
                ret.Height = tl.ContentHeight;
                pt.Y      += ret.Height;
                tl.Clear();
                var itemPrefix = "\u2022  ";

                tl.FirstLineIndent = -g.MeasureStringWithTrailingWhitespace(itemPrefix, tf).Width;
                foreach (var item in items)
                {
                    tl.AppendLine(itemPrefix + item, tf);
                }
                tl.PerformLayout(true);
                g.DrawTextLayout(tl, pt);
                ret.Width   = Math.Max(ret.Width, tl.ContentWidth);
                ret.Height += tl.ContentHeight;
                return(ret);
            }
        }
示例#5
0
        // Adds a word index to the end of the passed document:
        private void AddWordIndex(GcPdfDocument doc, IEnumerable <string> words)
        {
            var tStart = DateTime.Now;

            // Words and page indices where they occur, sorted on words:
            SortedDictionary <string, List <int> > index = new SortedDictionary <string, List <int> >();

            // Here the main loop building the index is on key words.
            // An alternative would be to loop over the pages.
            // Depending on the relative sizes of the keyword dictionary vs
            // the number of pages in the document, one or the other might be better,
            // but this is beyond the scope of this sample.
            foreach (string word in words)
            {
                bool wholeWord = word.IndexOf(' ') == -1;
                var  ft        = doc.FindText(new FindTextParams(word, wholeWord, false), OutputRange.All);
                var  pgs       = ft.Select(fp_ => fp_.PageIndex).Distinct();
                // A very simplistic way of also finding plurals:
                if (wholeWord && !word.EndsWith('s'))
                {
                    var ftpl = doc.FindText(new FindTextParams(word + "s", wholeWord, false), OutputRange.All);
                    pgs = pgs.Concat(ftpl.Select(fp_ => fp_.PageIndex).Distinct()).Distinct();
                }
                if (pgs.Any())
                {
                    var sorted = pgs.ToList();
                    sorted.Sort();
                    index.Add(word, sorted);
                }
            }

            // Prepare to render the index. The whole index is built
            // in a single TextLayout instance, set up to render it
            // in two columns per page.
            // The main rendering loop uses the TextLayout.SplitAndBalance method
            // using the approach demonstrated in BalancedColumns sample.
            // The complication here is that we need to associate a link to the
            // relevant page with each page number rendered, see linkIndices below.
            // Set up the TextLayout:
            const float margin     = 72;
            var         pageWidth  = doc.PageSize.Width;
            var         pageHeight = doc.PageSize.Height;
            var         cW         = pageWidth - margin * 2;
            // Caption (index letter) format:
            var tfCap = new TextFormat()
            {
                FontName = _fontFamily,
                FontBold = true,
                FontSize = 16,
                LineGap  = 24,
            };
            // Index word and pages format:
            var tfRun = new TextFormat()
            {
                FontName = _fontFamily,
                FontSize = 10,
            };
            // Page headers/footers:
            var tfHdr = new TextFormat()
            {
                FontName   = _fontFamily,
                FontItalic = true,
                FontSize   = 10,
            };
            // FirstLineIndent = -18 sets up hanging indent:
            var tl = new TextLayout(72)
            {
                FontCollection         = _fc,
                FirstLineIndent        = -18,
                MaxWidth               = pageWidth,
                MaxHeight              = pageHeight,
                MarginLeft             = margin,
                MarginRight            = margin,
                MarginBottom           = margin,
                MarginTop              = margin,
                ColumnWidth            = cW * 0.46f,
                TextAlignment          = TextAlignment.Leading,
                ParagraphSpacing       = 4,
                LineGapBeforeFirstLine = false,
            };

            // The list of text runs created for page numbers:
            List <Tuple <TextRun, int> > pgnumRuns = new List <Tuple <TextRun, int> >();
            // This loop builds the index on the TextLayout, saving the text runs
            // created for each page number rendered. Note that at this point
            // (prior to the PerformLayout(true) call) the text runs do not contain any info
            // about their code points and render locations, so we can only save the text runs here.
            // Later they will be used to add links to referenced pages in the PDF:
            char litera = ' ';

            foreach (KeyValuePair <string, List <int> > kvp in index)
            {
                var word        = kvp.Key;
                var pageIndices = kvp.Value;
                if (Char.ToUpper(word[0]) != litera)
                {
                    litera = Char.ToUpper(word[0]);
                    tl.Append($"{litera}\u2029", tfCap);
                }
                tl.Append(word, tfRun);
                tl.Append("  ", tfRun);
                for (int i = 0; i < pageIndices.Count; ++i)
                {
                    var from = pageIndices[i];
                    var tr   = tl.Append((from + 1).ToString(), tfRun);
                    pgnumRuns.Add(Tuple.Create(tr, from));
                    // We merge sequential pages into "..-M":
                    int k = i;
                    for (int j = i + 1; j < pageIndices.Count && pageIndices[j] == pageIndices[j - 1] + 1; ++j)
                    {
                        k = j;
                    }
                    if (k > i + 1)
                    {
                        tl.Append("-", tfRun);
                        var to = pageIndices[k];
                        tr = tl.Append((to + 1).ToString(), tfRun);
                        pgnumRuns.Add(Tuple.Create(tr, to));
                        // Fast forward:
                        i = k;
                    }
                    if (i < pageIndices.Count - 1)
                    {
                        tl.Append(", ", tfRun);
                    }
                    else
                    {
                        tl.AppendLine(tfRun);
                    }
                }
            }
            // This calculates the glyphs and lays out the whole index.
            // The tl.SplitAndBalance() call in the loop below does not require redoing the layout:
            tl.PerformLayout(true);

            //
            // Now we are ready to split and render the text layout, and also add links to page numbers.
            //

            // Split areas and options - see BalancedColumns for details:
            var psas = new PageSplitArea[] {
                new PageSplitArea(tl)
                {
                    MarginLeft = tl.MarginLeft + (cW * 0.54f)
                },
            };
            TextSplitOptions tso = new TextSplitOptions(tl)
            {
                KeepParagraphLinesTogether = true,
            };

            // First original code point index in the current column:
            int cpiStart = 0;
            // Max+1 original code point index in the current column:
            int cpiEnd = 0;
            // Current index in pgnumRuns:
            int pgnumRunsIdx = 0;

            // Split and render the index in 2 columns:
            for (var page = doc.Pages.Add(); ; page = doc.Pages.Add())
            {
                var g = page.Graphics;
                // Add a simple page header:
                g.DrawString($"Index generated by GcPdf on {tStart}", tfHdr,
                             new RectangleF(margin, 0, pageWidth - margin * 2, margin),
                             TextAlignment.Center, ParagraphAlignment.Center, false);
                // 'rest' will accept the text that did not fit on this page:
                var splitResult = tl.SplitAndBalance(psas, tso, out TextLayout rest);
                // Render text:
                g.DrawTextLayout(tl, PointF.Empty);
                g.DrawTextLayout(psas[0].TextLayout, PointF.Empty);
                // Add links from page numbers to pages:
                linkIndices(tl, page);
                linkIndices(psas[0].TextLayout, page);
                // Are we done yet?
                if (splitResult != SplitResult.Split)
                {
                    break;
                }
                tl = rest;
            }
            // Done:
            return;

            // Method to add links to actual pages over page numbers in the current column:
            void linkIndices(TextLayout tl_, Page page_)
            {
                cpiEnd += tl_.CodePointCount;
                for (; pgnumRunsIdx < pgnumRuns.Count; ++pgnumRunsIdx)
                {
                    var run     = pgnumRuns[pgnumRunsIdx];
                    var textRun = run.Item1;
                    int cpi     = textRun.CodePointIndex;
                    if (cpi >= cpiEnd)
                    {
                        break;
                    }
                    cpi -= cpiStart;
                    var rects = tl_.GetTextRects(cpi, textRun.CodePointCount);
                    System.Diagnostics.Debug.Assert(rects.Count > 0);
                    page_.Annotations.Add(new LinkAnnotation(rects[0].ToRectangleF(), new DestinationFit(run.Item2)));
                }
                cpiStart += tl_.CodePointCount;
            }
        }
示例#6
0
        public int CreatePDF(Stream stream)
        {
            GcPdfDocument doc  = new GcPdfDocument();
            var           page = doc.NewPage();

            var rc = Common.Util.AddNote(
                "This sample loads the PDF created by the TimeSheet sample into a temporary GcPdfDocument, " +
                "gets the text map for the first page, and prints out the coordinates and texts of all " +
                "line fragments in the map. " +
                "It also uses the map's HitTest method to find the text at specific coordinates in the PDF " +
                "and prints the result. " +
                "The original TimeSheet.pdf used by this sample (consisting of 1 page) is appended for reference.",
                page);

            // Setup text formatting and layout:
            var tf = new TextFormat()
            {
                Font     = StandardFonts.Times,
                FontSize = 13
            };
            var tfFound = new TextFormat()
            {
                Font      = StandardFonts.TimesBold,
                FontSize  = 14,
                ForeColor = Color.DarkBlue
            };
            var tl = new TextLayout(72)
            {
                MaxWidth  = doc.PageSize.Width,
                MaxHeight = doc.PageSize.Height,
                MarginAll = rc.Left,
                MarginTop = rc.Bottom + 36,
                TabStops  = new List <TabStop>()
                {
                    new TabStop(72 * 2)
                },
            };
            TextSplitOptions to = new TextSplitOptions(tl)
            {
                MinLinesInFirstParagraph = 2,
                MinLinesInLastParagraph  = 2,
                RestMarginTop            = rc.Left,
            };

            // Open an arbitrary PDF, load it into a temp document and use the map to find some texts:
            using (var fs = new FileStream(Path.Combine("Resources", "PDFs", "TimeSheet.pdf"), FileMode.Open, FileAccess.Read))
            {
                var doc1 = new GcPdfDocument();
                doc1.Load(fs);
                var tmap = doc1.Pages[0].GetTextMap();

                // We retrieve the text at a specific (known to us) geometric location on the page:
                float       tx0 = 2.1f, ty0 = 3.37f, tx1 = 3.1f, ty1 = 3.5f;
                HitTestInfo htiFrom = tmap.HitTest(tx0 * 72, ty0 * 72);
                HitTestInfo htiTo   = tmap.HitTest(ty0 * 72, ty1 * 72);
                tmap.GetFragment(htiFrom.Pos, htiTo.Pos, out TextMapFragment range1, out string text1);
                tl.AppendLine($"Looked for text inside rectangle x={tx0:F2}\", y={ty0:F2}\", width={tx1-tx0:F2}\", height={ty1-ty0:F2}\", found:", tf);
                tl.AppendLine(text1, tfFound);
                tl.AppendLine();

                // Get all text fragments and their locations on the page:
                tl.AppendLine("List of all texts found on the page", tf);
                tmap.GetFragment(out TextMapFragment range, out string text);
                foreach (TextLineFragment tlf in range)
                {
                    var coords = tmap.GetCoords(tlf);
                    tl.Append($"Text at ({coords.B.X / 72:F2}\",{coords.B.Y / 72:F2}\"):\t", tf);
                    tl.AppendLine(tmap.GetText(tlf), tfFound);
                }

                // Print the results:
                tl.PerformLayout(true);
                while (true)
                {
                    // 'rest' will accept the text that did not fit:
                    var splitResult = tl.Split(to, out TextLayout rest);
                    doc.Pages.Last.Graphics.DrawTextLayout(tl, PointF.Empty);
                    if (splitResult != SplitResult.Split)
                    {
                        break;
                    }
                    tl = rest;
                    doc.NewPage();
                }

                // Append the original document for reference:
                doc.MergeWithDocument(doc1, new MergeDocumentOptions());
            }
            // Done:
            doc.Save(stream);
            return(doc.Pages.Count);
        }
示例#7
0
        // The main sample driver.
        public int CreatePDF(Stream stream)
        {
            GcPdfDocument doc = new GcPdfDocument();
            // This will hold the llst of images so we can dispose them after saving the document:
            List <IDisposable> disposables = new List <IDisposable>();

            // Page footer:
            var ftrImg = Image.FromFile(Path.Combine("Resources", "ImagesBis", "logo-GC-devsol.png"));

            disposables.Add(ftrImg);
            var fx    = ftrImg.HorizontalResolution / 72f;
            var fy    = ftrImg.VerticalResolution / 72f;
            var ftrRc = new RectangleF(
                doc.PageSize.Width / 2 - ftrImg.Width / fx / 2,
                doc.PageSize.Height - 40,
                ftrImg.Width / fx,
                ftrImg.Height / fy);

            // Color for the title:
            var colorBlue = Color.FromArgb(0x3B, 0x5C, 0xAA);
            // Color for the highlights:
            var colorRed = Color.Red;
            // The text layout used to render text:
            TextLayout tl = new TextLayout(72)
            {
                MaxWidth     = doc.PageSize.Width,
                MaxHeight    = doc.PageSize.Height,
                MarginLeft   = 72,
                MarginRight  = 72,
                MarginTop    = 72,
                MarginBottom = 72,
            };

            tl.DefaultFormat.Font     = Font.FromFile(Path.Combine("Resources", "Fonts", "segoeui.ttf"));
            tl.DefaultFormat.FontSize = 11;

            var page = doc.NewPage();

            addFtr();
            var g = page.Graphics;

            // Caption:
            tl.TextAlignment = TextAlignment.Center;
            tl.Append("Introduction\n", new TextFormat()
            {
                FontSize = 16, ForeColor = colorBlue
            });
            tl.Append("The Importance of Wetlands", new TextFormat()
            {
                FontSize = 13, ForeColor = colorBlue
            });
            tl.PerformLayout(true);
            g.DrawTextLayout(tl, PointF.Empty);

            // Move below the caption for the first para:
            tl.MarginTop = tl.ContentHeight + 72 * 2;
            tl.Clear();
            tl.TextAlignment    = TextAlignment.Leading;
            tl.ParagraphSpacing = 12;

            // For the first para we want a bigger initial letter, but no first line indent,
            // so we render it separately from the rest of the text:
            tl.Append(_paras[0].Substring(0, 1), new TextFormat(tl.DefaultFormat)
            {
                FontSize = 22
            });
            addPara(_paras[0].Substring(1));
            tl.PerformLayout(true);
            g.DrawTextLayout(tl, PointF.Empty);

            // Account for the first para, and set up the text layout
            // for the rest of the text (a TextLayout allows to render multiple paragraphs,
            // but they all must have the same paragraph format):
            tl.MarginTop = tl.ContentRectangle.Bottom;
            tl.Clear();
            tl.FirstLineIndent = 36;

            // Add remaining paragraphs:
            foreach (var para in _paras.Skip(1))
            {
                // Paragraphs starting with '::' indicate images to be rendered across the page width:
                if (para.StartsWith("::"))
                {
                    var img = Image.FromFile(Path.Combine("Resources", "ImagesBis", para.Substring(2)));
                    disposables.Add(img);
                    var w = tl.MaxWidth.Value - tl.MarginLeft - tl.MarginRight;
                    var h = (float)img.Height / (float)img.Width * w;
                    tl.AppendInlineObject(img, w, h);
                    tl.AppendLine();
                }
                else
                {
                    addPara(para);
                }
            }
            // Layout the paragraphs:
            tl.PerformLayout(true);
            // Text split options allow to implement widow and orphan control:
            var tso = new TextSplitOptions(tl)
            {
                RestMarginTop            = 72,
                MinLinesInFirstParagraph = 2,
                MinLinesInLastParagraph  = 2,
            };
            // Image alignment used to render the pictures:
            var ia = new ImageAlign(ImageAlignHorz.Left, ImageAlignVert.Top, true, true, true, false, false)
            {
                BestFit = true
            };

            // In a loop, split and render the text:
            while (true)
            {
                var splitResult = tl.Split(tso, out TextLayout rest);
                g = doc.Pages.Last.Graphics;
                doc.Pages.Last.Graphics.DrawTextLayout(tl, PointF.Empty);
                // Render all images that occurred on this page:
                foreach (var io in tl.InlineObjects)
                {
                    doc.Pages.Last.Graphics.DrawImage((Image)io.Object, io.ObjectRect.ToRectangleF(), null, ia);
                }
                // Break unless there is more to render:
                if (splitResult != SplitResult.Split)
                {
                    break;
                }
                // Assign the remaining text to the 'main' TextLayout, add a new page and continue:
                tl = rest;
                doc.Pages.Add();
                addFtr();
            }

            // Save the PDF:
            doc.Save(stream);
            // Dispose images (can be done only after saving the document):
            disposables.ForEach(d_ => d_.Dispose());
            // Done:
            return(doc.Pages.Count);

            void addPara(string para)
            {
                // We implement a primitive markup to highlight some fragments in red:
                var txt = para.Split(new string[] { "<red>", "</red>" }, StringSplitOptions.None);

                for (int i = 0; i < txt.Length; ++i)
                {
                    if (i % 2 == 0)
                    {
                        tl.Append(txt[i]);
                    }
                    else
                    {
                        tl.Append(txt[i], new TextFormat(tl.DefaultFormat)
                        {
                            ForeColor = colorRed
                        });
                    }
                }
                tl.AppendLine();
            }

            void addFtr()
            {
                doc.Pages.Last.Graphics.DrawImage(ftrImg, ftrRc, null, ImageAlign.StretchImage);
            }
        }
示例#8
0
        public void CreatePDF(Stream stream)
        {
            var doc = new GcPdfDocument();

            // Create a Part element, it will contain P (paragraph) elements:
            StructElement sePart = new StructElement("Part");

            doc.StructTreeRoot.Children.Add(sePart);

            // Create and set up a TextLayout to render paragraphs:
            var tl = new TextLayout(72);

            tl.DefaultFormat.Font     = StandardFonts.Times;
            tl.DefaultFormat.FontSize = 12;
            tl.FirstLineIndent        = 72 / 2;
            tl.MaxWidth  = doc.PageSize.Width;
            tl.MaxHeight = doc.PageSize.Height;
            tl.MarginAll = tl.Resolution;
            //
            // Append the text (20 paragraphs so they would not fit on a single page)
            // (note that TextLayout interprets "\r\n" as paragraph delimiter):
            //
            // Get the text (20 paragraphs):
            var text = Common.Util.LoremIpsum(20);
            // In order to tag the individual paragraphs, we need to split the text into paragraphs,
            // and use each paragraph format's Tag property (which is not related to PDF tags,
            // it is just an arbitrary data that can be associated with a TextFormat) to add the
            // paragraph's index to the paragraph:
            var pars = text.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);

            for (int i = 0; i < pars.Length; ++i)
            {
                var tf = new TextFormat(tl.DefaultFormat)
                {
                    Tag = i
                };
                tl.AppendLine(pars[i], tf);
            }

            // Layout the text:
            tl.PerformLayout(true);
            // Use split options to provide widow/orphan control:
            TextSplitOptions to = new TextSplitOptions(tl)
            {
                MinLinesInFirstParagraph = 2,
                MinLinesInLastParagraph  = 2,
            };
            // TextLayoutHandler implements ITextLayoutHandler, which
            // allows to tag the text as it is rendered:
            TextLayoutHandler tlh = new TextLayoutHandler()
            {
                ParentElement = sePart
            };

            // In a loop, split and render the text:
            while (true)
            {
                // 'rest' will accept the text that did not fit:
                var splitResult = tl.Split(to, out TextLayout rest);
                var page        = doc.Pages.Add();
                var g           = page.Graphics;
                // Tell the TextLayoutHandler which page we're on:
                tlh.Page = page;
                // ..and associate it with the graphics:
                g.TextLayoutHandler = tlh;
                // Draw the text that fits on the current page, and advance to next page unless we're done:
                g.DrawTextLayout(tl, PointF.Empty);
                if (splitResult != SplitResult.Split)
                {
                    break;
                }
                tl = rest;
            }
            // Mark document as tagged:
            doc.MarkInfo.Marked = true;

            // Done:
            doc.Save(stream);
        }
示例#9
0
        public int CreatePDF(Stream stream)
        {
            GcPdfDocument doc  = new GcPdfDocument();
            var           page = doc.NewPage();

            var rc = Common.Util.AddNote(
                "This sample loads an arbitrary PDF into a temporary GcPdfDocument, " +
                "then retrieves text from each page of the loaded document using the Page.GetText() method, " +
                "adds all those texts to a TextLayout and renders it into the current document. " +
                "An alternative to Page.GetText() is the method GcPdfDocument.GetText() " +
                "which retrieves the text from the whole document at once.",
                page);

            // Text format for captions:
            var tf = new TextFormat()
            {
                Font      = Font.FromFile(Path.Combine("Resources", "Fonts", "yumin.ttf")),
                FontSize  = 14,
                ForeColor = Color.Blue
            };
            // Text layout to render the text:
            var tl = new TextLayout(72);

            tl.DefaultFormat.Font     = StandardFonts.Times;
            tl.DefaultFormat.FontSize = 12;
            tl.MaxWidth  = doc.PageSize.Width;
            tl.MaxHeight = doc.PageSize.Height;
            tl.MarginAll = rc.Left;
            tl.MarginTop = rc.Bottom + 36;

            // Text split options for widow/orphan control:
            TextSplitOptions to = new TextSplitOptions(tl)
            {
                MinLinesInFirstParagraph = 2,
                MinLinesInLastParagraph  = 2,
                RestMarginTop            = rc.Left,
            };

            // Open an arbitrary PDF, load it into a temp document and get all page texts:
            using (var fs = new FileStream(Path.Combine("Resources", "PDFs", "Wetlands.pdf"), FileMode.Open, FileAccess.Read))
            {
                var doc1 = new GcPdfDocument();
                doc1.Load(fs);

                // Get the texts of the loaded document's pages:
                var texts = new List <string>();
                doc1.Pages.ToList().ForEach(p_ => texts.Add(p_.GetText()));

                // Add texts and captions to the text layout:
                for (int i = 0; i < texts.Count; ++i)
                {
                    tl.AppendLine(string.Format("Text from page {0} of the loaded document:", i + 1), tf);
                    tl.AppendLine(texts[i]);
                }
                tl.PerformLayout(true);
                while (true)
                {
                    // 'rest' will accept the text that did not fit:
                    var splitResult = tl.Split(to, out TextLayout rest);
                    doc.Pages.Last.Graphics.DrawTextLayout(tl, PointF.Empty);
                    if (splitResult != SplitResult.Split)
                    {
                        break;
                    }
                    tl = rest;
                    doc.NewPage();
                }
            }
            // Done:
            doc.Save(stream);
            return(doc.Pages.Count);
        }
示例#10
0
        public int CreatePDF(Stream stream)
        {
            const string pdfName = "ExternalCMapTest.pdf";

            // This line may not be needed if the GcPdfDocument class ctor finds
            // the GrapeCity.Documents.Pdf.Resources.dll at startup
            // (this depends on the way the app is deployed):
            GcPdfDocument.CMapProvider = CMapProvider.Instance;

            GcPdfDocument doc  = new GcPdfDocument();
            var           page = doc.NewPage();

            var rc = Common.Util.AddNote("This sample loads a PDF into a temporary GcPdfDocument, " +
                                         "retrieves all text from each page of the loaded document using the Page.GetText() method, " +
                                         "adds all those texts to a TextLayout and renders it into the current document. " +
                                         "CMaps used by the PDF in this sample are provided by the optional " +
                                         "https://www.nuget.org/packages/GrapeCity.Documents.Pdf.Resources/ package. " +
                                         "Without a reference to that package most of the text in this particular PDF will not be found " +
                                         "as it uses the less common CMaps that are not built into GcPdf itself." +
                                         "\n\n" +
                                         "To use GrapeCity.Documents.Pdf.Resources in a project, add a reference to it, " +
                                         "and either make sure that GrapeCity.Documents.Pdf.Resources.dll is present in the runtime directory, " +
                                         "or add the line:" +
                                         "\n\tGcPdfDocument.CMapProvider = CMapProvider.Instance;" +
                                         "\nto the project's initialization code.",
                                         page);

            Font arialbd  = Font.FromFile(Path.Combine("Resources", "Fonts", "arialbd.ttf"));
            Font segoe    = Font.FromFile(Path.Combine("Resources", "Fonts", "segoeui.ttf"));
            Font arialuni = Font.FromFile(Path.Combine("Resources", "Fonts", "arialuni.ttf"));

            segoe.AddLinkedFont(arialuni);

            // Text format for captions:
            var tf = new TextFormat()
            {
                Font      = arialbd,
                FontSize  = 14,
                ForeColor = Color.Blue
            };
            // Text layout to render the text:
            var tl = new TextLayout(72);

            tl.DefaultFormat.Font     = segoe;
            tl.DefaultFormat.FontSize = 12;
            tl.MaxWidth  = doc.PageSize.Width;
            tl.MaxHeight = doc.PageSize.Height;
            tl.MarginAll = rc.Left;
            tl.MarginTop = rc.Bottom + 36;

            // Text split options for widow/orphan control:
            TextSplitOptions to = new TextSplitOptions(tl)
            {
                MinLinesInFirstParagraph = 2,
                MinLinesInLastParagraph  = 2,
                RestMarginTop            = rc.Left,
            };

            // Open an arbitrary PDF, load it into a temp document and get all page texts:
            using (var fs = new FileStream(Path.Combine("Resources", "PDFs", pdfName), FileMode.Open, FileAccess.Read))
            {
                var doc1 = new GcPdfDocument();
                doc1.Load(fs);

                // Get the texts of the loaded document's pages:
                var texts = new List <string>();
                doc1.Pages.ToList().ForEach(p_ => texts.Add(p_.GetText()));

                // Add texts and captions to the text layout:
                for (int i = 0; i < texts.Count; ++i)
                {
                    tl.AppendLine($"Text from page {i + 1} of {pdfName}:", tf);
                    tl.AppendLine(texts[i]);
                }
                tl.PerformLayout(true);
                while (true)
                {
                    // 'rest' will accept the text that did not fit:
                    var splitResult = tl.Split(to, out TextLayout rest);
                    doc.Pages.Last.Graphics.DrawTextLayout(tl, PointF.Empty);
                    if (splitResult != SplitResult.Split)
                    {
                        break;
                    }
                    tl = rest;
                    doc.NewPage();
                }
            }
            // Done:
            doc.Save(stream);
            return(doc.Pages.Count);
        }
示例#11
0
        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);
        }