Skip to content

New Additions to PDFDocument

Xojo 2021r2 brings more enhancements, new features and a bunch of bug fixes to the PDFDocument class. Among these, probably the most important is the arrival of PDFDocument for iOS. But you’ll also find new features like adding annotations and links to your PDFs, new PDF viewer options and the ability to jump to a specific page in a PDF.

PDFDocument for iOS

For iOS, the fonts handling support are limited to the ones under the PDF Standard 14: Helvetica, Times, Courier, ZapfDingbats and Symbols. Using these fonts guarantees that PDFs generated on iOS work properly on Desktop and Web platforms too.

Rotate, Scale and Translate

Now, the methods included in the Graphics class are included in PDFDocument. This allows you to Rotate, Scale and Translate both text as shapes and text as images.

For example, the following fragment of code creates a PDF with scaled, translated and rotated text, plus an image that has been added to the Xojo project and that is rendered twice using differente Scale and Rotation values:

Var d As New PDFDocument
Var g As Graphics = d.Graphics
Var p As Picture = Picture.Open(SpecialFolder.Desktop.Child("r2d2.png"))

If p <> Nil Then

g.Translate(10,20)
g.Scale(2.5,2.5)
g.Rotate(-1.57)

g.FontSize = 30
g.DrawText("Sample Text", 30, (30+g.TextWidth("Sample Text")*2.5))

g.Rotate(-1.4)

g.Scale(0.5,0.5)
g.DrawPicture(p,200+p.Width,100,138,200,0,0,p.Width,p.Height)

g.Rotate(3.14)
g.Scale(0.5,1)
g.DrawPicture(p,220,0,138,138,0,0,p.Width,p.Height)

Var f As FolderItem = SpecialFolder.Desktop.Child("RotateScaleTranslate.pdf")
d.Save(f)
f.Open

End If

Adding Annotations…

You can also use the new AddAnnotation method to add as many annotations as your heart may desire to the current PDFDocument page.

For example, the following fragment of code will add a total of five annotations to a PDFDocument at random X and Y coordinates:

Var f As FolderItem = SpecialFolder.Desktop.Child("PDFAnnotations.pdf")

Var d As New PDFDocument
Var g As Graphics = d.Graphics

g.FontSize = 24
g.Bold = True

Const tHL As String = "PDFAnnotations Demo"

g.DrawText(tHL,10,40)
g.DrawLine(10,45,g.TextWidth(tHL)+10,45)

Const tBD As String = "This demo adds a total of five annotations to the PDF Document " + _
"at random positions in the page."

g.FontSize = 12
g.Bold = False

g.DrawText(tBD, 10, 80)

Var Rnd As New Random

For n As Integer = 0 To 4

d.AddAnnotation("Some example text for Annotation #" + Integer(n+1).tostring + ".", _
rnd.InRange(10,d.PageWidth), rnd.InRange(10,d.PageHeight))

Next n

Try
d.Save(f)
f.Open
Catch e As IOException
System.DebugLog(e.Message)
End Try

…and Adding Links

Now you can add as many links as you wish to the PDF Document (the one you are “drawing”); this is done via the new AddLinkArea method. The first method parameter is the one storing the target that will be opened once the user clicks on the active area. For example, it is possible to use protocols like “HTTP://”, “HTTPS://”, “mailto://”, “ftp://”, “sftp://” or even customized URIs like the ones used by the Xojo Feedback app: “feedback://”.

Once the user clicks on the active areas set by AddLinkArea, the PDF viewer app will open the default app designated in the preferences for this kind of link whether that is a web browser, email client app, FTP app, etc.

The following fragment of code creates a PDF that uses several kinds of links:

Var d As New PDFDocument
Var g As Graphics = d.Graphics

Var f As FolderItem = SpecialFolder.Desktop.Child("PDFLink Demo.pdf")

g.FontSize = 24
g.Bold = True

Const tHL As String = "PDF Links Demo"

g.DrawText(tHL,10,40)
g.DrawLine(10,45,g.TextWidth(tHL)+10,45)

Const tBD As String = "This demo adds several links to fragments (text) in the PDF page. Move the mouse pointer over the following entries:"

g.FontSize = 12
g.Bold = False

