예제 #1
0
        public int CreatePDF(Stream stream)
        {
            // Number of pages to generate:
            const int N   = Common.Util.LargeDocumentIterations;
            var       doc = new GcPdfDocument();

            // Start creating the document by this call:
            doc.StartDoc(stream);
            // Prep a TextLayout to hold/format the text:
            var tl = new TextLayout(72)
            {
                MaxWidth  = doc.PageSize.Width,
                MaxHeight = doc.PageSize.Height,
                MarginAll = 72,
            };

            tl.DefaultFormat.Font     = StandardFonts.Times;
            tl.DefaultFormat.FontSize = 12;
            // Start with a title page:
            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}.", DateTime.Now), tf1);
            tl.TextAlignment = TextAlignment.Center;
            tl.PerformLayout(true);
            doc.Pages.Add().Graphics.DrawTextLayout(tl, PointF.Empty);
            tl.Clear();
            tl.FirstLineIndent = 36;
            tl.TextAlignment   = TextAlignment.Leading;
            // Generate the document:
            for (int pageIdx = 0; pageIdx < N; ++pageIdx)
            {
                tl.Append(Common.Util.LoremIpsum(1));
                tl.PerformLayout(true);
                doc.NewPage().Graphics.DrawTextLayout(tl, PointF.Empty);
                tl.Clear();
            }
            // NOTE: Certain operations (e.g. the one below) will throw an error when using StartDoc/EndDoc:
            //   doc.Pages.Insert(0);
            //
            // Done - call EndDoc instead of Save():
            doc.EndDoc();
            return(doc.Pages.Count);
        }
예제 #2
0
        // Creates a sample document with 100 pages of 'lorem ipsum':
        private string MakeDocumentToIndex()
        {
            const int N     = 100;
            string    tfile = Path.GetTempFileName();

            using (var fsOut = new FileStream(tfile, FileMode.Open, FileAccess.ReadWrite))
            {
                var tdoc = new GcPdfDocument();
                // See StartEndDoc for details on StartDoc/EndDoc mode:
                tdoc.StartDoc(fsOut);
                // Prep a TextLayout to hold/format the text:
                var tl = new TextLayout(72);
                tl.FontCollection         = _fc;
                tl.DefaultFormat.FontName = _fontFamily;
                tl.DefaultFormat.FontSize = 12;
                // Use TextLayout to layout the whole page including margins:
                tl.MaxHeight       = tdoc.PageSize.Height;
                tl.MaxWidth        = tdoc.PageSize.Width;
                tl.MarginAll       = 72;
                tl.FirstLineIndent = 72 / 2;
                // Generate the document:
                for (int pageIdx = 0; pageIdx < N; ++pageIdx)
                {
                    tl.Append(Common.Util.LoremIpsum(1));
                    tl.PerformLayout(true);
                    tdoc.NewPage().Graphics.DrawTextLayout(tl, PointF.Empty);
                    tl.Clear();
                }
                tdoc.EndDoc();
            }
            return(tfile);
        }
예제 #3
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 pageIdx = 0; pageIdx < N; ++pageIdx)
            {
                tl.Append(Common.Util.LoremIpsum(1));
                tl.PerformLayout(true);
                doc.NewPage().Graphics.DrawTextLayout(tl, 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()
            {
                Font = fnt, FontSize = 24, FontBold = true
            };

            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);
        }
