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://documentation.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.