Creating Custom Signature Appearance Based on PFX Details

Hi All,

I was trying to sign a pdf document with custom appearance based on text and logo informations. Text information like Name, Contact Info, Email, Telephone and timestape text needs to be displayed on the visible sign. The logo represents the visual human signature. So the question arises that how to read pfx file details and list them in the signature with ElementBuilder Object.
The examples are not clear about digital signature and only shows to present image as visual apperance

The vb code I used is as follows:

    '===================== Sign PDF Function ========================

    Private Function SignPDF(ByVal pdfPath As String, ByVal outPath As String, ByVal signId As String) As Boolean
        Dim result As Boolean = True
        Dim infile As String = pdfPath
        Dim outfile As String = outPath
        Dim certfile As String = "C:\Users\DELL\Desktop\DigitalCert.pfx"
        Dim imagefile As String = "C:\Users\DELL\Desktop\Logo.jpg"
       
        ' Open an existing PDF
        Dim doc As PDFDoc = New PDFDoc(infile)
        Try
#If (USE_DOTNET_CRYPTO) Then
             Dim sigHandler As DotNetCryptoSignatureHandler = New DotNetCryptoSignatureHandler(certfile, "myPassword")
             ' Add the SignatureHandler instance to PDFDoc, making sure to keep track of it using the ID returned.
             Dim sigHandlerId As SignatureHandlerId = doc.AddSignatureHandler(sigHandler)
#Else
            ' USE_DOTNET_CRYPTO
            ' Add an StdSignatureHandler instance to PDFDoc, making sure to keep track of it using the ID returned.
            Dim sigHandlerId As SignatureHandlerId = doc.AddStdSignatureHandler(certfile, "myPassword")
#End If
            ' USE_DOTNET_CRYPTO
            ' Obtain the signature form field from the PDFDoc via Annotation;
            Dim sigField As Field = doc.GetField(signId)
            Dim widgetAnnot As Widget = New Widget(sigField.GetSDFObj)
            ' Tell PDFNet to use the SignatureHandler created to sign the new signature form field.
            Dim sigDict As Obj = sigField.UseSignatureHandler(sigHandlerId)
            
            ' Add more information to the signature dictionary
            sigDict.PutName("SubFilter", "adbe.pkcs7.detached")
            sigDict.PutString("Name", "anyName")
            sigDict.PutString("Location", "Ontario, Canada")
            sigDict.PutString("Reason", "Document verification.")
           
' ========= Add the signature appearance

            Dim apWriter As ElementWriter = New ElementWriter
            Dim apBuilder As ElementBuilder = New ElementBuilder

            apWriter.Begin(doc)
            Dim sigImg As pdftron.PDF.Image = pdftron.PDF.Image.Create(doc, imagefile)
            Dim h As Double = sigImg.GetImageHeight
            Dim w As Double = sigImg.GetImageWidth
            
            Dim apElement As Element = apBuilder.CreateImage(sigImg, 0, 0, w, h)
            apWriter.WritePlacedElement(apElement)
            
            apElement = apBuilder.CreateTextBegin(PDF.Font.Create(doc, PDF.Font.StandardType1Font.e_times_roman), 12)
            apWriter.WriteElement(apElement)
            Dim data As String = "Hello World!!!!!!!!!!!!"
            apElement = apBuilder.CreateTextRun(data)
            apWriter.WritePlacedElement(apElement)
            apWriter.WritePlacedElement(apBuilder.CreateTextEnd())
            Dim apObj As Obj = apWriter.End
            apObj.PutRect("BBox", 0, 0, w + 100, h + 100)
            apObj.PutName("Subtype", "Form")
            apObj.PutName("Type", "XObject")
            ''+++++++++++++++++++++
            apWriter.Begin(doc)
            apElement = apBuilder.CreateForm(apObj)
            apWriter.WritePlacedElement(apElement)
            apObj = apWriter.End

            apObj.PutRect("BBox", 0, 0, w + 40, h + 40)
            apObj.PutName("Subtype", "Form")
            apObj.PutName("Type", "XObject")

            widgetAnnot.SetAppearance(apObj)
            widgetAnnot.RefreshAppearance()

            ' Save the PDFDoc w Signature
            doc.Save(outfile, SDFDoc.SaveOptions.e_incremental)
        Catch e As Exception
            'Console.Error.WriteLine(e)
            MsgBox("Error Ocurred during signing:" & vbLf & e.Message)
            SignPDF = False
        End Try

        SignPDF = True
    End Function