예제 #4
0
        // Renders a list of nodes as a numbered list.
        private PointF RenderNodes(ref Page page, PointF pt, List <Node> nodes, int level)
        {
            TextLayout tlBullet = new TextLayout(72);

            tlBullet.DefaultFormat.Font = StandardFonts.Times;
            tlBullet.MarginLeft         = Layout.ListIndent * level;

            TextLayout tlText = new TextLayout(72);

            tlText.DefaultFormat.Font = StandardFonts.Times;
            tlText.MarginLeft         = Layout.ListOffset + Layout.ListIndent * level;

            for (int i = 0; i < nodes.Count; ++i)
            {
                var g = page.Graphics;
                // Prep item text:
                tlText.Clear();
                tlText.Append(nodes[i].Text);
                tlText.PerformLayout(true);
                if (pt.Y + tlText.ContentHeight > page.Size.Height - Layout.Margin)
                {
                    page = page.Doc.NewPage();
                    g    = page.Graphics;
                    pt.Y = Layout.Margin;
                }
                // Prep item number:
                tlBullet.Clear();
                tlBullet.Append(ItemIdxToString(i, level, tlBullet));
                tlBullet.PerformLayout(true);
                // Render item:
                g.DrawTextLayout(tlBullet, pt);
                g.DrawTextLayout(tlText, pt);
                // Advance insertion point:
                pt.Y += tlText.ContentHeight;
                // Render children:
                if (nodes[i].Children.Count > 0)
                {
                    pt = RenderNodes(ref page, pt, nodes[i].Children, level + 1);
                }
            }
            return(pt);
        }
예제 #5
0
        // Static ctor:
        static GoodsReturnForm()
        {
            // Init Textbox:
            TextLayout tl = new TextLayout(72);

            tl.Append("Qwerty");
            tl.DefaultFormat.Font     = Textbox.Font;
            tl.DefaultFormat.FontSize = Textbox.FontSize;
            tl.PerformLayout(true);
            Textbox.Height         = tl.ContentHeight;
            Textbox.BaselineOffset = tl.Lines[0].GlyphRuns[0].BaselineOffset;
            // Init Checkbox:
            tl.Clear();
            tl.Append("Qwerty");
            tl.DefaultFormat.Font     = Checkbox.Font;
            tl.DefaultFormat.FontSize = Checkbox.FontSize;
            tl.PerformLayout(true);
            Checkbox.Height         = tl.ContentHeight;
            Checkbox.BaselineOffset = tl.Lines[0].GlyphRuns[0].BaselineOffset;
        }
예제 #6
0
        // Method drawing a language's caption and test text:
        private void DrawText(string caption, string text, Font font, bool rtl)
        {
            _captionLayout.Clear();
            _captionLayout.Append(caption);
            _captionLayout.PerformLayout(true);

            _textLayout.Clear();
            _textLayout.DefaultFormat.Font = font;
            _textLayout.RightToLeft        = rtl;
            _textLayout.Append(text);
            _textLayout.PerformLayout(true);
            // Add new page if needed:
            GcGraphics g;

            if (_doc.Pages.Count == 0 || _ipY + tlHeight(_captionLayout) + tlHeight(_textLayout) + c_CaptionToText > _doc.PageSize.Height - c_Margin)
            {
                _ipY = c_Margin;
                g    = _doc.Pages.Add().Graphics;
            }
            else
            {
                g = _doc.Pages.Last.Graphics;
            }
            // Draw caption:
            g.FillRectangle(new RectangleF(c_Margin, _ipY, _captionLayout.MaxWidth.Value, tlHeight(_captionLayout)), Color.SteelBlue);
            g.DrawTextLayout(_captionLayout, new PointF(c_Margin, _ipY));
            _ipY += tlHeight(_captionLayout);
            _ipY += c_CaptionToText;
            // Draw test text:
            g.DrawRectangle(new RectangleF(c_Margin, _ipY, _textLayout.MaxWidth.Value, tlHeight(_textLayout)), Color.LightSteelBlue, 0.5f);
            g.DrawTextLayout(_textLayout, new PointF(c_Margin, _ipY));
            _ipY += tlHeight(_textLayout);
            _ipY += c_TextToCaption;
            return;

            float tlHeight(TextLayout tl)
            {
                return(tl.MarginTop + tl.ContentHeight + tl.MarginBottom);
            }
        }
예제 #7
0
 // Replaces any text fields in the document with regular text:
 private void FlattenDoc(GcPdfDocument doc)
 {
     foreach (var f in doc.AcroForm.Fields)
     {
         if (f is TextField fld)
         {
             var w = fld.Widget;
             var g = w.Page.Graphics;
             _inputTl.Clear();
             _inputTl.Append(fld.Value, _inputTf);
             _inputTl.MaxHeight = w.Rect.Height;
             _inputTl.PerformLayout(true);
             g.DrawTextLayout(_inputTl, w.Rect.Location);
         }
     }
     for (int i = doc.AcroForm.Fields.Count - 1; i >= 0; --i)
     {
         if (doc.AcroForm.Fields[i] is TextField)
         {
             doc.AcroForm.Fields.RemoveAt(i);
         }
     }
 }
