Alleged Literature >> Damian Cugley >> 2003 >> Sept.

Damian Cugley’s Archive

Generating the printed comic with ReportLab

Wed. 3 Sept. 2003

My Percy Street comic strip is published on-line at 100 dpi, using HTML to arrange the panels on the page. I draw the pages at 300 dpi, which should be just high enough resolution to print on paper. The printed version uses PDF rather than HTML to lay out the page. (The page has to be laid out because I am drawing each panel as a separate image.)

The ReportLab Toolkit makes this easy. This was a relief, because my previous experience with turning XML data in to PDF as with Apache FOP, which works, and works well, but is incredibly fiddly, and requires learning all about XSL-FO, which, because of its super-generalized model of page layout, has a high learning curve.

ReportLab, by contrast, expose an interface to PDF that reveals the secret truth: under the hood, PDF is not all that dissimilar to PostScript. This may not seem much of an advantage to most of my readers, but back before I started work at my current employer, I did a lot of work in PostScript (even writing programs in the PostScript language itself). For this particular application—where I know (or can calculate) exactly where on the page I want to place each illustration—being able to just say

self.canvas.drawImage(fileName,
    x + self.border, y + self.border,
    frame.width, frame.height)

seems really simple. Actually, calculating x and y was a little tricky, because I wanted to do most of it automatically (the program deduces some aspects of the layout from the sizes of the panels).

The printable version uses different graphic files—the 300-dpi ones—but the information used to lay out the page is extracted from the same XML file as is used to generate the HTML pages. The ReportLab Toolkit uses Python, so my script processes the files using Fredrik Lundh’s elementtree package, which gives a more Pythonic interface to XML than the usual DOM. It also uses PIL (also created by Fredrik Lundh) to handle the graphics themselves.

The XML description of the comic is rather dull reading. It divides the strip in to pages, the pages in to tiers, and the tiers in to frames. Each frame is a separate image. To generate the HTML version, the tiers are converted to HTML divs using a XSLT file striptoxhtml.xslt. A little jiggery-pokery with CSS is required to get the layout to fit together exactly as I want it to. The dimensions have to be carefully judged so that a tier with, say, three panels with borders and gutters between adds up to the exact same number of pixels as the adjacent tier with only two panels. The XSLT processing is done using the very convenient XSLT plug-in to jEdit.

With the PDF version, my program calculates the positions of the pictures so they line up nicely. There is one tricky bit. In most cases, the frames in a tier are all of the same height. The exception is on page 3, which has two smaller frames, one above the other. In the HTML version, this is achieved through use of the float property of the images. In my program it took me an extra afternoon of fiddling to get things to come out right. Luckily I can depend on various things, such as the first frame being the one that defines the height of the tier (because to do otherwise would confuse readers because of the way frames are read from left to right).

Here is sample PDF output using a mixture of the screen-resolution and printer-resolution images (it should be obvious which pages are which). There now remains the tedious task of converting the individual frames (in Painter’s proprietary format) in to high-resolution GIFs...

Update (10 Dec. 2005). Percy Street is now being drawn under a pseudonym Leckford; for updates see Leckford’s LiveJournal.