Simple Print to PDF question

I already have a document layout method for my log files that I’ve always had users print to PDF using the appropriate platform tools. However, with the PDF features maturing in Xojo, Should I be able to simply change my graphics object from the printer to the PDF layer?

I’ve tried using:

Dim ps As New PDFDocument
Dim g As Graphics = ps.Graphics

But the PageHeight and PageWidth parameters for a PDFDocument don’t seem to match the Height and Width properties for the printer setup.

Hi @Tim_Jones

You can pass along the desired Width and Height values for the page in the Constructor of the PDF:

Var PS As New PDFDocument(tWidth, tHeight)
Var g As Graphics = ps.Graphics
1 Like

Thanks, @Javier_Menendez - Does setting the document size to Letter or A4 service this same purpose?

Yep, you. can use any of the enum values… or any arbitrary value :slight_smile:

1 Like

@Javier_Menendez - One more - how do I set the font for a DrawString?

I see the list of built in fonts, but how do I assign on to the PDFGraphics.FontName?

I’ve tried:

PDFg.FontName = "LiberationSans"

and

PDFg.FontName = PDFDocument.StandardFontNames.LiberationSans

But both throw an error at compile time.

For the most common use, any font you want to use needs to be installed in your computer (and that also includes Web Server if you intend to deploy a Web app, for example).

Setting the font to use should be done as with the Graphics class. For example, on macOS:

Var d As New PDFDocument
Var g as Graphics = d.Graphics
g.FontName = "Times"

Will set the drawing font to “Times”.

As shown above, using the graphics object and setting the literal name to “LiberationSans” gives an error that I can’t use the graphics object outside of the paint event
Screen Shot 2022-08-11 at 8.40.39 AM

None of the other operations on the graphics object cause that.

Can you post the code that results in that exception? (or a small project reproducing it?)

“Exception Message: Graphics object cannot be used outside its Paint event” is a hint…

I was just doing that :slight_smile:

If curY > g.Height - 24 Then
  // Footer
  g.TextFont = "LiberationSans"
  g.TextSize = 9
  g.DrawString("Page " + Format(currentPage, "###"), 24, ps.PageHeight - 4)
  // start new page
  g.NextPage
  currentPage = currentPage + 1
  curY = 60
  g.Bold = True
  g.DrawString("Safe Migrate Job Log" + EndOfLine + _
  "Copied onto """ + DiskDestination + """" + EndOfLine + _
  "Created on " + PrintArchiveDate, leftmargin, 9)
  g.PenHeight = 2
  g.DrawLine(24, 36, ps.PageWidth - 24, 36)
  g.DrawString "File and Path", 24, 46
  g.DrawString "Size", leftMargin + (5.75 * 72), 46
  g.PenHeight = 2
  g.DrawLine(24, 48, ps.PageWidth - 24, 48)
  g.TextFont = "Ariel"
  g.TextSize = 8
  g.Bold = True
  leftmargin = 24
  // repeat the current folder info line
  If g.StringWidth(currentFolder) < 5.72 * 72 Then
    g.DrawString currentFolder, leftmargin, curY
  Else
    // theLine = NthFieldB(CatLine, "|", 1)
    g.DrawString LeftB(currentFolder, 25) + "..." + RightB(currentFolder, 55), leftmargin, curY
  End If
  curY = curY + g.StringHeight("MpM", 72 * 5)
End If

There are other calls to the graphics object before that instance that do not exhibit the error.

Oh that error usually means that you’re using the API 1 names.

Because PDFGraphics is a subclass of Graphics, they couldn’t actually remove the API 1 names so they all raise this exception.

Ah - that’s one way to get us to change …

Edit- Nevermind… it looks like you’ve already sorted that out, I’m a bit slow today.

g.TextFont or g.FontName ?

Hmmm, I’ve updated to API 2 conventions, but I’m still getting an unsupportedformat exception on this:

// Print cover page
UserBackgroundPicture = SafeMigrateMain_MasterHeader_584x165
g.DrawPicture(UserBackgroundPicture, 0, 464) // <<<<<<<<< Error here
g.FontName = "#kSystemFont"
g.Bold = True
g.FontSize = 24
g.DrawString "Safe Migrate Job Log", leftmargin, 48
g.FontSize = 12
g.DrawString EndOfLine + "From:" + Chr(9) + DiskSource + EndOfLine + "To:" + Chr(9) + Chr(9) + DiskDestination, leftmargin, 62
g.Bold = False
g.FontSize = 9
g.DrawString("Safe Migrate Job Results:", leftmargin, 2*72)
curY = 2.3*72

UserBackgroundPicture is a Xojo Image as is the Image being assigned.

Can you reproduce that in a simple project we can use/inspect, please? It would be helpful!

@Javier_Menendez - Can’t upload because the project includes all of the MBS and Einhugur plugins and is more than 100MB …

New Desktop Project
Add a PushButton to the window
Add the Pressed event to the PushButton
Add this code into the Pressed event:

Dim ps As New PDFDocument(PDFDocument.PageSizes.Letter)
Dim g As PDFGraphics
Dim PDFLogFile As FolderItem
Dim leftmargin, margin, curY As Integer


g = ps.Graphics
If g = Nil Then
  Return
Else
  leftmargin = 24
  margin = 36
  g.DrawPicture(SafeMigrateMain_MasterHeader, 0, 464)
  g.FontName = "LiberationSans"
  g.Bold = True
  g.FontSize = 24
  g.DrawString "Safe Migrate Job Log", leftmargin, 48
  g.FontSize = 9
  g.DrawString("Safe Migrate Job Results:", leftmargin, 2*72)
  curY = 2.3*72
  g.FontName = "LiberationMono"
End If
PDFLogFile = SpecialFolder.Documents.Child("Safe Migrate Logs").Child("Test PDF Save.pdf")
ps.Save(PDFLogFile)
ps = Nil

Just create a xojo_image to replace my image in the DrawPicture call.

Are you on Linux, I guess? :wink:

Yep. In fact, my main reason for chasing this is the hard crash that we witness on Linux if we try to print the created doc.

Hi @Tim_Jones

I changed a couple of things: mostly DrawString to the API 2.0 DrawText (this was the one raising the exception), and also the name for the fonts.

It is working just fine here (Lnx Mint)

Dim ps As New PDFDocument(PDFDocument.PageSizes.Letter)
Dim g As PDFGraphics
Dim PDFLogFile As FolderItem
Dim leftmargin, margin, curY As Integer


g = ps.Graphics
If g = Nil Then
  Return
Else
  leftmargin = 24
  margin = 36
  g.DrawPicture(SafeMigrateMain_MasterHeader, 0, 464)
  g.FontName = "Liberation Sans"
  g.Bold = True
  g.FontSize = 24
  g.DrawText "Safe Migrate Job Log", leftmargin, 48
  g.FontSize = 9
  g.DrawText("Safe Migrate Job Results:", leftmargin, 2*72)
  curY = 2.3*72
  g.FontName = "Liberation Mono"
End If
PDFLogFile = SpecialFolder.Documents.Child("Safe Migrate Logs").Child("Test PDF Save.pdf")
ps.Save(PDFLogFile)
ps = Nil

But, that’s not where I’m seeing the issue. I’m getting the exception on the DrawPicture call.

I’ve copied and pasted your code into another new project and I still get the same error on the DrawPicture line.

As for the Fonts, I was using the names listed in the PDFDocument help page:

https://documentation.xojo.com/api/pdf/pdfdocument.html#standardfontnames