public void AddDiffMarker(int comparePage) { if (_indexes != null) { int page = pdfViewer.Renderer.Page; Console.WriteLine("AddDiffMarker Page{0}:Count{1}", page, _indexes.Count); foreach (PdfTextSpan textSpan in _indexes) { //Console.WriteLine("textSpan Page{0}: Offset{1}, Len{2}", textSpan.Page, textSpan.Offset, textSpan.Length); var bounds = pdfViewer.Renderer.Document.GetTextBounds(textSpan); foreach (PdfRectangle pdfrect in bounds) { var boundsRect = new RectangleF( pdfrect.Bounds.Left - 1, pdfrect.Bounds.Top + 1, pdfrect.Bounds.Width + 2, pdfrect.Bounds.Height - 2); //Console.Write("({0}, {1}, {2}, {3})", boundsText.Left, boundsText.Top, boundsText.Right, boundsText.Bottom); var marker = new PdfMarker( page, boundsRect, Color.FromArgb(64, Color.Red), Color.FromArgb(64, Color.Red), 0, 1); // Add a tag1 that is a difference marker. pdfViewer.Renderer.Markers.Add(marker); //Console.WriteLine("Added"); } } _comparePage[page] = comparePage; // Remember the compared page } }
private byte[] generatePrinterFriendlyVersion(byte[] pdfContent, string verificationCode) { var client = Util.GetRestPkiClient(); // 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 = Util.FormatVerificationCode(verificationCode); // Build the verification link from the constant "VerificationLinkFormat" (see above) and the // formatted verification code. var verificationLink = string.Format(VerificationLinkFormat, formattedVerificationCode); // 1. Upload the PDF var blob = client.UploadFile(pdfContent); // 2. Inspect signatures on the uploaded PDF var sigExplorer = new PadesSignatureExplorer(client) { Validate = true, DefaultSignaturePolicyId = StandardPadesSignaturePolicies.Basic, SecurityContextId = Util.GetSecurityContextId(), }; sigExplorer.SetSignatureFile(blob); var signature = sigExplorer.Open(); // 3. Create PDF with verification information from uploaded PDF var pdfMarker = new PdfMarker(client); pdfMarker.SetFile(blob); // Build string with joined names of signers (see method getDisplayName below) var signerNames = Util.JoinStringsPt(signature.Signers.Select(s => getDisplayName(s.Certificate))); 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); // PdfHelper is a class from the Rest PKI Client "fluent API" that helps to create elements and // parameters for the PdfMarker. var pdf = new PdfHelper(); // 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.Marks.Add( pdf.Mark() .OnAllPages() .OnContainer(pdf.Container().Width(1).AnchorRight(1).Height(1).AnchorBottom(1)) .AddElement( pdf.ImageElement() .WithOpacity(75) .WithImage(StorageMock.GetIcpBrasilLogoContent(), "image/png") ) ); // Summary on bottom margin of every page (except on the page which will be created at the end of // the document). pdfMarker.Marks.Add( pdf.Mark() .OnAllPages() .OnContainer(pdf.Container().Height(2).AnchorBottom().VarWidth().Margins(1.5, 3.5)) .AddElement( pdf.TextElement() .WithOpacity(75) .AddSection(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.Marks.Add( pdf.Mark() .OnAllPages() .OnContainer(pdf.Container().Width(2).AnchorRight().VarHeight().Margins(1.5, 3.5)) .AddElement( pdf.TextElement() .Rotate90Counterclockwise() .WithOpacity(75) .AddSection(allPagesMessage) ) ); // Create a "manifest" mark on a new page added on the end of the document. We'll add several // elements to this mark. var manifestMark = pdf.Mark() .OnNewPage() // This mark's container is the whole page with 1-inch margins. .OnContainer(pdf.Container().VarWidthAndHeight().Margins(2.54, 2.54)); // We'll keep track of our "vertical offset" as we add elements to the mark. double verticalOffset = 0; double elementHeight; elementHeight = 3; manifestMark // ICP-Brasil logo on the upper-left corner. .AddElement( pdf.ImageElement() .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset).Width(elementHeight /* using elementHeight as width because the image is square */).AnchorLeft()) .WithImage(StorageMock.GetIcpBrasilLogoContent(), "image/png") ) // QR Code with the verification link on the upper-right corner. .AddElement( pdf.QRCodeElement() .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset).Width(elementHeight /* using elementHeight as width because QR Codes are square */).AnchorRight()) .WithQRCodeData(verificationLink) ) // Header "VERIFICAÇÃO DAS ASSINATURAS" centered between ICP-Brasil logo and QR Code. .AddElement( pdf.TextElement() .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset + 0.2).FullWidth()) .AlignTextCenter() .AddSection(pdf.TextSection().WithFontSize(NormalFontSize * 1.6).WithText("SIGNATURE\nVERIFICATION")) ); verticalOffset += elementHeight; // Vertical padding. verticalOffset += 1.7; // Header with verification code. elementHeight = 2; manifestMark.AddElement( pdf.TextElement() .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset).FullWidth()) .AlignTextCenter() .AddSection(pdf.TextSection().WithFontSize(NormalFontSize * 1.2).WithText(string.Format("Verification Code: {0}", formattedVerificationCode))) ); verticalOffset += elementHeight; // Paragraph saying "this document was signed by the following signers etc" and mentioning the // time zone of the date/times below. elementHeight = 2.5; manifestMark.AddElement( pdf.TextElement() .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset).FullWidth()) .AddSection(pdf.TextSection().WithFontSize(NormalFontSize).WithText(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; manifestMark // Green "check" or red "X" icon depending on result of validation for this signer. .AddElement( pdf.ImageElement() .OnContainer(pdf.Container().Height(0.5).AnchorTop(verticalOffset + 0.2).Width(0.5).AnchorLeft()) .WithImage(StorageMock.GetValidationResultIcon(signer.ValidationResults.IsValid), "image/png") ) // Description of signer (see method getSignerDescription() below). .AddElement( pdf.TextElement() .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset).VarWidth().Margins(0.8, 0)) .AddSection(pdf.TextSection().WithFontSize(NormalFontSize).WithText(getSignerDescription(signer))) ); verticalOffset += elementHeight; } // Some vertical padding from last signer. verticalOffset += 1; // Paragraph with link to verification site and citing both the verification code above and the // verification link below. elementHeight = 2.5; manifestMark.AddElement( pdf.TextElement() .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset).FullWidth()) .AddSection(pdf.TextSection().WithFontSize(NormalFontSize).WithText(string.Format("To verify the signatures, go to {0} on ", VerificationSiteNameWithArticle))) .AddSection(pdf.TextSection().WithFontSize(NormalFontSize).WithColor(Color.Blue).WithText(VerificationSite)) .AddSection(pdf.TextSection().WithFontSize(NormalFontSize).WithText(" and inform the code above or follow the link below:")) ); verticalOffset += elementHeight; // Verification link. elementHeight = 1.5; manifestMark.AddElement( pdf.TextElement() .OnContainer(pdf.Container().Height(elementHeight).AnchorTop(verticalOffset).FullWidth()) .AddSection(pdf.TextSection().WithFontSize(NormalFontSize).WithColor(Color.Blue).WithText(verificationLink)) .AlignTextCenter() ); // Apply marks. pdfMarker.Marks.Add(manifestMark); var result = pdfMarker.Apply(); // Return result. return(result.GetContent()); }
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); }
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(); }