예제 #8
0
        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);
        }
예제 #9
0
        // Creates the Time Sheet form:
        private GcPdfDocument MakeTimeSheetForm()
        {
            const float marginH = 72, marginV = 48;
            var         doc  = new GcPdfDocument();
            var         page = doc.NewPage();
            var         g    = page.Graphics;
            var         ip   = new PointF(marginH, marginV);

            var tl = new TextLayout(g.Resolution)
            {
                FontCollection = _fc
            };

            tl.Append("TIME SHEET", new TextFormat()
            {
                FontName = "Segoe UI", FontSize = 18
            });
            tl.PerformLayout(true);
            g.DrawTextLayout(tl, ip);
            ip.Y += tl.ContentHeight + 15;

            var logo = Image.FromFile(Path.Combine("Resources", "ImagesBis", "AcmeLogo-vertical-250px.png"));

            _disposables.Add(logo);
            var s = new SizeF(250f * 0.75f, 64f * 0.75f);

            g.DrawImage(logo, new RectangleF(ip, s), null, ImageAlign.Default);
            ip.Y += s.Height + 5;

            tl.Clear();
            tl.Append("Where Business meets Technology",
                      new TextFormat()
            {
                FontName = "Segoe UI", FontItalic = true, FontSize = 10
            });
            tl.PerformLayout(true);
            g.DrawTextLayout(tl, ip);
            ip.Y += tl.ContentHeight + 15;

            tl.Clear();
            tl.Append("1901, Halford Avenue,\r\nSanta Clara, California – 95051-2553,\r\nUnited States",
                      new TextFormat()
            {
                FontName = "Segoe UI", FontSize = 9
            });
            tl.MaxWidth      = page.Size.Width - marginH * 2;
            tl.TextAlignment = TextAlignment.Trailing;
            tl.PerformLayout(true);
            g.DrawTextLayout(tl, ip);
            ip.Y += tl.ContentHeight + 25;

            var pen = new Pen(Color.Gray, 0.5f);

            var colw    = (page.Size.Width - marginH * 2) / 2;
            var fields1 = DrawTable(ip,
                                    new float[] { colw, colw },
                                    new float[] { 30, 30, 30 },
                                    g, pen);

            var tf = new TextFormat()
            {
                FontName = "Segoe UI", FontSize = 9
            };

            tl.ParagraphAlignment = ParagraphAlignment.Center;
            tl.TextAlignment      = TextAlignment.Leading;
            tl.MarginLeft         = tl.MarginRight = tl.MarginTop = tl.MarginBottom = 4;

            // t_ - caption
            // b_ - bounds
            // f_ - field name, null means no field
            Action <string, RectangleF, string> drawField = (t_, b_, f_) =>
            {
                float tWidth;
                if (!string.IsNullOrEmpty(t_))
                {
                    tl.Clear();
                    tl.MaxHeight = b_.Height;
                    tl.MaxWidth  = b_.Width;
                    tl.Append(t_, tf);
                    tl.PerformLayout(true);
                    g.DrawTextLayout(tl, b_.Location);
                    tWidth = tl.ContentRectangle.Right;
                }
                else
                {
                    tWidth = 0;
                }
                if (!string.IsNullOrEmpty(f_))
                {
                    var fld = new TextField()
                    {
                        Name = f_
                    };
                    fld.Widget.Page = page;
                    fld.Widget.Rect = new RectangleF(
                        b_.X + tWidth + _inputMargin, b_.Y + _inputMargin,
                        b_.Width - tWidth - _inputMargin * 2, b_.Height - _inputMargin * 2);
                    fld.Widget.TextFormat   = _inputTf;
                    fld.Widget.Border.Color = Color.LightSlateGray;
                    fld.Widget.Border.Width = 0.5f;
                    doc.AcroForm.Fields.Add(fld);
                }
            };

            drawField("EMPLOYEE NAME: ", fields1[0, 0], _Names.EmpName);
            drawField("TITLE: ", fields1[1, 0], _Names.EmpTitle);
            drawField("EMPLOYEE NUMBER: ", fields1[0, 1], _Names.EmpNum);
            drawField("STATUS: ", fields1[1, 1], _Names.EmpStatus);
            drawField("DEPARTMENT: ", fields1[0, 2], _Names.EmpDep);
            drawField("SUPERVISOR: ", fields1[1, 2], _Names.EmpSuper);

            ip.Y = fields1[0, 2].Bottom;

            float col0 = 100;

            colw = (page.Size.Width - marginH * 2 - col0) / 5;
            float rowh    = 25;
            var   fields2 = DrawTable(ip,
                                      new float[] { col0, colw, colw, colw, colw, colw },
                                      new float[] { 50, rowh, rowh, rowh, rowh, rowh, rowh, rowh, rowh },
                                      g, pen);

            tl.ParagraphAlignment = ParagraphAlignment.Far;
            drawField("DATE", fields2[0, 0], null);
            drawField("START TIME", fields2[1, 0], null);
            drawField("END TIME", fields2[2, 0], null);
            drawField("REGULAR HOURS", fields2[3, 0], null);
            drawField("OVERTIME HOURS", fields2[4, 0], null);
            tf.FontBold = true;
            drawField("TOTAL HOURS", fields2[5, 0], null);
            tf.FontBold           = false;
            tl.ParagraphAlignment = ParagraphAlignment.Center;
            tf.ForeColor          = Color.Gray;
            for (int i = 0; i < 7; ++i)
            {
                drawField(_Names.Dows[i], fields2[0, i + 1], _Names.DtNames[_Names.Dows[i]][0]);
            }
            tf.ForeColor = Color.Black;
            for (int row = 1; row <= 7; ++row)
            {
                for (int col = 1; col <= 5; ++col)
                {
                    drawField(null, fields2[col, row], _Names.DtNames[_Names.Dows[row - 1]][col]);
                }
            }

            tf.FontBold = true;
            drawField("WEEKLY TOTALS", fields2[0, 8], null);
            tf.FontBold = false;

            drawField(null, fields2[3, 8], _Names.TotalReg);
            drawField(null, fields2[4, 8], _Names.TotalOvr);
            drawField(null, fields2[5, 8], _Names.TotalHours);

            ip.Y = fields2[0, 8].Bottom;

            col0 = 72 * 4;
            colw = page.Size.Width - marginH * 2 - col0;
            var fields3 = DrawTable(ip,
                                    new float[] { col0, colw },
                                    new float[] { rowh + 10, rowh, rowh },
                                    g, pen);

            drawField("EMPLOYEE SIGNATURE: ", fields3[0, 1], null);
            var r = fields3[0, 1];

            _empSignRect = new RectangleF(r.X + r.Width / 2, r.Y, r.Width / 2 - _inputMargin * 2, r.Height);
            // For a digital employee signature, uncomment this code:

            /*
             * SignatureField sf = new SignatureField();
             * sf.Name = _Names.EmpSign;
             * sf.Widget.Rect = new RectangleF(r.X + r.Width / 2, r.Y + _inputMargin, r.Width / 2 - _inputMargin * 2, r.Height - _inputMargin * 2);
             * sf.Widget.Page = page;
             * sf.Widget.BackColor = Color.LightSeaGreen;
             * doc.AcroForm.Fields.Add(sf);
             */
            drawField("DATE: ", fields3[1, 1], _Names.EmpSignDate);

            drawField("SUPERVISOR SIGNATURE: ", fields3[0, 2], null);
            // Supervisor signature:
            r = fields3[0, 2];
            SignatureField sf = new SignatureField();

            sf.Name             = _Names.SupSign;
            sf.Widget.Rect      = new RectangleF(r.X + r.Width / 2, r.Y + _inputMargin, r.Width / 2 - _inputMargin * 2, r.Height - _inputMargin * 2);
            sf.Widget.Page      = page;
            sf.Widget.BackColor = Color.LightYellow;
            doc.AcroForm.Fields.Add(sf);
            drawField("DATE: ", fields3[1, 2], _Names.SupSignDate);

            // Done:
            return(doc);
        }
