textout("Hello World", 50, 50); // header("Content-Type: application/pdf"); // echo $x->getPDF(); // class PDFHack { var $pages = ""; var $pagelist = ""; var $text = array(); // X between 0 .. 612, Y between 0 .. 792 function textout($txt, $x, $y, $size = 14, $page = 0) { $y = 792 - $y; if (!array_key_exists($page, $this->text)) $this->text[$page] = ""; $this->text[$page] .= "BT /F1 ${size} Tf ${x} ${y} Td ( ${txt} ) Tj ET\n"; } // Gets the actual PDF file that can be outputted function getPDF() { // Copy and pasted example PDF file from G.2 of // http://www.adobe.com/devnet/acrobat/pdfs/pdf_reference.pdf $c = <<> endobj 2 0 obj << /Type /Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [ %PAGELIST%] /Count %PAGECOUNT% >> endobj 4 0 obj [ /PDF /Text ] endobj 5 0 obj << /Type /Font /Subtype /Type1 /Name /F1 /BaseFont /Helvetica /Encoding /MacRomanEncoding >> endobj %PAGES%xref 0 8 0000000000 65535 f MINIMAL_HEAD; // Create necessary pages and their content. The counters are // for object numbers, the page and its content have to refer // to each other properly. $pages = ""; $nextobj = 6; foreach ($this->text as $number => $content) { $nextnextobj = $nextobj + 1; $pages .= <<> >> >> endobj PAGE; $contentlength = strlen($content)-5; // -5 because "BT", "ET", "\n" are not part of content $nextobj++; $pages .= <<> stream ${content}endstream endobj PAGECONTENT; $nextobj++; } $c = str_replace("%PAGES%", $pages, $c); // List of pages in 8 0 R 9 0 R 10 0 R ... format $pagelist = ""; $pagecount = 0; for ($i=6;$i<=$nextobj-1;$i+=2) { $pagelist .= "$i 0 R "; $pagecount++; } $c = str_replace("%PAGELIST%", $pagelist, $c); $c = str_replace("%PAGECOUNT%", $pagecount, $c); // Compute the catalog for the PDF file by naively looking for objects $i = 1; $catalog = ""; for (;;) { if (($pos = strpos($c, $i." 0 obj")) === false) break; $catalog .= sprintf("%010d", $pos)." 00000 n\n"; $i++; } // Footer, with a reference to the position of the catalog $catalogpos = strpos($c, "xref"); $footer = "trailer\n<< /Size 8\n/Root 1 0 R\n>>\nstartxref\n${catalogpos}\n%%EOF"; // Output PDF file, replacing the text part with actual text content $c = str_replace("%TEXT%", $this->text, $c); return str_replace("\n", "\r\n", $c.$catalog.$footer); } } ?>