[ Index ] |
PHP Cross Reference of phpwcms V1.4.7 _r403 (01.11.10) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Software: FPDF * 4 * Version: 1.52(modified) * 5 * Date: 2003-12-30 * 6 * Author: Olivier PLATHEY * 7 * License: Freeware * 8 * 9 * You may use, modify and redistribute this software as you wish. * 10 */ 11 // Modified by Renato A.C. [html2fpdf.sf.net] 12 // (look for 'EDITEI' in the code) 13 if ( !class_exists( 'FPDF' ) ) { 14 define( 'FPDF_VERSION', '1.52' ); 15 16 class FPDF { 17 // Private properties 18 var $DisplayPreferences = ''; //EDITEI - added 19 var $outlines = array(); //EDITEI - added 20 var $OutlineRoot; //EDITEI - added 21 var $flowingBlockAttr; //EDITEI - added 22 var $page; //current page number 23 var $n; //current object number 24 var $offsets; //array of object offsets 25 var $buffer; //buffer holding in-memory PDF 26 var $pages; //array containing pages 27 var $state; //current document state 28 var $compress; //compression flag 29 var $DefOrientation; //default orientation 30 var $CurOrientation; //current orientation 31 var $OrientationChanges; //array indicating orientation changes 32 var $k; //scale factor (number of points in user unit) 33 var $fwPt, $fhPt; //dimensions of page format in points 34 var $fw, $fh; //dimensions of page format in user unit 35 var $wPt, $hPt; //current dimensions of page in points 36 var $w, $h; //current dimensions of page in user unit 37 var $lMargin; //left margin 38 var $tMargin; //top margin 39 var $rMargin; //right margin 40 var $bMargin; //page break margin 41 var $cMargin; //cell margin 42 var $x, $y; //current position in user unit for cell positioning 43 var $lasth; //height of last cell printed 44 var $LineWidth; //line width in user unit 45 var $CoreFonts; //array of standard font names 46 var $fonts; //array of used fonts 47 var $FontFiles; //array of font files 48 var $diffs; //array of encoding differences 49 var $images; //array of used images 50 var $PageLinks; //array of links in pages 51 var $links; //array of internal links 52 var $FontFamily; //current font family 53 var $FontStyle; //current font style 54 var $underline; //underlining flag 55 var $CurrentFont; //current font info 56 var $FontSizePt; //current font size in points 57 var $FontSize; //current font size in user unit 58 var $DrawColor; //commands for drawing color 59 var $FillColor; //commands for filling color 60 var $TextColor; //commands for text color 61 var $ColorFlag; //indicates whether fill and text colors are different 62 var $ws; //word spacing 63 var $AutoPageBreak; //automatic page breaking 64 var $PageBreakTrigger; //threshold used to trigger page breaks 65 var $InFooter; //flag set when processing footer 66 var $ZoomMode; //zoom display mode 67 var $LayoutMode; //layout display mode 68 var $title; //title 69 var $subject; //subject 70 var $author; //author 71 var $keywords; //keywords 72 var $creator; //creator 73 var $AliasNbPages; //alias for total number of pages 74 75 /** 76 * Public methods * 77 */ 78 function FPDF( $orientation = 'P', $unit = 'mm', $format = 'A4' ) 79 { 80 // Some checks 81 $this->_dochecks(); 82 // Initialization of properties 83 $this->page = 0; 84 $this->n = 2; 85 $this->buffer = ''; 86 $this->pages = array(); 87 $this->OrientationChanges = array(); 88 $this->state = 0; 89 $this->fonts = array(); 90 $this->FontFiles = array(); 91 $this->diffs = array(); 92 $this->images = array(); 93 $this->links = array(); 94 $this->InFooter = false; 95 $this->lasth = 0; 96 $this->FontFamily = ''; 97 $this->FontStyle = ''; 98 $this->FontSizePt = 12; 99 $this->underline = false; 100 $this->DrawColor = '0 G'; 101 $this->FillColor = '0 g'; 102 $this->TextColor = '0 g'; 103 $this->ColorFlag = false; 104 $this->ws = 0; 105 // Standard fonts 106 $this->CoreFonts = array( 'courier' => 'Courier', 'courierB' => 'Courier-Bold', 'courierI' => 'Courier-Oblique', 'courierBI' => 'Courier-BoldOblique', 107 'helvetica' => 'Helvetica', 'helveticaB' => 'Helvetica-Bold', 'helveticaI' => 'Helvetica-Oblique', 'helveticaBI' => 'Helvetica-BoldOblique', 108 'times' => 'Times-Roman', 'timesB' => 'Times-Bold', 'timesI' => 'Times-Italic', 'timesBI' => 'Times-BoldItalic', 109 'symbol' => 'Symbol', 'zapfdingbats' => 'ZapfDingbats' ); 110 // Scale factor 111 if ( $unit == 'pt' ) $this->k = 1; 112 elseif ( $unit == 'mm' ) $this->k = 72 / 25.4; 113 elseif ( $unit == 'cm' ) $this->k = 72 / 2.54; 114 elseif ( $unit == 'in' ) $this->k = 72; 115 else $this->Error( 'Incorrect unit: ' . $unit ); 116 // Page format 117 if ( is_string( $format ) ) { 118 // 2002-07-24 - Nicola Asuni (info@tecnick.com) 119 // Added new page formats (45 standard ISO paper formats and 4 american common formats). 120 // Paper cordinates are calculated in this way: (inches * 72) where (1 inch = 2.54 cm) 121 switch ( strtoupper( $format ) ) { 122 case '4A0': { 123 $format = array( 4767.87, 6740.79 ); 124 break; 125 } 126 case '2A0': { 127 $format = array( 3370.39, 4767.87 ); 128 break; 129 } 130 case 'A0': { 131 $format = array( 2383.94, 3370.39 ); 132 break; 133 } 134 case 'A1': { 135 $format = array( 1683.78, 2383.94 ); 136 break; 137 } 138 case 'A2': { 139 $format = array( 1190.55, 1683.78 ); 140 break; 141 } 142 case 'A3': { 143 $format = array( 841.89, 1190.55 ); 144 break; 145 } 146 case 'A4': default: { 147 $format = array( 595.28, 841.89 ); 148 break; 149 } 150 case 'A5': { 151 $format = array( 419.53, 595.28 ); 152 break; 153 } 154 case 'A6': { 155 $format = array( 297.64, 419.53 ); 156 break; 157 } 158 case 'A7': { 159 $format = array( 209.76, 297.64 ); 160 break; 161 } 162 case 'A8': { 163 $format = array( 147.40, 209.76 ); 164 break; 165 } 166 case 'A9': { 167 $format = array( 104.88, 147.40 ); 168 break; 169 } 170 case 'A10': { 171 $format = array( 73.70, 104.88 ); 172 break; 173 } 174 case 'B0': { 175 $format = array( 2834.65, 4008.19 ); 176 break; 177 } 178 case 'B1': { 179 $format = array( 2004.09, 2834.65 ); 180 break; 181 } 182 case 'B2': { 183 $format = array( 1417.32, 2004.09 ); 184 break; 185 } 186 case 'B3': { 187 $format = array( 1000.63, 1417.32 ); 188 break; 189 } 190 case 'B4': { 191 $format = array( 708.66, 1000.63 ); 192 break; 193 } 194 case 'B5': { 195 $format = array( 498.90, 708.66 ); 196 break; 197 } 198 case 'B6': { 199 $format = array( 354.33, 498.90 ); 200 break; 201 } 202 case 'B7': { 203 $format = array( 249.45, 354.33 ); 204 break; 205 } 206 case 'B8': { 207 $format = array( 175.75, 249.45 ); 208 break; 209 } 210 case 'B9': { 211 $format = array( 124.72, 175.75 ); 212 break; 213 } 214 case 'B10': { 215 $format = array( 87.87, 124.72 ); 216 break; 217 } 218 case 'C0': { 219 $format = array( 2599.37, 3676.54 ); 220 break; 221 } 222 case 'C1': { 223 $format = array( 1836.85, 2599.37 ); 224 break; 225 } 226 case 'C2': { 227 $format = array( 1298.27, 1836.85 ); 228 break; 229 } 230 case 'C3': { 231 $format = array( 918.43, 1298.27 ); 232 break; 233 } 234 case 'C4': { 235 $format = array( 649.13, 918.43 ); 236 break; 237 } 238 case 'C5': { 239 $format = array( 459.21, 649.13 ); 240 break; 241 } 242 case 'C6': { 243 $format = array( 323.15, 459.21 ); 244 break; 245 } 246 case 'C7': { 247 $format = array( 229.61, 323.15 ); 248 break; 249 } 250 case 'C8': { 251 $format = array( 161.57, 229.61 ); 252 break; 253 } 254 case 'C9': { 255 $format = array( 113.39, 161.57 ); 256 break; 257 } 258 case 'C10': { 259 $format = array( 79.37, 113.39 ); 260 break; 261 } 262 case 'RA0': { 263 $format = array( 2437.80, 3458.27 ); 264 break; 265 } 266 case 'RA1': { 267 $format = array( 1729.13, 2437.80 ); 268 break; 269 } 270 case 'RA2': { 271 $format = array( 1218.90, 1729.13 ); 272 break; 273 } 274 case 'RA3': { 275 $format = array( 864.57, 1218.90 ); 276 break; 277 } 278 case 'RA4': { 279 $format = array( 609.45, 864.57 ); 280 break; 281 } 282 case 'SRA0': { 283 $format = array( 2551.18, 3628.35 ); 284 break; 285 } 286 case 'SRA1': { 287 $format = array( 1814.17, 2551.18 ); 288 break; 289 } 290 case 'SRA2': { 291 $format = array( 1275.59, 1814.17 ); 292 break; 293 } 294 case 'SRA3': { 295 $format = array( 907.09, 1275.59 ); 296 break; 297 } 298 case 'SRA4': { 299 $format = array( 637.80, 907.09 ); 300 break; 301 } 302 case 'LETTER': { 303 $format = array( 612.00, 792.00 ); 304 break; 305 } 306 case 'LEGAL': { 307 $format = array( 612.00, 1008.00 ); 308 break; 309 } 310 case 'EXECUTIVE': { 311 $format = array( 521.86, 756.00 ); 312 break; 313 } 314 case 'FOLIO': { 315 $format = array( 612.00, 936.00 ); 316 break; 317 } 318 // default: {$this->Error('Unknown page format: '.$format); break;} 319 // END CHANGES Nicola Asuni 320 } 321 /* 322 $format = strtolower( $format ); 323 if ( $format == 'a3' ) $format = array( 841.89, 1190.55 ); 324 elseif ( $format == 'a4' ) $format = array( 595.28, 841.89 ); 325 elseif ( $format == 'a5' ) $format = array( 420.94, 595.28 ); 326 elseif ( $format == 'letter' ) $format = array( 612, 792 ); 327 elseif ( $format == 'legal' ) $format = array( 612, 1008 ); 328 else $this->Error( 'Unknown page format: ' . $format ); 329 */ 330 $this->fwPt = $format[0]; 331 $this->fhPt = $format[1]; 332 } else { 333 $this->fwPt = $format[0] * $this->k; 334 $this->fhPt = $format[1] * $this->k; 335 } 336 $this->fw = $this->fwPt / $this->k; 337 $this->fh = $this->fhPt / $this->k; 338 // Page orientation 339 $orientation = strtolower( $orientation ); 340 if ( $orientation == 'p' || $orientation == 'portrait' ) { 341 $this->DefOrientation = 'P'; 342 $this->wPt = $this->fwPt; 343 $this->hPt = $this->fhPt; 344 } elseif ( $orientation == 'l' || $orientation == 'landscape' ) { 345 $this->DefOrientation = 'L'; 346 $this->wPt = $this->fhPt; 347 $this->hPt = $this->fwPt; 348 } else $this->Error( 'Incorrect orientation: ' . $orientation ); 349 $this->CurOrientation = $this->DefOrientation; 350 $this->w = $this->wPt / $this->k; 351 $this->h = $this->hPt / $this->k; 352 // Page margins (1 cm) 353 $margin = 28.35 / $this->k; 354 $this->SetMargins( $margin, $margin ); 355 // Interior cell margin (1 mm) 356 $this->cMargin = $margin / 10; 357 // Line width (0.2 mm) 358 $this->LineWidth = .567 / $this->k; 359 // Automatic page break 360 $this->SetAutoPageBreak( true, 2 * $margin ); 361 // Full width display mode 362 $this->SetDisplayMode( 'fullwidth' ); 363 // Compression 364 $this->SetCompression( true ); 365 } 366 367 function SetMargins( $left, $top, $right = -1 ) 368 { 369 // Set left, top and right margins 370 $this->lMargin = $left; 371 $this->tMargin = $top; 372 if ( $right == -1 ) $right = $left; 373 $this->rMargin = $right; 374 } 375 376 function SetLeftMargin( $margin ) 377 { 378 // Set left margin 379 $this->lMargin = $margin; 380 if ( $this->page > 0 and $this->x < $margin ) $this->x = $margin; 381 } 382 383 function SetTopMargin( $margin ) 384 { 385 // Set top margin 386 $this->tMargin = $margin; 387 } 388 389 function SetRightMargin( $margin ) 390 { 391 // Set right margin 392 $this->rMargin = $margin; 393 } 394 395 function SetAutoPageBreak( $auto, $margin = 0 ) 396 { 397 // Set auto page break mode and triggering margin 398 $this->AutoPageBreak = $auto; 399 $this->bMargin = $margin; 400 $this->PageBreakTrigger = $this->h - $margin; 401 } 402 403 function SetDisplayMode( $zoom, $layout = 'continuous' ) 404 { 405 // Set display mode in viewer 406 if ( $zoom == 'fullpage' || $zoom == 'fullwidth' || $zoom == 'real' || $zoom == 'default' || !is_string( $zoom ) ) 407 $this->ZoomMode = $zoom; 408 else 409 $this->Error( 'Incorrect zoom display mode: ' . $zoom ); 410 if ( $layout == 'single' || $layout == 'continuous' || $layout == 'two' || $layout == 'default' ) 411 $this->LayoutMode = $layout; 412 else 413 $this->Error( 'Incorrect layout display mode: ' . $layout ); 414 } 415 416 function SetCompression( $compress ) 417 { 418 // Set page compression 419 if ( function_exists( 'gzcompress' ) ) $this->compress = $compress; 420 else $this->compress = false; 421 } 422 423 function SetTitle( $title ) 424 { 425 // Title of document 426 $this->title = $title; 427 } 428 429 function SetSubject( $subject ) 430 { 431 // Subject of document 432 $this->subject = $subject; 433 } 434 435 function SetAuthor( $author ) 436 { 437 // Author of document 438 $this->author = $author; 439 } 440 441 function SetKeywords( $keywords ) 442 { 443 // Keywords of document 444 $this->keywords = $keywords; 445 } 446 447 function SetCreator( $creator ) 448 { 449 // Creator of document 450 $this->creator = $creator; 451 } 452 453 function AliasNbPages( $alias = '{nb}' ) 454 { 455 // Define an alias for total number of pages 456 $this->AliasNbPages = $alias; 457 } 458 459 function Error( $msg ) 460 { 461 // Fatal error 462 die( '<B>FPDF error: </B>' . $msg ); 463 } 464 465 function Open() 466 { 467 // Begin document 468 if ( $this->state == 0 ) $this->_begindoc(); 469 } 470 471 function Close() 472 { 473 // Terminate document 474 if ( $this->state == 3 ) return; 475 if ( $this->page == 0 ) $this->AddPage(); 476 // Page footer 477 $this->InFooter = true; 478 $this->Footer(); 479 $this->InFooter = false; 480 // Close page 481 $this->_endpage(); 482 // Close document 483 $this->_enddoc(); 484 } 485 486 function AddPage( $orientation = '' ) 487 { 488 // Start a new page 489 if ( $this->state == 0 ) $this->Open(); 490 $family = $this->FontFamily; 491 $style = $this->FontStyle . ( $this->underline ? 'U' : '' ); 492 $size = $this->FontSizePt; 493 $lw = $this->LineWidth; 494 $dc = $this->DrawColor; 495 $fc = $this->FillColor; 496 $tc = $this->TextColor; 497 $cf = $this->ColorFlag; 498 if ( $this->page > 0 ) { 499 // Page footer 500 $this->InFooter = true; 501 $this->Footer(); 502 $this->InFooter = false; 503 // Close page 504 $this->_endpage(); 505 } 506 // Start new page 507 $this->_beginpage( $orientation ); 508 // Set line cap style to square 509 $this->_out( '2 J' ); 510 // Set line width 511 $this->LineWidth = $lw; 512 $this->_out( sprintf( '%.2f w', $lw * $this->k ) ); 513 // Set font 514 if ( $family ) $this->SetFont( $family, $style, $size ); 515 // Set colors 516 $this->DrawColor = $dc; 517 if ( $dc != '0 G' ) $this->_out( $dc ); 518 $this->FillColor = $fc; 519 if ( $fc != '0 g' ) $this->_out( $fc ); 520 $this->TextColor = $tc; 521 $this->ColorFlag = $cf; 522 // Page header 523 $this->Header(); 524 // Restore line width 525 if ( $this->LineWidth != $lw ) { 526 $this->LineWidth = $lw; 527 $this->_out( sprintf( '%.2f w', $lw * $this->k ) ); 528 } 529 // Restore font 530 if ( $family ) $this->SetFont( $family, $style, $size ); 531 // Restore colors 532 if ( $this->DrawColor != $dc ) { 533 $this->DrawColor = $dc; 534 $this->_out( $dc ); 535 } 536 if ( $this->FillColor != $fc ) { 537 $this->FillColor = $fc; 538 $this->_out( $fc ); 539 } 540 $this->TextColor = $tc; 541 $this->ColorFlag = $cf; 542 } 543 544 function Header() 545 { 546 // To be implemented in your own inherited class 547 } 548 549 function Footer() 550 { 551 // To be implemented in your own inherited class 552 } 553 554 function PageNo() 555 { 556 // Get current page number 557 return $this->page; 558 } 559 560 function SetDrawColor( $r, $g = -1, $b = -1 ) 561 { 562 // Set color for all stroking operations 563 if ( ( $r == 0 and $g == 0 and $b == 0 ) || $g == -1 ) $this->DrawColor = sprintf( '%.3f G', $r / 255 ); 564 else $this->DrawColor = sprintf( '%.3f %.3f %.3f RG', $r / 255, $g / 255, $b / 255 ); 565 if ( $this->page > 0 ) $this->_out( $this->DrawColor ); 566 } 567 568 function SetFillColor( $r, $g = -1, $b = -1 ) 569 { 570 // Set color for all filling operations 571 if ( ( $r == 0 and $g == 0 and $b == 0 ) || $g == -1 ) $this->FillColor = sprintf( '%.3f g', $r / 255 ); 572 else$this->FillColor = sprintf( '%.3f %.3f %.3f rg', $r / 255, $g / 255, $b / 255 ); 573 $this->ColorFlag = ( $this->FillColor != $this->TextColor ); 574 if ( $this->page > 0 ) $this->_out( $this->FillColor ); 575 } 576 577 function SetTextColor( $r, $g = -1, $b = -1 ) 578 { 579 // Set color for text 580 if ( ( $r == 0 and $g == 0 and $b == 0 ) || $g == -1 ) $this->TextColor = sprintf( '%.3f g', $r / 255 ); 581 else $this->TextColor = sprintf( '%.3f %.3f %.3f rg', $r / 255, $g / 255, $b / 255 ); 582 $this->ColorFlag = ( $this->FillColor != $this->TextColor ); 583 } 584 585 function GetStringWidth( $s ) 586 { 587 // Get width of a string in the current font 588 $s = ( string )$s; 589 $cw = &$this->CurrentFont['cw']; 590 $w = 0; 591 $l = strlen( $s ); 592 for( $i = 0;$i < $l;$i++ ) $w += $cw[$s{$i}]; 593 return $w * $this->FontSize / 1000; 594 } 595 596 function SetLineWidth( $width ) 597 { 598 // Set line width 599 $this->LineWidth = $width; 600 if ( $this->page > 0 ) $this->_out( sprintf( '%.2f w', $width * $this->k ) ); 601 } 602 603 function Line( $x1, $y1, $x2, $y2 ) 604 { 605 // Draw a line 606 $this->_out( sprintf( '%.2f %.2f m %.2f %.2f l S', $x1 * $this->k, ( $this->h - $y1 ) * $this->k, $x2 * $this->k, ( $this->h - $y2 ) * $this->k ) ); 607 } 608 609 function Rect( $x, $y, $w, $h, $style = '' ) 610 { 611 // Draw a rectangle 612 if ( $style == 'F' ) $op = 'f'; 613 elseif ( $style == 'FD' || $style == 'DF' ) $op = 'B'; 614 else $op = 'S'; 615 $this->_out( sprintf( '%.2f %.2f %.2f %.2f re %s', $x * $this->k, ( $this->h - $y ) * $this->k, $w * $this->k, - $h * $this->k, $op ) ); 616 } 617 618 function AddFont( $family, $style = '', $file = '' ) 619 { 620 // Add a TrueType || Type1 font 621 $family = strtolower( $family ); 622 if ( $family == 'arial' ) $family = 'helvetica'; 623 $style = strtoupper( $style ); 624 if ( $style == 'IB' ) $style = 'BI'; 625 if ( isset( $this->fonts[$family . $style] ) ) $this->Error( 'Font already added: ' . $family . ' ' . $style ); 626 if ( $file == '' ) $file = str_replace( ' ', '', $family ) . strtolower( $style ) . '.php'; 627 if ( defined( 'FPDF_FONTPATH' ) ) $file = FPDF_FONTPATH . $file; 628 include( $file ); 629 if ( !isset( $name ) ) $this->Error( 'Could not include font definition file' ); 630 $i = count( $this->fonts ) + 1; 631 $this->fonts[$family . $style] = array( 'i' => $i, 'type' => $type, 'name' => $name, 'desc' => $desc, 'up' => $up, 'ut' => $ut, 'cw' => $cw, 'enc' => $enc, 'file' => $file ); 632 if ( $diff ) { 633 // Search existing encodings 634 $d = 0; 635 $nb = count( $this->diffs ); 636 for( $i = 1;$i <= $nb;$i++ ) 637 if ( $this->diffs[$i] == $diff ) { 638 $d = $i; 639 break; 640 } 641 if ( $d == 0 ) { 642 $d = $nb + 1; 643 $this->diffs[$d] = $diff; 644 } 645 $this->fonts[$family . $style]['diff'] = $d; 646 } 647 if ( $file ) { 648 if ( $type == 'TrueType' ) $this->FontFiles[$file] = array( 'length1' => $originalsize ); 649 else $this->FontFiles[$file] = array( 'length1' => $size1, 'length2' => $size2 ); 650 } 651 } 652 653 function SetFont( $family, $style = '', $size = 0 ) 654 { 655 // Select a font; size given in points 656 global $fpdf_charwidths; 657 658 $family = strtolower( $family ); 659 if ( $family == '' ) $family = $this->FontFamily; 660 // EDITEI - now understands: monospace,serif,sans [serif] 661 if ( $family == 'monospace' ) $family = 'courier'; 662 if ( $family == 'serif' ) $family = 'times'; 663 if ( $family == 'sans' ) $family = 'arial'; 664 if ( $family == 'arial' ) $family = 'helvetica'; 665 elseif ( $family == 'symbol' || $family == 'zapfdingbats' ) $style = ''; 666 $style = strtoupper( $style ); 667 if ( is_int( strpos( $style, 'U' ) ) ) { 668 $this->underline = true; 669 $style = str_replace( 'U', '', $style ); 670 } else $this->underline = false; 671 if ( $style == 'IB' ) $style = 'BI'; 672 if ( $size == 0 ) $size = $this->FontSizePt; 673 // Test if font is already selected 674 if ( $this->FontFamily == $family and $this->FontStyle == $style and $this->FontSizePt == $size ) return; 675 // Test if used for the first time 676 $fontkey = $family . $style; 677 if ( !isset( $this->fonts[$fontkey] ) ) { 678 // Check if one of the standard fonts 679 if ( isset( $this->CoreFonts[$fontkey] ) ) { 680 if ( !isset( $fpdf_charwidths[$fontkey] ) ) { 681 // Load metric file 682 $file = $family; 683 if ( $family == 'times' || $family == 'helvetica' ) $file .= strtolower( $style ); 684 $file .= '.php'; 685 if ( defined( 'FPDF_FONTPATH' ) ) $file = FPDF_FONTPATH . $file; 686 include( $file ); 687 if ( !isset( $fpdf_charwidths[$fontkey] ) ) $this->Error( 'Could not include font metric file' ); 688 } 689 $i = count( $this->fonts ) + 1; 690 $this->fonts[$fontkey] = array( 'i' => $i, 'type' => 'core', 'name' => $this->CoreFonts[$fontkey], 'up' => -100, 'ut' => 50, 'cw' => $fpdf_charwidths[$fontkey] ); 691 } else $this->Error( 'Undefined font: ' . $family . ' ' . $style ); 692 } 693 // Select it 694 $this->FontFamily = $family; 695 $this->FontStyle = $style; 696 $this->FontSizePt = $size; 697 $this->FontSize = $size / $this->k; 698 $this->CurrentFont = &$this->fonts[$fontkey]; 699 if ( $this->page > 0 ) 700 $this->_out( sprintf( 'BT /F%d %.2f Tf ET', $this->CurrentFont['i'], $this->FontSizePt ) ); 701 } 702 703 function SetFontSize( $size ) 704 { 705 // Set font size in points 706 if ( $this->FontSizePt == $size ) return; 707 $this->FontSizePt = $size; 708 $this->FontSize = $size / $this->k; 709 if ( $this->page > 0 ) 710 $this->_out( sprintf( 'BT /F%d %.2f Tf ET', $this->CurrentFont['i'], $this->FontSizePt ) ); 711 } 712 713 function AddLink() 714 { 715 // Create a new internal link 716 $n = count( $this->links ) + 1; 717 $this->links[$n] = array( 0, 0 ); 718 return $n; 719 } 720 721 function SetLink( $link, $y = 0, $page = -1 ) 722 { 723 // Set destination of internal link 724 if ( $y == -1 ) $y = $this->y; 725 if ( $page == -1 ) $page = $this->page; 726 $this->links[$link] = array( $page, $y ); 727 } 728 729 function Link( $x, $y, $w, $h, $link ) 730 { 731 // Put a link on the page 732 $this->PageLinks[$this->page][] = array( $x * $this->k, $this->hPt - $y * $this->k, $w * $this->k, $h * $this->k, $link ); 733 } 734 735 function Text( $x, $y, $txt ) 736 { 737 // Output a string 738 $s = sprintf( 'BT %.2f %.2f Td (%s) Tj ET', $x * $this->k, ( $this->h - $y ) * $this->k, $this->_escape( $txt ) ); 739 if ( $this->underline and $txt != '' ) $s .= ' ' . $this->_dounderline( $x, $y, $txt ); 740 if ( $this->ColorFlag ) $s = 'q ' . $this->TextColor . ' ' . $s . ' Q'; 741 $this->_out( $s ); 742 } 743 744 function AcceptPageBreak() 745 { 746 // Accept automatic page break or not 747 return $this->AutoPageBreak; 748 } 749 750 function Cell( $w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = 0, $link = '', $currentx = 0 ) // EDITEI 751 { 752 // Output a cell 753 $k = $this->k; 754 if ( $this->y + $h > $this->PageBreakTrigger && !$this->InFooter && $this->AcceptPageBreak() ) { 755 // Automatic page break 756 $x = $this->x; //Current X position 757 $ws = $this->ws; //Word Spacing 758 if ( $ws > 0 ) { 759 $this->ws = 0; 760 $this->_out( '0 Tw' ); 761 } 762 $this->AddPage( $this->CurOrientation ); 763 $this->x = $x; 764 if ( $ws > 0 ) { 765 $this->ws = $ws; 766 $this->_out( sprintf( '%.3f Tw', $ws * $k ) ); 767 } 768 } 769 if ( $w == 0 ) $w = $this->w - $this->rMargin - $this->x; 770 $s = ''; 771 if ( $fill == 1 || $border == 1 ) { 772 if ( $fill == 1 ) $op = ( $border == 1 ) ? 'B' : 'f'; 773 else $op = 'S'; 774 // $op='S';//DEBUG 775 $s = sprintf( '%.2f %.2f %.2f %.2f re %s ', $this->x * $k, ( $this->h - $this->y ) * $k, $w * $k, - $h * $k, $op ); 776 } 777 if ( is_string( $border ) ) { 778 $x = $this->x; 779 $y = $this->y; 780 if ( is_int( strpos( $border, 'L' ) ) ) 781 $s .= sprintf( '%.2f %.2f m %.2f %.2f l S ', $x * $k, ( $this->h - $y ) * $k, $x * $k, ( $this->h - ( $y + $h ) ) * $k ); 782 if ( is_int( strpos( $border, 'T' ) ) ) 783 $s .= sprintf( '%.2f %.2f m %.2f %.2f l S ', $x * $k, ( $this->h - $y ) * $k, ( $x + $w ) * $k, ( $this->h - $y ) * $k ); 784 if ( is_int( strpos( $border, 'R' ) ) ) 785 $s .= sprintf( '%.2f %.2f m %.2f %.2f l S ', ( $x + $w ) * $k, ( $this->h - $y ) * $k, ( $x + $w ) * $k, ( $this->h - ( $y + $h ) ) * $k ); 786 if ( is_int( strpos( $border, 'B' ) ) ) 787 $s .= sprintf( '%.2f %.2f m %.2f %.2f l S ', $x * $k, ( $this->h - ( $y + $h ) ) * $k, ( $x + $w ) * $k, ( $this->h - ( $y + $h ) ) * $k ); 788 } 789 if ( $txt != '' ) { 790 if ( $align == 'R' ) $dx = $w - $this->cMargin - $this->GetStringWidth( $txt ); 791 elseif ( $align == 'C' ) $dx = ( $w - $this->GetStringWidth( $txt ) ) / 2; 792 elseif ( $align == 'L' || $align == 'J' ) $dx = $this->cMargin; 793 else $dx = 0; 794 if ( $this->ColorFlag ) $s .= 'q ' . $this->TextColor . ' '; 795 $txt2 = str_replace( ')', '\\)', str_replace( '(', '\\(', str_replace( '\\', '\\\\', $txt ) ) ); 796 // Check whether we are going to outline text or not 797 if ( $this->outline_on ) { 798 $s .= ' ' . sprintf( '%.2f w', $this->LineWidth * $this->k ) . ' '; 799 $s .= " $this->DrawColor "; 800 $s .= " 2 Tr "; 801 } 802 // Superscript and Subscript Y coordinate adjustment 803 $adjusty = 0; 804 if ( $this->SUB ) $adjusty = 1; 805 if ( $this->SUP ) $adjusty = -1; 806 // End of coordinate adjustment 807 $s .= sprintf( 'BT %.2f %.2f Td (%s) Tj ET', ( $this->x + $dx ) * $k, ( $this->h - ( ( $this->y + $adjusty ) + .5 * $h + .3 * $this->FontSize ) ) * $k, $txt2 ); //EDITEI 808 if ( $this->underline ) 809 $s .= ' ' . $this->_dounderline( $this->x + $dx, $this->y + .5 * $h + .3 * $this->FontSize + $adjusty, $txt2 ); 810 // Superscript and Subscript Y coordinate adjustment (now for striked-through texts) 811 $adjusty = 1.6; 812 if ( $this->SUB ) $adjusty = 3.05; 813 if ( $this->SUP ) $adjusty = 1.1; 814 // End of coordinate adjustment 815 if ( $this->strike ) // EDITEI 816 $s .= ' ' . $this->_dounderline( $this->x + $dx, $this->y + $adjusty, $txt ); 817 if ( $this->ColorFlag ) $s .= ' Q'; 818 if ( $link != '' ) $this->Link( $this->x + $dx, $this->y + .5 * $h - .5 * $this->FontSize, $this->GetStringWidth( $txt ), $this->FontSize, $link ); 819 } 820 if ( $s ) $this->_out( $s ); 821 $this->lasth = $h; 822 if ( strpos( $txt, "\n" ) !== false ) $ln = 1; //EDITEI - cell now recognizes \n! << comes from <BR> tag 823 if ( $ln > 0 ) { 824 // Go to next line 825 $this->y += $h; 826 if ( $ln == 1 ) { // EDITEI 827 // Move to next line 828 if ( $currentx != 0 ) $this->x = $currentx; 829 else $this->x = $this->lMargin; 830 } 831 } else { 832 $this->x += $w; 833 } 834 } 835 // EDITEI 836 function MultiCell( $w, $h, $txt, $border = 0, $align = 'J', $fill = 0, $link = '' ) 837 { 838 // Output text with automatic or explicit line breaks 839 $cw = &$this->CurrentFont['cw']; 840 if ( $w == 0 ) $w = $this->w - $this->rMargin - $this->x; 841 $wmax = ( $w-2 * $this->cMargin ) * 1000 / $this->FontSize; 842 $s = str_replace( "\r", '', $txt ); 843 $nb = strlen( $s ); 844 if ( $nb > 0 && $s[$nb-1] == "\n" ) $nb--; 845 $b = 0; 846 if ( $border ) { 847 if ( $border == 1 ) { 848 $border = 'LTRB'; 849 $b = 'LRT'; 850 $b2 = 'LR'; 851 } else { 852 $b2 = ''; 853 if ( is_int( strpos( $border, 'L' ) ) ) $b2 .= 'L'; 854 if ( is_int( strpos( $border, 'R' ) ) ) $b2 .= 'R'; 855 $b = is_int( strpos( $border, 'T' ) ) ? $b2 . 'T' : $b2; 856 } 857 } 858 $sep = -1; 859 $i = 0; 860 $j = 0; 861 $l = 0; 862 $ns = 0; 863 $nl = 1; 864 while ( $i < $nb ) { 865 // Get next character 866 $c = $s{$i}; 867 if ( $c == "\n" ) { 868 // Explicit line break 869 if ( $this->ws > 0 ) { 870 $this->ws = 0; 871 $this->_out( '0 Tw' ); 872 } 873 $this->Cell( $w, $h, substr( $s, $j, $i - $j ), $b, 2, $align, $fill, $link ); 874 $i++; 875 $sep = -1; 876 $j = $i; 877 $l = 0; 878 $ns = 0; 879 $nl++; 880 if ( $border && $nl == 2 ) $b = $b2; 881 continue; 882 } 883 if ( $c == ' ' ) { 884 $sep = $i; 885 $ls = $l; 886 $ns++; 887 } 888 $l += $cw[$c]; 889 if ( $l > $wmax ) { 890 // Automatic line break 891 if ( $sep == -1 ) { 892 if ( $i == $j ) $i++; 893 if ( $this->ws > 0 ) { 894 $this->ws = 0; 895 $this->_out( '0 Tw' ); 896 } 897 $this->Cell( $w, $h, substr( $s, $j, $i - $j ), $b, 2, $align, $fill, $link ); 898 } else { 899 if ( $align == 'J' ) { 900 $this->ws = ( $ns > 1 ) ? ( $wmax - $ls ) / 1000 * $this->FontSize / ( $ns-1 ) : 0; 901 $this->_out( sprintf( '%.3f Tw', $this->ws * $this->k ) ); 902 } 903 $this->Cell( $w, $h, substr( $s, $j, $sep - $j ), $b, 2, $align, $fill, $link ); 904 $i = $sep + 1; 905 } 906 $sep = -1; 907 $j = $i; 908 $l = 0; 909 $ns = 0; 910 $nl++; 911 if ( $border && $nl == 2 ) $b = $b2; 912 } else $i++; 913 } 914 // Last chunk 915 if ( $this->ws > 0 ) { 916 $this->ws = 0; 917 $this->_out( '0 Tw' ); 918 } 919 if ( $border && is_int( strpos( $border, 'B' ) ) ) $b .= 'B'; 920 $this->Cell( $w, $h, substr( $s, $j, $i - $j ), $b, 2, $align, $fill, $link ); 921 $this->x = $this->lMargin; 922 } 923 924 function Write( $h, $txt, $currentx = 0, $link = '' ) // EDITEI 925 { 926 // Output text in flowing mode 927 $cw = &$this->CurrentFont['cw']; 928 $w = $this->w - $this->rMargin - $this->x; 929 $wmax = ( $w-2 * $this->cMargin ) * 1000 / $this->FontSize; 930 $s = str_replace( "\r", '', $txt ); 931 $nb = strlen( $s ); 932 $sep = -1; 933 $i = 0; 934 $j = 0; 935 $l = 0; 936 $nl = 1; 937 while ( $i < $nb ) { 938 // Get next character 939 $c = $s{$i}; 940 if ( $c == "\n" ) { 941 // Explicit line break 942 $this->Cell( $w, $h, substr( $s, $j, $i - $j ), 0, 2, '', 0, $link ); 943 $i++; 944 $sep = -1; 945 $j = $i; 946 $l = 0; 947 if ( $nl == 1 ) { 948 if ( $currentx != 0 ) $this->x = $currentx; //EDITEI 949 else $this->x = $this->lMargin; 950 $w = $this->w - $this->rMargin - $this->x; 951 $wmax = ( $w-2 * $this->cMargin ) * 1000 / $this->FontSize; 952 } 953 $nl++; 954 continue; 955 } 956 if ( $c == ' ' ) $sep = $i; 957 $l += $cw[$c]; 958 if ( $l > $wmax ) { 959 // Automatic line break 960 if ( $sep == -1 ) { 961 if ( $this->x > $this->lMargin ) { 962 // Move to next line 963 if ( $currentx != 0 ) $this->x = $currentx; //EDITEI 964 else $this->x = $this->lMargin; 965 $this->y += $h; 966 $w = $this->w - $this->rMargin - $this->x; 967 $wmax = ( $w-2 * $this->cMargin ) * 1000 / $this->FontSize; 968 $i++; 969 $nl++; 970 continue; 971 } 972 if ( $i == $j ) $i++; 973 $this->Cell( $w, $h, substr( $s, $j, $i - $j ), 0, 2, '', 0, $link ); 974 } else { 975 $this->Cell( $w, $h, substr( $s, $j, $sep - $j ), 0, 2, '', 0, $link ); 976 $i = $sep + 1; 977 } 978 $sep = -1; 979 $j = $i; 980 $l = 0; 981 if ( $nl == 1 ) { 982 if ( $currentx != 0 ) $this->x = $currentx; //EDITEI 983 else $this->x = $this->lMargin; 984 $w = $this->w - $this->rMargin - $this->x; 985 $wmax = ( $w-2 * $this->cMargin ) * 1000 / $this->FontSize; 986 } 987 $nl++; 988 } else $i++; 989 } 990 // Last chunk 991 if ( $i != $j ) $this->Cell( $l / 1000 * $this->FontSize, $h, substr( $s, $j ), 0, 0, '', 0, $link ); 992 } 993 // -------------------------FLOWING BLOCK------------------------------------// 994 // EDITEI some things (added/changed) // 995 // The following functions were originally written by Damon Kohler // 996 // --------------------------------------------------------------------------// 997 function saveFont() 998 { 999 $saved = array(); 1000 $saved[ 'family' ] = $this->FontFamily; 1001 $saved[ 'style' ] = $this->FontStyle; 1002 $saved[ 'sizePt' ] = $this->FontSizePt; 1003 $saved[ 'size' ] = $this->FontSize; 1004 $saved[ 'curr' ] = &$this->CurrentFont; 1005 $saved[ 'color' ] = $this->TextColor; //EDITEI 1006 $saved[ 'bgcolor' ] = $this->FillColor; //EDITEI 1007 $saved[ 'HREF' ] = $this->HREF; //EDITEI 1008 $saved[ 'underline' ] = $this->underline; //EDITEI 1009 $saved[ 'strike' ] = $this->strike; //EDITEI 1010 $saved[ 'SUP' ] = $this->SUP; //EDITEI 1011 $saved[ 'SUB' ] = $this->SUB; //EDITEI 1012 $saved[ 'linewidth' ] = $this->LineWidth; //EDITEI 1013 $saved[ 'drawcolor' ] = $this->DrawColor; //EDITEI 1014 $saved[ 'is_outline' ] = $this->outline_on; //EDITEI 1015 1016 return $saved; 1017 } 1018 1019 function restoreFont( $saved ) 1020 { 1021 $this->FontFamily = $saved[ 'family' ]; 1022 $this->FontStyle = $saved[ 'style' ]; 1023 $this->FontSizePt = $saved[ 'sizePt' ]; 1024 $this->FontSize = $saved[ 'size' ]; 1025 $this->CurrentFont = &$saved[ 'curr' ]; 1026 $this->TextColor = $saved[ 'color' ]; //EDITEI 1027 $this->FillColor = $saved[ 'bgcolor' ]; //EDITEI 1028 $this->ColorFlag = ( $this->FillColor != $this->TextColor ); //Restore ColorFlag as well 1029 $this->HREF = $saved[ 'HREF' ]; //EDITEI 1030 $this->underline = $saved[ 'underline' ]; //EDITEI 1031 $this->strike = $saved[ 'strike' ]; //EDITEI 1032 $this->SUP = $saved[ 'SUP' ]; //EDITEI 1033 $this->SUB = $saved[ 'SUB' ]; //EDITEI 1034 $this->LineWidth = $saved[ 'linewidth' ]; //EDITEI 1035 $this->DrawColor = $saved[ 'drawcolor' ]; //EDITEI 1036 $this->outline_on = $saved[ 'is_outline' ]; //EDITEI 1037 1038 if ( $this->page > 0 ) 1039 $this->_out( sprintf( 'BT /F%d %.2f Tf ET', $this->CurrentFont[ 'i' ], $this->FontSizePt ) ); 1040 } 1041 1042 function newFlowingBlock( $w, $h, $b = 0, $a = 'J', $f = 0 , $is_table = false ) 1043 { 1044 // cell width in points 1045 if ( $is_table ) $this->flowingBlockAttr[ 'width' ] = ( $w * $this->k ); 1046 else $this->flowingBlockAttr[ 'width' ] = ( $w * $this->k ) - ( 2 * $this->cMargin * $this->k ); 1047 // line height in user units 1048 $this->flowingBlockAttr[ 'is_table' ] = $is_table; 1049 $this->flowingBlockAttr[ 'height' ] = $h; 1050 $this->flowingBlockAttr[ 'lineCount' ] = 0; 1051 $this->flowingBlockAttr[ 'border' ] = $b; 1052 $this->flowingBlockAttr[ 'align' ] = $a; 1053 $this->flowingBlockAttr[ 'fill' ] = $f; 1054 $this->flowingBlockAttr[ 'font' ] = array(); 1055 $this->flowingBlockAttr[ 'content' ] = array(); 1056 $this->flowingBlockAttr[ 'contentWidth' ] = 0; 1057 } 1058 1059 function finishFlowingBlock( $outofblock = false ) 1060 { 1061 if ( !$outofblock ) { 1062 $currentx = $this->x; //EDITEI - in order to make the Cell method work better 1063 } elseif(!isset($currentx)) { 1064 $currentx = 0; // OG 2007-04-28 check if set 1065 } 1066 // prints out the last chunk 1067 $is_table = $this->flowingBlockAttr[ 'is_table' ]; 1068 $maxWidth = &$this->flowingBlockAttr[ 'width' ]; 1069 $lineHeight = &$this->flowingBlockAttr[ 'height' ]; 1070 $border = &$this->flowingBlockAttr[ 'border' ]; 1071 $align = &$this->flowingBlockAttr[ 'align' ]; 1072 $fill = &$this->flowingBlockAttr[ 'fill' ]; 1073 $content = &$this->flowingBlockAttr[ 'content' ]; 1074 $font = &$this->flowingBlockAttr[ 'font' ]; 1075 $contentWidth = &$this->flowingBlockAttr[ 'contentWidth' ]; 1076 $lineCount = &$this->flowingBlockAttr[ 'lineCount' ]; 1077 // set normal spacing 1078 $this->_out( sprintf( '%.3f Tw', 0 ) ); 1079 $this->ws = 0; 1080 // the amount of space taken up so far in user units 1081 $usedWidth = 0; 1082 // Print out each chunk 1083 // EDITEI - Print content according to alignment 1084 $empty = $maxWidth - $contentWidth; 1085 $empty /= $this->k; 1086 $b = ''; //do not use borders 1087 $arraysize = count( $content ); 1088 $margins = ( 2 * $this->cMargin ); 1089 if ( $outofblock ) { 1090 $align = 'C'; 1091 $empty = 0; 1092 $margins = $this->cMargin; 1093 } 1094 switch ( $align ) { 1095 case 'R': 1096 foreach ( $content as $k => $chunk ) { 1097 $this->restoreFont( $font[ $k ] ); 1098 $stringWidth = $this->GetStringWidth( $chunk ) + ( $this->ws * substr_count( $chunk, ' ' ) / $this->k ); 1099 // determine which borders should be used 1100 $b = ''; 1101 if ( $lineCount == 1 && is_int( strpos( $border, 'T' ) ) ) $b .= 'T'; 1102 if ( $k == count( $content ) - 1 && is_int( strpos( $border, 'R' ) ) ) $b .= 'R'; 1103 1104 if ( $k == $arraysize-1 && !$outofblock ) $skipln = 1; 1105 else $skipln = 0; 1106 1107 if ( $arraysize == 1 ) $this->Cell( $stringWidth + $margins + $empty, $lineHeight, $chunk, $b, $skipln, $align, $fill, $this->HREF , $currentx ); //mono-style line 1108 elseif ( $k == 0 ) $this->Cell( $stringWidth + ( $margins / 2 ) + $empty, $lineHeight, $chunk, $b, 0, 'R', $fill, $this->HREF ); //first part 1109 elseif ( $k == $arraysize-1 ) $this->Cell( $stringWidth + ( $margins / 2 ), $lineHeight, $chunk, $b, $skipln, '', $fill, $this->HREF, $currentx ); //last part 1110 else $this->Cell( $stringWidth , $lineHeight, $chunk, $b, 0, '', $fill, $this->HREF ); //middle part 1111 } 1112 break; 1113 case 'L': 1114 case 'J': 1115 foreach ( $content as $k => $chunk ) { 1116 $this->restoreFont( $font[ $k ] ); 1117 $stringWidth = $this->GetStringWidth( $chunk ) + ( $this->ws * substr_count( $chunk, ' ' ) / $this->k ); 1118 // determine which borders should be used 1119 $b = ''; 1120 if ( $lineCount == 1 && is_int( strpos( $border, 'T' ) ) ) $b .= 'T'; 1121 if ( $k == 0 && is_int( strpos( $border, 'L' ) ) ) $b .= 'L'; 1122 1123 if ( $k == $arraysize-1 && !$outofblock ) $skipln = 1; 1124 else $skipln = 0; 1125 1126 if ( !$is_table && !$outofblock && !$fill && $align == 'L' && $k == 0 ) { 1127 $align = ''; 1128 $margins = 0; 1129 } //Remove margins in this special (though often) case 1130 if ( $arraysize == 1 ) $this->Cell( $stringWidth + $margins + $empty, $lineHeight, $chunk, $b, $skipln, $align, $fill, $this->HREF , $currentx ); //mono-style line 1131 elseif ( $k == 0 ) $this->Cell( $stringWidth + ( $margins / 2 ), $lineHeight, $chunk, $b, $skipln, $align, $fill, $this->HREF ); //first part 1132 elseif ( $k == $arraysize-1 ) $this->Cell( $stringWidth + ( $margins / 2 ) + $empty, $lineHeight, $chunk, $b, $skipln, '', $fill, $this->HREF, $currentx ); //last part 1133 else $this->Cell( $stringWidth , $lineHeight, $chunk, $b, $skipln, '', $fill, $this->HREF ); //middle part 1134 } 1135 break; 1136 case 'C': 1137 foreach ( $content as $k => $chunk ) { 1138 $this->restoreFont( $font[ $k ] ); 1139 $stringWidth = $this->GetStringWidth( $chunk ) + ( $this->ws * substr_count( $chunk, ' ' ) / $this->k ); 1140 // determine which borders should be used 1141 $b = ''; 1142 if ( $lineCount == 1 && is_int( strpos( $border, 'T' ) ) ) { 1143 $b .= 'T'; 1144 } 1145 1146 if ( $k == $arraysize-1 && !$outofblock ) { 1147 $skipln = 1; 1148 } else { 1149 $skipln = 0; 1150 } 1151 1152 if ( $arraysize == 1 ) { 1153 $this->Cell( $stringWidth + $margins + $empty, $lineHeight, $chunk, $b, $skipln, $align, $fill, $this->HREF , $currentx ); //mono-style line 1154 } elseif ( $k == 0 ) { 1155 $this->Cell( $stringWidth + ( $margins / 2 ) + ( $empty / 2 ), $lineHeight, $chunk, $b, 0, 'R', $fill, $this->HREF ); //first part 1156 } elseif ( $k == $arraysize-1 ) { 1157 $this->Cell( $stringWidth + ( $margins / 2 ) + ( $empty / 2 ), $lineHeight, $chunk, $b, $skipln, 'L', $fill, $this->HREF, $currentx ); //last part 1158 } else { 1159 $this->Cell( $stringWidth , $lineHeight, $chunk, $b, 0, '', $fill, $this->HREF ); //middle part 1160 } 1161 } 1162 break; 1163 default: break; 1164 } 1165 } 1166 1167 function WriteFlowingBlock( $s , $outofblock = false ) 1168 { 1169 if ( !$outofblock ) { 1170 $currentx = $this->x; //EDITEI - in order to make the Cell method work better 1171 } elseif(!isset($currentx)) { 1172 $currentx = 0; // OG 2007-04-28 check if set 1173 } 1174 $is_table = $this->flowingBlockAttr[ 'is_table' ]; 1175 // width of all the content so far in points 1176 $contentWidth = &$this->flowingBlockAttr[ 'contentWidth' ]; 1177 // cell width in points 1178 $maxWidth = &$this->flowingBlockAttr[ 'width' ]; 1179 $lineCount = &$this->flowingBlockAttr[ 'lineCount' ]; 1180 // line height in user units 1181 $lineHeight = &$this->flowingBlockAttr[ 'height' ]; 1182 $border = &$this->flowingBlockAttr[ 'border' ]; 1183 $align = &$this->flowingBlockAttr[ 'align' ]; 1184 $fill = &$this->flowingBlockAttr[ 'fill' ]; 1185 $content = &$this->flowingBlockAttr[ 'content' ]; 1186 $font = &$this->flowingBlockAttr[ 'font' ]; 1187 1188 $font[] = $this->saveFont(); 1189 $content[] = ''; 1190 1191 $currContent = &$content[ count( $content ) - 1 ]; 1192 // where the line should be cutoff if it is to be justified 1193 $cutoffWidth = $contentWidth; 1194 // for every character in the string 1195 for ( $i = 0; $i < strlen( $s ); $i++ ) { 1196 // extract the current character 1197 $c = $s{$i}; 1198 // get the width of the character in points 1199 $cw = $this->CurrentFont[ 'cw' ][ $c ] * ( $this->FontSizePt / 1000 ); 1200 1201 if ( $c == ' ' ) { 1202 $currContent .= ' '; 1203 $cutoffWidth = $contentWidth; 1204 $contentWidth += $cw; 1205 continue; 1206 } 1207 // try adding another char 1208 if ( $contentWidth + $cw > $maxWidth ) { 1209 // it won't fit, output what we already have 1210 $lineCount++; 1211 // Readjust MaxSize in order to use the whole page width 1212 if ( $outofblock && ( $lineCount == 1 ) ) $maxWidth = $this->pgwidth * $this->k; 1213 // contains any content that didn't make it into this print 1214 $savedContent = ''; 1215 $savedFont = array(); 1216 // first, cut off && save any partial words at the end of the string 1217 $words = explode( ' ', $currContent ); 1218 // if it looks like we didn't finish any words for this chunk 1219 if ( count( $words ) == 1 ) { 1220 // save and crop off the content currently on the stack 1221 $savedContent = array_pop( $content ); 1222 $savedFont = array_pop( $font ); 1223 // trim any trailing spaces off the last bit of content 1224 $currContent = &$content[ count( $content ) - 1 ]; 1225 $currContent = rtrim( $currContent ); 1226 } else { // otherwise, we need to find which bit to cut off 1227 $lastContent = ''; 1228 for ( $w = 0; $w < count( $words ) - 1; $w++ ) $lastContent .= "{$words[ $w ]} "; 1229 1230 $savedContent = $words[ count( $words ) - 1 ]; 1231 $savedFont = $this->saveFont(); 1232 // replace the current content with the cropped version 1233 $currContent = rtrim( $lastContent ); 1234 } 1235 // update $contentWidth and $cutoffWidth since they changed with cropping 1236 $contentWidth = 0; 1237 foreach ( $content as $k => $chunk ) { 1238 $this->restoreFont( $font[ $k ] ); 1239 $contentWidth += $this->GetStringWidth( $chunk ) * $this->k; 1240 } 1241 $cutoffWidth = $contentWidth; 1242 // if it's justified, we need to find the char spacing 1243 if ( $align == 'J' ) { 1244 // count how many spaces there are in the entire content string 1245 $numSpaces = 0; 1246 foreach ( $content as $chunk ) $numSpaces += substr_count( $chunk, ' ' ); 1247 // if there's more than one space, find word spacing in points 1248 if ( $numSpaces > 0 ) $this->ws = ( $maxWidth - $cutoffWidth ) / $numSpaces; 1249 else $this->ws = 0; 1250 $this->_out( sprintf( '%.3f Tw', $this->ws ) ); 1251 } 1252 // otherwise, we want normal spacing 1253 else $this->_out( sprintf( '%.3f Tw', 0 ) ); 1254 // EDITEI - Print content according to alignment 1255 if ( !isset( $numSpaces ) ) $numSpaces = 0; 1256 $contentWidth -= ( $this->ws * $numSpaces ); 1257 $empty = $maxWidth - $contentWidth - 2 * ( $this->ws * $numSpaces ); 1258 $empty /= $this->k; 1259 $b = ''; //do not use borders 1260 /*'If' below used in order to fix "first-line of other page with justify on" bug*/ 1261 if ( $this->y + $this->divheight > $this->PageBreakTrigger && !$this->InFooter && $this->AcceptPageBreak() ) { 1262 $bak_x = $this->x; //Current X position 1263 $ws = $this->ws; //Word Spacing 1264 if ( $ws > 0 ) { 1265 $this->ws = 0; 1266 $this->_out( '0 Tw' ); 1267 } 1268 $this->AddPage( $this->CurOrientation ); 1269 $this->x = $bak_x; 1270 if ( $ws > 0 ) { 1271 $this->ws = $ws; 1272 $this->_out( sprintf( '%.3f Tw', $ws ) ); 1273 } 1274 } 1275 $arraysize = count( $content ); 1276 $margins = ( 2 * $this->cMargin ); 1277 if ( $outofblock ) { 1278 $align = 'C'; 1279 $empty = 0; 1280 $margins = $this->cMargin; 1281 } 1282 switch ( $align ) { 1283 case 'R': 1284 foreach ( $content as $k => $chunk ) { 1285 $this->restoreFont( $font[ $k ] ); 1286 $stringWidth = $this->GetStringWidth( $chunk ) + ( $this->ws * substr_count( $chunk, ' ' ) / $this->k ); 1287 // determine which borders should be used 1288 $b = ''; 1289 if ( $lineCount == 1 && is_int( strpos( $border, 'T' ) ) ) $b .= 'T'; 1290 if ( $k == count( $content ) - 1 && is_int( strpos( $border, 'R' ) ) ) $b .= 'R'; 1291 1292 if ( $arraysize == 1 ) $this->Cell( $stringWidth + $margins + $empty, $lineHeight, $chunk, $b, 1, $align, $fill, $this->HREF , $currentx ); //mono-style line 1293 elseif ( $k == 0 ) $this->Cell( $stringWidth + ( $margins / 2 ) + $empty, $lineHeight, $chunk, $b, 0, 'R', $fill, $this->HREF ); //first part 1294 elseif ( $k == $arraysize-1 ) $this->Cell( $stringWidth + ( $margins / 2 ), $lineHeight, $chunk, $b, 1, '', $fill, $this->HREF, $currentx ); //last part 1295 else $this->Cell( $stringWidth , $lineHeight, $chunk, $b, 0, '', $fill, $this->HREF ); //middle part 1296 } 1297 break; 1298 case 'L': 1299 case 'J': 1300 foreach ( $content as $k => $chunk ) { 1301 $this->restoreFont( $font[ $k ] ); 1302 $stringWidth = $this->GetStringWidth( $chunk ) + ( $this->ws * substr_count( $chunk, ' ' ) / $this->k ); 1303 // determine which borders should be used 1304 $b = ''; 1305 if ( $lineCount == 1 && is_int( strpos( $border, 'T' ) ) ) $b .= 'T'; 1306 if ( $k == 0 && is_int( strpos( $border, 'L' ) ) ) $b .= 'L'; 1307 1308 if ( !$is_table && !$outofblock && !$fill && $align == 'L' && $k == 0 ) { 1309 // Remove margins in this special (though often) case 1310 $align = ''; 1311 $margins = 0; 1312 } 1313 1314 if ( $arraysize == 1 ) $this->Cell( $stringWidth + $margins + $empty, $lineHeight, $chunk, $b, 1, $align, $fill, $this->HREF , $currentx ); //mono-style line 1315 elseif ( $k == 0 ) $this->Cell( $stringWidth + ( $margins / 2 ), $lineHeight, $chunk, $b, 0, $align, $fill, $this->HREF ); //first part 1316 elseif ( $k == $arraysize-1 ) $this->Cell( $stringWidth + ( $margins / 2 ) + $empty, $lineHeight, $chunk, $b, 1, '', $fill, $this->HREF, $currentx ); //last part 1317 else $this->Cell( $stringWidth , $lineHeight, $chunk, $b, 0, '', $fill, $this->HREF ); //middle part 1318 1319 if ( !$is_table && !$outofblock && !$fill && $align == '' && $k == 0 ) { 1320 $align = 'L'; 1321 $margins = ( 2 * $this->cMargin ); 1322 } 1323 } 1324 break; 1325 case 'C': 1326 foreach ( $content as $k => $chunk ) { 1327 $this->restoreFont( $font[ $k ] ); 1328 $stringWidth = $this->GetStringWidth( $chunk ) + ( $this->ws * substr_count( $chunk, ' ' ) / $this->k ); 1329 // determine which borders should be used 1330 $b = ''; 1331 if ( $lineCount == 1 && is_int( strpos( $border, 'T' ) ) ) $b .= 'T'; 1332 1333 if ( $arraysize == 1 ) $this->Cell( $stringWidth + $margins + $empty, $lineHeight, $chunk, $b, 1, $align, $fill, $this->HREF , $currentx ); //mono-style line 1334 elseif ( $k == 0 ) $this->Cell( $stringWidth + ( $margins / 2 ) + ( $empty / 2 ), $lineHeight, $chunk, $b, 0, 'R', $fill, $this->HREF ); //first part 1335 elseif ( $k == $arraysize-1 ) $this->Cell( $stringWidth + ( $margins / 2 ) + ( $empty / 2 ), $lineHeight, $chunk, $b, 1, 'L', $fill, $this->HREF, $currentx ); //last part 1336 else $this->Cell( $stringWidth , $lineHeight, $chunk, $b, 0, '', $fill, $this->HREF ); //middle part 1337 } 1338 break; 1339 default: break; 1340 } 1341 // move on to the next line, reset variables, tack on saved content and current char 1342 $this->restoreFont( $savedFont ); 1343 $font = array( $savedFont ); 1344 $content = array( $savedContent . $s{ $i } ); 1345 1346 $currContent = &$content[ 0 ]; 1347 $contentWidth = $this->GetStringWidth( $currContent ) * $this->k; 1348 $cutoffWidth = $contentWidth; 1349 } 1350 // another character will fit, so add it on 1351 else { 1352 $contentWidth += $cw; 1353 $currContent .= $s{ $i }; 1354 } 1355 } 1356 } 1357 // ----------------------END OF FLOWING BLOCK------------------------------------// 1358 // EDITEI 1359 // Thanks to Ron Korving for the WordWrap() function 1360 function WordWrap( &$text, $maxwidth ) 1361 { 1362 $biggestword = 0; //EDITEI 1363 $toonarrow = false; //EDITEI 1364 1365 $text = trim( $text ); 1366 if ( $text === '' ) return 0; 1367 $space = $this->GetStringWidth( ' ' ); 1368 $lines = explode( "\n", $text ); 1369 $text = ''; 1370 $count = 0; 1371 1372 foreach ( $lines as $line ) { 1373 $words = preg_split( '/ +/', $line ); 1374 $width = 0; 1375 1376 foreach ( $words as $word ) { 1377 $wordwidth = $this->GetStringWidth( $word ); 1378 // EDITEI 1379 // Warn user that maxwidth is insufficient 1380 if ( $wordwidth > $maxwidth ) { 1381 if ( $wordwidth > $biggestword ) $biggestword = $wordwidth; 1382 $toonarrow = true; //EDITEI 1383 } 1384 if ( $width + $wordwidth <= $maxwidth ) { 1385 $width += $wordwidth + $space; 1386 $text .= $word . ' '; 1387 } else { 1388 $width = $wordwidth + $space; 1389 $text = rtrim( $text ) . "\n" . $word . ' '; 1390 $count++; 1391 } 1392 } 1393 $text = rtrim( $text ) . "\n"; 1394 $count++; 1395 } 1396 $text = rtrim( $text ); 1397 // Return -(wordsize) if word is bigger than maxwidth 1398 if ( $toonarrow ) return - $biggestword; 1399 else return $count; 1400 } 1401 // EDITEI 1402 // Thanks to Seb(captainseb@wanadoo.fr) for the _SetTextRendering() and SetTextOutline() functions 1403 /** 1404 * Set Text Rendering Mode 1405 * 1406 * @param int $mode Set the rendering mode.<ul><li>0 : Fill text (default)</li><li>1 : Stroke</li><li>2 : Fill & stroke</li></ul> 1407 * @see SetTextOutline 1408 */ 1409 // This function is not being currently used 1410 function _SetTextRendering( $mode ) 1411 { 1412 if ( !( ( $mode == 0 ) || ( $mode == 1 ) || ( $mode == 2 ) ) ) 1413 $this->Error( "Text rendering mode should be 0, 1 or 2 (value : $mode)" ); 1414 $this->_out( $mode . ' Tr' ); 1415 } 1416 1417 /** 1418 * Set Text Ouline On/Off 1419 * 1420 * @param mixed $width If set to false the text rending mode is set to fill, else it's the width of the outline 1421 * @param int $r If g et b are given, red component; if not, indicates the gray level. Value between 0 and 255 1422 * @param int $g Green component (between 0 and 255) 1423 * @param int $b Blue component (between 0 and 255) 1424 * @see _SetTextRendering 1425 */ 1426 function SetTextOutline( $width, $r = 0, $g = -1, $b = -1 ) // EDITEI 1427 { 1428 if ( $width == false ) { // Now resets all values 1429 $this->outline_on = false; 1430 $this->SetLineWidth( 0.2 ); 1431 $this->SetDrawColor( 0 ); 1432 $this->_setTextRendering( 0 ); 1433 $this->_out( '0 Tr' ); 1434 } else { 1435 $this->SetLineWidth( $width ); 1436 $this->SetDrawColor( $r, $g , $b ); 1437 $this->_out( '2 Tr' ); //Fixed 1438 } 1439 } 1440 // function Circle() thanks to Olivier PLATHEY 1441 // EDITEI 1442 function Circle( $x, $y, $r, $style = '' ) 1443 { 1444 $this->Ellipse( $x, $y, $r, $r, $style ); 1445 } 1446 // function Ellipse() thanks to Olivier PLATHEY 1447 // EDITEI 1448 function Ellipse( $x, $y, $rx, $ry, $style = 'D' ) 1449 { 1450 if ( $style == 'F' ) $op = 'f'; 1451 elseif ( $style == 'FD' || $style == 'DF' ) $op = 'B'; 1452 else $op = 'S'; 1453 $lx = 4 / 3 * ( M_SQRT2-1 ) * $rx; 1454 $ly = 4 / 3 * ( M_SQRT2-1 ) * $ry; 1455 $k = $this->k; 1456 $h = $this->h; 1457 $this->_out( sprintf( '%.2f %.2f m %.2f %.2f %.2f %.2f %.2f %.2f c', 1458 ( $x + $rx ) * $k, ( $h - $y ) * $k, 1459 ( $x + $rx ) * $k, ( $h - ( $y - $ly ) ) * $k, 1460 ( $x + $lx ) * $k, ( $h - ( $y - $ry ) ) * $k, 1461 $x * $k, ( $h - ( $y - $ry ) ) * $k ) ); 1462 $this->_out( sprintf( '%.2f %.2f %.2f %.2f %.2f %.2f c', 1463 ( $x - $lx ) * $k, ( $h - ( $y - $ry ) ) * $k, 1464 ( $x - $rx ) * $k, ( $h - ( $y - $ly ) ) * $k, 1465 ( $x - $rx ) * $k, ( $h - $y ) * $k ) ); 1466 $this->_out( sprintf( '%.2f %.2f %.2f %.2f %.2f %.2f c', 1467 ( $x - $rx ) * $k, ( $h - ( $y + $ly ) ) * $k, 1468 ( $x - $lx ) * $k, ( $h - ( $y + $ry ) ) * $k, 1469 $x * $k, ( $h - ( $y + $ry ) ) * $k ) ); 1470 $this->_out( sprintf( '%.2f %.2f %.2f %.2f %.2f %.2f c %s', 1471 ( $x + $lx ) * $k, ( $h - ( $y + $ry ) ) * $k, 1472 ( $x + $rx ) * $k, ( $h - ( $y + $ly ) ) * $k, 1473 ( $x + $rx ) * $k, ( $h - $y ) * $k, 1474 $op ) ); 1475 } 1476 1477 function Image( $file, $x, $y, $w = 0, $h = 0, $type = '', $link = '', $paint = true ) 1478 { 1479 // Put an image on the page 1480 if ( !isset( $this->images[$file] ) ) { 1481 // First use of image, get info 1482 1483 // Edited by Oliver Georgi, 2007-04-30 to better handle image type 1484 // you often see file extensions like *.php?do and so on... 1485 // with old style checking it will always fail 1486 if ( $type == '' ) { 1487 1488 $handle = @fopen($file, 'rb'); 1489 if($handle) { 1490 1491 $imgdata = getimagesize($file); 1492 1493 if($imgdata) { 1494 switch($imgdata[2]) { 1495 1496 case 1: $type = 'gif'; break; 1497 case 2: $type = 'jpg'; break; 1498 case 3: $type = 'png'; break; 1499 1500 } 1501 } 1502 1503 } 1504 if($type == '') { 1505 1506 $file = PHPWCMS_URL.'img/leer.gif'; 1507 $type = 'gif'; 1508 1509 } 1510 1511 /* 1512 $pos = strrpos( $file, '.' ); 1513 if ( !$pos ) $this->Error( 'Image file has no extension and no type was specified: ' . $file ); 1514 $type = substr( $file, $pos + 1 ); 1515 */ 1516 } 1517 //$type = strtolower( $type ); 1518 $mqr = get_magic_quotes_runtime(); 1519 set_magic_quotes_runtime( 0 ); 1520 if ( $type == 'jpg' || $type == 'jpeg' ) { 1521 $info = $this->_parsejpg( $file ); 1522 } elseif ( $type == 'png' ) { 1523 $info = $this->_parsepng( $file ); 1524 } elseif ( $type == 'gif' ) { 1525 $info = $this->_parsegif( $file ); //EDITEI - GIF format included 1526 } else { 1527 // Allow for additional formats 1528 $mtd = '_parse' . $type; 1529 if ( !method_exists( $this, $mtd ) ) { 1530 $this->Error( 'Unsupported image type: ' . $type ); 1531 } 1532 $info = $this->$mtd( $file ); 1533 } 1534 set_magic_quotes_runtime( $mqr ); 1535 $info['i'] = count( $this->images ) + 1; 1536 $this->images[$file] = $info; 1537 1538 } else { 1539 1540 $info = $this->images[$file]; 1541 1542 } 1543 // Automatic width and height calculation if needed 1544 if ( $w == 0 && $h == 0 ) { 1545 // Put image at 72 dpi 1546 $w = $info['w'] / $this->k; 1547 $h = $info['h'] / $this->k; 1548 } 1549 if ( $w == 0 ) $w = $h * $info['w'] / $info['h']; 1550 if ( $h == 0 ) $h = $w * $info['h'] / $info['w']; 1551 1552 $changedpage = false; //EDITEI 1553 1554 // Avoid drawing out of the paper(exceeding width limits). //EDITEI 1555 if ( ( $x + $w ) > $this->fw ) { 1556 $x = $this->lMargin; 1557 $y += 5; 1558 } 1559 // Avoid drawing out of the page. //EDITEI 1560 if ( ( $y + $h ) > $this->fh ) { 1561 $this->AddPage(); 1562 // Edited Oliver Georgi 2007-04-30 -> missing $this->tMargin 1563 $y = $this->tMargin + 10; // +10 to avoid drawing too close to border of page 1564 $changedpage = true; 1565 } 1566 1567 $outstring = sprintf( 'q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q', $w * $this->k, $h * $this->k, $x * $this->k, ( $this->h - ( $y + $h ) ) * $this->k, $info['i'] ); 1568 1569 if ( $paint ) { // EDITEI 1570 $this->_out( $outstring ); 1571 if ( $link ) $this->Link( $x, $y, $w, $h, $link ); 1572 } 1573 // Avoid writing text on top of the image. //EDITEI 1574 if ( $changedpage ) $this->y = $y + $h; 1575 else $this->y = $y + $h; 1576 // Return width-height array //EDITEI 1577 $sizesarray['WIDTH'] = $w; 1578 $sizesarray['HEIGHT'] = $h; 1579 $sizesarray['X'] = $x; //Position before painting image 1580 $sizesarray['Y'] = $y; //Position before painting image 1581 $sizesarray['OUTPUT'] = $outstring; 1582 return $sizesarray; 1583 } 1584 // EDITEI - Done after reading a little about PDF reference guide 1585 function DottedRect( $x = 100, $y = 150, $w = 50, $h = 50 ) 1586 { 1587 $x *= $this->k ; 1588 $y = ( $this->h - $y ) * $this->k; 1589 $w *= $this->k ; 1590 $h *= $this->k ; // - h? 1591 $herex = $x; 1592 $herey = $y; 1593 // Make fillcolor == drawcolor 1594 $bak_fill = $this->FillColor; 1595 $this->FillColor = $this->DrawColor; 1596 $this->FillColor = str_replace( 'RG', 'rg', $this->FillColor ); 1597 $this->_out( $this->FillColor ); 1598 1599 while ( $herex < ( $x + $w ) ) { // draw from upper left to upper right 1600 $this->DrawDot( $herex, $herey ); 1601 $herex += ( 3 * $this->k ); 1602 } 1603 $herex = $x + $w; 1604 while ( $herey > ( $y - $h ) ) { // draw from upper right to lower right 1605 $this->DrawDot( $herex, $herey ); 1606 $herey -= ( 3 * $this->k ); 1607 } 1608 $herey = $y - $h; 1609 while ( $herex > $x ) { // draw from lower right to lower left 1610 $this->DrawDot( $herex, $herey ); 1611 $herex -= ( 3 * $this->k ); 1612 } 1613 $herex = $x; 1614 while ( $herey < $y ) { // draw from lower left to upper left 1615 $this->DrawDot( $herex, $herey ); 1616 $herey += ( 3 * $this->k ); 1617 } 1618 $herey = $y; 1619 1620 $this->FillColor = $bak_fill; 1621 $this->_out( $this->FillColor ); //return fillcolor back to normal 1622 } 1623 // EDITEI - Done after reading a little about PDF reference guide 1624 function DrawDot( $x, $y ) // center x y 1625 { 1626 $op = 'B'; // draw Filled Dots 1627 // F == fill //S == stroke //B == stroke and fill 1628 $r = 0.5 * $this->k; //raio 1629 // Start Point 1630 $x1 = $x - $r; 1631 $y1 = $y; 1632 // End Point 1633 $x2 = $x + $r; 1634 $y2 = $y; 1635 // Auxiliar Point 1636 $x3 = $x; 1637 $y3 = $y + ( 2 * $r ); // 2*raio to make a round (not oval) shape 1638 1639 // Round join and cap 1640 $s = "\n" . '1 J' . "\n"; 1641 $s .= '1 j' . "\n"; 1642 // Upper circle 1643 $s .= sprintf( '%.3f %.3f m' . "\n", $x1, $y1 ); //x y start drawing 1644 $s .= sprintf( '%.3f %.3f %.3f %.3f %.3f %.3f c' . "\n", $x1, $y1, $x3, $y3, $x2, $y2 ); //Bezier curve 1645 // Lower circle 1646 $y3 = $y - ( 2 * $r ); 1647 $s .= sprintf( "\n" . '%.3f %.3f m' . "\n", $x1, $y1 ); //x y start drawing 1648 $s .= sprintf( '%.3f %.3f %.3f %.3f %.3f %.3f c' . "\n", $x1, $y1, $x3, $y3, $x2, $y2 ); 1649 $s .= $op . "\n"; //stroke and fill 1650 1651 // Draw in PDF file 1652 $this->_out( $s ); 1653 } 1654 1655 function SetDash( $black = false, $white = false ) 1656 { 1657 if ( $black && $white ) $s = sprintf( '[%.3f %.3f] 0 d', $black * $this->k, $white * $this->k ); 1658 else $s = '[] 0 d'; 1659 $this->_out( $s ); 1660 } 1661 1662 function Bookmark( $txt, $level = 0, $y = 0 ) 1663 { 1664 if ( $y == -1 ) $y = $this->GetY(); 1665 $this->outlines[] = array( 't' => $txt, 'l' => $level, 'y' => $y, 'p' => $this->PageNo() ); 1666 } 1667 1668 function DisplayPreferences( $preferences ) 1669 { 1670 $this->DisplayPreferences .= $preferences; 1671 } 1672 1673 function _putbookmarks() 1674 { 1675 $nb = count( $this->outlines ); 1676 if ( $nb == 0 ) return; 1677 $lru = array(); 1678 $level = 0; 1679 foreach( $this->outlines as $i => $o ) { 1680 if ( $o['l'] > 0 ) { 1681 $parent = $lru[$o['l']-1]; 1682 // Set parent and last pointers 1683 $this->outlines[$i]['parent'] = $parent; 1684 $this->outlines[$parent]['last'] = $i; 1685 if ( $o['l'] > $level ) { 1686 // Level increasing: set first pointer 1687 $this->outlines[$parent]['first'] = $i; 1688 } 1689 } else 1690 $this->outlines[$i]['parent'] = $nb; 1691 if ( $o['l'] <= $level && $i > 0 ) { 1692 // Set prev and next pointers 1693 $prev = $lru[$o['l']]; 1694 $this->outlines[$prev]['next'] = $i; 1695 $this->outlines[$i]['prev'] = $prev; 1696 } 1697 $lru[$o['l']] = $i; 1698 $level = $o['l']; 1699 } 1700 // Outline items 1701 $n = $this->n + 1; 1702 foreach( $this->outlines as $i => $o ) { 1703 $this->_newobj(); 1704 $this->_out( '<</Title ' . $this->_textstring( $o['t'] ) ); 1705 $this->_out( '/Parent ' . ( $n + $o['parent'] ) . ' 0 R' ); 1706 if ( isset( $o['prev'] ) ) 1707 $this->_out( '/Prev ' . ( $n + $o['prev'] ) . ' 0 R' ); 1708 if ( isset( $o['next'] ) ) 1709 $this->_out( '/Next ' . ( $n + $o['next'] ) . ' 0 R' ); 1710 if ( isset( $o['first'] ) ) 1711 $this->_out( '/First ' . ( $n + $o['first'] ) . ' 0 R' ); 1712 if ( isset( $o['last'] ) ) 1713 $this->_out( '/Last ' . ( $n + $o['last'] ) . ' 0 R' ); 1714 $this->_out( sprintf( '/Dest [%d 0 R /XYZ 0 %.2f null]', 1 + 2 * $o['p'], ( $this->h - $o['y'] ) * $this->k ) ); 1715 $this->_out( '/Count 0>>' ); 1716 $this->_out( 'endobj' ); 1717 } 1718 // Outline root 1719 $this->_newobj(); 1720 $this->OutlineRoot = $this->n; 1721 $this->_out( '<</Type /Outlines /First ' . $n . ' 0 R' ); 1722 $this->_out( '/Last ' . ( $n + $lru[0] ) . ' 0 R>>' ); 1723 $this->_out( 'endobj' ); 1724 } 1725 1726 function Ln( $h = '' ) 1727 { 1728 // Line feed; default value is last cell height 1729 $this->x = $this->lMargin; 1730 if ( is_string( $h ) ) $this->y += $this->lasth; 1731 else $this->y += $h; 1732 } 1733 1734 function GetX() 1735 { 1736 // Get x position 1737 return $this->x; 1738 } 1739 1740 function SetX( $x ) 1741 { 1742 // Set x position 1743 if ( $x >= 0 ) $this->x = $x; 1744 else $this->x = $this->w + $x; 1745 } 1746 1747 function GetY() 1748 { 1749 // Get y position 1750 return $this->y; 1751 } 1752 1753 function SetY( $y ) 1754 { 1755 // Set y position and reset x 1756 $this->x = $this->lMargin; 1757 if ( $y >= 0 ) 1758 $this->y = $y; 1759 else 1760 $this->y = $this->h + $y; 1761 } 1762 1763 function SetXY( $x, $y ) 1764 { 1765 // Set x and y positions 1766 $this->SetY( $y ); 1767 $this->SetX( $x ); 1768 } 1769 1770 function Output( $name = '', $dest = '' ) 1771 { 1772 // Finish document if necessary 1773 if ( $this->state < 3 ) $this->Close(); 1774 // Normalize parameters 1775 if ( is_bool( $dest ) ) $dest = $dest ? 'D' : 'F'; 1776 $dest = strtoupper( $dest ); 1777 if ( $dest == '' ) { 1778 if ( $name == '' ) { 1779 $name = 'doc.pdf'; 1780 $dest = 'I'; 1781 } else 1782 $dest = 'F'; 1783 } 1784 switch ( $dest ) { 1785 case 'I': 1786 // Send to standard output 1787 if ( isset( $_SERVER['SERVER_NAME'] ) ) { 1788 // We send to a browser 1789 Header( 'Content-Type: application/pdf' ); 1790 if ( headers_sent() ) 1791 $this->Error( 'Some data has already been output to browser, can\'t send PDF file' ); 1792 Header( 'Content-Length: ' . strlen( $this->buffer ) ); 1793 Header( 'Content-disposition: inline; filename=' . $name ); 1794 } 1795 echo $this->buffer; 1796 break; 1797 case 'D': 1798 // Download file 1799 if ( isset( $_SERVER['HTTP_USER_AGENT'] ) && strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) ) 1800 Header( 'Content-Type: application/force-download' ); 1801 else 1802 Header( 'Content-Type: application/octet-stream' ); 1803 if ( headers_sent() ) 1804 $this->Error( 'Some data has already been output to browser, can\'t send PDF file' ); 1805 Header( 'Content-Length: ' . strlen( $this->buffer ) ); 1806 Header( 'Content-disposition: attachment; filename=' . $name ); 1807 echo $this->buffer; 1808 break; 1809 case 'F': 1810 // Save to local file 1811 $f = fopen( $name, 'wb' ); 1812 if ( !$f ) $this->Error( 'Unable to create output file: ' . $name ); 1813 fwrite( $f, $this->buffer, strlen( $this->buffer ) ); 1814 fclose( $f ); 1815 break; 1816 case 'S': 1817 // Return as a string 1818 return $this->buffer; 1819 default: 1820 $this->Error( 'Incorrect output destination: ' . $dest ); 1821 } 1822 return ''; 1823 } 1824 1825 /** 1826 * Protected methods * 1827 */ 1828 function _dochecks() 1829 { 1830 // Check for locale-related bug 1831 if ( 1.1 == 1 ) 1832 $this->Error( 'Don\'t alter the locale before including class file' ); 1833 // Check for decimal separator 1834 if ( sprintf( '%.1f', 1.0 ) != '1.0' ) 1835 setlocale( LC_NUMERIC, 'C' ); 1836 } 1837 1838 function _begindoc() 1839 { 1840 // Start document 1841 $this->state = 1; 1842 $this->_out( '%PDF-1.3' ); 1843 } 1844 1845 function _putpages() 1846 { 1847 $nb = $this->page; 1848 if ( !empty( $this->AliasNbPages ) ) { 1849 // Replace number of pages 1850 for( $n = 1;$n <= $nb;$n++ ) 1851 $this->pages[$n] = str_replace( $this->AliasNbPages, $nb, $this->pages[$n] ); 1852 } 1853 if ( $this->DefOrientation == 'P' ) { 1854 $wPt = $this->fwPt; 1855 $hPt = $this->fhPt; 1856 } else { 1857 $wPt = $this->fhPt; 1858 $hPt = $this->fwPt; 1859 } 1860 $filter = ( $this->compress ) ? '/Filter /FlateDecode ' : ''; 1861 for( $n = 1;$n <= $nb;$n++ ) { 1862 // Page 1863 $this->_newobj(); 1864 $this->_out( '<</Type /Page' ); 1865 $this->_out( '/Parent 1 0 R' ); 1866 if ( isset( $this->OrientationChanges[$n] ) ) 1867 $this->_out( sprintf( '/MediaBox [0 0 %.2f %.2f]', $hPt, $wPt ) ); 1868 $this->_out( '/Resources 2 0 R' ); 1869 if ( isset( $this->PageLinks[$n] ) ) { 1870 // Links 1871 $annots = '/Annots ['; 1872 foreach( $this->PageLinks[$n] as $pl ) { 1873 $rect = sprintf( '%.2f %.2f %.2f %.2f', $pl[0], $pl[1], $pl[0] + $pl[2], $pl[1] - $pl[3] ); 1874 $annots .= '<</Type /Annot /Subtype /Link /Rect [' . $rect . '] /Border [0 0 0] '; 1875 if ( is_string( $pl[4] ) ) 1876 $annots .= '/A <</S /URI /URI ' . $this->_textstring( $pl[4] ) . '>>>>'; 1877 else { 1878 $l = $this->links[$pl[4]]; 1879 $h = isset( $this->OrientationChanges[$l[0]] ) ? $wPt : $hPt; 1880 $annots .= sprintf( '/Dest [%d 0 R /XYZ 0 %.2f null]>>', 1 + 2 * $l[0], $h - $l[1] * $this->k ); 1881 } 1882 } 1883 $this->_out( $annots . ']' ); 1884 } 1885 $this->_out( '/Contents ' . ( $this->n + 1 ) . ' 0 R>>' ); 1886 $this->_out( 'endobj' ); 1887 // Page content 1888 $p = ( $this->compress ) ? gzcompress( $this->pages[$n] ) : $this->pages[$n]; 1889 $this->_newobj(); 1890 $this->_out( '<<' . $filter . '/Length ' . strlen( $p ) . '>>' ); 1891 $this->_putstream( $p ); 1892 $this->_out( 'endobj' ); 1893 } 1894 // Pages root 1895 $this->offsets[1] = strlen( $this->buffer ); 1896 $this->_out( '1 0 obj' ); 1897 $this->_out( '<</Type /Pages' ); 1898 $kids = '/Kids ['; 1899 for( $i = 0;$i < $nb;$i++ ) 1900 $kids .= ( 3 + 2 * $i ) . ' 0 R '; 1901 $this->_out( $kids . ']' ); 1902 $this->_out( '/Count ' . $nb ); 1903 $this->_out( sprintf( '/MediaBox [0 0 %.2f %.2f]', $wPt, $hPt ) ); 1904 $this->_out( '>>' ); 1905 $this->_out( 'endobj' ); 1906 } 1907 1908 function _putfonts() 1909 { 1910 $nf = $this->n; 1911 foreach( $this->diffs as $diff ) { 1912 // Encodings 1913 $this->_newobj(); 1914 $this->_out( '<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [' . $diff . ']>>' ); 1915 $this->_out( 'endobj' ); 1916 } 1917 $mqr = get_magic_quotes_runtime(); 1918 set_magic_quotes_runtime( 0 ); 1919 foreach( $this->FontFiles as $file => $info ) { 1920 // Font file embedding 1921 $this->_newobj(); 1922 $this->FontFiles[$file]['n'] = $this->n; 1923 if ( defined( 'FPDF_FONTPATH' ) ) 1924 $file = FPDF_FONTPATH . $file; 1925 $size = filesize( $file ); 1926 if ( !$size ) 1927 $this->Error( 'Font file not found' ); 1928 $this->_out( '<</Length ' . $size ); 1929 if ( substr( $file, -2 ) == '.z' ) 1930 $this->_out( '/Filter /FlateDecode' ); 1931 $this->_out( '/Length1 ' . $info['length1'] ); 1932 if ( isset( $info['length2'] ) ) 1933 $this->_out( '/Length2 ' . $info['length2'] . ' /Length3 0' ); 1934 $this->_out( '>>' ); 1935 $f = fopen( $file, 'rb' ); 1936 $this->_putstream( fread( $f, $size ) ); 1937 fclose( $f ); 1938 $this->_out( 'endobj' ); 1939 } 1940 set_magic_quotes_runtime( $mqr ); 1941 foreach( $this->fonts as $k => $font ) { 1942 // Font objects 1943 $this->fonts[$k]['n'] = $this->n + 1; 1944 $type = $font['type']; 1945 $name = $font['name']; 1946 if ( $type == 'core' ) { 1947 // Standard font 1948 $this->_newobj(); 1949 $this->_out( '<</Type /Font' ); 1950 $this->_out( '/BaseFont /' . $name ); 1951 $this->_out( '/Subtype /Type1' ); 1952 if ( $name != 'Symbol' && $name != 'ZapfDingbats' ) 1953 $this->_out( '/Encoding /WinAnsiEncoding' ); 1954 $this->_out( '>>' ); 1955 $this->_out( 'endobj' ); 1956 } elseif ( $type == 'Type1' || $type == 'TrueType' ) { 1957 // Additional Type1 or TrueType font 1958 $this->_newobj(); 1959 $this->_out( '<</Type /Font' ); 1960 $this->_out( '/BaseFont /' . $name ); 1961 $this->_out( '/Subtype /' . $type ); 1962 $this->_out( '/FirstChar 32 /LastChar 255' ); 1963 $this->_out( '/Widths ' . ( $this->n + 1 ) . ' 0 R' ); 1964 $this->_out( '/FontDescriptor ' . ( $this->n + 2 ) . ' 0 R' ); 1965 if ( $font['enc'] ) { 1966 if ( isset( $font['diff'] ) ) 1967 $this->_out( '/Encoding ' . ( $nf + $font['diff'] ) . ' 0 R' ); 1968 else 1969 $this->_out( '/Encoding /WinAnsiEncoding' ); 1970 } 1971 $this->_out( '>>' ); 1972 $this->_out( 'endobj' ); 1973 // Widths 1974 $this->_newobj(); 1975 $cw = &$font['cw']; 1976 $s = '['; 1977 for( $i = 32;$i <= 255;$i++ ) 1978 $s .= $cw[chr( $i )] . ' '; 1979 $this->_out( $s . ']' ); 1980 $this->_out( 'endobj' ); 1981 // Descriptor 1982 $this->_newobj(); 1983 $s = '<</Type /FontDescriptor /FontName /' . $name; 1984 foreach( $font['desc'] as $k => $v ) 1985 $s .= ' /' . $k . ' ' . $v; 1986 $file = $font['file']; 1987 if ( $file ) 1988 $s .= ' /FontFile' . ( $type == 'Type1' ? '' : '2' ) . ' ' . $this->FontFiles[$file]['n'] . ' 0 R'; 1989 $this->_out( $s . '>>' ); 1990 $this->_out( 'endobj' ); 1991 } else { 1992 // Allow for additional types 1993 $mtd = '_put' . strtolower( $type ); 1994 if ( !method_exists( $this, $mtd ) ) 1995 $this->Error( 'Unsupported font type: ' . $type ); 1996 $this->$mtd( $font ); 1997 } 1998 } 1999 } 2000 2001 function _putimages() 2002 { 2003 $filter = ( $this->compress ) ? '/Filter /FlateDecode ' : ''; 2004 reset( $this->images ); 2005 while ( list( $file, $info ) = each( $this->images ) ) { 2006 $this->_newobj(); 2007 $this->images[$file]['n'] = $this->n; 2008 $this->_out( '<</Type /XObject' ); 2009 $this->_out( '/Subtype /Image' ); 2010 $this->_out( '/Width ' . $info['w'] ); 2011 $this->_out( '/Height ' . $info['h'] ); 2012 if ( $info['cs'] == 'Indexed' ) 2013 $this->_out( '/ColorSpace [/Indexed /DeviceRGB ' . ( strlen( $info['pal'] ) / 3-1 ) . ' ' . ( $this->n + 1 ) . ' 0 R]' ); 2014 else { 2015 $this->_out( '/ColorSpace /' . $info['cs'] ); 2016 if ( $info['cs'] == 'DeviceCMYK' ) 2017 $this->_out( '/Decode [1 0 1 0 1 0 1 0]' ); 2018 } 2019 $this->_out( '/BitsPerComponent ' . $info['bpc'] ); 2020 $this->_out( '/Filter /' . $info['f'] ); 2021 if ( isset( $info['parms'] ) ) 2022 $this->_out( $info['parms'] ); 2023 if ( isset( $info['trns'] ) && is_array( $info['trns'] ) ) { 2024 $trns = ''; 2025 for( $i = 0;$i < count( $info['trns'] );$i++ ) 2026 $trns .= $info['trns'][$i] . ' ' . $info['trns'][$i] . ' '; 2027 $this->_out( '/Mask [' . $trns . ']' ); 2028 } 2029 $this->_out( '/Length ' . strlen( $info['data'] ) . '>>' ); 2030 $this->_putstream( $info['data'] ); 2031 unset( $this->images[$file]['data'] ); 2032 $this->_out( 'endobj' ); 2033 // Palette 2034 if ( $info['cs'] == 'Indexed' ) { 2035 $this->_newobj(); 2036 $pal = ( $this->compress ) ? gzcompress( $info['pal'] ) : $info['pal']; 2037 $this->_out( '<<' . $filter . '/Length ' . strlen( $pal ) . '>>' ); 2038 $this->_putstream( $pal ); 2039 $this->_out( 'endobj' ); 2040 } 2041 } 2042 } 2043 2044 function _putresources() 2045 { 2046 $this->_putfonts(); 2047 $this->_putimages(); 2048 // Resource dictionary 2049 $this->offsets[2] = strlen( $this->buffer ); 2050 $this->_out( '2 0 obj' ); 2051 $this->_out( '<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]' ); 2052 $this->_out( '/Font <<' ); 2053 foreach( $this->fonts as $font ) 2054 $this->_out( '/F' . $font['i'] . ' ' . $font['n'] . ' 0 R' ); 2055 $this->_out( '>>' ); 2056 if ( count( $this->images ) ) { 2057 $this->_out( '/XObject <<' ); 2058 foreach( $this->images as $image ) 2059 $this->_out( '/I' . $image['i'] . ' ' . $image['n'] . ' 0 R' ); 2060 $this->_out( '>>' ); 2061 } 2062 $this->_out( '>>' ); 2063 $this->_out( 'endobj' ); 2064 $this->_putbookmarks(); //EDITEI 2065 } 2066 2067 function _putinfo() 2068 { 2069 $this->_out( '/Producer ' . $this->_textstring( 'FPDF ' . FPDF_VERSION ) ); 2070 if ( !empty( $this->title ) ) 2071 $this->_out( '/Title ' . $this->_textstring( $this->title ) ); 2072 if ( !empty( $this->subject ) ) 2073 $this->_out( '/Subject ' . $this->_textstring( $this->subject ) ); 2074 if ( !empty( $this->author ) ) 2075 $this->_out( '/Author ' . $this->_textstring( $this->author ) ); 2076 if ( !empty( $this->keywords ) ) 2077 $this->_out( '/Keywords ' . $this->_textstring( $this->keywords ) ); 2078 if ( !empty( $this->creator ) ) 2079 $this->_out( '/Creator ' . $this->_textstring( $this->creator ) ); 2080 $this->_out( '/CreationDate ' . $this->_textstring( 'D:' . date( 'YmdHis' ) ) ); 2081 } 2082 2083 function _putcatalog() 2084 { 2085 $this->_out( '/Type /Catalog' ); 2086 $this->_out( '/Pages 1 0 R' ); 2087 if ( $this->ZoomMode == 'fullpage' ) $this->_out( '/OpenAction [3 0 R /Fit]' ); 2088 elseif ( $this->ZoomMode == 'fullwidth' ) $this->_out( '/OpenAction [3 0 R /FitH null]' ); 2089 elseif ( $this->ZoomMode == 'real' ) $this->_out( '/OpenAction [3 0 R /XYZ null null 1]' ); 2090 elseif ( !is_string( $this->ZoomMode ) ) $this->_out( '/OpenAction [3 0 R /XYZ null null ' . ( $this->ZoomMode / 100 ) . ']' ); 2091 if ( $this->LayoutMode == 'single' ) $this->_out( '/PageLayout /SinglePage' ); 2092 elseif ( $this->LayoutMode == 'continuous' ) $this->_out( '/PageLayout /OneColumn' ); 2093 elseif ( $this->LayoutMode == 'two' ) $this->_out( '/PageLayout /TwoColumnLeft' ); 2094 // EDITEI - added lines below 2095 if ( count( $this->outlines ) > 0 ) { 2096 $this->_out( '/Outlines ' . $this->OutlineRoot . ' 0 R' ); 2097 $this->_out( '/PageMode /UseOutlines' ); 2098 } 2099 if ( is_int( strpos( $this->DisplayPreferences, 'FullScreen' ) ) ) $this->_out( '/PageMode /FullScreen' ); 2100 if ( $this->DisplayPreferences ) { 2101 $this->_out( '/ViewerPreferences<<' ); 2102 if ( is_int( strpos( $this->DisplayPreferences, 'HideMenubar' ) ) ) $this->_out( '/HideMenubar true' ); 2103 if ( is_int( strpos( $this->DisplayPreferences, 'HideToolbar' ) ) ) $this->_out( '/HideToolbar true' ); 2104 if ( is_int( strpos( $this->DisplayPreferences, 'HideWindowUI' ) ) ) $this->_out( '/HideWindowUI true' ); 2105 if ( is_int( strpos( $this->DisplayPreferences, 'DisplayDocTitle' ) ) ) $this->_out( '/DisplayDocTitle true' ); 2106 if ( is_int( strpos( $this->DisplayPreferences, 'CenterWindow' ) ) ) $this->_out( '/CenterWindow true' ); 2107 if ( is_int( strpos( $this->DisplayPreferences, 'FitWindow' ) ) ) $this->_out( '/FitWindow true' ); 2108 $this->_out( '>>' ); 2109 } 2110 } 2111 2112 function _puttrailer() 2113 { 2114 $this->_out( '/Size ' . ( $this->n + 1 ) ); 2115 $this->_out( '/Root ' . $this->n . ' 0 R' ); 2116 $this->_out( '/Info ' . ( $this->n-1 ) . ' 0 R' ); 2117 } 2118 2119 function _enddoc() 2120 { 2121 $this->_putpages(); 2122 $this->_putresources(); 2123 // Info 2124 $this->_newobj(); 2125 $this->_out( '<<' ); 2126 $this->_putinfo(); 2127 $this->_out( '>>' ); 2128 $this->_out( 'endobj' ); 2129 // Catalog 2130 $this->_newobj(); 2131 $this->_out( '<<' ); 2132 $this->_putcatalog(); 2133 $this->_out( '>>' ); 2134 $this->_out( 'endobj' ); 2135 // Cross-ref 2136 $o = strlen( $this->buffer ); 2137 $this->_out( 'xref' ); 2138 $this->_out( '0 ' . ( $this->n + 1 ) ); 2139 $this->_out( '0000000000 65535 f ' ); 2140 for( $i = 1; $i <= $this->n ; $i++ ) 2141 $this->_out( sprintf( '%010d 00000 n ', $this->offsets[$i] ) ); 2142 // Trailer 2143 $this->_out( 'trailer' ); 2144 $this->_out( '<<' ); 2145 $this->_puttrailer(); 2146 $this->_out( '>>' ); 2147 $this->_out( 'startxref' ); 2148 $this->_out( $o ); 2149 $this->_out( '%%EOF' ); 2150 $this->state = 3; 2151 } 2152 2153 function _beginpage( $orientation ) 2154 { 2155 $this->page++; 2156 $this->pages[$this->page] = ''; 2157 $this->state = 2; 2158 $this->x = $this->lMargin; 2159 $this->y = $this->tMargin; 2160 $this->FontFamily = ''; 2161 // Page orientation 2162 if ( !$orientation ) 2163 $orientation = $this->DefOrientation; 2164 else { 2165 $orientation = strtoupper( $orientation{0} ); 2166 if ( $orientation != $this->DefOrientation ) 2167 $this->OrientationChanges[$this->page] = true; 2168 } 2169 if ( $orientation != $this->CurOrientation ) { 2170 // Change orientation 2171 if ( $orientation == 'P' ) { 2172 $this->wPt = $this->fwPt; 2173 $this->hPt = $this->fhPt; 2174 $this->w = $this->fw; 2175 $this->h = $this->fh; 2176 } else { 2177 $this->wPt = $this->fhPt; 2178 $this->hPt = $this->fwPt; 2179 $this->w = $this->fh; 2180 $this->h = $this->fw; 2181 } 2182 $this->PageBreakTrigger = $this->h - $this->bMargin; 2183 $this->CurOrientation = $orientation; 2184 } 2185 } 2186 2187 function _endpage() 2188 { 2189 // End of page contents 2190 $this->state = 1; 2191 } 2192 2193 function _newobj() 2194 { 2195 // Begin a new object 2196 $this->n++; 2197 $this->offsets[$this->n] = strlen( $this->buffer ); 2198 $this->_out( $this->n . ' 0 obj' ); 2199 } 2200 2201 function _dounderline( $x, $y, $txt ) 2202 { 2203 // Underline text 2204 $up = $this->CurrentFont['up']; 2205 $ut = $this->CurrentFont['ut']; 2206 $w = $this->GetStringWidth( $txt ) + $this->ws * substr_count( $txt, ' ' ); 2207 return sprintf( '%.2f %.2f %.2f %.2f re f', $x * $this->k, ( $this->h - ( $y - $up / 1000 * $this->FontSize ) ) * $this->k, $w * $this->k, - $ut / 1000 * $this->FontSizePt ); 2208 } 2209 2210 function _parsejpg( $file ) 2211 { 2212 // Extract info from a JPEG file 2213 $a = GetImageSize( $file ); 2214 if ( !$a ) 2215 $this->Error( 'Missing or incorrect image file: ' . $file ); 2216 if ( $a[2] != 2 ) 2217 $this->Error( 'Not a JPEG file: ' . $file ); 2218 if ( !isset( $a['channels'] ) || $a['channels'] == 3 ) 2219 $colspace = 'DeviceRGB'; 2220 elseif ( $a['channels'] == 4 ) 2221 $colspace = 'DeviceCMYK'; 2222 else 2223 $colspace = 'DeviceGray'; 2224 $bpc = isset( $a['bits'] ) ? $a['bits'] : 8; 2225 // Read whole file 2226 $f = fopen( $file, 'rb' ); 2227 $data = ''; 2228 while ( !feof( $f ) ) 2229 $data .= fread( $f, 4096 ); 2230 fclose( $f ); 2231 return array( 'w' => $a[0], 'h' => $a[1], 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'DCTDecode', 'data' => $data ); 2232 } 2233 2234 function _parsepng( $file ) 2235 { 2236 // Extract info from a PNG file 2237 $f = fopen( $file, 'rb' ); 2238 // Extract info from a PNG file 2239 if ( !$f ) $this->Error( 'Can\'t open image file: ' . $file ); 2240 // Check signature 2241 if ( fread( $f, 8 ) != chr( 137 ) . 'PNG' . chr( 13 ) . chr( 10 ) . chr( 26 ) . chr( 10 ) ) 2242 $this->Error( 'Not a PNG file: ' . $file ); 2243 // Read header chunk 2244 fread( $f, 4 ); 2245 if ( fread( $f, 4 ) != 'IHDR' ) $this->Error( 'Incorrect PNG file: ' . $file ); 2246 $w = $this->_freadint( $f ); 2247 $h = $this->_freadint( $f ); 2248 $bpc = ord( fread( $f, 1 ) ); 2249 if ( $bpc > 8 ) $this->Error( '16-bit depth not supported: ' . $file ); 2250 $ct = ord( fread( $f, 1 ) ); 2251 if ( $ct == 0 ) $colspace = 'DeviceGray'; 2252 elseif ( $ct == 2 ) $colspace = 'DeviceRGB'; 2253 elseif ( $ct == 3 ) $colspace = 'Indexed'; 2254 else $this->Error( 'Alpha channel not supported: ' . $file ); 2255 if ( ord( fread( $f, 1 ) ) != 0 ) $this->Error( 'Unknown compression method: ' . $file ); 2256 if ( ord( fread( $f, 1 ) ) != 0 ) $this->Error( 'Unknown filter method: ' . $file ); 2257 if ( ord( fread( $f, 1 ) ) != 0 ) $this->Error( 'Interlacing not supported: ' . $file ); 2258 fread( $f, 4 ); 2259 $parms = '/DecodeParms <</Predictor 15 /Colors ' . ( $ct == 2 ? 3 : 1 ) . ' /BitsPerComponent ' . $bpc . ' /Columns ' . $w . '>>'; 2260 // Scan chunks looking for palette, transparency and image data 2261 $pal = ''; 2262 $trns = ''; 2263 $data = ''; 2264 do { 2265 $n = $this->_freadint( $f ); 2266 $type = fread( $f, 4 ); 2267 if ( $type == 'PLTE' ) { 2268 // Read palette 2269 $pal = fread( $f, $n ); 2270 fread( $f, 4 ); 2271 } elseif ( $type == 'tRNS' ) { 2272 // Read transparency info 2273 $t = fread( $f, $n ); 2274 if ( $ct == 0 ) $trns = array( ord( substr( $t, 1, 1 ) ) ); 2275 elseif ( $ct == 2 ) $trns = array( ord( substr( $t, 1, 1 ) ), ord( substr( $t, 3, 1 ) ), ord( substr( $t, 5, 1 ) ) ); 2276 else { 2277 $pos = strpos( $t, chr( 0 ) ); 2278 if ( is_int( $pos ) ) $trns = array( $pos ); 2279 } 2280 fread( $f, 4 ); 2281 } elseif ( $type == 'IDAT' ) { 2282 // Read image data block 2283 $data .= fread( $f, $n ); 2284 fread( $f, 4 ); 2285 } elseif ( $type == 'IEND' ) break; 2286 else fread( $f, $n + 4 ); 2287 } while ( $n ); 2288 if ( $colspace == 'Indexed' && empty( $pal ) ) $this->Error( 'Missing palette in ' . $file ); 2289 fclose( $f ); 2290 return array( 'w' => $w, 'h' => $h, 'cs' => $colspace, 'bpc' => $bpc, 'f' => 'FlateDecode', 'parms' => $parms, 'pal' => $pal, 'trns' => $trns, 'data' => $data ); 2291 } 2292 2293 function _parsegif( $file ) // EDITEI - GIF support is now included 2294 { 2295 // Function by Jérôme Fenal 2296 require_once ( RELATIVE_PATH . 'gif.php' ); //GIF class in pure PHP from Yamasoft (http://www.yamasoft.com/php-gif.zip) 2297 2298 $h = 0; 2299 $w = 0; 2300 $gif = new CGIF(); 2301 2302 if ( !$gif->loadFile( $file, 0 ) ) 2303 $this->Error( "GIF parser: unable to open file $file" ); 2304 2305 if ( $gif->m_img->m_gih->m_bLocalClr ) { 2306 $nColors = $gif->m_img->m_gih->m_nTableSize; 2307 $pal = $gif->m_img->m_gih->m_colorTable->toString(); 2308 if ( $bgColor != -1 ) { 2309 $bgColor = $this->m_img->m_gih->m_colorTable->colorIndex( $bgColor ); 2310 } 2311 $colspace = 'Indexed'; 2312 } elseif ( $gif->m_gfh->m_bGlobalClr ) { 2313 $nColors = $gif->m_gfh->m_nTableSize; 2314 $pal = $gif->m_gfh->m_colorTable->toString(); 2315 if ( ( isset( $bgColor ) ) && $bgColor != -1 ) { 2316 $bgColor = $gif->m_gfh->m_colorTable->colorIndex( $bgColor ); 2317 } 2318 $colspace = 'Indexed'; 2319 } else { 2320 $nColors = 0; 2321 $bgColor = -1; 2322 $colspace = 'DeviceGray'; 2323 $pal = ''; 2324 } 2325 2326 $trns = ''; 2327 if ( $gif->m_img->m_bTrans && ( $nColors > 0 ) ) { 2328 $trns = array( $gif->m_img->m_nTrans ); 2329 } 2330 2331 $data = $gif->m_img->m_data; 2332 $w = $gif->m_gfh->m_nWidth; 2333 $h = $gif->m_gfh->m_nHeight; 2334 2335 if ( $colspace == 'Indexed' && empty( $pal ) ) 2336 $this->Error( 'Missing palette in ' . $file ); 2337 2338 if ( $this->compress ) { 2339 $data = gzcompress( $data ); 2340 return array( 'w' => $w, 'h' => $h, 'cs' => $colspace, 'bpc' => 8, 'f' => 'FlateDecode', 'pal' => $pal, 'trns' => $trns, 'data' => $data ); 2341 } else { 2342 return array( 'w' => $w, 'h' => $h, 'cs' => $colspace, 'bpc' => 8, 'pal' => $pal, 'trns' => $trns, 'data' => $data ); 2343 } 2344 } 2345 2346 function _freadint( $f ) 2347 { 2348 // Read a 4-byte integer from file 2349 $i = ord( fread( $f, 1 ) ) << 24; 2350 $i += ord( fread( $f, 1 ) ) << 16; 2351 $i += ord( fread( $f, 1 ) ) << 8; 2352 $i += ord( fread( $f, 1 ) ); 2353 return $i; 2354 } 2355 2356 function _textstring( $s ) 2357 { 2358 // Format a text string 2359 return '(' . $this->_escape( $s ) . ')'; 2360 } 2361 2362 function _escape( $s ) 2363 { 2364 // Add \ before \, ( and ) 2365 return str_replace( ')', '\\)', str_replace( '(', '\\(', str_replace( '\\', '\\\\', $s ) ) ); 2366 } 2367 2368 function _putstream( $s ) 2369 { 2370 $this->_out( 'stream' ); 2371 $this->_out( $s ); 2372 $this->_out( 'endstream' ); 2373 } 2374 2375 function _out( $s ) 2376 { 2377 // Add a line to the document 2378 if ( $this->state == 2 ) $this->pages[$this->page] .= $s . "\n"; 2379 else $this->buffer .= $s . "\n"; 2380 } 2381 } //End of class 2382 // Handle special IE contype request 2383 if ( isset( $_SERVER['HTTP_USER_AGENT'] ) && $_SERVER['HTTP_USER_AGENT'] == 'contype' ) { 2384 Header( 'Content-Type: application/pdf' ); 2385 exit; 2386 } 2387 } //end of 'if(!class_exists('FPDF'))'' 2388 2389 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Nov 16 22:51:00 2010 | Cross-referenced by PHPXref 0.7 |