Continuing my attempt to dissect FDPF to understand PDF's, we'll create the simplest PDF: a blank page.
We need a couple of objects:
- Catalog
- This serves as the root object and describes the data structures in the document, which for our purposes is just the collection of printed pages. Other things, like the data for interactive forms, Javascript routines and metadata (author, subject, keywords) would go here.
1 0 obj << /Type /Catalog /Pages 0 2 R % reference to object number 2 >> endobj
- One useful optional entry in the catalog is the
/OpenAction
that can be used to set the zoom level and opening page./OpenAction [3 0 R /Fit]
starts at the page described in object 3 and zooms in to fit the page on the screen.
- Pages
- The collection of pages. This is just an array of references to the actual pages or to sub-collections of pages. The manual talks about organizing the pages in a balanced tree to make skipping around faster, but we're not that fancy. Our tree is flat. It also includes a
/Count
entry with the total number of pages (which is not the same as the number of items in the array, since the array could contain references to other Pages collections). 2 0 obj << /Type /Pages /Kids [ 4 0 R ] % One page. They were too cute by half, calling the child objects "Kids" /Count 1 >> endobj
- Resources
- The resource dictionary that assigns names to all the "stuff" we need on the page—images, fonts, "graphic states" (sets of graphic commands to set the color, pen size, line styles, transparency, etc.) and other things. The page-drawing language (called a "content stream" does not refer to objects in the PDF by number (like
2 0 R
) but by the name given in the page's resource dictionary. Since our page doesn't have any content, the dictionary is empty: 3 0 obj << >> endobj
- PDF originally required a
/ProcSet
entry listing the types of commands used on a page, but that's now obsolete; all the commands are always available. fPDF still includes it, though. - Page
- A description of a single page. Mostly just a reference to its contents, which is a stream and as such cannot be directly included (the definition could have allowed the page itself to be the content stream, but that would have been too easy), and the page size, as a rectangle of point (1/72 inch) measures that sets the coordinate system for drawing. Also includes references to its parent
Pages
collection and the resource dictionary (you could have a separate resource dictionary for every page, but I can't imagine why you'd want to ). 4 0 obj << /Type /Page /Parent 2 0 R /Resources 3 0 R /Contents 5 0 R /MediaBox [ 0 0 612 792 ] % letter-size, in points. >> endobj
- Contents
- The actual content stream for drawing the page. We don't do anything, so this is empty:
5 0 obj << /Length 0 >> stream endstream endobj
We can put these parts together to create a class that produces blank pages:
$pdf = new bililitePDF_1();
$pdf->newPage();
$pdf->output();
And you can see the result here. Or even create multiple pages. 150 lines of code to do nothing! Whoohoo! But it's a start to putting some real content in those pages.
Leave a Reply