2024-06-25 13:26:35 +02:00

218 lines
8.3 KiB
VB.net

Imports System.Drawing
Imports System.IO
Imports DigitalData.Modules.Base
Imports DigitalData.Modules.Logging
Imports GdPicture14
Imports Newtonsoft.Json
Imports EnvelopeGenerator.Common.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"
Public Sub New(pLogConfig As LogConfig, pGDPictureLicenseKey As String)
MyBase.New(pLogConfig)
LicenseManager = New LicenseManager()
LicenseManager.RegisterKEY(pGDPictureLicenseKey)
Manager = New AnnotationManager()
End Sub
Public Function BurnInstantJSONAnnotationsToPDF(pSourceBuffer As Byte(), pInstantJSONList As List(Of String)) As Byte()
Dim oResult As GdPictureStatus
Try
Using oSourceStream As New MemoryStream(pSourceBuffer)
oResult = Manager.InitFromStream(oSourceStream)
If oResult <> GdPictureStatus.OK Then
Throw New BurnAnnotationException($"Could not open document for burning: [{oResult}]")
End If
For Each oJSON In pInstantJSONList
If AddInstantJSONAnnotationToPDF(oJSON) = False Then
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
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
Catch ex As Exception
Logger.Error(ex)
Return Nothing
End Try
End Function
Private Function AddInstantJSONAnnotationToPDF(pInstantJSON As String) As Boolean
Try
Dim oAnnotationData = JsonConvert.DeserializeObject(Of AnnotationData)(pInstantJSON)
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 Then
AddFormFieldValue(oAnnotation, formFieldValue)
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) 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)
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 = "Arial"
ant.FontSize = 8
ant.FontStyle = FontStyle.Italic
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