1<?php 2// $Header: /cvsroot/html2ps/output.pdflib.class.php,v 1.18 2007/05/17 13:55:13 Konstantin Exp $ 3 4define('PDFLIB_STATUS_INITIALIZED', 0); 5define('PDFLIB_STATUS_DOCUMENT_STARTED', 1); 6define('PDFLIB_STATUS_PAGE_STARTED', 2); 7 8class OutputDriverPdflib extends OutputDriverGenericPDF { 9 var $pdf; 10 11 /** 12 * @var ? Contains the PDFLIB handle of currently selected PDF font 13 * @access private 14 */ 15 var $_currentfont; 16 var $_forms; 17 var $_field_names; 18 19 var $_radiogroups; 20 var $_watermark; 21 22 var $_status; 23 24 // Converts common encoding names to their PDFLIB equivalents 25 // (for example, PDFLIB does not understand iso-8859-1 encoding name, 26 // but have its equivalent names winansi..) 27 // 28 function encoding($encoding) { 29 $encoding = trim(strtolower($encoding)); 30 31 $translations = array('iso-8859-1' => 'winansi', 32 'iso-8859-2' => 'iso8859-2', 33 'iso-8859-3' => 'iso8859-3', 34 'iso-8859-4' => 'iso8859-4', 35 'iso-8859-5' => 'iso8859-5', 36 'iso-8859-6' => 'iso8859-6', 37 'iso-8859-7' => 'iso8859-7', 38 'iso-8859-8' => 'iso8859-8', 39 'iso-8859-9' => 'iso8859-9', 40 'iso-8859-10' => 'iso8859-10', 41 'iso-8859-13' => 'iso8859-13', 42 'iso-8859-14' => 'iso8859-14', 43 'iso-8859-15' => 'iso8859-15', 44 'iso-8859-16' => 'iso8859-16', 45 'windows-1250' => 'cp1250', 46 'windows-1251' => 'cp1251', 47 'windows-1252' => 'cp1252', 48 'symbol' => 'symbol'); 49 50 if (isset($translations[$encoding])) { return $translations[$encoding]; }; 51 return $encoding; 52 } 53 54 function add_link($left, $top, $width, $height, $url) { 55 pdf_add_weblink($this->pdf, $left, $top-$height, $left+$width, $top, $url); 56 } 57 58 function add_local_link($left, $top, $width, $height, $anchor) { 59 pdf_add_locallink($this->pdf, 60 $left, 61 $top-$height - $this->offset , 62 $left+$width, 63 $top - $this->offset, 64 $anchor->page, 65 "fitwidth"); 66 } 67 68 function circle($x, $y, $r) { 69 pdf_circle($this->pdf, $x, $y, $r); 70 } 71 72 function clip() { 73 pdf_clip($this->pdf); 74 } 75 76 function close() { 77 pdf_end_page($this->pdf); 78 pdf_close($this->pdf); 79 pdf_delete($this->pdf); 80 } 81 82 function closepath() { 83 pdf_closepath($this->pdf); 84 } 85 86 function dash($x, $y) { 87 pdf_setdash($this->pdf, $x, $y); 88 } 89 90 function decoration($underline, $overline, $strikeout) { 91 // underline 92 pdf_set_parameter($this->pdf, "underline", $underline ? "true" : "false"); 93 // overline 94 pdf_set_parameter($this->pdf, "overline", $overline ? "true" : "false"); 95 // line through 96 pdf_set_parameter($this->pdf, "strikeout", $strikeout ? "true" : "false"); 97 } 98 99 function fill() { 100 pdf_fill($this->pdf); 101 } 102 103 function findfont($name, $encoding) { 104 // PDFLIB is limited by 'builtin' encoding for "Symbol" font 105 if ($name == 'Symbol') { 106 $encoding = 'builtin'; 107 }; 108 109 global $g_font_resolver_pdf; 110 $embed = $g_font_resolver_pdf->embed[$name]; 111 return pdf_findfont($this->pdf, $name, $this->encoding($encoding), $embed); 112 } 113 114 function font_ascender($name, $encoding) { 115 return pdf_get_value($this->pdf, "ascender", $this->findfont($name, $encoding)); 116 } 117 118 function font_descender($name, $encoding) { 119 return -pdf_get_value($this->pdf, "descender", $this->findfont($name, $encoding)); 120 } 121 122 function get_bottom() { 123 return $this->bottom + $this->offset; 124 } 125 126 function image($image, $x, $y, $scale) { 127 $tmpname = tempnam(WRITER_TEMPDIR,WRITER_FILE_PREFIX); 128 imagepng($image->get_handle(), $tmpname); 129 $pim = pdf_open_image_file($this->pdf, "png", $tmpname, "", 0); 130 pdf_place_image($this->pdf, $pim, $x, $y, $scale); 131 pdf_close_image($this->pdf, $pim); 132 unlink($tmpname); 133 } 134 135 function image_scaled($image, $x, $y, $scale_x, $scale_y) { 136 $tmpname = tempnam(WRITER_TEMPDIR,WRITER_FILE_PREFIX); 137 imagepng($image->get_handle(), $tmpname); 138 139 $pim = pdf_open_image_file($this->pdf, "png", $tmpname, "", 0); 140 141 $this->save(); 142 pdf_translate($this->pdf, $x, $y); 143 pdf_scale($this->pdf, $scale_x, $scale_y); 144 pdf_place_image($this->pdf, $pim, 0, 0, 1); 145 $this->restore(); 146 147 pdf_close_image($this->pdf, $pim); 148 unlink($tmpname); 149 } 150 151 function image_ry($image, $x, $y, $height, $bottom, $ox, $oy, $scale) { 152 $tmpname = tempnam(WRITER_TEMPDIR,WRITER_FILE_PREFIX); 153 imagepng($image->get_handle(), $tmpname); 154 $pim = pdf_open_image_file($this->pdf, "png", $tmpname, "", 0); 155 156 // Fill part to the bottom 157 $cy = $y; 158 while ($cy+$height > $bottom) { 159 pdf_place_image($this->pdf, $pim, $x, $cy, $scale); 160 $cy -= $height; 161 }; 162 163 // Fill part to the top 164 $cy = $y; 165 while ($cy-$height < $y + $oy) { 166 pdf_place_image($this->pdf, $pim, $x, $cy, $scale); 167 $cy += $height; 168 }; 169 170 pdf_close_image($this->pdf, $pim); 171 unlink($tmpname); 172 } 173 174 function image_rx($image, $x, $y, $width, $right, $ox, $oy, $scale) { 175 $tmpname = tempnam(WRITER_TEMPDIR,WRITER_FILE_PREFIX); 176 imagepng($image->get_handle(), $tmpname); 177 $pim = pdf_open_image_file($this->pdf, "png", $tmpname, "", 0); 178 179 // Fill part to the right 180 $cx = $x; 181 while ($cx < $right) { 182 pdf_place_image($this->pdf, $pim, $cx, $y, $scale); 183 $cx += $width; 184 }; 185 186 // Fill part to the left 187 $cx = $x; 188 while ($cx+$width >= $x - $ox) { 189 pdf_place_image($this->pdf, $pim, $cx-$width, $y, $scale); 190 $cx -= $width; 191 }; 192 193 pdf_close_image($this->pdf, $pim); 194 unlink($tmpname); 195 } 196 197 function image_rx_ry($image, $x, $y, $width, $height, $right, $bottom, $ox, $oy, $scale) { 198 $tmpname = tempnam(WRITER_TEMPDIR,WRITER_FILE_PREFIX); 199 imagepng($image->get_handle(), $tmpname); 200 $pim = pdf_open_image_file($this->pdf, "png", $tmpname, "", 0); 201 202 // Fill bottom-right quadrant 203 $cy = $y; 204 while ($cy+$height > $bottom) { 205 $cx = $x; 206 while ($cx < $right) { 207 pdf_place_image($this->pdf, $pim, $cx, $cy, $scale); 208 $cx += $width; 209 }; 210 $cy -= $height; 211 } 212 213 // Fill bottom-left quadrant 214 $cy = $y; 215 while ($cy+$height > $bottom) { 216 $cx = $x; 217 while ($cx+$width > $x - $ox) { 218 pdf_place_image($this->pdf, $pim, $cx, $cy, $scale); 219 $cx -= $width; 220 }; 221 $cy -= $height; 222 } 223 224 // Fill top-right quadrant 225 $cy = $y; 226 while ($cy < $y + $oy) { 227 $cx = $x; 228 while ($cx < $right) { 229 pdf_place_image($this->pdf, $pim, $cx, $cy, $scale); 230 $cx += $width; 231 }; 232 $cy += $height; 233 } 234 235 // Fill top-left quadrant 236 $cy = $y; 237 while ($cy < $y + $oy) { 238 $cx = $x; 239 while ($cx+$width > $x - $ox) { 240 pdf_place_image($this->pdf, $pim, $cx, $cy, $scale); 241 $cx -= $width; 242 }; 243 $cy += $height; 244 } 245 246 pdf_close_image($this->pdf, $pim); 247 unlink($tmpname); 248 } 249 250 function lineto($x, $y) { 251 pdf_lineto($this->pdf, $x, $y); 252 } 253 254 function moveto($x, $y) { 255 pdf_moveto($this->pdf, $x, $y); 256 } 257 258 // OutputDriver interface functions 259 function next_page($height) { 260 if ($this->_status == PDFLIB_STATUS_PAGE_STARTED) { 261 pdf_end_page($this->pdf); 262 }; 263 pdf_begin_page($this->pdf, mm2pt($this->media->width()), mm2pt($this->media->height())); 264 265 // Calculate coordinate of the next page bottom edge 266 $this->offset -= $height - $this->offset_delta; 267 268 // Reset the "correction" offset to it normal value 269 // Note: "correction" offset is an offset value required to avoid page breaking 270 // in the middle of text boxes 271 $this->offset_delta = 0; 272 273 pdf_translate($this->pdf, 0, -$this->offset); 274 275 parent::next_page($height); 276 277 $this->_status = PDFLIB_STATUS_PAGE_STARTED; 278 } 279 280 function OutputDriverPdflib($version) { 281 $this->OutputDriverGenericPDF(); 282 $this->set_pdf_version($version); 283 284 $this->_currentfont = null; 285 $this->_radiogroups = array(); 286 $this->_field_names = array(); 287 288 $this->_status = PDFLIB_STATUS_INITIALIZED; 289 } 290 291 function prepare() { 292 parent::prepare(); 293 294 // Generate custom encoding vector mappings 295 $manager_encoding = ManagerEncoding::get(); 296 for ($i = 1, $size = $manager_encoding->get_custom_vector_index(); $i <= $size; $i++) { 297 $encoding_name = $manager_encoding->get_custom_encoding_name($i); 298 $filename = $this->generate_cpg($encoding_name, 299 true); 300 pdf_set_parameter($this->pdf, 301 'Encoding', 302 sprintf('%s=%s', 303 $encoding_name, 304 $filename)); 305 }; 306 } 307 308 function reset(&$media) { 309 OutputDriverGenericPDF::reset($media); 310 311 // Check if PDFLIB is available 312 if (!extension_loaded('pdf')) { 313 314 // Try to use "dl" to dynamically load PDFLIB 315 $result = dl(PDFLIB_DL_PATH); 316 317 if (!$result) { 318 readfile(HTML2PS_DIR.'templates/missing_pdflib.html'); 319 error_log("No PDFLIB extension found"); 320 die("HTML2PS Error"); 321 } 322 } 323 324 $this->pdf = pdf_new(); 325 326 // Set PDF compatibility level 327 pdf_set_parameter($this->pdf, "compatibility", $this->get_pdf_version()); 328 329 /** 330 * Use PDF license key, if present 331 * 332 * PDFLIB_LICENSE constant is defined in 'config.inc.php' file in "PDFLIB-specific" section. 333 */ 334 if (defined("PDFLIB_LICENSE")) { 335 pdf_set_parameter($this->pdf, "license", PDFLIB_LICENSE); 336 }; 337 338 pdf_open_file($this->pdf, $this->get_filename()); 339 340 // @TODO: compression level, debug 341 pdf_set_value($this->pdf, "compress", 0); 342 343 // Set path to the PDFLIB UPR file containig information about fonts and encodings 344 if (defined("PDFLIB_UPR_PATH")) { 345 pdf_set_parameter($this->pdf, "resourcefile", PDFLIB_UPR_PATH); 346 }; 347 348 // Setup encodings not bundled with PDFLIB 349 $filename = $this->generate_cpg('koi8-r'); 350 pdf_set_parameter($this->pdf, 'Encoding', sprintf('koi8-r=%s', $filename)); 351 352 // Setup font outlines 353 global $g_font_resolver_pdf; 354 $g_font_resolver_pdf->setup_ttf_mappings($this->pdf); 355 356 $pdf = $this->pdf; 357 pdf_set_info($pdf, "Creator", "html2ps (PHP version)"); 358 359 // No borders around links in the generated PDF 360 pdf_set_border_style($this->pdf, "solid", 0); 361 362 $this->_status = PDFLIB_STATUS_DOCUMENT_STARTED; 363 } 364 365 function rect($x, $y, $w, $h) { 366 pdf_rect($this->pdf, $x, $y, $w, $h); 367 } 368 369 function restore() { 370 pdf_restore($this->pdf); 371 } 372 373 function save() { 374 pdf_save($this->pdf); 375 } 376 377 function setfont($name, $encoding, $size) { 378 $this->_currentfont = $this->findfont($name, $encoding); 379 380 pdf_setfont($this->pdf, $this->_currentfont, $size); 381 382 return true; 383 } 384 385// function setfontcore($name, $size) { 386// $this->_currentfont = pdf_findfont($this->pdf, $name, 'host', 1 /* embed */); 387 388// pdf_setfont($this->pdf, $this->_currentfont, $size); 389 390// return true; 391// } 392 393 function setlinewidth($x) { 394 pdf_setlinewidth($this->pdf, $x); 395 } 396 397 // PDFLIB wrapper functions 398 function setrgbcolor($r, $g, $b) { 399 pdf_setcolor($this->pdf, "both", "rgb", $r, $g, $b, 0); 400 } 401 402 function show_xy($text, $x, $y) { 403 pdf_show_xy($this->pdf, $text, $x, $y); 404 } 405 406 function stroke() { 407 pdf_stroke($this->pdf); 408 } 409 410 function stringwidth($string, $name, $encoding, $size) { 411 return pdf_stringwidth($this->pdf, $string, $this->findfont($name, $encoding), $size); 412 } 413 414 /* private routines */ 415 416 function _show_watermark($watermark) { 417 $font = $this->findfont('Helvetica', 'iso-8859-1'); 418 pdf_setfont($this->pdf, $font, 100); 419 420 $x = $this->left + $this->width / 2; 421 $y = $this->bottom + $this->height / 2 + $this->offset; 422 423 pdf_set_value($this->pdf, "textrendering", 1); 424 pdf_translate($this->pdf, $x, $y); 425 pdf_rotate($this->pdf, 60); 426 pdf_show_xy($this->pdf, $watermark, -pdf_stringwidth($this->pdf, $watermark, $font, 100)/2, -50); 427 } 428 429 function generate_cpg($encoding, $force = false) { 430 if (!$force) { 431 $filename = CACHE_DIR.$encoding.'.cpg'; 432 } else { 433 $filename = CACHE_DIR.uniqid('', false).'.cpg'; 434 }; 435 436 if (file_exists($filename)) { 437 return $filename; 438 }; 439 440 $output = fopen($filename, 'w'); 441 $manager_encoding =& ManagerEncoding::get(); 442 $vector = $manager_encoding->get_encoding_vector($encoding); 443 444 foreach ($vector as $code => $utf) { 445 fwrite($output, sprintf("0x%04X 0x%02X\n", $utf, ord($code))); 446 }; 447 fclose($output); 448 449 return $filename; 450 } 451} 452?>