Creare un file PDF con le funzioni esterne della libreria PDFGen

Da Gambas-it.org - Wikipedia.

PDFGen è una semplice libreria C per la creazione di file PDF, che non dipende da altre librerie esterne.

Mostriamo un semplice esempio pratico per generare un file PDF:
Per utilizzare in tale esempio le risorse della libreria esterna PDFGen, non installeremo, né caricheremo nel sistema alcun suo file di libreria condivisa, ma la genereremo temporaneamente, usando uno stratagemma: si scaricheranno dal sito "https://github.com/AndreRenaud/PDFGen " sia il file di testo grezzo sorgente .c, contenente le risorse della libreria PDFGen, sia il file di testo grezzo header, nel quale sono dichiarate le predette risorse.
In particolare gli indirizzi web dei predetti file di testo grezzi da scaricare sono:

In fine creeremo da tali file scaricati un'apposita libreria condivisa .so per richiamare e usare le risorse della libreria principale PDFGen.
Per scaricare i due file, bisognerà attivare anche i Componenti "gb.net" e "gb.net.curl". [nota 1]
Pertanto, si dovrà ricordare che, per usare questo esempio pratico di codice, bisognerà essere collegati a internet.

Library "/tmp/libPDFGen"

Private Const PDF_A4_WIDTH As Single = 210.0
Private Const PDF_A4_HEIGHT As Single = 297.0
Private Const PDF_A3_WIDTH As Single = 297.0
Private Const PDF_A3_HEIGHT As Single = 420.0

Private Enum PDF_ALIGN_LEFT, PDF_ALIGN_RIGHT, PDF_ALIGN_CENTER, PDF_ALIGN_JUSTIFY, PDF_ALIGN_JUSTIFY_ALL, PDF_ALIGN_NO_WRITE

' struct pdf_doc *pdf_create(float width, float height, const struct pdf_info *info)
' Create a new PDF object, with the given page width/height.
Private Extern pdf_create(width As Single, height As Single, info As Pointer) As Pointer

' int pdf_set_font(struct pdf_doc *pdf, const char *font)
' Sets the font to use for text objects.
Private Extern pdf_set_font(pdf As Pointer, __font As String) As Integer

' struct pdf_object *pdf_append_page(struct pdf_doc *pdf)
' Add a new page to the given pdf.
Private Extern pdf_append_page(pdf As Pointer) As Pointer

' int pdf_add_text(struct pdf_doc *pdf, struct pdf_object *page, const char *text, float size, float xoff, float yoff, uint32_t colour)
' Add a text string to the document.
Private Extern pdf_add_text(pdf As Pointer, page As Pointer, text As String, size As Single, xoff As Single, yoff As Single, colour As Integer) As Integer

' int pdf_add_text_wrap(struct pdf_doc *pdf, struct pdf_object *page, const char *text, float size, float xoff, float yoff, uint32_t colour, float wrap_width, int align, float *height)
' Add a text string to the document, making it wrap if it is too long.
Private Extern pdf_add_text_wrap(pdf As Pointer, page As Pointer, text As String, size As Single, xoff As Single, yoff As Single, colour As Integer, wrap_width As Single, align As Integer, height As Pointer) As Integer

' int pdf_add_image_file(struct pdf_doc *pdf, struct pdf_object *page, float x, float y, float display_width, float display_height, const char *image_filename) As Integer
' Add an image file as an image to the document.
Private Extern pdf_add_image_file(pdf As Pointer, page As Pointer, x As Single, y As Single, display_width As Single, display_height As Single, image_filename As String) As Integer

' int pdf_add_line(struct pdf_doc *pdf, struct pdf_object *page, float x1, float y1, float x2, float y2, float width, uint32_t colour)
' Add a line to the document.
Private Extern pdf_add_line(pdf As Pointer, page As Pointer, x1 As Single, y1 As Single, x2 As Single, y2 As Single, width As Single, colour As Integer) As Integer

' int pdf_save(struct pdf_doc *pdf, const char *filename)
' Save the given pdf document to the supplied filename.
Private Extern pdf_save(pdf As Pointer, filename As String) As Integer

' void pdf_destroy(struct pdf_doc *pdf)
' Destroy the pdf object, and all of its associated memory.
Private Extern pdf_destroy(pdf As Pointer)


Public Sub Main()

 Dim pdfdoc As Pointer
 Dim height As Single

' Carica il file contenente le risorse della libreria "PDFGen" e il correlatofile header:
 File.save("/tmp/pdfgen.h", HttpClient.Download("https://raw.githubusercontent.com/AndreRenaud/PDFGen/master/pdfgen.h"))
 File.save("/tmp/pdfgen.c", HttpClient.Download("https://raw.githubusercontent.com/AndreRenaud/PDFGen/master/pdfgen.c"))

' Corregge nel file sorgente .c "pdfgen.c" il percorso attuale del file d'intestazione "pdfgen.h":
 File.Save("/tmp/pdfgen.c", Replace(File.Load("/tmp/pdfgen.c"), "pdfgen.h", "/tmp/pdfgen.h"))

 If Not Exist("/tmp/libPDFGen.so") Then Creaso()
 
 pdfdoc = pdf_create(MMtoPoint(PDF_A4_WIDTH), MMtoPoint(PDF_A4_HEIGHT), 0)
 
 pdf_set_font(pdfdoc, "Times-Roman")
 
 pdf_append_page(pdfdoc)
 
 pdf_add_text(pdfdoc, 0, "Questa è la prima riga di testo.", 24, 50, 700, &000000)
 pdf_add_text(pdfdoc, 0, "Questa è la seconda riga di testo.", 12, 50, 680, &000000)
 
 pdf_add_line(pdfdoc, 0, 50, 600, 400, 600, 3, &00FF00)

' In quest'altro caso carichiamo un file di testo grezzo:
 Print pdf_add_text_wrap(pdfdoc, 0, File.Load("/percorso/di/un/file/di/testo"), 12, 20, 350, &FF0000, MMtoPoint(PDF_A4_WIDTH) - 40, PDF_ALIGN_JUSTIFY, VarPtr(height))

' Carica un file immagine da inserire nsulla uperficie del file PDF finale:
 pdf_add_image_file(pdfdoc, 0, 100, 400, 150, 150, "/percorso/di/un/file/immagine")

 pdf_save(pdfdoc, "/tmp/output.pdf")
  
 pdf_destroy(pdfdoc)

End

Private Function MMtoPoint(mm As Single) As Single

 Return (mm * 72.0 / 25.4)

End

Private Procedure Creaso()

 Shell "gcc -o /tmp/libPDFGen.so /tmp/pdfgen.c -shared -fPIC" Wait
 
End


Note

[1] Al riguardo vedere anche la seguente pagina: Scaricare un file da internet