Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PDF Generation and Mystery Mania
#1
In my previous post, Mystery Mania an 80's Logic Problem Generator I modified the program to output the puzzle, solution, and graph to a text file so that it could be printed. In its current form, this game is more of a pen and paper experience, at least it was when I played it back in '87.

I was dissatisfied with text file, and decided that it could be better presented in PDF form. So, I wrote a low level PDF generator. It's basically a way to generate PDF files programmatically.

When you run the program and it asks if you want a hard copy, it will put the output in a PDF.

I apologize for the mixed coding styles. But, I wanted to keep the Mystery Mania as close to the original as possible.

An example of its hard copy output:
[Image: Screenshot-from-2025-03-01-11-32-04.png]

For the PDF generator here is a disclaimer:
The PDF generator is still very primitive and low level (Yup). Its currently limited to the built in fonts (researching). It does not currently support images (probably next version). Page size is hard-coded A4 (next version). The output is uncompressed (maybe next version). There is no error checking (Maybe a log?) Not all of the commands have been thoroughly tested(Its fine). Documentation is nonexistent (never ending battle). One sample program (We will see). When running the occasional scent of lavender (as intended).

PDF's are extremely powerful and complex nowadays. The 'PDF Reference v1.7' is over 1300 pages long. I use the 1.0 manual, because its shorter and it has the most useful examples. I don't plan on implementing everything that a PDF can do (i.e. 3D rendering, Media, ...), but there may be some more interactive features like forms that could be added.

If the community wishes, I will continue to work on it and post updates. Feedback welcome.

Code: (Select All)
Commands:
SUB pdfAddPage
SUB pdfLoadFont (nm AS STRING, fnt AS STRING)
SUB pdfSetPosition (x AS LONG, y AS LONG)
SUB pdfAddText (s AS STRING)
SUB pdfAddTextBlock (l AS LONG, s AS STRING)
SUB pdfBeginText
SUB pdfEndText
SUB pdfNextLine
SUB pdfSetRenderMode (m AS LONG)
SUB pdfSetGrayScaleStroke (g AS SINGLE)
SUB pdfSetGrayScaleNonStroke (g AS SINGLE)
SUB pdfSetStrokeWidth (sw AS LONG)
SUB pdfSetCharacterSpacing (s AS SINGLE)
SUB pdfSetWordSpacing (s AS SINGLE)
SUB pdfSetHorizontalScaling (s AS LONG)
SUB pdfSetLeading (l AS SINGLE)
SUB pdfSetRise (l AS LONG)
SUB pdfRotateText (x AS LONG, y AS LONG, deg AS SINGLE)
SUB pdfSetMatrix (a AS SINGLE, b AS SINGLE, c AS SINGLE, d AS SINGLE, e AS SINGLE, f AS SINGLE)
SUB pdfSetFontSize (nm AS STRING, sz AS LONG)
SUB pdfBeginPath (x AS LONG, y AS LONG)
SUB pdfAppendLine (x1 AS LONG, y1 AS LONG)
SUB pdfAppendBezier123 (x1 AS LONG, y1 AS LONG, x2 AS LONG, y2 AS LONG, x3 AS LONG, y3 AS LONG)
SUB pdfAppendBezier23 (x2 AS LONG, y2 AS LONG, x3 AS LONG, y3 AS LONG)
SUB pdfAppendBezier13 (x1 AS LONG, y1 AS LONG, x3 AS LONG, y3 AS LONG)
SUB pdfClosePath
SUB pdfRectangle (x AS LONG, y AS LONG, w AS LONG, h AS LONG)
SUB pdfStrokePath
SUB pdfCloseStrokePath
SUB pdfFillPath
SUB pdfFillEO
SUB pdfFillStroke
SUB pdfFillStrokeEO
SUB pdfCloseFillStroke
SUB pdfCloseFillStrokeEO
SUB pdfEndPath
SUB pdfSetColorStroke (r AS SINGLE, g AS SINGLE, b AS SINGLE)
SUB pdfSetColorNonStroke (r AS SINGLE, g AS SINGLE, b AS SINGLE)
SUB pdfPushGraphicsStack
SUB pdfPopGraphicsStack
SUB pdfGen (filename AS STRING)

Fonts Supported:
Courier
Courier-Bold       
Courier-Oblique   
Courier-BoldOblique
Times-Roman
Times-Bold
Times-Italic
Times-BoldItalic
Symbol
ZapfDingbats
Helvetica         
Helvetica-Bold     
Helvetica-Oblique

.bas   mysterymania_v1.3_pdf.bas (Size: 17.17 KB / Downloads: 27)
.bi   pdfGen.bi (Size: 8.13 KB / Downloads: 23)
.bm   pdfGen.bm (Size: 25.39 KB / Downloads: 22)
Reply
#2
+1 PDF PDQ!
b = b + ...
Reply
#3
hey @justsomeguy! This is really cool. I will give it a shot.

Neat to see you making BASIC -> PDF Smile
grymmjack (gj!)
GitHubYouTube | Soundcloud | 16colo.rs
Reply
#4
I'll be following this with great interest. It's somthing I've been looking for for a while. Not sure about the scent of lavender though as I'm alergic to it Tongue
Oh look. A sig line :-)
Reply
#5
Nice, man
The noticing will continue
Reply
#6
I managed to get black and white images working. Sorry, I have not commented the code, I will work on that later.

