1<?php 2/******************************************************************************* 3* Software: FPDF * 4* Version: 1.53 * 5* Date: 2004-12-31 * 6* Author: Olivier PLATHEY * 7* License: Freeware * 8* * 9* You may use, modify and redistribute this software as you wish. * 10*******************************************************************************/ 11 12if(!class_exists('FPDF')) 13{ 14define('FPDF_VERSION','1.53'); 15 16class FPDF 17{ 18//Private properties 19var $page; //current page number 20var $n; //current object number 21var $offsets; //array of object offsets 22var $buffer; //buffer holding in-memory PDF 23var $pages; //array containing pages 24var $state; //current document state 25var $compress; //compression flag 26var $DefOrientation; //default orientation 27var $CurOrientation; //current orientation 28var $OrientationChanges; //array indicating orientation changes 29var $k; //scale factor (number of points in user unit) 30var $fwPt,$fhPt; //dimensions of page format in points 31var $fw,$fh; //dimensions of page format in user unit 32var $wPt,$hPt; //current dimensions of page in points 33var $w,$h; //current dimensions of page in user unit 34var $lMargin; //left margin 35var $tMargin; //top margin 36var $rMargin; //right margin 37var $bMargin; //page break margin 38var $cMargin; //cell margin 39var $x,$y; //current position in user unit for cell positioning 40var $lasth; //height of last cell printed 41var $LineWidth; //line width in user unit 42var $CoreFonts; //array of standard font names 43var $fonts; //array of used fonts 44var $FontFiles; //array of font files 45var $diffs; //array of encoding differences 46var $images; //array of used images 47var $PageLinks; //array of links in pages 48var $links; //array of internal links 49var $FontFamily; //current font family 50var $FontStyle; //current font style 51var $underline; //underlining flag 52var $CurrentFont; //current font info 53var $FontSizePt; //current font size in points 54var $FontSize; //current font size in user unit 55var $DrawColor; //commands for drawing color 56var $FillColor; //commands for filling color 57var $TextColor; //commands for text color 58var $ColorFlag; //indicates whether fill and text colors are different 59var $ws; //word spacing 60var $AutoPageBreak; //automatic page breaking 61var $PageBreakTrigger; //threshold used to trigger page breaks 62var $InFooter; //flag set when processing footer 63var $ZoomMode; //zoom display mode 64var $LayoutMode; //layout display mode 65var $title; //title 66var $subject; //subject 67var $author; //author 68var $keywords; //keywords 69var $creator; //creator 70var $AliasNbPages; //alias for total number of pages 71var $PDFVersion; //PDF version number 72 73/******************************************************************************* 74* * 75* Public methods * 76* * 77*******************************************************************************/ 78function 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') 112 $this->k=1; 113 elseif($unit=='mm') 114 $this->k=72/25.4; 115 elseif($unit=='cm') 116 $this->k=72/2.54; 117 elseif($unit=='in') 118 $this->k=72; 119 else 120 $this->Error('Incorrect unit: '.$unit); 121 //Page format 122 if(is_string($format)) 123 { 124 $format=strtolower($format); 125 if($format=='a3') 126 $format=array(841.89,1190.55); 127 elseif($format=='a4') 128 $format=array(595.28,841.89); 129 elseif($format=='a5') 130 $format=array(420.94,595.28); 131 elseif($format=='letter') 132 $format=array(612,792); 133 elseif($format=='legal') 134 $format=array(612,1008); 135 else 136 $this->Error('Unknown page format: '.$format); 137 $this->fwPt=$format[0]; 138 $this->fhPt=$format[1]; 139 } 140 else 141 { 142 $this->fwPt=$format[0]*$this->k; 143 $this->fhPt=$format[1]*$this->k; 144 } 145 $this->fw=$this->fwPt/$this->k; 146 $this->fh=$this->fhPt/$this->k; 147 //Page orientation 148 $orientation=strtolower($orientation); 149 if($orientation=='p' || $orientation=='portrait') 150 { 151 $this->DefOrientation='P'; 152 $this->wPt=$this->fwPt; 153 $this->hPt=$this->fhPt; 154 } 155 elseif($orientation=='l' || $orientation=='landscape') 156 { 157 $this->DefOrientation='L'; 158 $this->wPt=$this->fhPt; 159 $this->hPt=$this->fwPt; 160 } 161 else 162 $this->Error('Incorrect orientation: '.$orientation); 163 $this->CurOrientation=$this->DefOrientation; 164 $this->w=$this->wPt/$this->k; 165 $this->h=$this->hPt/$this->k; 166 //Page margins (1 cm) 167 $margin=28.35/$this->k; 168 $this->SetMargins($margin,$margin); 169 //Interior cell margin (1 mm) 170 $this->cMargin=$margin/10; 171 //Line width (0.2 mm) 172 $this->LineWidth=.567/$this->k; 173 //Automatic page break 174 $this->SetAutoPageBreak(true,2*$margin); 175 //Full width display mode 176 $this->SetDisplayMode('fullwidth'); 177 //Enable compression 178 $this->SetCompression(true); 179 //Set default PDF version number 180 $this->PDFVersion='1.3'; 181} 182 183function SetMargins($left,$top,$right=-1) 184{ 185 //Set left, top and right margins 186 $this->lMargin=$left; 187 $this->tMargin=$top; 188 if($right==-1) 189 $right=$left; 190 $this->rMargin=$right; 191} 192 193function SetLeftMargin($margin) 194{ 195 //Set left margin 196 $this->lMargin=$margin; 197 if($this->page>0 && $this->x<$margin) 198 $this->x=$margin; 199} 200 201function SetTopMargin($margin) 202{ 203 //Set top margin 204 $this->tMargin=$margin; 205} 206 207function SetRightMargin($margin) 208{ 209 //Set right margin 210 $this->rMargin=$margin; 211} 212 213function SetAutoPageBreak($auto,$margin=0) 214{ 215 //Set auto page break mode and triggering margin 216 $this->AutoPageBreak=$auto; 217 $this->bMargin=$margin; 218 $this->PageBreakTrigger=$this->h-$margin; 219} 220 221function SetDisplayMode($zoom,$layout='continuous') 222{ 223 //Set display mode in viewer 224 if($zoom=='fullpage' || $zoom=='fullwidth' || $zoom=='real' || $zoom=='default' || !is_string($zoom)) 225 $this->ZoomMode=$zoom; 226 else 227 $this->Error('Incorrect zoom display mode: '.$zoom); 228 if($layout=='single' || $layout=='continuous' || $layout=='two' || $layout=='default') 229 $this->LayoutMode=$layout; 230 else 231 $this->Error('Incorrect layout display mode: '.$layout); 232} 233 234function SetCompression($compress) 235{ 236 //Set page compression 237 if(function_exists('gzcompress')) 238 $this->compress=$compress; 239 else 240 $this->compress=false; 241} 242 243function SetTitle($title) 244{ 245 //Title of document 246 $this->title=$title; 247} 248 249function SetSubject($subject) 250{ 251 //Subject of document 252 $this->subject=$subject; 253} 254 255function SetAuthor($author) 256{ 257 //Author of document 258 $this->author=$author; 259} 260 261function SetKeywords($keywords) 262{ 263 //Keywords of document 264 $this->keywords=$keywords; 265} 266 267function SetCreator($creator) 268{ 269 //Creator of document 270 $this->creator=$creator; 271} 272 273function AliasNbPages($alias='{nb}') 274{ 275 //Define an alias for total number of pages 276 $this->AliasNbPages=$alias; 277} 278 279function Error($msg) 280{ 281 //Fatal error 282 die('<B>FPDF error: </B>'.$msg); 283} 284 285function Open() 286{ 287 //Begin document 288 $this->state=1; 289} 290 291function Close() 292{ 293 //Terminate document 294 if($this->state==3) 295 return; 296 if($this->page==0) 297 $this->AddPage(); 298 //Page footer 299 $this->InFooter=true; 300 $this->Footer(); 301 $this->InFooter=false; 302 //Close page 303 $this->_endpage(); 304 //Close document 305 $this->_enddoc(); 306} 307 308function AddPage($orientation='') 309{ 310 //Start a new page 311 if($this->state==0) 312 $this->Open(); 313 $family=$this->FontFamily; 314 $style=$this->FontStyle.($this->underline ? 'U' : ''); 315 $size=$this->FontSizePt; 316 $lw=$this->LineWidth; 317 $dc=$this->DrawColor; 318 $fc=$this->FillColor; 319 $tc=$this->TextColor; 320 $cf=$this->ColorFlag; 321 if($this->page>0) 322 { 323 //Page footer 324 $this->InFooter=true; 325 $this->Footer(); 326 $this->InFooter=false; 327 //Close page 328 $this->_endpage(); 329 } 330 //Start new page 331 $this->_beginpage($orientation); 332 //Set line cap style to square 333 $this->_out('2 J'); 334 //Set line width 335 $this->LineWidth=$lw; 336 $this->_out(sprintf('%.2f w',$lw*$this->k)); 337 //Set font 338 if($family) 339 $this->SetFont($family,$style,$size); 340 //Set colors 341 $this->DrawColor=$dc; 342 if($dc!='0 G') 343 $this->_out($dc); 344 $this->FillColor=$fc; 345 if($fc!='0 g') 346 $this->_out($fc); 347 $this->TextColor=$tc; 348 $this->ColorFlag=$cf; 349 //Page header 350 $this->Header(); 351 //Restore line width 352 if($this->LineWidth!=$lw) 353 { 354 $this->LineWidth=$lw; 355 $this->_out(sprintf('%.2f w',$lw*$this->k)); 356 } 357 //Restore font 358 if($family) 359 $this->SetFont($family,$style,$size); 360 //Restore colors 361 if($this->DrawColor!=$dc) 362 { 363 $this->DrawColor=$dc; 364 $this->_out($dc); 365 } 366 if($this->FillColor!=$fc) 367 { 368 $this->FillColor=$fc; 369 $this->_out($fc); 370 } 371 $this->TextColor=$tc; 372 $this->ColorFlag=$cf; 373} 374 375function Header() 376{ 377 //To be implemented in your own inherited class 378} 379 380function Footer() 381{ 382 //To be implemented in your own inherited class 383} 384 385function PageNo() 386{ 387 //Get current page number 388 return $this->page; 389} 390 391function SetDrawColor($r,$g=-1,$b=-1) 392{ 393 //Set color for all stroking operations 394 if(($r==0 && $g==0 && $b==0) || $g==-1) 395 $this->DrawColor=sprintf('%.3f G',$r/255); 396 else 397 $this->DrawColor=sprintf('%.3f %.3f %.3f RG',$r/255,$g/255,$b/255); 398 if($this->page>0) 399 $this->_out($this->DrawColor); 400} 401 402function SetFillColor($r,$g=-1,$b=-1) 403{ 404 //Set color for all filling operations 405 if(($r==0 && $g==0 && $b==0) || $g==-1) 406 $this->FillColor=sprintf('%.3f g',$r/255); 407 else 408 $this->FillColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255); 409 $this->ColorFlag=($this->FillColor!=$this->TextColor); 410 if($this->page>0) 411 $this->_out($this->FillColor); 412} 413 414function SetTextColor($r,$g=-1,$b=-1) 415{ 416 //Set color for text 417 if(($r==0 && $g==0 && $b==0) || $g==-1) 418 $this->TextColor=sprintf('%.3f g',$r/255); 419 else 420 $this->TextColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255); 421 $this->ColorFlag=($this->FillColor!=$this->TextColor); 422} 423 424function GetStringWidth($s) 425{ 426 //Get width of a string in the current font 427 $s=(string)$s; 428 $cw=&$this->CurrentFont['cw']; 429 $w=0; 430 $l=strlen($s); 431 for($i=0;$i<$l;$i++) 432 $w+=$cw[$s{$i}]; 433 return $w*$this->FontSize/1000; 434} 435 436function SetLineWidth($width) 437{ 438 //Set line width 439 $this->LineWidth=$width; 440 if($this->page>0) 441 $this->_out(sprintf('%.2f w',$width*$this->k)); 442} 443 444function Line($x1,$y1,$x2,$y2) 445{ 446 //Draw a line 447 $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)); 448} 449 450function Rect($x,$y,$w,$h,$style='') 451{ 452 //Draw a rectangle 453 if($style=='F') 454 $op='f'; 455 elseif($style=='FD' || $style=='DF') 456 $op='B'; 457 else 458 $op='S'; 459 $this->_out(sprintf('%.2f %.2f %.2f %.2f re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op)); 460} 461 462function AddFont($family,$style='',$file='') 463{ 464 //Add a TrueType or Type1 font 465 $family=strtolower($family); 466 if($file=='') 467 $file=str_replace(' ','',$family).strtolower($style).'.php'; 468 if($family=='arial') 469 $family='helvetica'; 470 $style=strtoupper($style); 471 if($style=='IB') 472 $style='BI'; 473 $fontkey=$family.$style; 474 if(isset($this->fonts[$fontkey])) 475 $this->Error('Font already added: '.$family.' '.$style); 476 include($this->_getfontpath().$file); 477 if(!isset($name)) 478 $this->Error('Could not include font definition file'); 479 $i=count($this->fonts)+1; 480 $this->fonts[$fontkey]=array('i'=>$i,'type'=>$type,'name'=>$name,'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw,'enc'=>$enc,'file'=>$file); 481 if($diff) 482 { 483 //Search existing encodings 484 $d=0; 485 $nb=count($this->diffs); 486 for($i=1;$i<=$nb;$i++) 487 { 488 if($this->diffs[$i]==$diff) 489 { 490 $d=$i; 491 break; 492 } 493 } 494 if($d==0) 495 { 496 $d=$nb+1; 497 $this->diffs[$d]=$diff; 498 } 499 $this->fonts[$fontkey]['diff']=$d; 500 } 501 if($file) 502 { 503 if($type=='TrueType') 504 $this->FontFiles[$file]=array('length1'=>$originalsize); 505 else 506 $this->FontFiles[$file]=array('length1'=>$size1,'length2'=>$size2); 507 } 508} 509 510function SetFont($family,$style='',$size=0) 511{ 512 //Select a font; size given in points 513 global $fpdf_charwidths; 514 515 $family=strtolower($family); 516 if($family=='') 517 $family=$this->FontFamily; 518 if($family=='arial') 519 $family='helvetica'; 520 elseif($family=='symbol' || $family=='zapfdingbats') 521 $style=''; 522 $style=strtoupper($style); 523 if(strpos($style,'U')!==false) 524 { 525 $this->underline=true; 526 $style=str_replace('U','',$style); 527 } 528 else 529 $this->underline=false; 530 if($style=='IB') 531 $style='BI'; 532 if($size==0) 533 $size=$this->FontSizePt; 534 //Test if font is already selected 535 if($this->FontFamily==$family && $this->FontStyle==$style && $this->FontSizePt==$size) 536 return; 537 //Test if used for the first time 538 $fontkey=$family.$style; 539 if(!isset($this->fonts[$fontkey])) 540 { 541 //Check if one of the standard fonts 542 if(isset($this->CoreFonts[$fontkey])) 543 { 544 if(!isset($fpdf_charwidths[$fontkey])) 545 { 546 //Load metric file 547 $file=$family; 548 if($family=='times' || $family=='helvetica') 549 $file.=strtolower($style); 550 include($this->_getfontpath().$file.'.php'); 551 if(!isset($fpdf_charwidths[$fontkey])) 552 $this->Error('Could not include font metric file'); 553 } 554 $i=count($this->fonts)+1; 555 $this->fonts[$fontkey]=array('i'=>$i,'type'=>'core','name'=>$this->CoreFonts[$fontkey],'up'=>-100,'ut'=>50,'cw'=>$fpdf_charwidths[$fontkey]); 556 } 557 else 558 $this->Error('Undefined font: '.$family.' '.$style); 559 } 560 //Select it 561 $this->FontFamily=$family; 562 $this->FontStyle=$style; 563 $this->FontSizePt=$size; 564 $this->FontSize=$size/$this->k; 565 $this->CurrentFont=&$this->fonts[$fontkey]; 566 if($this->page>0) 567 $this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt)); 568} 569 570function SetFontSize($size) 571{ 572 //Set font size in points 573 if($this->FontSizePt==$size) 574 return; 575 $this->FontSizePt=$size; 576 $this->FontSize=$size/$this->k; 577 if($this->page>0) 578 $this->_out(sprintf('BT /F%d %.2f Tf ET',$this->CurrentFont['i'],$this->FontSizePt)); 579} 580 581function AddLink() 582{ 583 //Create a new internal link 584 $n=count($this->links)+1; 585 $this->links[$n]=array(0,0); 586 return $n; 587} 588 589function SetLink($link,$y=0,$page=-1) 590{ 591 //Set destination of internal link 592 if($y==-1) 593 $y=$this->y; 594 if($page==-1) 595 $page=$this->page; 596 $this->links[$link]=array($page,$y); 597} 598 599function Link($x,$y,$w,$h,$link) 600{ 601 //Put a link on the page 602 $this->PageLinks[$this->page][]=array($x*$this->k,$this->hPt-$y*$this->k,$w*$this->k,$h*$this->k,$link); 603} 604 605function Text($x,$y,$txt) 606{ 607 //Output a string 608 $s=sprintf('BT %.2f %.2f Td (%s) Tj ET',$x*$this->k,($this->h-$y)*$this->k,$this->_escape($txt)); 609 if($this->underline && $txt!='') 610 $s.=' '.$this->_dounderline($x,$y,$txt); 611 if($this->ColorFlag) 612 $s='q '.$this->TextColor.' '.$s.' Q'; 613 $this->_out($s); 614} 615 616function AcceptPageBreak() 617{ 618 //Accept automatic page break or not 619 return $this->AutoPageBreak; 620} 621 622function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='') 623{ 624 //Output a cell 625 $k=$this->k; 626 if($this->y+$h>$this->PageBreakTrigger && !$this->InFooter && $this->AcceptPageBreak()) 627 { 628 //Automatic page break 629 $x=$this->x; 630 $ws=$this->ws; 631 if($ws>0) 632 { 633 $this->ws=0; 634 $this->_out('0 Tw'); 635 } 636 $this->AddPage($this->CurOrientation); 637 $this->x=$x; 638 if($ws>0) 639 { 640 $this->ws=$ws; 641 $this->_out(sprintf('%.3f Tw',$ws*$k)); 642 } 643 } 644 if($w==0) 645 $w=$this->w-$this->rMargin-$this->x; 646 $s=''; 647 if($fill==1 || $border==1) 648 { 649 if($fill==1) 650 $op=($border==1) ? 'B' : 'f'; 651 else 652 $op='S'; 653 $s=sprintf('%.2f %.2f %.2f %.2f re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op); 654 } 655 if(is_string($border)) 656 { 657 $x=$this->x; 658 $y=$this->y; 659 if(strpos($border,'L')!==false) 660 $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k); 661 if(strpos($border,'T')!==false) 662 $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k); 663 if(strpos($border,'R')!==false) 664 $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k); 665 if(strpos($border,'B')!==false) 666 $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k); 667 } 668 if($txt!=='') 669 { 670 if($align=='R') 671 $dx=$w-$this->cMargin-$this->GetStringWidth($txt); 672 elseif($align=='C') 673 $dx=($w-$this->GetStringWidth($txt))/2; 674 else 675 $dx=$this->cMargin; 676 if($this->ColorFlag) 677 $s.='q '.$this->TextColor.' '; 678 $txt2=str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt))); 679 $s.=sprintf('BT %.2f %.2f Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt2); 680 if($this->underline) 681 $s.=' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$txt); 682 if($this->ColorFlag) 683 $s.=' Q'; 684 if($link) 685 $this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$this->GetStringWidth($txt),$this->FontSize,$link); 686 } 687 if($s) 688 $this->_out($s); 689 $this->lasth=$h; 690 if($ln>0) 691 { 692 //Go to next line 693 $this->y+=$h; 694 if($ln==1) 695 $this->x=$this->lMargin; 696 } 697 else 698 $this->x+=$w; 699} 700 701function MultiCell($w,$h,$txt,$border=0,$align='J',$fill=0) 702{ 703 //Output text with automatic or explicit line breaks 704 $cw=&$this->CurrentFont['cw']; 705 if($w==0) 706 $w=$this->w-$this->rMargin-$this->x; 707 $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; 708 $s=str_replace("\r",'',$txt); 709 $nb=strlen($s); 710 if($nb>0 && $s[$nb-1]=="\n") 711 $nb--; 712 $b=0; 713 if($border) 714 { 715 if($border==1) 716 { 717 $border='LTRB'; 718 $b='LRT'; 719 $b2='LR'; 720 } 721 else 722 { 723 $b2=''; 724 if(strpos($border,'L')!==false) 725 $b2.='L'; 726 if(strpos($border,'R')!==false) 727 $b2.='R'; 728 $b=(strpos($border,'T')!==false) ? $b2.'T' : $b2; 729 } 730 } 731 $sep=-1; 732 $i=0; 733 $j=0; 734 $l=0; 735 $ns=0; 736 $nl=1; 737 while($i<$nb) 738 { 739 //Get next character 740 $c=$s{$i}; 741 if($c=="\n") 742 { 743 //Explicit line break 744 if($this->ws>0) 745 { 746 $this->ws=0; 747 $this->_out('0 Tw'); 748 } 749 $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill); 750 $i++; 751 $sep=-1; 752 $j=$i; 753 $l=0; 754 $ns=0; 755 $nl++; 756 if($border && $nl==2) 757 $b=$b2; 758 continue; 759 } 760 if($c==' ') 761 { 762 $sep=$i; 763 $ls=$l; 764 $ns++; 765 } 766 $l+=$cw[$c]; 767 if($l>$wmax) 768 { 769 //Automatic line break 770 if($sep==-1) 771 { 772 if($i==$j) 773 $i++; 774 if($this->ws>0) 775 { 776 $this->ws=0; 777 $this->_out('0 Tw'); 778 } 779 $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill); 780 } 781 else 782 { 783 if($align=='J') 784 { 785 $this->ws=($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0; 786 $this->_out(sprintf('%.3f Tw',$this->ws*$this->k)); 787 } 788 $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill); 789 $i=$sep+1; 790 } 791 $sep=-1; 792 $j=$i; 793 $l=0; 794 $ns=0; 795 $nl++; 796 if($border && $nl==2) 797 $b=$b2; 798 } 799 else 800 $i++; 801 } 802 //Last chunk 803 if($this->ws>0) 804 { 805 $this->ws=0; 806 $this->_out('0 Tw'); 807 } 808 if($border && strpos($border,'B')!==false) 809 $b.='B'; 810 $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill); 811 $this->x=$this->lMargin; 812} 813 814function Write($h,$txt,$link='') 815{ 816 //Output text in flowing mode 817 $cw=&$this->CurrentFont['cw']; 818 $w=$this->w-$this->rMargin-$this->x; 819 $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; 820 $s=str_replace("\r",'',$txt); 821 $nb=strlen($s); 822 $sep=-1; 823 $i=0; 824 $j=0; 825 $l=0; 826 $nl=1; 827 while($i<$nb) 828 { 829 //Get next character 830 $c=$s{$i}; 831 if($c=="\n") 832 { 833 //Explicit line break 834 $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link); 835 $i++; 836 $sep=-1; 837 $j=$i; 838 $l=0; 839 if($nl==1) 840 { 841 $this->x=$this->lMargin; 842 $w=$this->w-$this->rMargin-$this->x; 843 $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; 844 } 845 $nl++; 846 continue; 847 } 848 if($c==' ') 849 $sep=$i; 850 $l+=$cw[$c]; 851 if($l>$wmax) 852 { 853 //Automatic line break 854 if($sep==-1) 855 { 856 if($this->x>$this->lMargin) 857 { 858 //Move to next line 859 $this->x=$this->lMargin; 860 $this->y+=$h; 861 $w=$this->w-$this->rMargin-$this->x; 862 $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; 863 $i++; 864 $nl++; 865 continue; 866 } 867 if($i==$j) 868 $i++; 869 $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link); 870 } 871 else 872 { 873 $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link); 874 $i=$sep+1; 875 } 876 $sep=-1; 877 $j=$i; 878 $l=0; 879 if($nl==1) 880 { 881 $this->x=$this->lMargin; 882 $w=$this->w-$this->rMargin-$this->x; 883 $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; 884 } 885 $nl++; 886 } 887 else 888 $i++; 889 } 890 //Last chunk 891 if($i!=$j) 892 $this->Cell($l/1000*$this->FontSize,$h,substr($s,$j),0,0,'',0,$link); 893} 894 895function Image($file,$x,$y,$w=0,$h=0,$type='',$link='') 896{ 897 //Put an image on the page 898 if(!isset($this->images[$file])) 899 { 900 //First use of image, get info 901 if($type=='') 902 { 903 $pos=strrpos($file,'.'); 904 if(!$pos) 905 $this->Error('Image file has no extension and no type was specified: '.$file); 906 $type=substr($file,$pos+1); 907 } 908 $type=strtolower($type); 909 $mqr=get_magic_quotes_runtime(); 910 set_magic_quotes_runtime(0); 911 if($type=='jpg' || $type=='jpeg') 912 $info=$this->_parsejpg($file); 913 elseif($type=='png') 914 $info=$this->_parsepng($file); 915 else 916 { 917 //Allow for additional formats 918 $mtd='_parse'.$type; 919 if(!method_exists($this,$mtd)) 920 $this->Error('Unsupported image type: '.$type); 921 $info=$this->$mtd($file); 922 } 923 set_magic_quotes_runtime($mqr); 924 $info['i']=count($this->images)+1; 925 $this->images[$file]=$info; 926 } 927 else 928 $info=$this->images[$file]; 929 //Automatic width and height calculation if needed 930 if($w==0 && $h==0) 931 { 932 //Put image at 72 dpi 933 $w=$info['w']/$this->k; 934 $h=$info['h']/$this->k; 935 } 936 if($w==0) 937 $w=$h*$info['w']/$info['h']; 938 if($h==0) 939 $h=$w*$info['h']/$info['w']; 940 $this->_out(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'])); 941 if($link) 942 $this->Link($x,$y,$w,$h,$link); 943} 944 945function Ln($h='') 946{ 947 //Line feed; default value is last cell height 948 $this->x=$this->lMargin; 949 if(is_string($h)) 950 $this->y+=$this->lasth; 951 else 952 $this->y+=$h; 953} 954 955function GetX() 956{ 957 //Get x position 958 return $this->x; 959} 960 961function SetX($x) 962{ 963 //Set x position 964 if($x>=0) 965 $this->x=$x; 966 else 967 $this->x=$this->w+$x; 968} 969 970function GetY() 971{ 972 //Get y position 973 return $this->y; 974} 975 976function SetY($y) 977{ 978 //Set y position and reset x 979 $this->x=$this->lMargin; 980 if($y>=0) 981 $this->y=$y; 982 else 983 $this->y=$this->h+$y; 984} 985 986function SetXY($x,$y) 987{ 988 //Set x and y positions 989 $this->SetY($y); 990 $this->SetX($x); 991} 992 993function Output($name='',$dest='') 994{ 995 //Output PDF to some destination 996 //Finish document if necessary 997 if($this->state<3) 998 $this->Close(); 999 //Normalize parameters 1000 if(is_bool($dest)) 1001 $dest=$dest ? 'D' : 'F'; 1002 $dest=strtoupper($dest); 1003 if($dest=='') 1004 { 1005 if($name=='') 1006 { 1007 $name='doc.pdf'; 1008 $dest='I'; 1009 } 1010 else 1011 $dest='F'; 1012 } 1013 switch($dest) 1014 { 1015 case 'I': 1016 //Send to standard output 1017 if(ob_get_contents()) 1018 $this->Error('Some data has already been output, can\'t send PDF file'); 1019 if(php_sapi_name()!='cli') 1020 { 1021 //We send to a browser 1022 header('Content-Type: application/pdf'); 1023 if(headers_sent()) 1024 $this->Error('Some data has already been output to browser, can\'t send PDF file'); 1025 header('Content-Length: '.strlen($this->buffer)); 1026 header('Content-disposition: inline; filename="'.$name.'"'); 1027 } 1028 echo $this->buffer; 1029 break; 1030 case 'D': 1031 //Download file 1032 if(ob_get_contents()) 1033 $this->Error('Some data has already been output, can\'t send PDF file'); 1034 if(isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'],'MSIE')) 1035 header('Content-Type: application/force-download'); 1036 else 1037 header('Content-Type: application/octet-stream'); 1038 if(headers_sent()) 1039 $this->Error('Some data has already been output to browser, can\'t send PDF file'); 1040 header('Content-Length: '.strlen($this->buffer)); 1041 header('Content-disposition: attachment; filename="'.$name.'"'); 1042 echo $this->buffer; 1043 break; 1044 case 'F': 1045 //Save to local file 1046 $f=fopen($name,'wb'); 1047 if(!$f) 1048 $this->Error('Unable to create output file: '.$name); 1049 fwrite($f,$this->buffer,strlen($this->buffer)); 1050 fclose($f); 1051 break; 1052 case 'S': 1053 //Return as a string 1054 return $this->buffer; 1055 default: 1056 $this->Error('Incorrect output destination: '.$dest); 1057 } 1058 return ''; 1059} 1060 1061/******************************************************************************* 1062* * 1063* Protected methods * 1064* * 1065*******************************************************************************/ 1066function _dochecks() 1067{ 1068 //Check for locale-related bug 1069 if(1.1==1) 1070 $this->Error('Don\'t alter the locale before including class file'); 1071 //Check for decimal separator 1072 if(sprintf('%.1f',1.0)!='1.0') 1073 setlocale(LC_NUMERIC,'C'); 1074} 1075 1076function _getfontpath() 1077{ 1078 if(!defined('FPDF_FONTPATH') && is_dir(dirname(__FILE__).'/font')) 1079 define('FPDF_FONTPATH',dirname(__FILE__).'/font/'); 1080 return defined('FPDF_FONTPATH') ? FPDF_FONTPATH : ''; 1081} 1082 1083function _putpages() 1084{ 1085 $nb=$this->page; 1086 if(!empty($this->AliasNbPages)) 1087 { 1088 //Replace number of pages 1089 for($n=1;$n<=$nb;$n++) 1090 $this->pages[$n]=str_replace($this->AliasNbPages,$nb,$this->pages[$n]); 1091 } 1092 if($this->DefOrientation=='P') 1093 { 1094 $wPt=$this->fwPt; 1095 $hPt=$this->fhPt; 1096 } 1097 else 1098 { 1099 $wPt=$this->fhPt; 1100 $hPt=$this->fwPt; 1101 } 1102 $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; 1103 for($n=1;$n<=$nb;$n++) 1104 { 1105 //Page 1106 $this->_newobj(); 1107 $this->_out('<</Type /Page'); 1108 $this->_out('/Parent 1 0 R'); 1109 if(isset($this->OrientationChanges[$n])) 1110 $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$hPt,$wPt)); 1111 $this->_out('/Resources 2 0 R'); 1112 if(isset($this->PageLinks[$n])) 1113 { 1114 //Links 1115 $annots='/Annots ['; 1116 foreach($this->PageLinks[$n] as $pl) 1117 { 1118 $rect=sprintf('%.2f %.2f %.2f %.2f',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]); 1119 $annots.='<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] '; 1120 if(is_string($pl[4])) 1121 $annots.='/A <</S /URI /URI '.$this->_textstring($pl[4]).'>>>>'; 1122 else 1123 { 1124 $l=$this->links[$pl[4]]; 1125 $h=isset($this->OrientationChanges[$l[0]]) ? $wPt : $hPt; 1126 $annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>',1+2*$l[0],$h-$l[1]*$this->k); 1127 } 1128 } 1129 $this->_out($annots.']'); 1130 } 1131 $this->_out('/Contents '.($this->n+1).' 0 R>>'); 1132 $this->_out('endobj'); 1133 //Page content 1134 $p=($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n]; 1135 $this->_newobj(); 1136 $this->_out('<<'.$filter.'/Length '.strlen($p).'>>'); 1137 $this->_putstream($p); 1138 $this->_out('endobj'); 1139 } 1140 //Pages root 1141 $this->offsets[1]=strlen($this->buffer); 1142 $this->_out('1 0 obj'); 1143 $this->_out('<</Type /Pages'); 1144 $kids='/Kids ['; 1145 for($i=0;$i<$nb;$i++) 1146 $kids.=(3+2*$i).' 0 R '; 1147 $this->_out($kids.']'); 1148 $this->_out('/Count '.$nb); 1149 $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$wPt,$hPt)); 1150 $this->_out('>>'); 1151 $this->_out('endobj'); 1152} 1153 1154function _putfonts() 1155{ 1156 $nf=$this->n; 1157 foreach($this->diffs as $diff) 1158 { 1159 //Encodings 1160 $this->_newobj(); 1161 $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>'); 1162 $this->_out('endobj'); 1163 } 1164 $mqr=get_magic_quotes_runtime(); 1165 set_magic_quotes_runtime(0); 1166 foreach($this->FontFiles as $file=>$info) 1167 { 1168 //Font file embedding 1169 $this->_newobj(); 1170 $this->FontFiles[$file]['n']=$this->n; 1171 $font=''; 1172 $f=fopen($this->_getfontpath().$file,'rb',1); 1173 if(!$f) 1174 $this->Error('Font file not found'); 1175 while(!feof($f)) 1176 $font.=fread($f,8192); 1177 fclose($f); 1178 $compressed=(substr($file,-2)=='.z'); 1179 if(!$compressed && isset($info['length2'])) 1180 { 1181 $header=(ord($font{0})==128); 1182 if($header) 1183 { 1184 //Strip first binary header 1185 $font=substr($font,6); 1186 } 1187 if($header && ord($font{$info['length1']})==128) 1188 { 1189 //Strip second binary header 1190 $font=substr($font,0,$info['length1']).substr($font,$info['length1']+6); 1191 } 1192 } 1193 $this->_out('<</Length '.strlen($font)); 1194 if($compressed) 1195 $this->_out('/Filter /FlateDecode'); 1196 $this->_out('/Length1 '.$info['length1']); 1197 if(isset($info['length2'])) 1198 $this->_out('/Length2 '.$info['length2'].' /Length3 0'); 1199 $this->_out('>>'); 1200 $this->_putstream($font); 1201 $this->_out('endobj'); 1202 } 1203 set_magic_quotes_runtime($mqr); 1204 foreach($this->fonts as $k=>$font) 1205 { 1206 //Font objects 1207 $this->fonts[$k]['n']=$this->n+1; 1208 $type=$font['type']; 1209 $name=$font['name']; 1210 if($type=='core') 1211 { 1212 //Standard font 1213 $this->_newobj(); 1214 $this->_out('<</Type /Font'); 1215 $this->_out('/BaseFont /'.$name); 1216 $this->_out('/Subtype /Type1'); 1217 if($name!='Symbol' && $name!='ZapfDingbats') 1218 $this->_out('/Encoding /WinAnsiEncoding'); 1219 $this->_out('>>'); 1220 $this->_out('endobj'); 1221 } 1222 elseif($type=='Type1' || $type=='TrueType') 1223 { 1224 //Additional Type1 or TrueType font 1225 $this->_newobj(); 1226 $this->_out('<</Type /Font'); 1227 $this->_out('/BaseFont /'.$name); 1228 $this->_out('/Subtype /'.$type); 1229 $this->_out('/FirstChar 32 /LastChar 255'); 1230 $this->_out('/Widths '.($this->n+1).' 0 R'); 1231 $this->_out('/FontDescriptor '.($this->n+2).' 0 R'); 1232 if($font['enc']) 1233 { 1234 if(isset($font['diff'])) 1235 $this->_out('/Encoding '.($nf+$font['diff']).' 0 R'); 1236 else 1237 $this->_out('/Encoding /WinAnsiEncoding'); 1238 } 1239 $this->_out('>>'); 1240 $this->_out('endobj'); 1241 //Widths 1242 $this->_newobj(); 1243 $cw=&$font['cw']; 1244 $s='['; 1245 for($i=32;$i<=255;$i++) 1246 $s.=$cw[chr($i)].' '; 1247 $this->_out($s.']'); 1248 $this->_out('endobj'); 1249 //Descriptor 1250 $this->_newobj(); 1251 $s='<</Type /FontDescriptor /FontName /'.$name; 1252 foreach($font['desc'] as $k=>$v) 1253 $s.=' /'.$k.' '.$v; 1254 $file=$font['file']; 1255 if($file) 1256 $s.=' /FontFile'.($type=='Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0 R'; 1257 $this->_out($s.'>>'); 1258 $this->_out('endobj'); 1259 } 1260 else 1261 { 1262 //Allow for additional types 1263 $mtd='_put'.strtolower($type); 1264 if(!method_exists($this,$mtd)) 1265 $this->Error('Unsupported font type: '.$type); 1266 $this->$mtd($font); 1267 } 1268 } 1269} 1270 1271function _putimages() 1272{ 1273 $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; 1274 reset($this->images); 1275 while(list($file,$info)=each($this->images)) 1276 { 1277 $this->_newobj(); 1278 $this->images[$file]['n']=$this->n; 1279 $this->_out('<</Type /XObject'); 1280 $this->_out('/Subtype /Image'); 1281 $this->_out('/Width '.$info['w']); 1282 $this->_out('/Height '.$info['h']); 1283 if($info['cs']=='Indexed') 1284 $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]'); 1285 else 1286 { 1287 $this->_out('/ColorSpace /'.$info['cs']); 1288 if($info['cs']=='DeviceCMYK') 1289 $this->_out('/Decode [1 0 1 0 1 0 1 0]'); 1290 } 1291 $this->_out('/BitsPerComponent '.$info['bpc']); 1292 if(isset($info['f'])) 1293 $this->_out('/Filter /'.$info['f']); 1294 if(isset($info['parms'])) 1295 $this->_out($info['parms']); 1296 if(isset($info['trns']) && is_array($info['trns'])) 1297 { 1298 $trns=''; 1299 for($i=0;$i<count($info['trns']);$i++) 1300 $trns.=$info['trns'][$i].' '.$info['trns'][$i].' '; 1301 $this->_out('/Mask ['.$trns.']'); 1302 } 1303 $this->_out('/Length '.strlen($info['data']).'>>'); 1304 $this->_putstream($info['data']); 1305 unset($this->images[$file]['data']); 1306 $this->_out('endobj'); 1307 //Palette 1308 if($info['cs']=='Indexed') 1309 { 1310 $this->_newobj(); 1311 $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal']; 1312 $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>'); 1313 $this->_putstream($pal); 1314 $this->_out('endobj'); 1315 } 1316 } 1317} 1318 1319function _putxobjectdict() 1320{ 1321 foreach($this->images as $image) 1322 $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R'); 1323} 1324 1325function _putresourcedict() 1326{ 1327 $this->_out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); 1328 $this->_out('/Font <<'); 1329 foreach($this->fonts as $font) 1330 $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R'); 1331 $this->_out('>>'); 1332 $this->_out('/XObject <<'); 1333 $this->_putxobjectdict(); 1334 $this->_out('>>'); 1335} 1336 1337function _putresources() 1338{ 1339 $this->_putfonts(); 1340 $this->_putimages(); 1341 //Resource dictionary 1342 $this->offsets[2]=strlen($this->buffer); 1343 $this->_out('2 0 obj'); 1344 $this->_out('<<'); 1345 $this->_putresourcedict(); 1346 $this->_out('>>'); 1347 $this->_out('endobj'); 1348} 1349 1350function _putinfo() 1351{ 1352 $this->_out('/Producer '.$this->_textstring('FPDF '.FPDF_VERSION)); 1353 if(!empty($this->title)) 1354 $this->_out('/Title '.$this->_textstring($this->title)); 1355 if(!empty($this->subject)) 1356 $this->_out('/Subject '.$this->_textstring($this->subject)); 1357 if(!empty($this->author)) 1358 $this->_out('/Author '.$this->_textstring($this->author)); 1359 if(!empty($this->keywords)) 1360 $this->_out('/Keywords '.$this->_textstring($this->keywords)); 1361 if(!empty($this->creator)) 1362 $this->_out('/Creator '.$this->_textstring($this->creator)); 1363 $this->_out('/CreationDate '.$this->_textstring('D:'.date('YmdHis'))); 1364} 1365 1366function _putcatalog() 1367{ 1368 $this->_out('/Type /Catalog'); 1369 $this->_out('/Pages 1 0 R'); 1370 if($this->ZoomMode=='fullpage') 1371 $this->_out('/OpenAction [3 0 R /Fit]'); 1372 elseif($this->ZoomMode=='fullwidth') 1373 $this->_out('/OpenAction [3 0 R /FitH null]'); 1374 elseif($this->ZoomMode=='real') 1375 $this->_out('/OpenAction [3 0 R /XYZ null null 1]'); 1376 elseif(!is_string($this->ZoomMode)) 1377 $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']'); 1378 if($this->LayoutMode=='single') 1379 $this->_out('/PageLayout /SinglePage'); 1380 elseif($this->LayoutMode=='continuous') 1381 $this->_out('/PageLayout /OneColumn'); 1382 elseif($this->LayoutMode=='two') 1383 $this->_out('/PageLayout /TwoColumnLeft'); 1384} 1385 1386function _putheader() 1387{ 1388 $this->_out('%PDF-'.$this->PDFVersion); 1389} 1390 1391function _puttrailer() 1392{ 1393 $this->_out('/Size '.($this->n+1)); 1394 $this->_out('/Root '.$this->n.' 0 R'); 1395 $this->_out('/Info '.($this->n-1).' 0 R'); 1396} 1397 1398function _enddoc() 1399{ 1400 $this->_putheader(); 1401 $this->_putpages(); 1402 $this->_putresources(); 1403 //Info 1404 $this->_newobj(); 1405 $this->_out('<<'); 1406 $this->_putinfo(); 1407 $this->_out('>>'); 1408 $this->_out('endobj'); 1409 //Catalog 1410 $this->_newobj(); 1411 $this->_out('<<'); 1412 $this->_putcatalog(); 1413 $this->_out('>>'); 1414 $this->_out('endobj'); 1415 //Cross-ref 1416 $o=strlen($this->buffer); 1417 $this->_out('xref'); 1418 $this->_out('0 '.($this->n+1)); 1419 $this->_out('0000000000 65535 f '); 1420 for($i=1;$i<=$this->n;$i++) 1421 $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i])); 1422 //Trailer 1423 $this->_out('trailer'); 1424 $this->_out('<<'); 1425 $this->_puttrailer(); 1426 $this->_out('>>'); 1427 $this->_out('startxref'); 1428 $this->_out($o); 1429 $this->_out('%%EOF'); 1430 $this->state=3; 1431} 1432 1433function _beginpage($orientation) 1434{ 1435 $this->page++; 1436 $this->pages[$this->page]=''; 1437 $this->state=2; 1438 $this->x=$this->lMargin; 1439 $this->y=$this->tMargin; 1440 $this->FontFamily=''; 1441 //Page orientation 1442 if(!$orientation) 1443 $orientation=$this->DefOrientation; 1444 else 1445 { 1446 $orientation=strtoupper($orientation{0}); 1447 if($orientation!=$this->DefOrientation) 1448 $this->OrientationChanges[$this->page]=true; 1449 } 1450 if($orientation!=$this->CurOrientation) 1451 { 1452 //Change orientation 1453 if($orientation=='P') 1454 { 1455 $this->wPt=$this->fwPt; 1456 $this->hPt=$this->fhPt; 1457 $this->w=$this->fw; 1458 $this->h=$this->fh; 1459 } 1460 else 1461 { 1462 $this->wPt=$this->fhPt; 1463 $this->hPt=$this->fwPt; 1464 $this->w=$this->fh; 1465 $this->h=$this->fw; 1466 } 1467 $this->PageBreakTrigger=$this->h-$this->bMargin; 1468 $this->CurOrientation=$orientation; 1469 } 1470} 1471 1472function _endpage() 1473{ 1474 //End of page contents 1475 $this->state=1; 1476} 1477 1478function _newobj() 1479{ 1480 //Begin a new object 1481 $this->n++; 1482 $this->offsets[$this->n]=strlen($this->buffer); 1483 $this->_out($this->n.' 0 obj'); 1484} 1485 1486function _dounderline($x,$y,$txt) 1487{ 1488 //Underline text 1489 $up=$this->CurrentFont['up']; 1490 $ut=$this->CurrentFont['ut']; 1491 $w=$this->GetStringWidth($txt)+$this->ws*substr_count($txt,' '); 1492 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); 1493} 1494 1495function _parsejpg($file) 1496{ 1497 //Extract info from a JPEG file 1498 $a=GetImageSize($file); 1499 if(!$a) 1500 $this->Error('Missing or incorrect image file: '.$file); 1501 if($a[2]!=2) 1502 $this->Error('Not a JPEG file: '.$file); 1503 if(!isset($a['channels']) || $a['channels']==3) 1504 $colspace='DeviceRGB'; 1505 elseif($a['channels']==4) 1506 $colspace='DeviceCMYK'; 1507 else 1508 $colspace='DeviceGray'; 1509 $bpc=isset($a['bits']) ? $a['bits'] : 8; 1510 //Read whole file 1511 $f=fopen($file,'rb'); 1512 $data=''; 1513 while(!feof($f)) 1514 $data.=fread($f,4096); 1515 fclose($f); 1516 return array('w'=>$a[0],'h'=>$a[1],'cs'=>$colspace,'bpc'=>$bpc,'f'=>'DCTDecode','data'=>$data); 1517} 1518 1519function _parsepng($file) 1520{ 1521 //Extract info from a PNG file 1522 $f=fopen($file,'rb'); 1523 if(!$f) 1524 $this->Error('Can\'t open image file: '.$file); 1525 //Check signature 1526 if(fread($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) 1527 $this->Error('Not a PNG file: '.$file); 1528 //Read header chunk 1529 fread($f,4); 1530 if(fread($f,4)!='IHDR') 1531 $this->Error('Incorrect PNG file: '.$file); 1532 $w=$this->_freadint($f); 1533 $h=$this->_freadint($f); 1534 $bpc=ord(fread($f,1)); 1535 if($bpc>8) 1536 $this->Error('16-bit depth not supported: '.$file); 1537 $ct=ord(fread($f,1)); 1538 if($ct==0) 1539 $colspace='DeviceGray'; 1540 elseif($ct==2) 1541 $colspace='DeviceRGB'; 1542 elseif($ct==3) 1543 $colspace='Indexed'; 1544 else 1545 $this->Error('Alpha channel not supported: '.$file); 1546 if(ord(fread($f,1))!=0) 1547 $this->Error('Unknown compression method: '.$file); 1548 if(ord(fread($f,1))!=0) 1549 $this->Error('Unknown filter method: '.$file); 1550 if(ord(fread($f,1))!=0) 1551 $this->Error('Interlacing not supported: '.$file); 1552 fread($f,4); 1553 $parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>'; 1554 //Scan chunks looking for palette, transparency and image data 1555 $pal=''; 1556 $trns=''; 1557 $data=''; 1558 do 1559 { 1560 $n=$this->_freadint($f); 1561 $type=fread($f,4); 1562 if($type=='PLTE') 1563 { 1564 //Read palette 1565 $pal=fread($f,$n); 1566 fread($f,4); 1567 } 1568 elseif($type=='tRNS') 1569 { 1570 //Read transparency info 1571 $t=fread($f,$n); 1572 if($ct==0) 1573 $trns=array(ord(substr($t,1,1))); 1574 elseif($ct==2) 1575 $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1))); 1576 else 1577 { 1578 $pos=strpos($t,chr(0)); 1579 if($pos!==false) 1580 $trns=array($pos); 1581 } 1582 fread($f,4); 1583 } 1584 elseif($type=='IDAT') 1585 { 1586 //Read image data block 1587 $data.=fread($f,$n); 1588 fread($f,4); 1589 } 1590 elseif($type=='IEND') 1591 break; 1592 else 1593 fread($f,$n+4); 1594 } 1595 while($n); 1596 if($colspace=='Indexed' && empty($pal)) 1597 $this->Error('Missing palette in '.$file); 1598 fclose($f); 1599 return array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$data); 1600} 1601 1602function _freadint($f) 1603{ 1604 //Read a 4-byte integer from file 1605 $a=unpack('Ni',fread($f,4)); 1606 return $a['i']; 1607} 1608 1609function _textstring($s) 1610{ 1611 //Format a text string 1612 return '('.$this->_escape($s).')'; 1613} 1614 1615function _escape($s) 1616{ 1617 //Add \ before \, ( and ) 1618 return str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$s))); 1619} 1620 1621function _putstream($s) 1622{ 1623 $this->_out('stream'); 1624 $this->_out($s); 1625 $this->_out('endstream'); 1626} 1627 1628function _out($s) 1629{ 1630 //Add a line to the document 1631 if($this->state==2) 1632 $this->pages[$this->page].=$s."\n"; 1633 else 1634 $this->buffer.=$s."\n"; 1635} 1636//End of class 1637} 1638 1639//Handle special IE contype request 1640if(isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT']=='contype') 1641{ 1642 header('Content-Type: application/pdf'); 1643 exit; 1644} 1645 1646} 1647?> 1648