예제 #10
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;
            }
        }
예제 #11
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);
            }
        }
예제 #12
0
파일: PdfA.cs 프로젝트: GrapeCity/GcPdf
        public void CreatePDF(Stream stream)
        {
            var doc  = new GcPdfDocument();
            var date = new DateTime(1961, 4, 12, 6, 7, 0, DateTimeKind.Utc);

            // Mark the document as PDF/A-3u conformant:
            doc.ConformanceLevel = PdfAConformanceLevel.PdfA3u;

            var fnt = Font.FromFile(Path.Combine("Resources", "Fonts", "arial.ttf"));
            var gap = 36;

            // PDF/A-3a requires all content to be tagged so create and populate StructElement when rendering:
            StructElement sePart = new StructElement("Part");

            doc.StructTreeRoot.Children.Add(sePart);

            TextLayout tl = null;

            // Add 3 pages with sample content tagged according to PDF/A rules:
            for (int pageNo = 1; pageNo <= 3; ++pageNo)
            {
                var   page = doc.Pages.Add();
                var   g    = page.Graphics;
                float y    = 72;
                if (doc.Pages.Count == 1)
                {
                    // Create paragraph element:
                    var seParagraph = new StructElement("P")
                    {
                        DefaultPage = page
                    };
                    // Add it to Part element:
                    sePart.Children.Add(seParagraph);

                    tl           = g.CreateTextLayout();
                    tl.MarginAll = 72;
                    tl.MaxWidth  = page.Size.Width;

                    tl.DefaultFormat.Font     = fnt;
                    tl.DefaultFormat.FontBold = true;
                    tl.DefaultFormat.FontSize = 20;
                    tl.Append("PDF/A-3A Document");

                    // PerformLayout is done automatically in a new TextLayout or after a Clear():
                    //tl.PerformLayout(true);

                    // Draw TextLayout within tagged content:
                    g.BeginMarkedContent(new TagMcid("P", 0));
                    g.DrawTextLayout(tl, PointF.Empty);
                    g.EndMarkedContent();

                    y = tl.ContentRectangle.Bottom + gap;

                    seParagraph.ContentItems.Add(new McidContentItemLink(0));
                }

                // Add some sample paragraphs tagged according to PDF/A rules:
                for (int i = 1; i <= 3; ++i)
                {
                    // Create paragraph element:
                    var seParagraph = new StructElement("P")
                    {
                        DefaultPage = page
                    };
                    // Add it to Part element:
                    sePart.Children.Add(seParagraph);

                    var sb = new StringBuilder();
                    sb.Append(string.Format("Paragraph {0} on page {1}: ", i, pageNo));
                    sb.Append(Common.Util.LoremIpsum(1, 2, 4, 5, 10));
                    var para = sb.ToString();

                    tl.Clear();
                    tl.DefaultFormat.FontSize = 14;
                    tl.DefaultFormat.FontBold = false;
                    tl.MarginTop = y;
                    tl.Append(para);

                    // Draw TextLayout within tagged content:
                    g.BeginMarkedContent(new TagMcid("P", i));
                    g.DrawTextLayout(tl, PointF.Empty);
                    g.EndMarkedContent();

                    y += tl.ContentHeight + gap;

                    // Add content item to paragraph StructElement:
                    seParagraph.ContentItems.Add(new McidContentItemLink(i));

                    // PDF/A-3 allows to embed files into document, but they should be associated with some document element
                    // add embedded file associated with seParagraph:
                    var ef1 = EmbeddedFileStream.FromBytes(doc, Encoding.UTF8.GetBytes(para));
                    // ModificationDate and MimeType should be specified in case of PDF/A:
                    ef1.ModificationDate = date;
                    ef1.MimeType         = "text/plain";
                    var fn  = string.Format("Page{0}_Paragraph{1}.txt", pageNo, i);
                    var fs1 = FileSpecification.FromEmbeddedStream(fn, ef1);
                    // Relationship should be specified in case of PDF/A:
                    fs1.Relationship = AFRelationship.Unspecified;
                    doc.EmbeddedFiles.Add(fn, fs1);
                    seParagraph.AssociatedFiles.Add(fs1);
                }
            }

            // PDF/A-3 allows transparency drawing in PDF file, add some:
            var gpage = doc.Pages[0].Graphics;

            gpage.FillRectangle(new RectangleF(20, 20, 200, 200), Color.FromArgb(40, Color.Red));

            // PDF/A-3 allows to use FormXObjects, add one with transparency:
            var r    = new RectangleF(0, 0, 144, 72);
            var fxo  = new FormXObject(doc, r);
            var gfxo = fxo.Graphics;

            gfxo.FillRectangle(r, Color.FromArgb(40, Color.Violet));
            TextFormat tf = new TextFormat()
            {
                Font      = fnt,
                FontSize  = 16,
                ForeColor = Color.FromArgb(100, Color.Black),
            };

            gfxo.DrawString("FormXObject", tf, r, TextAlignment.Center, ParagraphAlignment.Center);
            gfxo.DrawRectangle(r, Color.Blue, 3);
            gpage.DrawForm(fxo, new RectangleF(300, 250, r.Width, r.Height), null, ImageAlign.ScaleImage);

            // PDF/A-3 allows to use embedded files, but each embedded file must be associated with a document's element:
            EmbeddedFileStream ef = EmbeddedFileStream.FromFile(doc, Path.Combine("Resources", "WordDocs", "ProcurementLetter.docx"));

            // ModificationDate and MimeType should be specified for EmbeddedFile in PDF/A:
            ef.ModificationDate = date;
            ef.MimeType         = "application/msword";
            var fs = FileSpecification.FromEmbeddedFile(ef);

            fs.Relationship = AFRelationship.Unspecified;
            doc.EmbeddedFiles.Add("ProcurementLetter.docx", fs);
            // Associate embedded file with the document:
            doc.AssociatedFiles.Add(fs);

            // Add an attachment associated with an annotation:
            var sa = new StampAnnotation()
            {
                UserName = "******",
                Font     = fnt,
                Rect     = new RectangleF(300, 36, 220, 72),
            };

            sa.Flags |= AnnotationFlags.Print;
            // Use a FormXObject to represent the stamp annotation:
            var stampFxo  = new FormXObject(doc, new RectangleF(PointF.Empty, sa.Rect.Size));
            var gstampFxo = stampFxo.Graphics;

            gstampFxo.FillRectangle(stampFxo.Bounds, Color.FromArgb(40, Color.Green));
            gstampFxo.DrawString("Stamp Annotation\nassociated with minerva.jpg", tf, stampFxo.Bounds, TextAlignment.Center, ParagraphAlignment.Center);
            gstampFxo.DrawRectangle(stampFxo.Bounds, Color.Green, 3);
            //
            sa.AppearanceStreams.Normal.Default = stampFxo;
            doc.Pages[0].Annotations.Add(sa);
            ef = EmbeddedFileStream.FromFile(doc, Path.Combine("Resources", "Images", "minerva.jpg"));
            ef.ModificationDate = date;
            ef.MimeType         = "image/jpeg";
            fs = FileSpecification.FromEmbeddedFile(ef);
            fs.Relationship = AFRelationship.Unspecified;
            doc.EmbeddedFiles.Add("minerva.jpg", fs);
            sa.AssociatedFiles.Add(fs);

            // Mark the document as conforming to Tagged PDF conventions (required for PDF/A):
            doc.MarkInfo.Marked = true;

            // Metadata.CreatorTool and DocumentInfo.Creator should be the same for a PDF/A document:
            doc.Metadata.CreatorTool = doc.DocumentInfo.Creator;
            // A title should be specified for PDF/A document:
            doc.Metadata.Title = "GcPdf Document";
            doc.ViewerPreferences.DisplayDocTitle = true;

            // Done:
            doc.Save(stream);
        }
