// This function is called by the Pades Signature Starter action (see PadesSignatureController.cs).
        // It contains examples of PDF marks, isual elements of arbitrary content placed in every page.
        public static PdfMark GetPdfMark(int sampleNumber)
        {
            switch (sampleNumber)
            {
            case 1:
                // Example #1: A sample text and image are placed at the bottom of every page.
                // First, we create the mark object. It contains no elements, being a simple empty box.
                var mark = new PdfMark()
                {
                    // Here, we set the mark's position in every page.
                    Container = new PadesVisualRectangle()
                    {
                        // Specifying the width (but no left nor right) results in a horizontally centered fixed-width container
                        Width = 8,
                        // Specifying bottom and height (but no top) results in a bottom-aligned fixed-height container
                        Bottom = 0.2,
                        Height = 0.6
                    }
                    // This example has no background and no borders, so we don't set BackgroundColor nor BorderColor
                };

                // First, the image.
                mark.Elements.Add(new PdfMarkImageElement()
                {
                    // We'll position it to the right of the text.
                    RelativeContainer = new PadesVisualRectangle()
                    {
                        // Specifying right and width (but no left) results in a right-aligned fixed-width container
                        Right = 0,
                        Width = 1,
                        // Specifying top and bottom (but no height) results in a variable-height container with the given margins
                        Top    = 0,
                        Bottom = 0
                    },
                    // We'll use the image at 'Content/PdfStamp.png'.
                    Image = new PdfMarkImage(Util.GetPdfStampContent(), "image/png")
                    {
                        // Opacity is an integer from 0 to 100 (0 is completely transparent, 100 is completely opaque).
                        Opacity = 75,
                    }
                });

                // Then, the text.
                mark.Elements.Add(new PdfMarkTextElement()
                {
                    // We center the text.
                    RelativeContainer = new PadesVisualRectangle()
                    {
                        // Specifying left and right (but no width) results in a variable-width container with the given margins
                        Left  = 1,
                        Right = 0,
                        // Specifying just the height results in a vertically centered fixed-height container
                        Height = 0.5
                    },
                    // Then add the text sections.
                    TextSections =
                    {
                        // First, a simple message.
                        new PdfTextSection()
                        {
                            // We set the text.
                            Text = "This document was digitally signed with ",
                            // Its color.
                            Color = Color.Black,
                            // Its size.
                            FontSize = 8,
                            // And the style.
                            Style = PdfTextStyle.Normal
                        },
                        // And a bold ending.
                        new PdfTextSection()
                        {
                            // We set the text.
                            Text = "RestPKI",
                            // Its color.
                            Color = Color.Black,
                            // Its size.
                            FontSize = 8,
                            // And the style.
                            Style = PdfTextStyle.Bold
                        }
                    }
                });

                return(mark);

            case 2:
                // Example #2: An image will be placed at the bottom of every page.
                // First, we create the mark object. It contains no elements, being a simple empty box.
                mark = new PdfMark()
                {
                    // Then, we set the mark's position in every page.
                    Container = new PadesVisualRectangle()
                    {
                        // Specifying right and width (but no left) results in a right-aligned fixed-width container
                        Right = 1,
                        Width = 2.54,
                        // Specifying bottom and height (but no top) results in a bottom-aligned fixed-height container
                        Bottom = 1,
                        Height = 2.54
                    },
                    // After that, its border must be configured.
                    BorderWidth = 0.02,
                    BorderColor = Color.Black
                };

                // Add a single image element
                mark.Elements.Add(new PdfMarkImageElement()
                {
                    // We'll make the image fill the entire mark, leaving space for the border
                    RelativeContainer = new PadesVisualRectangle()
                    {
                        Left   = 0.1,
                        Right  = 0.1,
                        Top    = 0.1,
                        Bottom = 0.1
                    },
                    // We'll use the 'Content/PdfStamp.png' as background.
                    Image = new PdfMarkImage(Util.GetPdfStampContent(), "image/png")
                    {
                        // Opacity is an integer from 0 to 100 (0 is completely transparent, 100 is completely opaque).
                        Opacity = 50,
                    }
                });

                return(mark);

            case 3:
                // Example #3: 'Signed with RestPKI' is printed at the top of every page in a blue horizontal bar.
                // First, we create the mark object. It contains no elements, being a simple empty box.
                mark = new PdfMark()
                {
                    // Then, we set the mark's position in every page.
                    Container = new PadesVisualRectangle()
                    {
                        // Specifying left and right (but no width) results in a variable-width container with the given margins
                        Left  = 0,
                        Right = 0,
                        // Specifying top and height (but no bottom) results in a top-aligned fixed-height container
                        Top    = 0.5,
                        Height = 1
                    },
                    // We'll not need a border, just a background color.
                    BackgroundColor = Color.FromArgb(127, 0, 128, 192)
                };

                // Add a single text element.
                mark.Elements.Add(new PdfMarkTextElement()
                {
                    // We center the text.
                    RelativeContainer = new PadesVisualRectangle()
                    {
                        // Specifying just the width results in a horizontally centered fixed-width container
                        Width = 5,
                        // Specifying just the height results in a vertically centered fixed-height container
                        Height = 1
                    },
                    // Then add the text sections.
                    TextSections =
                    {
                        // This example has a single section.
                        new PdfTextSection()
                        {
                            // We set the text.
                            Text = "Signed with RestPKI",
                            // Its color.
                            Color = Color.White,
                            // Its size.
                            FontSize = 12,
                            // And the style.
                            Style = PdfTextStyle.Bold
                        }
                    }
                });

                return(mark);

            default:
                return(null);
            }
        }
        private byte[] generatePrinterFriendlyVersion(byte[] pdfContent, string verificationCode)
        {
            // The verification code is generated without hyphens to save storage space and avoid copy-and-paste
            // problems. On the PDF generation, we use the "formatted" version, with hyphens (which will later
            // be discarded on the verification page).
            var formattedVerificationCode = AlphaCode.Format(verificationCode);

            // Build the verification link from the constant "VerificationLinkFormat" (see above) and the
            // formatted verification code.
            var verificationLink = string.Format(VerificationLinkFormat, formattedVerificationCode);

            // 1. Inspect signatures on the PDF.
            var signature = Lacuna.Pki.Pades.PadesSignature.Open(pdfContent);

            // 2. Create PDF with verification information from the signed PDF.
            var pdfMarker = new PdfMarker();

            // Build string with joined names of signers (see method getDisplayName() below).
            var signerNames     = Util.JoinStringsPt(signature.Signers.Select(s => getDisplayName(s.Signer.SigningCertificate)));
            var allPagesMessage = string.Format("This document was digitally signed by {0}.\nTo verify the signatures go to {1} on {2} and inform the code {3}", signerNames, VerificationSiteNameWithArticle, VerificationSite, formattedVerificationCode);

            // ICP-Brasil logo on bottom-right corner of every page (except on the page which will be created at
            // the end of the document).
            pdfMarker.AddMark(new PdfMark()
            {
                PageOption = PdfMarkPageOptions.AllPages,
                Container  = new PadesVisualRectangle()
                {
                    Width  = 1,
                    Right  = 1,
                    Height = 1,
                    Bottom = 1
                },
                Elements = new List <PdfMarkElement>()
                {
                    new PdfMarkImage()
                    {
                        ImageContent = Storage.GetIcpBrasilLogoContent(),
                        Opacity      = 75
                    }
                }
            });

            // Summary on bottom margin of every page (except on the page which will be created at the end of
            // the document).
            pdfMarker.AddMark(new PdfMark()
            {
                PageOption = PdfMarkPageOptions.AllPages,
                Container  = new PadesVisualRectangle()
                {
                    Height = 2,
                    Bottom = 0,
                    Left   = 1.5,
                    Right  = 3.5
                },
                Elements = new List <PdfMarkElement>()
                {
                    new PdfMarkText()
                    {
                        Texts = new List <PdfTextSection>()
                        {
                            new PdfTextSection()
                            {
                                Style = PdfTextStyle.Normal,
                                Text  = allPagesMessage
                            }
                        }
                    }
                }
            });

            // Summary on right margin of every page (except on the page which will be created at the end of the
            // document), rotated 90 degrees counterclockwise (text goes up).
            pdfMarker.AddMark(new PdfMark()
            {
                PageOption = PdfMarkPageOptions.AllPages,
                Container  = new PadesVisualRectangle()
                {
                    Width  = 2,
                    Right  = 0,
                    Top    = 1.5,
                    Bottom = 3.5
                },
                Elements = new List <PdfMarkElement>()
                {
                    new PdfMarkText()
                    {
                        Rotation = PdfMarkRotation.D90,
                        Texts    = new List <PdfTextSection>()
                        {
                            new PdfTextSection()
                            {
                                Style = PdfTextStyle.Normal,
                                Text  = allPagesMessage
                            }
                        }
                    }
                }
            });

            // Create a "manifest" mark on a new page added on the end of the document. We'll add several
            // elements to this marks.
            var manifestMark = new PdfMark()
            {
                PageOption = PdfMarkPageOptions.NewPage,
                // This mark's container is the whole page with 1-inch margins.
                Container = new PadesVisualRectangle()
                {
                    Top    = 2.54,
                    Bottom = 2.54,
                    Right  = 2.54,
                    Left   = 2.54
                }
            };

            // We'll keep track of our "vertical offset" as we add elements to the mark.
            double verticalOffset = 0;
            double elementHeight;

            elementHeight = 3;
            // ICP-Brasil logo on the upper-left corner.
            manifestMark.Elements.Add(new PdfMarkImage()
            {
                RelativeContainer = new PadesVisualRectangle()
                {
                    Height = elementHeight,
                    Top    = verticalOffset,
                    Width  = elementHeight,                    /* Using elemengHeight as width because the image is square. */
                    Left   = 0
                },
                ImageContent = Storage.GetIcpBrasilLogoContent()
            });
            // QR Code with the verification link on the upper-right corner. We will generate a PdfMarkImage from
            // a QR Code generated using the QRCoder library.
            byte[] qrCodeImageContent;
            using (var qrGenerator = new QRCodeGenerator()) {
                using (var qrCodeData = qrGenerator.CreateQrCode(verificationLink, QRCodeGenerator.ECCLevel.M)) {
                    using (var qrCode = new QRCode(qrCodeData)) {
                        var qrCodeBitmap = qrCode.GetGraphic(10, Color.Black, Color.White, false);
                        using (var buffer = new MemoryStream()) {
                            qrCodeBitmap.Save(buffer, ImageFormat.Png);
                            qrCodeImageContent = buffer.ToArray();
                        };
                    }
                }
            }
            manifestMark.Elements.Add(new PdfMarkImage()
            {
                RelativeContainer = new PadesVisualRectangle()
                {
                    Height = elementHeight,
                    Top    = verticalOffset,
                    Width  = elementHeight,                    /* Using elemengHeight as width because the image is square. */
                    Right  = 0
                },
                ImageContent = qrCodeImageContent
            });
            // Header "SIGNATURES VERIFICATION" centered between ICP-Brasil logo and QR Code.
            manifestMark.Elements.Add(new PdfMarkText()
            {
                RelativeContainer = new PadesVisualRectangle()
                {
                    Height = elementHeight,
                    Top    = verticalOffset + 0.2,
                    Right  = 0,
                    Left   = 0
                },
                Align = PadesHorizontalAlign.Center,
                Texts = new List <PdfTextSection>()
                {
                    new PdfTextSection()
                    {
                        Style    = PdfTextStyle.Normal,
                        FontSize = NormalFontSize * 1.6,
                        Text     = "SIGNATURES\nVERIFICATION"
                    }
                }
            });
            verticalOffset += elementHeight;

            // Verifical padding.
            verticalOffset += 1.7;

            // Header with verification code.
            elementHeight = 2;
            manifestMark.Elements.Add(new PdfMarkText()
            {
                RelativeContainer = new PadesVisualRectangle()
                {
                    Height = elementHeight,
                    Top    = verticalOffset,
                    Right  = 0,
                    Left   = 0
                },
                Align = PadesHorizontalAlign.Center,
                Texts = new List <PdfTextSection>()
                {
                    new PdfTextSection()
                    {
                        Style    = PdfTextStyle.Normal,
                        FontSize = NormalFontSize * 1.2,
                        Text     = string.Format("Verification Code: {0}", formattedVerificationCode)
                    }
                }
            });
            verticalOffset += elementHeight;

            // Paragraph saying "this document was signed by the following signer etc" and mentioning the time zone of the
            // date/times below.
            elementHeight = 2.5;
            manifestMark.Elements.Add(new PdfMarkText()
            {
                RelativeContainer = new PadesVisualRectangle()
                {
                    Height = elementHeight,
                    Top    = verticalOffset,
                    Left   = 0,
                    Right  = 0
                },
                Texts = new List <PdfTextSection>()
                {
                    new PdfTextSection()
                    {
                        Style    = PdfTextStyle.Normal,
                        FontSize = NormalFontSize,
                        Text     = string.Format("This document was digitally signed by the following signers on the indicated dates ({0}):", TimeZoneDisplayName)
                    }
                }
            });
            verticalOffset += elementHeight;

            // Iterate signers.
            foreach (var signer in signature.Signers)
            {
                elementHeight = 1.5;

                // Validate signature based on the PAdES Basic policy.
                var policyMapper      = PadesPoliciesForGeneration.GetPadesBasic(Util.GetTrustArbitrator());
                var validationResults = signature.ValidateSignature(signer, policyMapper);

                // Green "check" or red "X" icon depending on result of validation for this signer.
                manifestMark.Elements.Add(new PdfMarkImage()
                {
                    RelativeContainer = new PadesVisualRectangle()
                    {
                        Height = 0.5,
                        Top    = verticalOffset + 0.2,
                        Width  = 0.5,
                        Left   = 0
                    },
                    ImageContent = Storage.GetValidationResultIcon(validationResults.IsValid)
                });
                // Description of signer (see method getSignerDescription() below).
                manifestMark.Elements.Add(new PdfMarkText()
                {
                    RelativeContainer = new PadesVisualRectangle()
                    {
                        Height = elementHeight,
                        Top    = verticalOffset,
                        Left   = 0.8,
                        Right  = 0
                    },
                    Texts = new List <PdfTextSection>()
                    {
                        new PdfTextSection()
                        {
                            Style    = PdfTextStyle.Normal,
                            FontSize = NormalFontSize,
                            Text     = getSignerDescription(signer)
                        }
                    }
                });

                verticalOffset += elementHeight;
            }

            // Some vertical padding from last signer.
            verticalOffset += 1;

            // Paragraph with link to veritifcation site and citing both the verification code above and the
            // verification link below.
            elementHeight = 2.5;
            manifestMark.Elements.Add(new PdfMarkText()
            {
                RelativeContainer = new PadesVisualRectangle()
                {
                    Height = elementHeight,
                    Top    = verticalOffset,
                    Right  = 0,
                    Left   = 0
                },
                Texts = new List <PdfTextSection>()
                {
                    new PdfTextSection()
                    {
                        Style    = PdfTextStyle.Normal,
                        FontSize = NormalFontSize,
                        Text     = string.Format("To verify the signatures, go to {0} on ", VerificationSiteNameWithArticle)
                    },
                    new PdfTextSection()
                    {
                        Color    = Color.Blue,
                        Style    = PdfTextStyle.Normal,
                        FontSize = NormalFontSize,
                        Text     = VerificationSite
                    },
                    new PdfTextSection()
                    {
                        Style    = PdfTextStyle.Normal,
                        FontSize = NormalFontSize,
                        Text     = " and inform the code above or follow the link below:"
                    }
                }
            });
            verticalOffset += elementHeight;

            // Verification link.
            elementHeight = 1.5;
            manifestMark.Elements.Add(new PdfMarkText()
            {
                RelativeContainer = new PadesVisualRectangle()
                {
                    Height = elementHeight,
                    Top    = verticalOffset,
                    Right  = 0,
                    Left   = 0
                },
                Align = PadesHorizontalAlign.Center,
                Texts = new List <PdfTextSection>()
                {
                    new PdfTextSection()
                    {
                        Color    = Color.Blue,
                        Style    = PdfTextStyle.Normal,
                        FontSize = NormalFontSize,
                        Text     = verificationLink
                    }
                }
            });
            pdfMarker.AddMark(manifestMark);

            // Prevent from throwing exception when the file to be marked already have a signature (default: true).
            pdfMarker.ThrowIfSignedPdf = false;
            // Note: Before applying the marks, all signature from the signed file will be removed.

            // Apply marks and return the printer-friendly PDF's content.
            byte[] pfvContent = pdfMarker.WriteMarks(pdfContent);
            return(pfvContent);
        }
        // This function is called by the Pades Signature Starter action (see PadesSignatureController.cs).
        // It contains examples of PDF marks, isual elements of arbitrary content placed in every page.
        public static PdfMark GetPdfMark(int sampleNumber)
        {
            switch (sampleNumber) {

                case 1:
                    // Example #1: A sample text and image are placed at the bottom of every page.
                    // First, we create the mark object. It contains no elements, being a simple empty box.
                    var mark = new PdfMark() {
                        // Here, we set the mark's position in every page.
                        Container = new PadesVisualRectangle() {
                            // Specifying the width (but no left nor right) results in a horizontally centered fixed-width container
                            Width = 8,
                            // Specifying bottom and height (but no top) results in a bottom-aligned fixed-height container
                            Bottom = 0.2,
                            Height = 0.6
                        }
                        // This example has no background and no borders, so we don't set BackgroundColor nor BorderColor
                    };

                    // First, the image.
                    mark.Elements.Add(new PdfMarkImageElement() {
                        // We'll position it to the right of the text.
                        RelativeContainer = new PadesVisualRectangle() {
                            // Specifying right and width (but no left) results in a right-aligned fixed-width container
                            Right = 0,
                            Width = 1,
                            // Specifying top and bottom (but no height) results in a variable-height container with the given margins
                            Top = 0,
                            Bottom = 0
                        },
                        // We'll use the image at 'Content/PdfStamp.png'.
                        Image = new PdfMarkImage(Util.GetPdfStampContent(), "image/png") {
                            // Opacity is an integer from 0 to 100 (0 is completely transparent, 100 is completely opaque).
                            Opacity = 75,
                        }
                    });

                    // Then, the text.
                    mark.Elements.Add(new PdfMarkTextElement() {
                        // We center the text.
                        RelativeContainer = new PadesVisualRectangle() {
                            // Specifying left and right (but no width) results in a variable-width container with the given margins
                            Left = 1,
                            Right = 0,
                            // Specifying just the height results in a vertically centered fixed-height container
                            Height = 0.5
                        },
                        // Then add the text sections.
                        TextSections = {
                            // First, a simple message.
                            new PdfTextSection() {
                                // We set the text.
                                Text = "This document was digitally signed with ",
                                // Its color.
                                Color = Color.Black,
                                // Its size.
                                FontSize = 8,
                                // And the style.
                                Style = PdfTextStyle.Normal
                            },
                            // And a bold ending.
                            new PdfTextSection() {
                                // We set the text.
                                Text = "RestPKI",
                                // Its color.
                                Color = Color.Black,
                                // Its size.
                                FontSize = 8,
                                // And the style.
                                Style = PdfTextStyle.Bold
                            }
                        }
                    });

                    return mark;

                case 2:
                    // Example #2: An image will be placed at the bottom of every page.
                    // First, we create the mark object. It contains no elements, being a simple empty box.
                    mark = new PdfMark() {
                        // Then, we set the mark's position in every page.
                        Container = new PadesVisualRectangle() {
                            // Specifying right and width (but no left) results in a right-aligned fixed-width container
                            Right = 1,
                            Width = 2.54,
                            // Specifying bottom and height (but no top) results in a bottom-aligned fixed-height container
                            Bottom = 1,
                            Height = 2.54
                        },
                        // After that, its border must be configured.
                        BorderWidth = 0.02,
                        BorderColor = Color.Black
                    };

                    // Add a single image element
                    mark.Elements.Add(new PdfMarkImageElement() {
                        // We'll make the image fill the entire mark, leaving space for the border
                        RelativeContainer = new PadesVisualRectangle() {
                            Left = 0.1,
                            Right = 0.1,
                            Top = 0.1,
                            Bottom = 0.1
                        },
                        // We'll use the 'Content/PdfStamp.png' as background.
                        Image = new PdfMarkImage(Util.GetPdfStampContent(), "image/png") {
                            // Opacity is an integer from 0 to 100 (0 is completely transparent, 100 is completely opaque).
                            Opacity = 50,
                        }
                    });

                    return mark;

                case 3:
                    // Example #3: 'Signed with RestPKI' is printed at the top of every page in a blue horizontal bar.
                    // First, we create the mark object. It contains no elements, being a simple empty box.
                    mark = new PdfMark() {
                        // Then, we set the mark's position in every page.
                        Container = new PadesVisualRectangle() {
                            // Specifying left and right (but no width) results in a variable-width container with the given margins
                            Left = 0,
                            Right = 0,
                            // Specifying top and height (but no bottom) results in a top-aligned fixed-height container
                            Top = 0.5,
                            Height = 1
                        },
                        // We'll not need a border, just a background color.
                        BackgroundColor = Color.FromArgb(127, 0, 128, 192)
                    };

                    // Add a single text element.
                    mark.Elements.Add(new PdfMarkTextElement() {
                        // We center the text.
                        RelativeContainer = new PadesVisualRectangle() {
                            // Specifying just the width results in a horizontally centered fixed-width container
                            Width = 5,
                            // Specifying just the height results in a vertically centered fixed-height container
                            Height = 1
                        },
                        // Then add the text sections.
                        TextSections = {
                            // This example has a single section.
                            new PdfTextSection() {
                                // We set the text.
                                Text = "Signed with RestPKI",
                                // Its color.
                                Color = Color.White,
                                // Its size.
                                FontSize = 12,
                                // And the style.
                                Style = PdfTextStyle.Bold
                            }
                        }
                    });

                    return mark;

                default:
                    return null;

            }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            var cadesSignatureContent = Storage.GetSampleCadesSignatureOfPdf();
            var cadesSignature        = Lacuna.Pki.Cades.CadesSignature.Open(cadesSignatureContent);

            var fontSize  = 10;
            var markTexts = new List <PdfTextSection>()
            {
                new PdfTextSection()
                {
                    Text     = "Document digitally signed by ",
                    FontSize = fontSize
                }
            };

            for (int i = 0; i < cadesSignature.Signers.Count; i++)
            {
                var signer = cadesSignature.Signers[i];
                if (i > 0)
                {
                    markTexts.Add(new PdfTextSection()
                    {
                        Text     = i < cadesSignature.Signers.Count - 1 ? ", " : " and ",
                        FontSize = fontSize
                    });
                }
                markTexts.Add(new PdfTextSection()
                {
                    Text     = getDisplayName(signer.SigningCertificate),
                    FontSize = fontSize,
                    Style    = PdfTextStyle.Bold
                });
            }

            var mark = new PdfMark()
            {
                MeasurementUnits = Lacuna.Pki.Pades.PadesMeasurementUnits.Centimeters,
                Container        = new Lacuna.Pki.Pades.PadesVisualRectangle()
                {
                    Right  = 1,
                    Top    = 1,
                    Bottom = 1,
                    Width  = 2
                },
                BorderColor     = Color.Black,
                BorderWidth     = 0.01,
                BackgroundColor = Color.FromArgb(77, Color.LightGreen),                 // Light green with 30% opacity
                Elements        = new List <PdfMarkElement>()
                {
                    new PdfMarkText()
                    {
                        Rotation          = PdfMarkRotation.D90,
                        Texts             = markTexts,
                        RelativeContainer = new Lacuna.Pki.Pades.PadesVisualRectangle()
                        {
                            Left   = 0.3,
                            Top    = 0.3,
                            Bottom = 0.3,
                            Right  = 0.3
                        }
                    }
                }
            };

            var pdfMarker = new PdfMarker();

            pdfMarker.AddMark(mark);
            var pdfWithMarks = pdfMarker.WriteMarks(cadesSignature.GetEncapsulatedContent());

            Response.ContentType = "application/pdf";
            Response.AddHeader("Content-Disposition", "attachment; filename=printable-version.pdf");
            Response.BinaryWrite(pdfWithMarks);
            Response.End();
        }