g.DrawText(tBD, 10, 70,400)

Const kFirstLinkText As String = "• Click to go to the Xojo website."
Const kSecondLinkText As String = "• Click to go to Xojo's Documentation website."
Const kThirdLinkText As String = "• Click to go to Xojo's YouTube channel."
Const kFourthLinkText As String = "• Click to send an email to hello@xojo.com."
Const kFifthLinkText As String = "• Click to open a case on Feedback app."
Const kSixthLinkText As String = "• Click here to download a file from FTP server. If asked, use 'anonymous' as the password and any password you want."

g.DrawingColor = Color.Blue

Var tHeight As Double = g.TextHeight

g.DrawText(kFirstLinkText,10,120)
// Let's add the first Link, setting the area to surround the text of the "kFirstLinkText"
d.AddLinkArea("https://www.xojo.com",10,110,g.TextWidth(kFirstLinkText), tHeight)

g.DrawText(kSecondLinkText,10,140)
// Let's add the second Link, setting the area to surround the text of the "kSecondLinkText"
d.AddLinkArea("https://docs.xojo.com",10,130,g.TextWidth(kSecondLinkText), tHeight)

g.DrawText(kThirdLinkText,10,160)
// Let's add the third Link, setting the area to surround the text of the "kThirdLinkText"
d.AddLinkArea("https://www.youtube.com/c/XojoInc",10,150,g.TextWidth(kThirdLinkText), tHeight)

g.DrawText(kFourthLinkText,10,180)
// Let's add the fourth Link, setting the area to surround the text of the "kFourthLinkText"
d.AddLinkArea("mailto:hello@xojo.com",10,170,g.TextWidth(kFourthLinkText), tHeight)

g.DrawText(kFifthLinkText,10,200)
// Let's add the fourth Link, setting the area to surround the text of the "kFifthLinkText"
d.AddLinkArea("feedback://showreport?report_id=64876",10,190,g.TextWidth(kFifthLinkText), tHeight)

g.DrawText(kSixthLinkText,10,220,400)
// Let's add the fifth Link, setting the area to surround the text of the "kSixthLinkText"
d.AddLinkArea("ftp://speedtest.tele2.net/1KB.zip",10,210, 400, tHeight*2)

Try
d.Save(f)
f.Open
Catch e As IOException
System.DebugLog(e.Message)
End Try

Jumping to a Page in the PDF Document

You can also add an active area that will jump to a specified document page. Use the AddGotoPage to do this. The following fragment of code creates a three page PDF. Once the user clicks on the active area set in the first page, the PDF viewer will display the third page in the viewer area:

Var d As New PDFDocument
Var g As Graphics = d.Graphics

g.DrawText("Hello World",40,40)

d.AddGoToPageArea(3,40,40-g.TextHeight,100,40-g.TextHeight,300,400) // First parameter sets the page of the document to jump to.

g.NextPage

g.DrawText("Hello from the Second Page", 40, 40)

g.NextPage

g.DrawText("Hello from the Third Page", 40, 40)

Var f As FolderItem = SpecialFolder.Desktop.Child("JumpToPage.PDF")

d.Save(f)
f.Open

PDF Viewer Options

Lastly, now you can designate how the PDF will be displayed when it is opened. For example, you can set the PDF so it opens in full screen mode or you can display two pages at once in the viewer area plus the thumbnails or the TOC index.

However, one thing to consider is that these settings may or may not be applied by the PDF Viewer app. For example, the free Acrobat Reader app will apply the settings made in the PDF, while other apps may apply some or none of these.

The following fragment of code creates a PDF where it instructs the PDF viewer app to open it in full screen mode and display two pages at once once while hiding the toolbar, menu bar and any of the extra UI controls when the user exits full screen mode:

Var d as New PDFDocument
Var vp As New pdf.PDFViewerOptions
vp.ToolbarVisible = False
vp.MenubarVisible = False
vp.WindowControlsVisible = True
vp.FitWindowToPage = False
vp.FullScreen = True
vp.Layout = PDFDocument.Layouts.FaceLeft
d.ViewerOptions = vp

Questions? Ask me on Twitter @XojoES or on the Xojo Forum.