Untitled.jpg

This is the result output I want to generate. I hope it will clear my point.

I believe this Stackoverflow post, is what you are looking for, which utilizes .Net Framework to open and parse the PFX file.
https://stackoverflow.com/a/5036965/3761687

From there you could use ElementBuilder class directly to lay out the text, or use an intermediate layout tool like XAML or FlowDocument to reflow the text.

What I have achieved using:

Logo2.jpg

apWriter.Begin(doc)
Dim sigImg As pdftron.PDF.Image = pdftron.PDF.Image.Create(doc, imagefile)
Dim h As Double = sigImg.GetImageHeight
Dim w As Double = sigImg.GetImageWidth

Dim apElement As Element = apBuilder.CreateTextBegin(PDF.Font.Create(doc, PDF.Font.StandardType1Font.e_times_roman), 40)
apWriter.WriteElement(apElement)
Dim data As String = “LINE1: LINE1 LINE1 LINE1 LINE1 LINE1”
apElement = apBuilder.CreateTextRun(data)
apElement.SetTextMatrix(1, 0, 0, 1, 260, 100) 'Vertical move text at 100
'apElement.
apElement.GetGState().SetLeading(45)
apElement.GetGState().SetFillColor(New ColorPt(0.1, 0.23, 0))
apWriter.WriteElement(apElement)
apWriter.WriteElement(apBuilder.CreateTextNewLine())
apWriter.WriteElement(apBuilder.CreateTextRun("T* LINE2: LINE2 LINE2 LINE2 LINE2 LINE2 "))
apWriter.WriteElement(apBuilder.CreateTextNewLine())
apWriter.WriteElement(apBuilder.CreateTextRun("LINE3: LINE3 LINE3 LINE3 LINE3 LINE3 "))
'apWriter.WriteString(“Directly write to the element”)
apWriter.WriteElement(apBuilder.CreateTextEnd())

Dim apObj As Obj = apWriter.End
apObj.PutRect(“BBox”, 0, 0, w + 500, h) ''Bounding box for text
apObj.PutName(“Subtype”, “Form”)
apObj.PutName(“Type”, “XObject”)
‘’++++++++++++++++++++++

apWriter.Begin(doc)
apElement = apBuilder.CreateImage(sigImg, 0, 0, w, h)
apWriter.WritePlacedElement(apElement)
'-----------------------
apElement = apBuilder.CreateForm(apObj) ‘’ CreateForm
apWriter.WritePlacedElement(apElement)
apObj = apWriter.End

apObj.PutRect(“BBox”, 0, 0, w + 500, h + 200) ‘’’ REDUCE IMAGE SIZE
apObj.PutName(“Subtype”, “Form”)
apObj.PutName(“Type”, “XObject”)
widgetAnnot.SetAppearance(apObj)
widgetAnnot.RefreshAppearance()

So Using Elementbuilder the wrapping of text is not controlled and as per your suggestion could you please describe the method to use FlowDocument as per my code above. Or if it is possible with ElementBuilder. Thanks.

XAML / FlowDocument
Our .Net SDK downloads include a XAML2PDF sample
https://www.pdftron.com/documentation/samples/#xaml2pdf

You could also use GDI+, see the second half of this sample.
https://www.pdftron.com/documentation/samples#pdfdc?platforms=windows

Another option, is to use our ContentReplacer class, and give it the target rectangle and it will auto reflow for you.
https://www.pdftron.com/documentation/samples/#contentreplacer