예제 #13
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);
            }
        }
예제 #14
0
        public void CreatePDF(Stream stream)
        {
            var doc = new GcPdfDocument();
            // Text layout for main text (default GcPdf resolution is 72dpi):
            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;
            // Text layout for chapter headers:
            var tlCaption = new TextLayout(72);

            tlCaption.DefaultFormat.Font      = StandardFonts.TimesBold;
            tlCaption.DefaultFormat.FontSize  = tl.DefaultFormat.FontSize + 4;
            tlCaption.DefaultFormat.Underline = true;
            tlCaption.MaxWidth  = tl.MaxWidth;
            tlCaption.MarginAll = tlCaption.Resolution;
            // Split options to control splitting of text between pages:
            TextSplitOptions to = new TextSplitOptions(tl)
            {
                RestMarginTop            = tl.Resolution,
                MinLinesInFirstParagraph = 2,
                MinLinesInLastParagraph  = 2
            };
            // Generate a number of "chapters", provide outline entry for each:
            const int NChapters = 20;

            for (int i = 0; i < NChapters; ++i)
            {
                // Chapter title - print as chapter header and add as outline node:
                string chapter = $"Chapter {i + 1}";

                // All it takes to add page lables is to add a PageLabelingRange
                // associated with the index of the first page in the range,
                // and the range prefix and numbering style:
                doc.PageLabelingRanges.Add(doc.Pages.Count, new PageLabelingRange($"{chapter}, p. ", NumberingStyle.DecimalArabic, 1));

                doc.Pages.Add();
                tlCaption.Clear();
                tlCaption.Append(chapter);
                tlCaption.PerformLayout(true);
                // Add outline node for the chapter:
                doc.Outlines.Add(new OutlineNode(chapter, new DestinationFitH(doc.Pages.Count - 1, tlCaption.MarginTop)));
                // Print the caption:
                doc.Pages.Last.Graphics.DrawTextLayout(tlCaption, PointF.Empty);
                // Chapter text:
                tl.Clear();
                tl.FirstLineIsStartOfParagraph = true;
                tl.LastLineIsEndOfParagraph    = true;
                tl.Append(Common.Util.LoremIpsum(7));
                // Account for chapter header in the main text layout:
                tl.MarginTop = tlCaption.ContentRectangle.Bottom + 12;
                tl.PerformLayout(true);
                // Print the chapter:
                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;
                    var p = doc.Pages.Add();
                }
            }
            // Done:
            doc.Save(stream);
        }
