the signature field position was not setting that i was setting dynamically before the validate the signature

0 Answers 43 Views
General Discussions PdfProcessing SpreadProcessing SpreadStreamProcessing WordsProcessing ZipLibrary
Vaibhav
Top achievements
Rank 1
Iron
Iron
Vaibhav asked on 09 Jan 2025, 05:20 AM
Hi,

i have added and image and some text inside the digital signature and and set them inside properly but when i set the position of the signature field before the signature field like i was showing in below screenshot 


above screenshot i have added the signature field placed the top of the Letter M but when i validate the signature manually but in output the signature field position is not correct as i set the above screenshot below is the screenshot that you can check the position of the signature field

i don't know whats strange can anyone help me this to get it out  
Vaibhav
Top achievements
Rank 1
Iron
Iron
commented on 09 Jan 2025, 05:57 AM

This the Code
public static void SignPDFSynfusion(SignatureInfo signInfo, byte[] inDocByte, Cert objCert, string customSignatureDetails, out byte[] outDocPdf)
{
    //outDocPdf = GenerateSignedPdf(objCert, inDocByte);
    #region original functionality
    // Initialize necessary objects
    TimeStampSettings objTimeStampSettings = new TimeStampSettings();
    TimeStampInfo objTimeStampInfo = (TimeStampInfo)objTimeStampSettings.GetTimeStamp();
    PfxSettings objPfxSettings = new PfxSettings();

    // Params to take account in the input
    bool displaySignature = Convert.ToBoolean(HttpContext.Current.Session["showSign"]);

    bool needTimeStamp = false;
    string TsaServerUrl = "";
    string TsaServerUser = "";
    string TsaServerPassword = "";
    string strPasswrd = string.Empty;
    double imageWidth = 0;

    if (objTimeStampInfo != null)
    {
        needTimeStamp = (bool)objTimeStampInfo.TimeStampNeeded;
        TsaServerUrl = objTimeStampInfo.TimeStampUrl;

        if ((bool)objTimeStampInfo.AuthNeeded)
        {
            TsaServerUser = objTimeStampInfo.UserName;
            strPasswrd = SecurQueryString.decryptQueryString(objTimeStampInfo.Password);
            TsaServerPassword = strPasswrd;
        }
    }

    // Load the certificate
    X509Certificate2 certificate = new X509Certificate2(objCert.CertArray, objCert.Password);

    // Create a SignatureField and assign the digital signature to it
    SignatureField pdfSignature = new SignatureField("SignatureField");
    pdfSignature.Signature = new Telerik.Windows.Documents.Fixed.Model.DigitalSignatures.Signature(certificate);

    // Set signature details
    string strNotAvailable = HttpContext.GetGlobalResourceObject("GlobalResources", "lblNotAvlbl").ToString();
    pdfSignature.Signature.Properties.Reason = strNotAvailable;
    pdfSignature.Signature.Properties.ContactInfo = strNotAvailable;
    pdfSignature.Signature.Properties.Location = strNotAvailable;

    // Load the existing PDF from the byte array using PdfFormatProvider
    using (MemoryStream inputStream = new MemoryStream(inDocByte))
    {
        // Create PdfFormatProvider and load the existing document
        PdfFormatProvider provider = new PdfFormatProvider();
        RadFixedDocument document = provider.Import(inputStream);

        int pageNo = (signInfo.DigitalSignPage() == 0 ? 1 : document.Pages.Count);

        // Create a new form to place the signature field
        Form pdfForm = new Form();
        pdfForm.FormSource = new FormSource();
        FixedContentEditor editor = new FixedContentEditor(pdfForm.FormSource);

        // Path to the image (ensure this is correct)
        System.Drawing.Image signatureImage = null;
        if (signInfo.DigitalSignMode() == 2 && HttpContext.Current.Session["imagesyncfusion"] != null)
        {
            signatureImage = (System.Drawing.Image)HttpContext.Current.Session["imagesyncfusion"];
        }
        // Check if digital signature is needed
        if (signInfo.UseDigitalSign())
        {
            if ((signInfo.DigitalSignMode() == 1) || (signInfo.DigitalSignMode() == 2))
            {
                double signaturePositionLeft = (double)signInfo.DigitalSignLeftInPoints();
                double signaturePositionTop = (double)signInfo.DigitalSignTopInPoints();
                double signatureFieldWidth = (double)signInfo.DigitalSignWidthInPoints();
                double signatureFieldHeight = (double)signInfo.DigitalSignHeightInPoints();
                RadFixedPage radFixedPage = document.Pages[pageNo - 1];

                if (!string.IsNullOrEmpty(customSignatureDetails))
                {
                    // Movable signature case: Adjust the signature field based on custom details
                    signatureFieldWidth = signaturePositionLeft + (double)signInfo.DigitalSignWidthInPoints();
                    signatureFieldHeight = signaturePositionTop + (double)signInfo.DigitalSignHeightInPoints();

                    string[] separator = new string[] { "!_!" };
                    string[] offsetArray = customSignatureDetails.Split(separator, StringSplitOptions.RemoveEmptyEntries);

                    if (offsetArray.Length >= 9)
                    {
                        double offsetLeft = returnFloatWithCultureValue(offsetArray[0]);
                        double offsetTop = returnFloatWithCultureValue(offsetArray[1]);
                        double docHeight = returnFloatWithCultureValue(offsetArray[2]);
                        double greenDivHeight = returnFloatWithCultureValue(offsetArray[3]);
                        double greenDivWidth = returnFloatWithCultureValue(offsetArray[4]);
                        double dpi_x = returnFloatWithCultureValue(offsetArray[6]);
                        double dpi_y = returnFloatWithCultureValue(offsetArray[7]);
                        pageNo = int.Parse(offsetArray[8]);

                        // Calculate positions for drawing the text div;
                        signaturePositionLeft = (offsetLeft / dpi_x) * 72;
                        signaturePositionTop = (offsetTop / dpi_y) * 72;
                        signatureFieldWidth = (greenDivWidth / dpi_y) * 72;
                        signatureFieldHeight = (greenDivHeight / dpi_x) * 72;
                    }
                }
                else
                {
                    // Non-movable case: Place the signature field in a fixed location
                    radFixedPage = document.Pages[pageNo - 1];
                    Tuple<double, double> k = null;

                    if (signatureImage != null)
                    {
                        k = calculateAspectRatioFit(signatureImage.Width, signatureImage.Height, signatureFieldWidth, signatureFieldHeight);
                        signatureFieldWidth = k.Item1;
                        signatureFieldHeight = k.Item2;
                    }

                    signaturePositionLeft = radFixedPage.Size.Height - (double)(signatureFieldWidth + signatureFieldHeight + 1);
                    signaturePositionTop = signaturePositionTop + 1; 
                }

                pdfForm.FormSource.Size = new Telerik.Documents.Primitives.Size(signatureFieldWidth, signatureFieldHeight);

                // Drawing the image at the starting position (left side of the signature field)
                imageWidth = signatureFieldWidth / 2;  // Half the width for the image
                double imageHeight = signatureFieldHeight;  // Use full height of the signature field

                //signatureImage = new Image();
                if (signatureImage != null)
                {
                    // Create a memory stream to hold the image
                    using (MemoryStream ms = new MemoryStream())
                    {
                        // Save the image to the memory stream
                        signatureImage.Save(ms, signatureImage.RawFormat);
                       
                        ms.Position = 0;

                        // Pass the memory stream to the DrawImage method
                        editor.DrawImage(ms, new Telerik.Documents.Primitives.Size(imageWidth, imageHeight));
                    }
                }

                // Prepare text to draw beside the signature image
                string textToDraw = $"Digitally signed by {certificate.FriendlyName} \nDate: {DateTime.Now:yyyy.MM.dd HH:mm:ss zzz} \nReason: {pdfSignature.Signature.Properties.Reason} \nLocation: {pdfSignature.Signature.Properties.Location}";

                // Set text width and calculate font size
                double textWidth = signatureFieldWidth - imageWidth;
                double fontSize = CalculateFontSize(signatureFieldWidth - 23, signatureFieldHeight, textToDraw);

                // Define the position for the text and draw it
                Telerik.Windows.Documents.Fixed.Model.Editing.Block textBlock = new Telerik.Windows.Documents.Fixed.Model.Editing.Block();
                double textPositionLeft = signaturePositionLeft;  // Adding a 5px gap after the image
                textBlock.TextProperties.FontSize = fontSize;
                textBlock.InsertText($"Digitally signed by {certificate.FriendlyName}");
                textBlock.InsertText($" Date: {DateTime.Now:yyyy.MM.dd HH:mm:ss zzz}");
                textBlock.InsertText($" Reason: {pdfSignature.Signature.Properties.Reason}");
                textBlock.InsertText($" Location: {pdfSignature.Signature.Properties.Location}");

                Rect boundingRect;
                if (signatureImage != null)
                {
                    boundingRect = new Rect(imageWidth, 5, textWidth, signatureFieldHeight);
                }
                else
                {
                    boundingRect = new Rect(textPositionLeft, 5, textWidth, signatureFieldHeight);
                }
                textBlock.Draw(editor, boundingRect);

                // Add signature widget to the page and draw the content + signatureFieldWidth - 10 ;;+ signatureFieldHeight+80
                RadFixedPage pdfPage = document.Pages[pageNo - 1];
                FixedContentEditor pageEditor = new FixedContentEditor(pdfPage);
                pageEditor.Position.Translate(signaturePositionLeft + pdfForm.Width, signaturePositionTop + pdfForm.Height);
                pageEditor.DrawForm(pdfForm.FormSource);

                document.AcroForm.FormFields.Add(pdfSignature);
                document.AcroForm.SignatureFlags = SignatureFlags.SignaturesExist | SignatureFlags.AppendOnly;

            }

        }
        // Export the document to a byte array and return
        using (MemoryStream memoryStream = new MemoryStream())
        {

            Telerik.Documents.ImageUtils.ImagePropertiesResolver defaultImagePropertiesResolver = new Telerik.Documents.ImageUtils.ImagePropertiesResolver();
            Telerik.Windows.Documents.Extensibility.FixedExtensibilityManager.ImagePropertiesResolver = defaultImagePropertiesResolver;
            var settings = new PdfExportSettings();
            settings.ImageQuality = ImageQuality.High;
            //PdfFormatProvider provider = new PdfFormatProvider();
            provider.ExportSettings = settings;
            provider.Export(document, memoryStream);
            outDocPdf = memoryStream.ToArray();
        }
    }
    #endregion
}
Yoan
Telerik team
commented on 13 Jan 2025, 12:00 PM

