1<?php 2// $Header: /cvsroot/html2ps/output.fpdf.class.php,v 1.27 2007/05/17 13:55:13 Konstantin Exp $ 3 4require_once(HTML2PS_DIR.'pdf.fpdf.php'); 5require_once(HTML2PS_DIR.'pdf.fpdf.makefont.php'); 6// require_once(HTML2PS_DIR.'fpdf/font/makefont/makefont.php'); 7 8class OutputDriverFPDF extends OutputDriverGenericPDF { 9 var $pdf; 10 var $locallinks; 11 var $cx; 12 var $cy; 13 14 function OutputDriverFPDF() { 15 $this->OutputDriverGenericPDF(); 16 } 17 18 function add_link($x, $y, $w, $h, $target) { 19 $this->_coords2pdf_annotation($x, $y); 20 $this->pdf->add_link_external($x, $y, $w, $h, $target); 21 } 22 23 function add_local_link($left, $top, $width, $height, $anchor) { 24 if (!isset($this->locallinks[$anchor->name])) { 25 $x = 0; 26 $y = $anchor->y; 27 $this->_coords2pdf($x, $y); 28 29 $this->locallinks[$anchor->name] = $this->pdf->AddLink(); 30 $this->pdf->SetLink($this->locallinks[$anchor->name], 31 $y - 20, 32 $anchor->page); 33 }; 34 35 $x = $left; 36 $y = $top - $this->offset; 37 $this->_coords2pdf($x, $y); 38 39 $this->pdf->add_link_internal($x, 40 $y, 41 $width, 42 $height, 43 $this->locallinks[$anchor->name]); 44 } 45 46 // UNfortunately, FPDF do not provide any coordinate-space transformation routines 47 // so we need to reverse the Y-axis manually 48 function _coords2pdf(&$x, &$y) { 49 $y = mm2pt($this->media->height()) - $y; 50 } 51 52 // Annotation coordinates are always interpreted in the default (untranslated!) 53 // user space. (See PDF Reference 1.6 Section 8.4 p.575) 54 function _coords2pdf_annotation(&$x, &$y) { 55 $y = $y - $this->offset; 56 $this->_coords2pdf($x, $y); 57 } 58 59 function decoration($underline, $overline, $strikeout) { 60 // underline 61 $this->pdf->SetDecoration($underline, $overline, $strikeout); 62 } 63 64 function circle($x, $y, $r) { 65 $this->pdf->circle($x, $y, $r); 66 } 67 68 function clip() { 69 $this->pdf->Clip(); 70 } 71 72 function close() { 73 $this->pdf->Output($this->get_filename()); 74 } 75 76 function closepath() { 77 $this->pdf->closepath(); 78 } 79 80 function dash($x, $y) { 81 $this->pdf->SetDash(ceil($x), ceil($y)); 82 } 83 84 function get_bottom() { 85 return $this->bottom + $this->offset; 86 } 87 88 function field_multiline_text($x, $y, $w, $h, $value, $field_name) { 89 $this->_coords2pdf_annotation($x, $y); 90 $this->pdf->add_field_multiline_text($x, $y, $w, $h, $value, $field_name); 91 } 92 93 function field_text($x, $y, $w, $h, $value, $field_name) { 94 $this->_coords2pdf_annotation($x, $y); 95 $this->pdf->add_field_text($x, $y, $w, $h, $value, $field_name); 96 } 97 98 function field_password($x, $y, $w, $h, $value, $field_name) { 99 $this->_coords2pdf_annotation($x, $y); 100 $this->pdf->add_field_password($x, $y, $w, $h, $value, $field_name); 101 } 102 103 function field_pushbutton($x, $y, $w, $h) { 104 $this->_coords2pdf_annotation($x, $y); 105 $this->pdf->add_field_pushbutton($x, $y, $w, $h); 106 } 107 108 function field_pushbuttonimage($x, $y, $w, $h, $field_name, $value, $actionURL) { 109 $this->_coords2pdf_annotation($x, $y); 110 $this->pdf->add_field_pushbuttonimage($x, $y, $w, $h, $field_name, $value, $actionURL); 111 } 112 113 function field_pushbuttonreset($x, $y, $w, $h) { 114 $this->_coords2pdf_annotation($x, $y); 115 $this->pdf->add_field_pushbuttonreset($x, $y, $w, $h); 116 } 117 118 function field_pushbuttonsubmit($x, $y, $w, $h, $field_name, $value, $actionURL) { 119 $this->_coords2pdf_annotation($x, $y); 120 $this->pdf->add_field_pushbuttonsubmit($x, $y, $w, $h, $field_name, $value, $actionURL); 121 } 122 123 function field_checkbox($x, $y, $w, $h, $name, $value, $checked) { 124 $this->_coords2pdf_annotation($x, $y); 125 $this->pdf->add_field_checkbox($x, $y, $w, $h, $name, $value, $checked); 126 } 127 128 function field_radio($x, $y, $w, $h, $groupname, $value, $checked) { 129 static $generated_group_index = 0; 130 if (is_null($groupname)) { 131 $generated_group_index ++; 132 $groupname = "__generated_group_".$generated_group_index; 133 }; 134 135 $this->_coords2pdf_annotation($x, $y); 136 $this->pdf->add_field_radio($x, $y, $w, $h, $groupname, $value, $checked); 137 } 138 139 function field_select($x, $y, $w, $h, $name, $value, $options) { 140 $this->_coords2pdf_annotation($x, $y); 141 $this->pdf->add_field_select($x, $y, $w, $h, $name, $value, $options); 142 } 143 144 function fill() { 145 $this->pdf->Fill(); 146 } 147 148 function findfont($name, $encoding) { 149 // Todo: encodings handling 150 return $name; 151 } 152 153 function font_ascender($name, $encoding) { 154 return $this->pdf->GetFontAscender($name, $encoding); 155 } 156 157 function font_descender($name, $encoding) { 158 return $this->pdf->GetFontDescender($name, $encoding); 159 } 160 161 function image($image, $x, $y, $scale) { 162 $tmpname = $this->_mktempimage($image); 163 164 $this->_coords2pdf($x, $y); 165 $this->pdf->Image($tmpname, 166 $x, 167 $y - $image->sy() * $scale, 168 $image->sx() * $scale, 169 $image->sy() * $scale); 170 171 unlink($tmpname); 172 } 173 174 function image_rx($image, $x, $y, $width, $right, $ox, $oy, $scale) { 175 $tmpname = $this->_mktempimage($image); 176 177 // Fill part to the right 178 $cx = $x; 179 while ($cx < $right) { 180 $tx = $cx; 181 $ty = $y + px2pt($image->sy()); 182 $this->_coords2pdf($tx, $ty); 183 $this->pdf->Image($tmpname, $tx, $ty, $image->sx() * $scale, $image->sy() * $scale, "png"); 184 $cx += $width; 185 }; 186 187 // Fill part to the left 188 $cx = $x; 189 while ($cx+$width >= $x - $ox) { 190 $tx = $cx-$width; 191 $ty = $y + px2pt($image->sy()); 192 $this->_coords2pdf($tx, $ty); 193 $this->pdf->Image($tmpname, $tx, $ty, $image->sx() * $scale, $image->sy() * $scale, "png"); 194 $cx -= $width; 195 }; 196 197 unlink($tmpname); 198 } 199 200 function image_rx_ry($image, $x, $y, $width, $height, $right, $bottom, $ox, $oy, $scale) { 201 $tmpname = $this->_mktempimage($image); 202 203 // Fill bottom-right quadrant 204 $cy = $y; 205 while ($cy+$height > $bottom) { 206 $cx = $x; 207 while ($cx < $right) { 208 $tx = $cx; 209 $ty = $cy+$height; 210 $this->_coords2pdf($tx, $ty); 211 212 $this->pdf->Image($tmpname, $tx, $ty, $image->sx() * $scale, $image->sy() * $scale, "png"); 213 $cx += $width; 214 }; 215 $cy -= $height; 216 } 217 218 // Fill bottom-left quadrant 219 $cy = $y; 220 while ($cy+$height > $bottom) { 221 $cx = $x; 222 while ($cx+$width > $x - $ox) { 223 $tx = $cx; 224 $ty = $cy; 225 $this->_coords2pdf($tx, $ty); 226 $this->pdf->Image($tmpname, $tx, $ty, $image->sx() * $scale, $image->sy() * $scale, "png"); 227 $cx -= $width; 228 }; 229 $cy -= $height; 230 } 231 232 // Fill top-right quadrant 233 $cy = $y; 234 while ($cy < $y + $oy) { 235 $cx = $x; 236 while ($cx < $right) { 237 $tx = $cx; 238 $ty = $cy; 239 $this->_coords2pdf($tx, $ty); 240 $this->pdf->Image($tmpname, $tx, $ty, $image->sx() * $scale, $image->sy() * $scale, "png"); 241 $cx += $width; 242 }; 243 $cy += $height; 244 } 245 246 // Fill top-left quadrant 247 $cy = $y; 248 while ($cy < $y + $oy) { 249 $cx = $x; 250 while ($cx+$width > $x - $ox) { 251 $tx = $cx; 252 $ty = $cy; 253 $this->_coords2pdf($tx, $ty); 254 $this->pdf->Image($tmpname, $tx, $ty, $image->sx() * $scale, $image->sy() * $scale, "png"); 255 $cx -= $width; 256 }; 257 $cy += $height; 258 } 259 260 unlink($tmpname); 261 } 262 263 264 function image_ry($image, $x, $y, $height, $bottom, $ox, $oy, $scale) { 265 $tmpname = $this->_mktempimage($image); 266 267 // Fill part to the bottom 268 $cy = $y; 269 while ($cy+$height > $bottom) { 270 $tx = $x; 271 $ty = $cy + px2pt($image->sy()); 272 $this->_coords2pdf($tx, $ty); 273 $this->pdf->Image($tmpname, $tx, $ty, $image->sx() * $scale, $image->sy() * $scale, "png"); 274 $cy -= $height; 275 }; 276 277 // Fill part to the top 278 $cy = $y; 279 while ($cy-$height < $y + $oy) { 280 $tx = $x; 281 $ty = $cy + px2pt($image->sy()); 282 $this->_coords2pdf($tx, $ty); 283 $this->pdf->Image($tmpname, $tx, $ty, $image->sx() * $scale, $image->sy() * $scale, "png"); 284 $cy += $height; 285 }; 286 287 unlink($tmpname); 288 } 289 290 function image_scaled($image, $x, $y, $scale_x, $scale_y) { 291 $tmpname = $this->_mktempimage($image); 292 293 $this->_coords2pdf($x, $y); 294 $this->pdf->Image($tmpname, $x, $y - $image->sy() * $scale_y, $image->sx() * $scale_x, $image->sy() * $scale_y, "png"); 295 unlink($tmpname); 296 } 297 298 function lineto($x, $y) { 299 $this->_coords2pdf($x, $y); 300 $this->pdf->lineto($x, $y); 301 } 302 303 function moveto($x, $y) { 304 $this->_coords2pdf($x, $y); 305 $this->pdf->moveto($x, $y); 306 } 307 308 function new_form($name) { 309 $this->pdf->add_form($name); 310 } 311 312 function next_page($height) { 313 $this->pdf->AddPage(mm2pt($this->media->width()), mm2pt($this->media->height())); 314 315 // Calculate coordinate of the next page bottom edge 316 $this->offset -= $height - $this->offset_delta; 317 318 // Reset the "correction" offset to it normal value 319 // Note: "correction" offset is an offset value required to avoid page breaking 320 // in the middle of text boxes 321 $this->offset_delta = 0; 322 323 $this->pdf->Translate(0, -$this->offset); 324 325 parent::next_page($height); 326 } 327 328 function reset(&$media) { 329 parent::reset($media); 330 331 $this->pdf =& new FPDF('P','pt',array(mm2pt($media->width()), mm2pt($media->height()))); 332 333 if (defined('DEBUG_MODE')) { 334 $this->pdf->SetCompression(false); 335 } else { 336 $this->pdf->SetCompression(true); 337 }; 338 339 $this->cx = 0; 340 $this->cy = 0; 341 342 $this->locallinks = array(); 343 } 344 345 function restore() { 346 $this->pdf->Restore(); 347 } 348 349 function save() { 350 $this->pdf->Save(); 351 } 352 353 function setfont($name, $encoding, $size) { 354 $this->pdf->SetFont($this->findfont($name, $encoding), $encoding, $size); 355 356 return true; 357 } 358 359 function setlinewidth($x) { 360 $this->pdf->SetLineWidth($x); 361 } 362 363 // PDFLIB wrapper functions 364 function setrgbcolor($r, $g, $b) { 365 $this->pdf->SetDrawColor($r*255, $g*255, $b*255); 366 $this->pdf->SetFillColor($r*255, $g*255, $b*255); 367 $this->pdf->SetTextColor($r*255, $g*255, $b*255); 368 } 369 370 function show_xy($text, $x, $y) { 371 $this->_coords2pdf($x, $y); 372 373 $this->pdf->Text($x, $y, $text); 374 } 375 376 function stroke() { 377 $this->pdf->stroke(); 378 } 379 380 function stringwidth($string, $name, $encoding, $size) { 381 $this->setfont($name, $encoding, $size); 382 $width = $this->pdf->GetStringWidth($string); 383 return $width; 384 } 385 386 function _show_watermark($watermark) { 387 $this->pdf->SetFont("Helvetica", "iso-8859-1", 100); 388 389 $x = $this->left + $this->width / 2; 390 $y = $this->bottom + $this->height / 2 - $this->offset; 391 $this->_coords2pdf($x, $y); 392 393 $this->pdf->SetTextRendering(1); 394 $this->pdf->SetDecoration(false, false, false); 395 $this->pdf->Translate($x, $y); 396 $this->pdf->Rotate(60); 397 398 $tx = -$this->pdf->GetStringWidth($watermark)/2; 399 $ty = -50; 400 $this->_coords2pdf($tx, $ty); 401 402 // By default, "watermark" is rendered in black color 403 $this->setrgbcolor(0,0,0); 404 405 $this->pdf->Text($tx, 406 $ty, 407 $watermark); 408 } 409 410 function _mktempimage($image) { 411 $tempnam = tempnam(WRITER_TEMPDIR, WRITER_FILE_PREFIX); 412 413 switch ($image->get_type()) { 414 case 'image/png': 415 $filename = $tempnam . '.png'; 416 imagepng($image->get_handle(), $filename); 417 break; 418 419 case 'image/jpeg': 420 default: 421 $filename = $tempnam . '.jpg'; 422 imagejpeg($image->get_handle(), $filename); 423 break; 424 } 425 426 unlink($tempnam); 427 return $filename; 428 } 429} 430?>