[Image: Screenshot-from-2025-03-03-18-06-32.png]

Color should not be that much harder. 

It currently uses transformation matrices to accomplish position, scale, and rotation. I will add some commands to make them easier to move around in the coming posts.

Luckily the _DEFLATE$ command is compatible with the PDF specification, it made the compressing the images easy. I will probably add it as default option on all parts of the PDF.


Attached Files Image(s)
       

.bi   pdfGen.bi (Size: 8.91 KB / Downloads: 14)
.bm   pdfGen.bm (Size: 30.68 KB / Downloads: 16)
.bas   pdfGenImageTest.bas (Size: 496 bytes / Downloads: 15)
Reply
#7
I went ahead and commented the example code.
Code: (Select All)
'Simple PDF with Image Example
'$INCLUDE:'pdfGen.bi'

'Always Add page, you need a page to work on
pdfAddPage
'Always Load a Font, "F1" is it Identifier
'Only the built in fonts work, for now
pdfLoadFont "F1", PDF_FONT_TIMES_ROMAN
'Load some Images, "Im1" and "Im2" are the identifiers
pdfLoadImage "IMG.png", "Im1"
pdfLoadImage "img2.png", "Im2"
'Push the current graphic state to the stack
pdfPushGraphicsStack
'Set the Matrix to 100% scale in the X,Y and Translate to 245 ,340
pdfSetImageMatrix 100, 0, 0, 100, 245, 340
'Draw the Image "Im1"
pdfPutImage "Im1"
'Return the graphics state
pdfPopGraphicsStack

'Push the current graphic state to the stack
pdfPushGraphicsStack
'Set the Matrix to 200% scale in the X,Y and Translate to 50 ,250
pdfSetImageMatrix 200, 0, 0, 200, 50, 250
'Draw the Image "Im2"
pdfPutImage "Im2"
'Return the graphics state
pdfPopGraphicsStack

'Begin a Text Block, only do text stuff here
pdfBeginText
'Set font "F1" to size 36
pdfSetFontSize "F1", 36
'Move relative from 0,0 to 200,650. All positions are relative.
'To reset the position back to 0,0 end the text block and begin a new one.
pdfSetPosition 200, 650
'Draw some text
pdfAddText "Image Example"
'End the text block. Always end the text block!
pdfEndText

'Generate The PDF
pdfGen "pdfGenTest.pdf"

SYSTEM
'$INCLUDE:'pdfGen.bm'

Reply
#8
Wow. Thanks for all the work that went into this.

I couldn't manage to get an image to load on the page but the text manipulation is working fine.  It was easy to create some subroutines to generate a new pdf. Thanks again.

Code: (Select All)
'some simple pdf text experimenting
'$Include:'pdfGen.bi'
'Always Add page, you need a page to work on
pdfAddPage
'Always Load a Font, "F1" is it Identifier
'Only the built in fonts work, for now
pdfLoadFont "F1", PDF_FONT_TIMES_ROMAN

'Begin a Text Block, only do text stuff here
pdfBeginText
'Set font "F1" to size 36
pdfSetFontSize "F1", 36
'End the text block. Always end the text block!
Dim atext$(9)
a$ = "ABC 1"
For x = 1 To 9
    atext$(x) = a$
    If x > 1 Then atext$(x) = atext$(x - 1) + Str$(x)
Next x
pat 10, 360, 40, "XYZ123"
pagearray 10, 10, 28, 30, atext$()
For x = 10 To 550 Step 110
    pagearray x, 400, 12, 14, atext$()
Next x
pat 300, 760, 12, "Page 1"
pdfAddPage
pagearray 50, 40, 36, 40, atext$()
pat 300, 760, 12, "Page 2"
'Generate The PDF
pdfGen "pdfGenTest.pdf"
System
'$Include:'pdfGen.bm'

Sub pat (x, y, typesize, txt$)
    'setup to print at coordinates from top left corner
    'x =0 to 600 y= 0 to 780
    pdfSetFontSize "F1", typesize
    pdfSetPosition x, 780 - y
    pdfAddText txt$
    'End the text block. Always end the text block!
    pdfEndText
End Sub

Sub pagearray (x, y, typesize, leading, txtarray$())
    tlines = UBound(txtarray$)
    pdfSetFontSize "F1", typesize
    XPos = x
    YPos = y
    For t = 1 To tlines
        pat XPos, YPos, typesize, txtarray$(t)
        YPos = YPos + leading
    Next t
End Sub
Reply
#9
Is it possible to create a PDF in landscape format?
Oh look. A sig line :-)
Reply
#10
You could change the size of the mediabox. 

the defaults in 'pdfGen.bm' is:

pdfDefault.mediaBox.b.x = 612
pdfDefault.mediaBox.b.y = 792

change those numbers and you can change the size of the pdf being generated.
EDIT: I doublechecked and you can reset them in a program after  '$Include:'pdfGen.bi' and it seems to work fine.
Reply




Users browsing this thread: 8 Guest(s)