Hello Vaibhav,

The provided snippet and code screenshots are much appreciated. Correct me if I am wrong, but from what I understand you are experiencing unexpected results with the positioning of the signature content on the page, more specifically after manually validating the signature. 

I tried implementing the shared code snippet into a project on my end however I was unable to reproduce any unusual results as the signature field is correctly drawn with the values I have set. It is entirely possible that I am missing something as I do not have the full context of the code snippet and the required steps I need to take, which is why I skipped any unknown variables and used sample values instead. This is why I am attaching for your disposal my modified project. Please feel free to examine it and test it and do not hesitate to let me know if there is something that is preventing me from reproducing the same results.

One thing that can really help me with the investigation process is if you could share with me the exact steps required for reproducing the scenario and attach a runnable sample project that implements the shared code snippet which I can use to achieve the same results. This way I can observe the differences, investigate the cause, and get back to you as soon as possible with details and feedback.

That said, please keep in mind that due to this thread being a Q&A forum, all resources attached here will be publicly accessible to anyone. Make sure that you do not share any sensitive or confidential information, instead, you can replace it with dummy data.

One other thing that I have noticed is that the created FormSource is not related to a signature filed, meaning that the document is signed and the signature content is drawn on the page, however, the two are not related. To relate them you would have to create a widget for the signature field and set the FormSource as the Content of the widget:

SignatureWidget signatureWidget = pdfSignature.Widgets.AddWidget();
signatureWidget.Content.NormalContentSource = pdfForm.FormSource;
signatureWidget.Rect = new Rect(50, 250, 300, 300);
signatureWidget.RecalculateContent();
pdfPage.Annotations.Add(signatureWidget);

document.AcroForm.FormFields.Add(pdfSignature);

That said, I do not believe that this is a factor in the results you are experiencing however it is important to keep it in mind.

Thank you in advance for your cooperation.

Regards,

Yoan

No answers yet. Maybe you can help?

Tags
General Discussions PdfProcessing SpreadProcessing SpreadStreamProcessing WordsProcessing ZipLibrary
Asked by
Vaibhav
Top achievements
Rank 1
Iron
Iron
Share this question
or