예제 #15
0
        public void CreatePDF(Stream stream)
        {
            var doc  = new GcPdfDocument();
            var page = doc.NewPage();
            var g    = page.Graphics;
            // As in the Surrogates sample, we specify a standard font
            // (which lacks many of the glyphs we will be rendering),
            // and will rely on font fallback support provided by FontCollection:
            var font = StandardFonts.Helvetica;

            // Set up text formats for captions, "interesting chars" and spacing:
            TextFormat tf = new TextFormat()
            {
                Font = font, FontSize = 12
            };
            TextFormat tf1 = new TextFormat(tf)
            {
                FontSize = 14
            };
            TextFormat tfs = new TextFormat(tf)
            {
                FontSize = 6
            };

            // Create a font collection to use:
            FontCollection fc = new FontCollection();

            // Add our own fallback fonts to use (note that order is imortant here,
            // first come first found):
            fc.AppendFallbackFonts(
                Font.FromFile(Path.Combine("Resources", "Fonts", "arialuni.ttf")),
                Font.FromFile(Path.Combine("Resources", "Fonts", "l_10646.ttf")),
                Font.FromFile(Path.Combine("Resources", "Fonts", "seguiemj.ttf")),
                Font.FromFile(Path.Combine("Resources", "Fonts", "seguisym.ttf")),
                Font.FromFile(Path.Combine("Resources", "Fonts", "simsun.ttc")),
                Font.FromFile(Path.Combine("Resources", "Fonts", "times.ttf")),
                Font.FromFile(Path.Combine("Resources", "Fonts", "YuGothR.ttc"))
                );
            // Restricting default font lookup is done in the TextLayout, so unlike the
            // {Surrogates} sample, here we cannot use DrawString, but must use
            // TextLayout and DrawTextLayout directly:
            // - specify the font collection to use;
            // - restrict default fonts/fallbacks lookup to the specified collection only;
            // - set up other props to render the text.
            TextLayout tl = new TextLayout(72)
            {
                FontCollection       = fc,
                RestrictedFontLookup = true,
                FontFallbackScope    = FontFallbackScope.FontCollectionOnly,
                MaxWidth             = page.Size.Width,
                MaxHeight            = page.Size.Height,
                MarginLeft           = 72,
                MarginRight          = 72,
                MarginTop            = 36,
                MarginBottom         = 36,
                TextAlignment        = TextAlignment.Center,
            };

            tl.Append("Some Interesting Unicode Characters (system-independent)",
                      new TextFormat(tf)
            {
                Underline = true, FontSize = tf.FontSize + 2
            });
            tl.PerformLayout(true);
            g.DrawTextLayout(tl, PointF.Empty);

            tl.MarginTop = tl.ContentRectangle.Bottom + 20;
            tl.Clear();
            tl.TextAlignment = TextAlignment.Leading;

            // Draw the strings:
            tl.Append("Surrogate Pairs:\n", tf);
            tl.Append("\uD867\uDEDB \uD840\uDC0B \uD834\uDD1E \uD834\uDD61 \uD83D\uDC04\n", tf1);
            tl.Append("\n", tfs);

            tl.Append("Currency Symbols:\n", tf);
            tl.Append("\u0024 \u20A0 \u20A1 \u20A2 \u20A3 \u20A4 \u20AC \u20B9 \x20BD\n", tf1);
            tl.Append("\n", tfs);

            tl.Append("Mathematical Operators:\n", tf);
            tl.Append("\u221A \u222B \u2211 \u2210 \u2264 \u2265 \u2202 \u2208\n", tf1);
            tl.Append("\n", tfs);

            tl.Append("CJK Ideographs Extension A:\n", tf);
            tl.Append("\u3400 \u3401 \u3402 \u3403 \u3404 \u3405 \u3406 \u3407\n", tf1);
            tl.Append("\n", tfs);

            tl.Append("Letterlike Symbols:\n", tf);
            tl.Append("\u2110 \u2111 \u2112 \u2113 \u2114 \u2115 \u211B \u211C\n", tf1);
            tl.Append("\n", tfs);

            tl.Append("Private Use Area:\n", tf);
            tl.Append("\uE000 \uE001 \uE010 \uE011 \uE012 \uE013 \uE014 \uE015\n", tf1);
            tl.Append("\n", tfs);

            tl.Append("Arrows:\n", tf);
            tl.Append("\u2190 \u2191 \u2192 \u2193 \u21B0 \u21E6 \u21CB \u21A9\n", tf1);
            tl.Append("\n", tfs);

            tl.Append("Dingbats:\n", tf);
            tl.Append("\u2714 \u2717 \u275B \u275C \u2706 \u2707 \u2708 \u2709\n", tf1);
            tl.Append("\n", tfs);

            tl.Append("Braille Patterns:\n", tf);
            tl.Append("\u2830 \u2831 \u2832 \u2833 \u2834 \u2835 \u2836 \u2837\n", tf1);
            tl.Append("\n", tfs);

            tl.Append("Geometric Shapes:\n", tf);
            tl.Append("\u25D0 \u25D1 \u25D2 \u25D3 \u25A4 \u25F0 \u25BC \u25CE\n", tf1);
            tl.Append("\n", tfs);

            tl.Append("Latin Extended A:\n", tf);
            tl.Append("\u0100 \u0101 \u0102 \u0103 \u0104 \u0105 \u0106 \u0107\n", tf1);
            tl.Append("\n", tfs);

            tl.Append("Miscellaneous Symbols:\n", tf);
            tl.Append("\u2600 \u2601 \u2602 \u2603 \u2604 \u2605 \u2606 \u2607 \u2608 \u2609 \u2614 \u2615 \u26F0\n", tf1);
            tl.Append("\n", tfs);

            tl.PerformLayout(true);
            g.DrawTextLayout(tl, PointF.Empty);

            // Done:
            doc.Save(stream);
        }