Monday, May 31, 2010

PDF::API2 is Underrated

I feel like there has not been enough talk about PDF::API2 in the Perl community. Searching for code examples and tutorials does not yield many results, however it does lead to this tutorial, which is the only useful one that I have been able to find. It is worth reading. Oh, and it's written by my boss ;) Go and read it if you plan on using PDF::API2 in the future.

At work, for the past year, we have used PDF::API2 to create this nice looking report and many others like it. Since then, I have learnt a number of lessons and picked up a few tips for using this powerful library, so here are some of them. This is by no means a tutorial, or even an introduction to PDF::API2, so if you are looking for something like that, refer to the tutorial I referenced in the previous paragraph. This is more of a coredump of the part of my brain that knows PDF, so to speak.

The coordinate system is that of a Cartesian plane

Personally, every toolkit I have used in the past (which, admittedly, is not a long list) has placed the origin (0, 0) in the top-left corner. I assume, without actually researching, that this was because it was easier for developers to think about placing the top-left corner of a widget/window around the screen. We (mostly) read articles and books and posters from the top-left to the bottom-right.

However, coordinates in PDF::API2 work differently; the origin resides at the bottom-left of the document, just like the first quadrant of a Cartesian plane. Once you think of it this way, it becomes a lot easier to visualise what you are doing and the placement of your content.

Work from the bottom-left

This is linked to the previous point. If you are factoring out specific data or widgets into separate classes or functions, specify the position of the data by the bottom-left coordinate, rather than the top-left. This saves a lot of recalculating when you have to use various text/graphics object functions.

I prefer to refer to the coordinates as 'bottom' and 'left', which clears up any confusion that using 'x' and 'y' might introduce. I recommend doing the same.

Occasionally you may need to work from the top of your widget, e.g. for tabular data, in which case you can simply use the bottom + height to get the top-most Y-coordinate.

Useful CPAN documentation

PDF::API2 documentation is shocking. It's horrible. It's almost non-existant. However, PDF::API2::Content contains 95% of the functions that you probably want. Specifically, it contains all of the member functions for the text and graphics objects, which are the objects you will use most of the time.

Useful function that you might skim past

$text->advancewidth('foo bar', \%options)

Given the state of your text object, i.e. font name and size, this will return the width, in points, required to display the text 'foo bar' on the page. Great for figuring out how much space you need to display content like names of people. If you do not want to use the current state of your text object, the second parameter, with text object settings, can be used instead. I have never needed to use the second parameter so far.

That's it for now. In the future I would like to write some more about this library - preferably with more structure and a nice example rather than random ramblings - but that will have to wait until I can spare the time.