Imports System.Drawing Imports System.IO Imports DigitalData.Modules.Base Imports DigitalData.Modules.Logging Imports GdPicture14 Imports Newtonsoft.Json Imports EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument.FinalizeDocumentExceptions Namespace Jobs.FinalizeDocument Public Class PDFBurner Inherits BaseClass Private ReadOnly Manager As AnnotationManager Private ReadOnly LicenseManager As LicenseManager Private Const ANNOTATION_TYPE_IMAGE = "pspdfkit/image" Private Const ANNOTATION_TYPE_INK = "pspdfkit/ink" Private Const ANNOTATION_TYPE_WIDGET = "pspdfkit/widget" Private Property _pdfBurnerParams As PDFBurnerParams Public Sub New(pLogConfig As LogConfig, pGDPictureLicenseKey As String, pdfBurnerParams As PDFBurnerParams) MyBase.New(pLogConfig) LicenseManager = New LicenseManager() LicenseManager.RegisterKEY(pGDPictureLicenseKey) Manager = New AnnotationManager() _pdfBurnerParams = pdfBurnerParams End Sub Public Function BurnInstantJSONAnnotationsToPDF(pSourceBuffer As Byte(), pInstantJSONList As List(Of String)) As Byte() Dim oResult As GdPictureStatus Using oSourceStream As New MemoryStream(pSourceBuffer) ' Open PDF oResult = Manager.InitFromStream(oSourceStream) If oResult <> GdPictureStatus.OK Then Throw New BurnAnnotationException($"Could not open document for burning: [{oResult}]") End If ' Add annotation to PDF For Each oJSON In pInstantJSONList If AddInstantJSONAnnotationToPDF(oJSON) = False Then Logger.Warn($"Error in AddInstantJSONAnnotationToPDF - oJson: ") Logger.Warn(oJSON) Throw New BurnAnnotationException($"Adding Annotation failed") End If Next oResult = Manager.BurnAnnotationsToPage(RemoveInitialAnnots:=True, VectorMode:=True) If oResult <> GdPictureStatus.OK Then Throw New BurnAnnotationException($"Could not burn annotations to file: [{oResult}]") End If 'Save PDF Using oNewStream As New MemoryStream() oResult = Manager.SaveDocumentToPDF(oNewStream) If oResult <> GdPictureStatus.OK Then Throw New BurnAnnotationException($"Could not save document to stream: [{oResult}]") End If Manager.Close() Return oNewStream.ToArray() End Using End Using End Function Private Function AddInstantJSONAnnotationToPDF(pInstantJSON As String) As Boolean Try Dim oAnnotationData = JsonConvert.DeserializeObject(Of AnnotationData)(pInstantJSON) oAnnotationData.annotations.Reverse() Dim formFieldIndex = 0 For Each oAnnotation In oAnnotationData.annotations Logger.Debug("Adding AnnotationID: " + oAnnotation.id) Select Case oAnnotation.type Case ANNOTATION_TYPE_IMAGE AddImageAnnotation(oAnnotation, oAnnotationData.attachments) Case ANNOTATION_TYPE_INK AddInkAnnotation(oAnnotation) Case ANNOTATION_TYPE_WIDGET 'Add form field values Dim formFieldValue = oAnnotationData.formFieldValues.FirstOrDefault(Function(fv) fv.name = oAnnotation.id) If formFieldValue IsNot Nothing AndAlso Not _pdfBurnerParams.IgnoredLabels.Contains(formFieldValue.value) Then AddFormFieldValue(oAnnotation, formFieldValue, formFieldIndex) formFieldIndex += 1 End If End Select Next Return True Catch ex As Exception Logger.Warn("Could not create annotation from InstantJSON") Logger.Error(ex) Return False End Try End Function Private Function AddImageAnnotation(pAnnotation As Annotation, pAttachments As Dictionary(Of String, Attachment)) As Boolean Try Dim oAttachment = pAttachments.Where(Function(a) a.Key = pAnnotation.imageAttachmentId). SingleOrDefault() ' Convert pixels to Inches Dim oBounds = pAnnotation.bbox.Select(AddressOf ToInches).ToList() Dim oX = oBounds.Item(0) Dim oY = oBounds.Item(1) Dim oWidth = oBounds.Item(2) Dim oHeight = oBounds.Item(3) Manager.SelectPage(pAnnotation.pageIndex + 1) Manager.AddEmbeddedImageAnnotFromBase64(oAttachment.Value.binary, oX, oY, oWidth, oHeight) Return True Catch ex As Exception Logger.Warn("Could not add image annotation!") Logger.Error(ex) Return False End Try End Function Private Function AddInkAnnotation(pAnnotation As Annotation) As Boolean Try Dim oSegments = pAnnotation.lines.points Dim oColor = ColorTranslator.FromHtml(pAnnotation.strokeColor) Manager.SelectPage(pAnnotation.pageIndex + 1) For Each oSegment As List(Of List(Of Single)) In oSegments Dim oPoints = oSegment. Select(AddressOf ToPointF). ToArray() Manager.AddFreeHandAnnot(oColor, oPoints) Next Return True Catch ex As Exception Logger.Warn("Could not add image annotation!") Logger.Error(ex) Return False End Try End Function Private Function AddFormFieldValue(pAnnotation As Annotation, formFieldValue As FormFieldValue, index As Integer) As Boolean Try ' Convert pixels to Inches Dim oBounds = pAnnotation.bbox.Select(AddressOf ToInches).ToList() Dim oX = oBounds.Item(0) Dim oY = oBounds.Item(1) + _pdfBurnerParams.YOffset * index + _pdfBurnerParams.TopMargin Dim oWidth = oBounds.Item(2) Dim oHeight = oBounds.Item(3) Manager.SelectPage(pAnnotation.pageIndex + 1) ' Add the text annotation Dim ant = Manager.AddTextAnnot(oX, oY, oWidth, oHeight, formFieldValue.value) ' Set the font properties ant.FontName = _pdfBurnerParams.FontName ant.FontSize = _pdfBurnerParams.FontSize ant.FontStyle = _pdfBurnerParams.FontStyle Manager.SaveAnnotationsToPage() Return True Catch ex As Exception Logger.Warn("Could not add image annotation!") Logger.Error(ex) Return False End Try End Function Private Function ToPointF(pPoints As List(Of Single)) As PointF Dim oPoints = pPoints.Select(AddressOf ToInches).ToList() Return New PointF(oPoints.Item(0), oPoints.Item(1)) End Function Private Function ToInches(pValue As Double) As Double Return pValue / 72 End Function Private Function ToInches(pValue As Single) As Single Return pValue / 72 End Function Friend Class AnnotationData Public Property annotations As List(Of Annotation) Public Property attachments As Dictionary(Of String, Attachment) Public Property formFieldValues As List(Of FormFieldValue) End Class Friend Class Annotation Public Property id As String Public Property bbox As List(Of Double) Public Property type As String Public Property isSignature As Boolean Public Property imageAttachmentId As String Public Property lines As Lines Public Property pageIndex As Integer Public Property strokeColor As String End Class Friend Class Lines Public Property points As List(Of List(Of List(Of Single))) End Class Friend Class Attachment Public Property binary As String Public Property contentType As String End Class Friend Class FormFieldValue Public Property name As String Public Property value As String End Class End Class End Namespace