PDF creation from text (no libraries / third party apps)

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
labrint
Posts: 379
Joined: 14 Jun 2017, 05:06
Location: Malta

PDF creation from text (no libraries / third party apps)

15 Feb 2024, 13:38

Code: Select all

; Initialize the PDF document
InitPDF(filePath) {
    global file
    FileDelete, %filePath%
    file := FileOpen(filePath, "w")
    ; Write PDF header
    file.Write("%%PDF-1.4`n")
    ; Start writing objects, here we start with the Catalog and Pages (to be filled later)
}

; Add a page to the PDF
AddPage() {
    global file
    ; Assuming a very simple case with one page and direct reference
    ; Object 1: Catalog
    file.Write("1 0 obj`n<</Type /Catalog /Pages 2 0 R>>`nendobj`n")
    ; Object 2: Page Tree (only one page in this example)
    file.Write("2 0 obj`n<</Type /Pages /Kids [3 0 R] /Count 1>>`nendobj`n")
    ; Object 3: Page (MediaBox defines the size of the page, here we use a standard A4 size)
    file.Write("3 0 obj`n<</Type /Page /Parent 2 0 R /MediaBox [0 0 612 792]>>`nendobj`n")
}

; Add text to the PDF
AddText(x, y, text) {
    global file
    ; Content stream with text (simplifying by not managing multiple contents and fonts properly)
    ; Note: This does not handle text escaping and is very simplified
    content := "<</Length " . StrLen(text) + 20 . ">>stream`nBT /F1 24 Tf " . x . " " . y . " Td (" . text . ") Tj ET`nendstream"
    file.Write("4 0 obj`n" . content . "`nendobj`n")
    ; Update page object to include contents and a basic resource for fonts (very simplified)
    file.Write("3 0 obj`n<</Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R /Resources <</Font <</F1 5 0 R>>>>>>`nendobj`n")
    ; Object 5: Font
    file.Write("5 0 obj`n<</Type /Font /Subtype /Type1 /BaseFont /Helvetica>>`nendobj`n")
}

; Finalize the PDF
FinalizePDF() {
    global file
    ; Simplified xref table and trailer, not properly managing object offsets
    file.Write("xref`n0 6`n0000000016 00000 n `n0000000061 00000 n `n0000000111 00000 n `n0000000179 00000 n `n0000000301 00000 n `ntrailer`n<</Size 6/Root 1 0 R>>`nstartxref`n361`n%%EOF")
    file.Close()
}

; Example usage:
InitPDF("DynamicLabelPDF.pdf")
AddPage()
AddText(100, 700, "Hello, Dynamic World!")
FinalizePDF()
MsgBox, Dynamic PDF created!
I want to share this code with you so that perhaps someone with more experience can build a much better PDF generation library.
ahk7
Posts: 575
Joined: 06 Nov 2013, 16:35

Re: PDF creation from text (no libraries / third party apps)

15 Feb 2024, 15:47

Quite entertaining.
With a slight modification you can set the font and size, and assuming 792 in /MediaBox [0 0 612 792] is the page height, using 792-y makes y more natural with 0,0 being top left vs 0,792 being top left.

Code: Select all

; Add text to the PDF
AddText2(x, y, text, fontName:="Helvetica", fontSize:=12) {
    global file
    ; Content stream with text (simplifying by not managing multiple contents and fonts properly)
    ; Note: This does not handle text escaping and is very simplified
    content := "<</Length " . StrLen(text) + 20 . ">>stream`nBT /F1 " fontSize " Tf " . x . " " 792-y . " Td (" . text . ") Tj ET`nendstream"
    file.Write("4 0 obj`n" . content . "`nendobj`n")
    ; Update page object to include contents and a basic resource for fonts (very simplified)
    file.Write("3 0 obj`n<</Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R /Resources <</Font <</F1 5 0 R>>>>>>`nendobj`n")
    ; Object 5: Font
    file.Write("5 0 obj`n<</Type /Font /Subtype /Type1 /BaseFont /" fontName ">>`nendobj`n")
}

Code: Select all

AddText2(10, 10, "Courier: Lorem ipsum dolor sit amet, consectetur ...", "Courier", 12)

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 113 guests