source: trunk/phpgwapi/inc/fpdf/fpdf.php @ 7673

Revision 7673, 39.1 KB checked in by douglasz, 11 years ago (diff)

Ticket #3236 - Correcoes para Performance: Function Within Loop Declaration.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1<?php
2/*******************************************************************************
3* Software: FPDF                                                               *
4* Version:  1.52                                                               *
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
12if(!class_exists('FPDF'))
13{
14define('FPDF_VERSION','1.52');
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
71
72/*******************************************************************************
73*                                                                              *
74*                               Public methods                                 *
75*                                                                              *
76*******************************************************************************/
77function FPDF($orientation='P',$unit='mm',$format='A4')
78{
79        //Some checks
80        $this->_dochecks();
81        //Initialization of properties
82        $this->page=0;
83        $this->n=2;
84        $this->buffer='';
85        $this->pages=array();
86        $this->OrientationChanges=array();
87        $this->state=0;
88        $this->fonts=array();
89        $this->FontFiles=array();
90        $this->diffs=array();
91        $this->images=array();
92        $this->links=array();
93        $this->InFooter=false;
94        $this->lasth=0;
95        $this->FontFamily='';
96        $this->FontStyle='';
97        $this->FontSizePt=12;
98        $this->underline=false;
99        $this->DrawColor='0 G';
100        $this->FillColor='0 g';
101        $this->TextColor='0 g';
102        $this->ColorFlag=false;
103        $this->ws=0;
104        //Standard fonts
105        $this->CoreFonts=array('courier'=>'Courier','courierB'=>'Courier-Bold','courierI'=>'Courier-Oblique','courierBI'=>'Courier-BoldOblique',
106                'helvetica'=>'Helvetica','helveticaB'=>'Helvetica-Bold','helveticaI'=>'Helvetica-Oblique','helveticaBI'=>'Helvetica-BoldOblique',
107                'times'=>'Times-Roman','timesB'=>'Times-Bold','timesI'=>'Times-Italic','timesBI'=>'Times-BoldItalic',
108                'symbol'=>'Symbol','zapfdingbats'=>'ZapfDingbats');
109        //Scale factor
110        if($unit=='pt')
111                $this->k=1;
112        elseif($unit=='mm')
113                $this->k=72/25.4;
114        elseif($unit=='cm')
115                $this->k=72/2.54;
116        elseif($unit=='in')
117                $this->k=72;
118        else
119                $this->Error('Incorrect unit: '.$unit);
120        //Page format
121        if(is_string($format))
122        {
123                $format=strtolower($format);
124                if($format=='a3')
125                        $format=array(841.89,1190.55);
126                elseif($format=='a4')
127                        $format=array(595.28,841.89);
128                elseif($format=='a5')
129                        $format=array(420.94,595.28);
130                elseif($format=='letter')
131                        $format=array(612,792);
132                elseif($format=='legal')
133                        $format=array(612,1008);
134                else
135                        $this->Error('Unknown page format: '.$format);
136                $this->fwPt=$format[0];
137                $this->fhPt=$format[1];
138        }
139        else
140        {
141                $this->fwPt=$format[0]*$this->k;
142                $this->fhPt=$format[1]*$this->k;
143        }
144        $this->fw=$this->fwPt/$this->k;
145        $this->fh=$this->fhPt/$this->k;
146        //Page orientation
147        $orientation=strtolower($orientation);
148        if($orientation=='p' or $orientation=='portrait')
149        {
150                $this->DefOrientation='P';
151                $this->wPt=$this->fwPt;
152                $this->hPt=$this->fhPt;
153        }
154        elseif($orientation=='l' or $orientation=='landscape')
155        {
156                $this->DefOrientation='L';
157                $this->wPt=$this->fhPt;
158                $this->hPt=$this->fwPt;
159        }
160        else
161                $this->Error('Incorrect orientation: '.$orientation);
162        $this->CurOrientation=$this->DefOrientation;
163        $this->w=$this->wPt/$this->k;
164        $this->h=$this->hPt/$this->k;
165        //Page margins (1 cm)
166        $margin=28.35/$this->k;
167        $this->SetMargins($margin,$margin);
168        //Interior cell margin (1 mm)
169        $this->cMargin=$margin/10;
170        //Line width (0.2 mm)
171        $this->LineWidth=.567/$this->k;
172        //Automatic page break
173        $this->SetAutoPageBreak(true,2*$margin);
174        //Full width display mode
175        $this->SetDisplayMode('fullwidth');
176        //Compression
177        $this->SetCompression(true);
178}
179
180function SetMargins($left,$top,$right=-1)
181{
182        //Set left, top and right margins
183        $this->lMargin=$left;
184        $this->tMargin=$top;
185        if($right==-1)
186                $right=$left;
187        $this->rMargin=$right;
188}
189
190function SetLeftMargin($margin)
191{
192        //Set left margin
193        $this->lMargin=$margin;
194        if($this->page>0 and $this->x<$margin)
195                $this->x=$margin;
196}
197
198function SetTopMargin($margin)
199{
200        //Set top margin
201        $this->tMargin=$margin;
202}
203
204function SetRightMargin($margin)
205{
206        //Set right margin
207        $this->rMargin=$margin;
208}
209
210function SetAutoPageBreak($auto,$margin=0)
211{
212        //Set auto page break mode and triggering margin
213        $this->AutoPageBreak=$auto;
214        $this->bMargin=$margin;
215        $this->PageBreakTrigger=$this->h-$margin;
216}
217
218function SetDisplayMode($zoom,$layout='continuous')
219{
220        //Set display mode in viewer
221        if($zoom=='fullpage' or $zoom=='fullwidth' or $zoom=='real' or $zoom=='default' or !is_string($zoom))
222                $this->ZoomMode=$zoom;
223        else
224                $this->Error('Incorrect zoom display mode: '.$zoom);
225        if($layout=='single' or $layout=='continuous' or $layout=='two' or $layout=='default')
226                $this->LayoutMode=$layout;
227        else
228                $this->Error('Incorrect layout display mode: '.$layout);
229}
230
231function SetCompression($compress)
232{
233        //Set page compression
234        if(function_exists('gzcompress'))
235                $this->compress=$compress;
236        else
237                $this->compress=false;
238}
239
240function SetTitle($title)
241{
242        //Title of document
243        $this->title=$title;
244}
245
246function SetSubject($subject)
247{
248        //Subject of document
249        $this->subject=$subject;
250}
251
252function SetAuthor($author)
253{
254        //Author of document
255        $this->author=$author;
256}
257
258function SetKeywords($keywords)
259{
260        //Keywords of document
261        $this->keywords=$keywords;
262}
263
264function SetCreator($creator)
265{
266        //Creator of document
267        $this->creator=$creator;
268}
269
270function AliasNbPages($alias='{nb}')
271{
272        //Define an alias for total number of pages
273        $this->AliasNbPages=$alias;
274}
275
276function Error($msg)
277{
278        //Fatal error
279        die('<B>FPDF error: </B>'.$msg);
280}
281
282function Open()
283{
284        //Begin document
285        if($this->state==0)
286                $this->_begindoc();
287}
288
289function Close()
290{
291        //Terminate document
292        if($this->state==3)
293                return;
294        if($this->page==0)
295                $this->AddPage();
296        //Page footer
297        $this->InFooter=true;
298        $this->Footer();
299        $this->InFooter=false;
300        //Close page
301        $this->_endpage();
302        //Close document
303        $this->_enddoc();
304}
305
306function AddPage($orientation='')
307{
308        //Start a new page
309        if($this->state==0)
310                $this->Open();
311        $family=$this->FontFamily;
312        $style=$this->FontStyle.($this->underline ? 'U' : '');
313        $size=$this->FontSizePt;
314        $lw=$this->LineWidth;
315        $dc=$this->DrawColor;
316        $fc=$this->FillColor;
317        $tc=$this->TextColor;
318        $cf=$this->ColorFlag;
319        if($this->page>0)
320        {
321                //Page footer
322                $this->InFooter=true;
323                $this->Footer();
324                $this->InFooter=false;
325                //Close page
326                $this->_endpage();
327        }
328        //Start new page
329        $this->_beginpage($orientation);
330        //Set line cap style to square
331        $this->_out('2 J');
332        //Set line width
333        $this->LineWidth=$lw;
334        $this->_out(sprintf('%.2f w',$lw*$this->k));
335        //Set font
336        if($family)
337                $this->SetFont($family,$style,$size);
338        //Set colors
339        $this->DrawColor=$dc;
340        if($dc!='0 G')
341                $this->_out($dc);
342        $this->FillColor=$fc;
343        if($fc!='0 g')
344                $this->_out($fc);
345        $this->TextColor=$tc;
346        $this->ColorFlag=$cf;
347        //Page header
348        $this->Header();
349        //Restore line width
350        if($this->LineWidth!=$lw)
351        {
352                $this->LineWidth=$lw;
353                $this->_out(sprintf('%.2f w',$lw*$this->k));
354        }
355        //Restore font
356        if($family)
357                $this->SetFont($family,$style,$size);
358        //Restore colors
359        if($this->DrawColor!=$dc)
360        {
361                $this->DrawColor=$dc;
362                $this->_out($dc);
363        }
364        if($this->FillColor!=$fc)
365        {
366                $this->FillColor=$fc;
367                $this->_out($fc);
368        }
369        $this->TextColor=$tc;
370        $this->ColorFlag=$cf;
371}
372
373function Header()
374{
375        //To be implemented in your own inherited class
376}
377
378function Footer()
379{
380        //To be implemented in your own inherited class
381}
382
383function PageNo()
384{
385        //Get current page number
386        return $this->page;
387}
388
389function SetDrawColor($r,$g=-1,$b=-1)
390{
391        //Set color for all stroking operations
392        if(($r==0 and $g==0 and $b==0) or $g==-1)
393                $this->DrawColor=sprintf('%.3f G',$r/255);
394        else
395                $this->DrawColor=sprintf('%.3f %.3f %.3f RG',$r/255,$g/255,$b/255);
396        if($this->page>0)
397                $this->_out($this->DrawColor);
398}
399
400function SetFillColor($r,$g=-1,$b=-1)
401{
402        //Set color for all filling operations
403        if(($r==0 and $g==0 and $b==0) or $g==-1)
404                $this->FillColor=sprintf('%.3f g',$r/255);
405        else
406                $this->FillColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255);
407        $this->ColorFlag=($this->FillColor!=$this->TextColor);
408        if($this->page>0)
409                $this->_out($this->FillColor);
410}
411
412function SetTextColor($r,$g=-1,$b=-1)
413{
414        //Set color for text
415        if(($r==0 and $g==0 and $b==0) or $g==-1)
416                $this->TextColor=sprintf('%.3f g',$r/255);
417        else
418                $this->TextColor=sprintf('%.3f %.3f %.3f rg',$r/255,$g/255,$b/255);
419        $this->ColorFlag=($this->FillColor!=$this->TextColor);
420}
421
422function GetStringWidth($s)
423{
424        //Get width of a string in the current font
425        $s=(string)$s;
426        $cw=&$this->CurrentFont['cw'];
427        $w=0;
428        $l=strlen($s);
429        for($i=0;$i<$l;++$i)
430                $w+=$cw[$s{$i}];
431        return $w*$this->FontSize/1000;
432}
433
434function SetLineWidth($width)
435{
436        //Set line width
437        $this->LineWidth=$width;
438        if($this->page>0)
439                $this->_out(sprintf('%.2f w',$width*$this->k));
440}
441
442function Line($x1,$y1,$x2,$y2)
443{
444        //Draw a line
445        $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));
446}
447
448function Rect($x,$y,$w,$h,$style='')
449{
450        //Draw a rectangle
451        if($style=='F')
452                $op='f';
453        elseif($style=='FD' or $style=='DF')
454                $op='B';
455        else
456                $op='S';
457        $this->_out(sprintf('%.2f %.2f %.2f %.2f re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op));
458}
459
460function AddFont($family,$style='',$file='')
461{
462        //Add a TrueType or Type1 font
463        $family=strtolower($family);
464        if($family=='arial')
465                $family='helvetica';
466        $style=strtoupper($style);
467        if($style=='IB')
468                $style='BI';
469        if(isset($this->fonts[$family.$style]))
470                $this->Error('Font already added: '.$family.' '.$style);
471        if($file=='')
472                $file=str_replace(' ','',$family).strtolower($style).'.php';
473        if(defined('FPDF_FONTPATH'))
474                $file=FPDF_FONTPATH.$file;
475        include($file);
476        if(!isset($name))
477                $this->Error('Could not include font definition file');
478        $i=count($this->fonts)+1;
479        $this->fonts[$family.$style]=array('i'=>$i,'type'=>$type,'name'=>$name,'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw,'enc'=>$enc,'file'=>$file);
480        if($diff)
481        {
482                //Search existing encodings
483                $d=0;
484                $nb=count($this->diffs);
485                for($i=1;$i<=$nb;++$i)
486                        if($this->diffs[$i]==$diff)
487                        {
488                                $d=$i;
489                                break;
490                        }
491                if($d==0)
492                {
493                        $d=$nb+1;
494                        $this->diffs[$d]=$diff;
495                }
496                $this->fonts[$family.$style]['diff']=$d;
497        }
498        if($file)
499        {
500                if($type=='TrueType')
501                        $this->FontFiles[$file]=array('length1'=>$originalsize);
502                else
503                        $this->FontFiles[$file]=array('length1'=>$size1,'length2'=>$size2);
504        }
505}
506
507function SetFont($family,$style='',$size=0)
508{
509        //Select a font; size given in points
510        global $fpdf_charwidths;
511
512        $family=strtolower($family);
513        if($family=='')
514                $family=$this->FontFamily;
515        if($family=='arial')
516                $family='helvetica';
517        elseif($family=='symbol' or $family=='zapfdingbats')
518                $style='';
519        $style=strtoupper($style);
520        if(is_int(strpos($style,'U')))
521        {
522                $this->underline=true;
523                $style=str_replace('U','',$style);
524        }
525        else
526                $this->underline=false;
527        if($style=='IB')
528                $style='BI';
529        if($size==0)
530                $size=$this->FontSizePt;
531        //Test if font is already selected
532        if($this->FontFamily==$family and $this->FontStyle==$style and $this->FontSizePt==$size)
533                return;
534        //Test if used for the first time
535        $fontkey=$family.$style;
536        if(!isset($this->fonts[$fontkey]))
537        {
538                //Check if one of the standard fonts
539                if(isset($this->CoreFonts[$fontkey]))
540                {
541                        if(!isset($fpdf_charwidths[$fontkey]))
542                        {
543                                //Load metric file
544                                $file=$family;
545                                if($family=='times' or $family=='helvetica')
546                                        $file.=strtolower($style);
547                                $file.='.php';
548                                if(defined('FPDF_FONTPATH'))
549                                        $file=FPDF_FONTPATH.$file;
550                                include($file);
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 and $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 and !$this->InFooter and $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 or $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(is_int(strpos($border,'L')))
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(is_int(strpos($border,'T')))
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(is_int(strpos($border,'R')))
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(is_int(strpos($border,'B')))
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 and $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(is_int(strpos($border,'L')))
725                                $b2.='L';
726                        if(is_int(strpos($border,'R')))
727                                $b2.='R';
728                        $b=is_int(strpos($border,'T')) ? $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 and $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 and $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 and is_int(strpos($border,'B')))
809                $b.='B';
810               
811        // changed by Lars Kneschke to not add a line break after multicell
812        #$this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
813        #$this->x=$this->lMargin;
814        $this->Cell($w,$h,substr($s,$j,$i-$j),$b,0,$align,$fill);
815        #$this->x=$this->lMargin;
816}
817
818function Write($h,$txt,$link='')
819{
820        //Output text in flowing mode
821        $cw=&$this->CurrentFont['cw'];
822        $w=$this->w-$this->rMargin-$this->x;
823        $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
824        $s=str_replace("\r",'',$txt);
825        $nb=strlen($s);
826        $sep=-1;
827        $i=0;
828        $j=0;
829        $l=0;
830        $nl=1;
831        while($i<$nb)
832        {
833                //Get next character
834                $c=$s{$i};
835                if($c=="\n")
836                {
837                        //Explicit line break
838                        $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
839                        ++$i;
840                        $sep=-1;
841                        $j=$i;
842                        $l=0;
843                        if($nl==1)
844                        {
845                                $this->x=$this->lMargin;
846                                $w=$this->w-$this->rMargin-$this->x;
847                                $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
848                        }
849                        ++$nl;
850                        continue;
851                }
852                if($c==' ')
853                        $sep=$i;
854                $l+=$cw[$c];
855                if($l>$wmax)
856                {
857                        //Automatic line break
858                        if($sep==-1)
859                        {
860                                if($this->x>$this->lMargin)
861                                {
862                                        //Move to next line
863                                        $this->x=$this->lMargin;
864                                        $this->y+=$h;
865                                        $w=$this->w-$this->rMargin-$this->x;
866                                        $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
867                                        ++$i;
868                                        ++$nl;
869                                        continue;
870                                }
871                                if($i==$j)
872                                        ++$i;
873                                $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
874                        }
875                        else
876                        {
877                                $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link);
878                                $i=$sep+1;
879                        }
880                        $sep=-1;
881                        $j=$i;
882                        $l=0;
883                        if($nl==1)
884                        {
885                                $this->x=$this->lMargin;
886                                $w=$this->w-$this->rMargin-$this->x;
887                                $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
888                        }
889                        ++$nl;
890                }
891                else
892                        ++$i;
893        }
894        //Last chunk
895        if($i!=$j)
896                $this->Cell($l/1000*$this->FontSize,$h,substr($s,$j),0,0,'',0,$link);
897}
898
899function Image($file,$x,$y,$w=0,$h=0,$type='',$link='')
900{
901        //Put an image on the page
902        if(!isset($this->images[$file]))
903        {
904                //First use of image, get info
905                if($type=='')
906                {
907                        $pos=strrpos($file,'.');
908                        if(!$pos)
909                                $this->Error('Image file has no extension and no type was specified: '.$file);
910                        $type=substr($file,$pos+1);
911                }
912                $type=strtolower($type);
913                $mqr=get_magic_quotes_runtime();
914                set_magic_quotes_runtime(0);
915                if($type=='jpg' or $type=='jpeg')
916                        $info=$this->_parsejpg($file);
917                elseif($type=='png')
918                        $info=$this->_parsepng($file);
919                else
920                {
921                        //Allow for additional formats
922                        $mtd='_parse'.$type;
923                        if(!method_exists($this,$mtd))
924                                $this->Error('Unsupported image type: '.$type);
925                        $info=$this->$mtd($file);
926                }
927                set_magic_quotes_runtime($mqr);
928                $info['i']=count($this->images)+1;
929                $this->images[$file]=$info;
930        }
931        else
932                $info=$this->images[$file];
933        //Automatic width and height calculation if needed
934        if($w==0 and $h==0)
935        {
936                //Put image at 72 dpi
937                $w=$info['w']/$this->k;
938                $h=$info['h']/$this->k;
939        }
940        if($w==0)
941                $w=$h*$info['w']/$info['h'];
942        if($h==0)
943                $h=$w*$info['h']/$info['w'];
944        $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']));
945        if($link)
946                $this->Link($x,$y,$w,$h,$link);
947}
948
949function Ln($h='')
950{
951        //Line feed; default value is last cell height
952        $this->x=$this->lMargin;
953        if(is_string($h))
954                $this->y+=$this->lasth;
955        else
956                $this->y+=$h;
957}
958
959function GetX()
960{
961        //Get x position
962        return $this->x;
963}
964
965function SetX($x)
966{
967        //Set x position
968        if($x>=0)
969                $this->x=$x;
970        else
971                $this->x=$this->w+$x;
972}
973
974function GetY()
975{
976        //Get y position
977        return $this->y;
978}
979
980function SetY($y)
981{
982        //Set y position and reset x
983        $this->x=$this->lMargin;
984        if($y>=0)
985                $this->y=$y;
986        else
987                $this->y=$this->h+$y;
988}
989
990function SetXY($x,$y)
991{
992        //Set x and y positions
993        $this->SetY($y);
994        $this->SetX($x);
995}
996
997function Output($name='',$dest='')
998{
999        //Output PDF to some destination
1000        global $HTTP_SERVER_VARS;
1001
1002        //Finish document if necessary
1003        if($this->state<3)
1004                $this->Close();
1005        //Normalize parameters
1006        if(is_bool($dest))
1007                $dest=$dest ? 'D' : 'F';
1008        $dest=strtoupper($dest);
1009        if($dest=='')
1010        {
1011                if($name=='')
1012                {
1013                        $name='doc.pdf';
1014                        $dest='I';
1015                }
1016                else
1017                        $dest='F';
1018        }
1019        switch($dest)
1020        {
1021                case 'I':
1022                        //Send to standard output
1023                        if(isset($HTTP_SERVER_VARS['SERVER_NAME']))
1024                        {
1025                                //We send to a browser
1026                                Header('Content-Type: application/pdf');
1027                                if(headers_sent())
1028                                        $this->Error('Some data has already been output to browser, can\'t send PDF file');
1029                                Header('Content-Length: '.strlen($this->buffer));
1030                                Header('Content-disposition: inline; filename='.$name);
1031                        }
1032                        echo $this->buffer;
1033                        break;
1034                case 'D':
1035                        //Download file
1036                        if(isset($HTTP_SERVER_VARS['HTTP_USER_AGENT']) and strpos($HTTP_SERVER_VARS['HTTP_USER_AGENT'],'MSIE'))
1037                                Header('Content-Type: application/force-download');
1038                        else
1039                                Header('Content-Type: application/octet-stream');
1040                        if(headers_sent())
1041                                $this->Error('Some data has already been output to browser, can\'t send PDF file');
1042                        Header('Content-Length: '.strlen($this->buffer));
1043                        Header('Content-disposition: attachment; filename='.$name);
1044                        echo $this->buffer;
1045                        break;
1046                case 'F':
1047                        //Save to local file
1048                        $f=fopen($name,'wb');
1049                        if(!$f)
1050                                $this->Error('Unable to create output file: '.$name);
1051                        fwrite($f,$this->buffer,strlen($this->buffer));
1052                        fclose($f);
1053                        break;
1054                case 'S':
1055                        //Return as a string
1056                        return $this->buffer;
1057                default:
1058                        $this->Error('Incorrect output destination: '.$dest);
1059        }
1060        return '';
1061}
1062
1063/*******************************************************************************
1064*                                                                              *
1065*                              Protected methods                               *
1066*                                                                              *
1067*******************************************************************************/
1068function _dochecks()
1069{
1070        //Check for locale-related bug
1071        if(1.1==1)
1072                $this->Error('Don\'t alter the locale before including class file');
1073        //Check for decimal separator
1074        if(sprintf('%.1f',1.0)!='1.0')
1075                setlocale(LC_NUMERIC,'C');
1076}
1077
1078function _begindoc()
1079{
1080        //Start document
1081        $this->state=1;
1082        $this->_out('%PDF-1.3');
1083}
1084
1085function _putpages()
1086{
1087        $nb=$this->page;
1088        if(!empty($this->AliasNbPages))
1089        {
1090                //Replace number of pages
1091                for($n=1;$n<=$nb;++$n)
1092                        $this->pages[$n]=str_replace($this->AliasNbPages,$nb,$this->pages[$n]);
1093        }
1094        if($this->DefOrientation=='P')
1095        {
1096                $wPt=$this->fwPt;
1097                $hPt=$this->fhPt;
1098        }
1099        else
1100        {
1101                $wPt=$this->fhPt;
1102                $hPt=$this->fwPt;
1103        }
1104        $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
1105        for($n=1;$n<=$nb;++$n)
1106        {
1107                //Page
1108                $this->_newobj();
1109                $this->_out('<</Type /Page');
1110                $this->_out('/Parent 1 0 R');
1111                if(isset($this->OrientationChanges[$n]))
1112                        $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$hPt,$wPt));
1113                $this->_out('/Resources 2 0 R');
1114                if(isset($this->PageLinks[$n]))
1115                {
1116                        //Links
1117                        $annots='/Annots [';
1118                        foreach($this->PageLinks[$n] as $pl)
1119                        {
1120                                $rect=sprintf('%.2f %.2f %.2f %.2f',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]);
1121                                $annots.='<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] ';
1122                                if(is_string($pl[4]))
1123                                        $annots.='/A <</S /URI /URI '.$this->_textstring($pl[4]).'>>>>';
1124                                else
1125                                {
1126                                        $l=$this->links[$pl[4]];
1127                                        $h=isset($this->OrientationChanges[$l[0]]) ? $wPt : $hPt;
1128                                        $annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>',1+2*$l[0],$h-$l[1]*$this->k);
1129                                }
1130                        }
1131                        $this->_out($annots.']');
1132                }
1133                $this->_out('/Contents '.($this->n+1).' 0 R>>');
1134                $this->_out('endobj');
1135                //Page content
1136                $p=($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n];
1137                $this->_newobj();
1138                $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
1139                $this->_putstream($p);
1140                $this->_out('endobj');
1141        }
1142        //Pages root
1143        $this->offsets[1]=strlen($this->buffer);
1144        $this->_out('1 0 obj');
1145        $this->_out('<</Type /Pages');
1146        $kids='/Kids [';
1147        for($i=0;$i<$nb;++$i)
1148                $kids.=(3+2*$i).' 0 R ';
1149        $this->_out($kids.']');
1150        $this->_out('/Count '.$nb);
1151        $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$wPt,$hPt));
1152        $this->_out('>>');
1153        $this->_out('endobj');
1154}
1155
1156function _putfonts()
1157{
1158        $nf=$this->n;
1159        foreach($this->diffs as $diff)
1160        {
1161                //Encodings
1162                $this->_newobj();
1163                $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
1164                $this->_out('endobj');
1165        }
1166        $mqr=get_magic_quotes_runtime();
1167        set_magic_quotes_runtime(0);
1168        foreach($this->FontFiles as $file=>$info)
1169        {
1170                //Font file embedding
1171                $this->_newobj();
1172                $this->FontFiles[$file]['n']=$this->n;
1173                if(defined('FPDF_FONTPATH'))
1174                        $file=FPDF_FONTPATH.$file;
1175                $size=filesize($file);
1176                if(!$size)
1177                        $this->Error('Font file not found');
1178                $this->_out('<</Length '.$size);
1179                if(substr($file,-2)=='.z')
1180                        $this->_out('/Filter /FlateDecode');
1181                $this->_out('/Length1 '.$info['length1']);
1182                if(isset($info['length2']))
1183                        $this->_out('/Length2 '.$info['length2'].' /Length3 0');
1184                $this->_out('>>');
1185                $f=fopen($file,'rb');
1186                $this->_putstream(fread($f,$size));
1187                fclose($f);
1188                $this->_out('endobj');
1189        }
1190        set_magic_quotes_runtime($mqr);
1191        foreach($this->fonts as $k=>$font)
1192        {
1193                //Font objects
1194                $this->fonts[$k]['n']=$this->n+1;
1195                $type=$font['type'];
1196                $name=$font['name'];
1197                if($type=='core')
1198                {
1199                        //Standard font
1200                        $this->_newobj();
1201                        $this->_out('<</Type /Font');
1202                        $this->_out('/BaseFont /'.$name);
1203                        $this->_out('/Subtype /Type1');
1204                        if($name!='Symbol' and $name!='ZapfDingbats')
1205                                $this->_out('/Encoding /WinAnsiEncoding');
1206                        $this->_out('>>');
1207                        $this->_out('endobj');
1208                }
1209                elseif($type=='Type1' or $type=='TrueType')
1210                {
1211                        //Additional Type1 or TrueType font
1212                        $this->_newobj();
1213                        $this->_out('<</Type /Font');
1214                        $this->_out('/BaseFont /'.$name);
1215                        $this->_out('/Subtype /'.$type);
1216                        $this->_out('/FirstChar 32 /LastChar 255');
1217                        $this->_out('/Widths '.($this->n+1).' 0 R');
1218                        $this->_out('/FontDescriptor '.($this->n+2).' 0 R');
1219                        if($font['enc'])
1220                        {
1221                                if(isset($font['diff']))
1222                                        $this->_out('/Encoding '.($nf+$font['diff']).' 0 R');
1223                                else
1224                                        $this->_out('/Encoding /WinAnsiEncoding');
1225                        }
1226                        $this->_out('>>');
1227                        $this->_out('endobj');
1228                        //Widths
1229                        $this->_newobj();
1230                        $cw=&$font['cw'];
1231                        $s='[';
1232                        for($i=32;$i<=255;++$i)
1233                                $s.=$cw[chr($i)].' ';
1234                        $this->_out($s.']');
1235                        $this->_out('endobj');
1236                        //Descriptor
1237                        $this->_newobj();
1238                        $s='<</Type /FontDescriptor /FontName /'.$name;
1239                        foreach($font['desc'] as $k=>$v)
1240                                $s.=' /'.$k.' '.$v;
1241                        $file=$font['file'];
1242                        if($file)
1243                                $s.=' /FontFile'.($type=='Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0 R';
1244                        $this->_out($s.'>>');
1245                        $this->_out('endobj');
1246                }
1247                else
1248                {
1249                        //Allow for additional types
1250                        $mtd='_put'.strtolower($type);
1251                        if(!method_exists($this,$mtd))
1252                                $this->Error('Unsupported font type: '.$type);
1253                        $this->$mtd($font);
1254                }
1255        }
1256}
1257
1258function _putimages()
1259{
1260        $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
1261        reset($this->images);
1262        while(list($file,$info)=each($this->images))
1263        {
1264                $this->_newobj();
1265                $this->images[$file]['n']=$this->n;
1266                $this->_out('<</Type /XObject');
1267                $this->_out('/Subtype /Image');
1268                $this->_out('/Width '.$info['w']);
1269                $this->_out('/Height '.$info['h']);
1270                if($info['cs']=='Indexed')
1271                        $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
1272                else
1273                {
1274                        $this->_out('/ColorSpace /'.$info['cs']);
1275                        if($info['cs']=='DeviceCMYK')
1276                                $this->_out('/Decode [1 0 1 0 1 0 1 0]');
1277                }
1278                $this->_out('/BitsPerComponent '.$info['bpc']);
1279                $this->_out('/Filter /'.$info['f']);
1280                if(isset($info['parms']))
1281                        $this->_out($info['parms']);
1282                if(isset($info['trns']) and is_array($info['trns']))
1283                {
1284                        $trns='';
1285            $info_trns_count = count($info['trns']);
1286                        for($i=0;$i<$info_trns_count;++$i)
1287                                $trns.=$info['trns'][$i].' '.$info['trns'][$i].' ';
1288                        $this->_out('/Mask ['.$trns.']');
1289                }
1290                $this->_out('/Length '.strlen($info['data']).'>>');
1291                $this->_putstream($info['data']);
1292                unset($this->images[$file]['data']);
1293                $this->_out('endobj');
1294                //Palette
1295                if($info['cs']=='Indexed')
1296                {
1297                        $this->_newobj();
1298                        $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal'];
1299                        $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
1300                        $this->_putstream($pal);
1301                        $this->_out('endobj');
1302                }
1303        }
1304}
1305
1306function _putresources()
1307{
1308        $this->_putfonts();
1309        $this->_putimages();
1310        //Resource dictionary
1311        $this->offsets[2]=strlen($this->buffer);
1312        $this->_out('2 0 obj');
1313        $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
1314        $this->_out('/Font <<');
1315        foreach($this->fonts as $font)
1316                $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
1317        $this->_out('>>');
1318        if(count($this->images))
1319        {
1320                $this->_out('/XObject <<');
1321                foreach($this->images as $image)
1322                        $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
1323                $this->_out('>>');
1324        }
1325        $this->_out('>>');
1326        $this->_out('endobj');
1327}
1328
1329function _putinfo()
1330{
1331        $this->_out('/Producer '.$this->_textstring('FPDF '.FPDF_VERSION));
1332        if(!empty($this->title))
1333                $this->_out('/Title '.$this->_textstring($this->title));
1334        if(!empty($this->subject))
1335                $this->_out('/Subject '.$this->_textstring($this->subject));
1336        if(!empty($this->author))
1337                $this->_out('/Author '.$this->_textstring($this->author));
1338        if(!empty($this->keywords))
1339                $this->_out('/Keywords '.$this->_textstring($this->keywords));
1340        if(!empty($this->creator))
1341                $this->_out('/Creator '.$this->_textstring($this->creator));
1342        $this->_out('/CreationDate '.$this->_textstring('D:'.date('YmdHis')));
1343}
1344
1345function _putcatalog()
1346{
1347        $this->_out('/Type /Catalog');
1348        $this->_out('/Pages 1 0 R');
1349        if($this->ZoomMode=='fullpage')
1350                $this->_out('/OpenAction [3 0 R /Fit]');
1351        elseif($this->ZoomMode=='fullwidth')
1352                $this->_out('/OpenAction [3 0 R /FitH null]');
1353        elseif($this->ZoomMode=='real')
1354                $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
1355        elseif(!is_string($this->ZoomMode))
1356                $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']');
1357        if($this->LayoutMode=='single')
1358                $this->_out('/PageLayout /SinglePage');
1359        elseif($this->LayoutMode=='continuous')
1360                $this->_out('/PageLayout /OneColumn');
1361        elseif($this->LayoutMode=='two')
1362                $this->_out('/PageLayout /TwoColumnLeft');
1363}
1364
1365function _puttrailer()
1366{
1367        $this->_out('/Size '.($this->n+1));
1368        $this->_out('/Root '.$this->n.' 0 R');
1369        $this->_out('/Info '.($this->n-1).' 0 R');
1370}
1371
1372function _enddoc()
1373{
1374        $this->_putpages();
1375        $this->_putresources();
1376        //Info
1377        $this->_newobj();
1378        $this->_out('<<');
1379        $this->_putinfo();
1380        $this->_out('>>');
1381        $this->_out('endobj');
1382        //Catalog
1383        $this->_newobj();
1384        $this->_out('<<');
1385        $this->_putcatalog();
1386        $this->_out('>>');
1387        $this->_out('endobj');
1388        //Cross-ref
1389        $o=strlen($this->buffer);
1390        $this->_out('xref');
1391        $this->_out('0 '.($this->n+1));
1392        $this->_out('0000000000 65535 f ');
1393        for($i=1;$i<=$this->n;++$i)
1394                $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
1395        //Trailer
1396        $this->_out('trailer');
1397        $this->_out('<<');
1398        $this->_puttrailer();
1399        $this->_out('>>');
1400        $this->_out('startxref');
1401        $this->_out($o);
1402        $this->_out('%%EOF');
1403        $this->state=3;
1404}
1405
1406function _beginpage($orientation)
1407{
1408        $this->page++;
1409        $this->pages[$this->page]='';
1410        $this->state=2;
1411        $this->x=$this->lMargin;
1412        $this->y=$this->tMargin;
1413        $this->FontFamily='';
1414        //Page orientation
1415        if(!$orientation)
1416                $orientation=$this->DefOrientation;
1417        else
1418        {
1419                $orientation=strtoupper($orientation{0});
1420                if($orientation!=$this->DefOrientation)
1421                        $this->OrientationChanges[$this->page]=true;
1422        }
1423        if($orientation!=$this->CurOrientation)
1424        {
1425                //Change orientation
1426                if($orientation=='P')
1427                {
1428                        $this->wPt=$this->fwPt;
1429                        $this->hPt=$this->fhPt;
1430                        $this->w=$this->fw;
1431                        $this->h=$this->fh;
1432                }
1433                else
1434                {
1435                        $this->wPt=$this->fhPt;
1436                        $this->hPt=$this->fwPt;
1437                        $this->w=$this->fh;
1438                        $this->h=$this->fw;
1439                }
1440                $this->PageBreakTrigger=$this->h-$this->bMargin;
1441                $this->CurOrientation=$orientation;
1442        }
1443}
1444
1445function _endpage()
1446{
1447        //End of page contents
1448        $this->state=1;
1449}
1450
1451function _newobj()
1452{
1453        //Begin a new object
1454        $this->n++;
1455        $this->offsets[$this->n]=strlen($this->buffer);
1456        $this->_out($this->n.' 0 obj');
1457}
1458
1459function _dounderline($x,$y,$txt)
1460{
1461        //Underline text
1462        $up=$this->CurrentFont['up'];
1463        $ut=$this->CurrentFont['ut'];
1464        $w=$this->GetStringWidth($txt)+$this->ws*substr_count($txt,' ');
1465        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);
1466}
1467
1468function _parsejpg($file)
1469{
1470        //Extract info from a JPEG file
1471        $a=GetImageSize($file);
1472        if(!$a)
1473                $this->Error('Missing or incorrect image file: '.$file);
1474        if($a[2]!=2)
1475                $this->Error('Not a JPEG file: '.$file);
1476        if(!isset($a['channels']) or $a['channels']==3)
1477                $colspace='DeviceRGB';
1478        elseif($a['channels']==4)
1479                $colspace='DeviceCMYK';
1480        else
1481                $colspace='DeviceGray';
1482        $bpc=isset($a['bits']) ? $a['bits'] : 8;
1483        //Read whole file
1484        $f=fopen($file,'rb');
1485        $data='';
1486        while(!feof($f))
1487                $data.=fread($f,4096);
1488        fclose($f);
1489        return array('w'=>$a[0],'h'=>$a[1],'cs'=>$colspace,'bpc'=>$bpc,'f'=>'DCTDecode','data'=>$data);
1490}
1491
1492function _parsepng($file)
1493{
1494        //Extract info from a PNG file
1495        $f=fopen($file,'rb');
1496        if(!$f)
1497                $this->Error('Can\'t open image file: '.$file);
1498        //Check signature
1499        if(fread($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10))
1500                $this->Error('Not a PNG file: '.$file);
1501        //Read header chunk
1502        fread($f,4);
1503        if(fread($f,4)!='IHDR')
1504                $this->Error('Incorrect PNG file: '.$file);
1505        $w=$this->_freadint($f);
1506        $h=$this->_freadint($f);
1507        $bpc=ord(fread($f,1));
1508        if($bpc>8)
1509                $this->Error('16-bit depth not supported: '.$file);
1510        $ct=ord(fread($f,1));
1511        if($ct==0)
1512                $colspace='DeviceGray';
1513        elseif($ct==2)
1514                $colspace='DeviceRGB';
1515        elseif($ct==3)
1516                $colspace='Indexed';
1517        else
1518                $this->Error('Alpha channel not supported: '.$file);
1519        if(ord(fread($f,1))!=0)
1520                $this->Error('Unknown compression method: '.$file);
1521        if(ord(fread($f,1))!=0)
1522                $this->Error('Unknown filter method: '.$file);
1523        if(ord(fread($f,1))!=0)
1524                $this->Error('Interlacing not supported: '.$file);
1525        fread($f,4);
1526        $parms='/DecodeParms <</Predictor 15 /Colors '.($ct==2 ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w.'>>';
1527        //Scan chunks looking for palette, transparency and image data
1528        $pal='';
1529        $trns='';
1530        $data='';
1531        do
1532        {
1533                $n=$this->_freadint($f);
1534                $type=fread($f,4);
1535                if($type=='PLTE')
1536                {
1537                        //Read palette
1538                        $pal=fread($f,$n);
1539                        fread($f,4);
1540                }
1541                elseif($type=='tRNS')
1542                {
1543                        //Read transparency info
1544                        $t=fread($f,$n);
1545                        if($ct==0)
1546                                $trns=array(ord(substr($t,1,1)));
1547                        elseif($ct==2)
1548                                $trns=array(ord(substr($t,1,1)),ord(substr($t,3,1)),ord(substr($t,5,1)));
1549                        else
1550                        {
1551                                $pos=strpos($t,chr(0));
1552                                if(is_int($pos))
1553                                        $trns=array($pos);
1554                        }
1555                        fread($f,4);
1556                }
1557                elseif($type=='IDAT')
1558                {
1559                        //Read image data block
1560                        $data.=fread($f,$n);
1561                        fread($f,4);
1562                }
1563                elseif($type=='IEND')
1564                        break;
1565                else
1566                        fread($f,$n+4);
1567        }
1568        while($n);
1569        if($colspace=='Indexed' and empty($pal))
1570                $this->Error('Missing palette in '.$file);
1571        fclose($f);
1572        return array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$data);
1573}
1574
1575function _freadint($f)
1576{
1577        //Read a 4-byte integer from file
1578        $i=ord(fread($f,1))<<24;
1579        $i+=ord(fread($f,1))<<16;
1580        $i+=ord(fread($f,1))<<8;
1581        $i+=ord(fread($f,1));
1582        return $i;
1583}
1584
1585function _textstring($s)
1586{
1587        //Format a text string
1588        return '('.$this->_escape($s).')';
1589}
1590
1591function _escape($s)
1592{
1593        //Add \ before \, ( and )
1594        return str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$s)));
1595}
1596
1597function _putstream($s)
1598{
1599        $this->_out('stream');
1600        $this->_out($s);
1601        $this->_out('endstream');
1602}
1603
1604function _out($s)
1605{
1606        //Add a line to the document
1607        if($this->state==2)
1608                $this->pages[$this->page].=$s."\n";
1609        else
1610                $this->buffer.=$s."\n";
1611}
1612//End of class
1613}
1614
1615//Handle special IE contype request
1616if(isset($HTTP_SERVER_VARS['HTTP_USER_AGENT']) and $HTTP_SERVER_VARS['HTTP_USER_AGENT']=='contype')
1617{
1618        Header('Content-Type: application/pdf');
1619        exit;
1620}
1621
1622}
1623?>
Note: See TracBrowser for help on using the repository browser.