PluginProbe
Welcart e-Commerce / 2.12.4
Welcart e-Commerce v2.12.4
2.12.4 2.12.3 2.11.35 2.12.2 2.12.1 2.11.34 2.11.33 2.11.32 2.11.31 2.11.30 1.3.16 1.3.17 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 All 292 releases
← All changes | classes/fpdf/fpdf.php +1647 -1647 1.3.22.12.4 View file →
@@ -1,1647 +1,1647 @@
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 -
12 -if(!class_exists('FPDF'))
13 -{
14 -define('FPDF_VERSION','1.53');
15 -
16 -class FPDF
17 -{
18 -//Private properties
19 -var $page; //current page number
20 -var $n; //current object number
21 -var $offsets; //array of object offsets
22 -var $buffer; //buffer holding in-memory PDF
23 -var $pages; //array containing pages
24 -var $state; //current document state
25 -var $compress; //compression flag
26 -var $DefOrientation; //default orientation
27 -var $CurOrientation; //current orientation
28 -var $OrientationChanges; //array indicating orientation changes
29 -var $k; //scale factor (number of points in user unit)
30 -var $fwPt,$fhPt; //dimensions of page format in points
31 -var $fw,$fh; //dimensions of page format in user unit
32 -var $wPt,$hPt; //current dimensions of page in points
33 -var $w,$h; //current dimensions of page in user unit
34 -var $lMargin; //left margin
35 -var $tMargin; //top margin
36 -var $rMargin; //right margin
37 -var $bMargin; //page break margin
38 -var $cMargin; //cell margin
39 -var $x,$y; //current position in user unit for cell positioning
40 -var $lasth; //height of last cell printed
41 -var $LineWidth; //line width in user unit
42 -var $CoreFonts; //array of standard font names
43 -var $fonts; //array of used fonts
44 -var $FontFiles; //array of font files
45 -var $diffs; //array of encoding differences
46 -var $images; //array of used images
47 -var $PageLinks; //array of links in pages
48 -var $links; //array of internal links
49 -var $FontFamily; //current font family
50 -var $FontStyle; //current font style
51 -var $underline; //underlining flag
52 -var $CurrentFont; //current font info
53 -var $FontSizePt; //current font size in points
54 -var $FontSize; //current font size in user unit
55 -var $DrawColor; //commands for drawing color
56 -var $FillColor; //commands for filling color
57 -var $TextColor; //commands for text color
58 -var $ColorFlag; //indicates whether fill and text colors are different
59 -var $ws; //word spacing
60 -var $AutoPageBreak; //automatic page breaking
61 -var $PageBreakTrigger; //threshold used to trigger page breaks
62 -var $InFooter; //flag set when processing footer
63 -var $ZoomMode; //zoom display mode
64 -var $LayoutMode; //layout display mode
65 -var $title; //title
66 -var $subject; //subject
67 -var $author; //author
68 -var $keywords; //keywords
69 -var $creator; //creator
70 -var $AliasNbPages; //alias for total number of pages
71 -var $PDFVersion; //PDF version number
72 -
73 -/*******************************************************************************
74 -* *
75 -* Public methods *
76 -* *
77 -*******************************************************************************/
78 -function FPDF($orientation='P',$unit='mm',$format='A4')
79 -{
80 - //Some checks
81 - $this->_dochecks();
82 - //Initialization of properties
83 - $this->page=0;
84 - $this->n=2;
85 - $this->buffer='';
86 - $this->pages=array();
87 - $this->OrientationChanges=array();
88 - $this->state=0;
89 - $this->fonts=array();
90 - $this->FontFiles=array();
91 - $this->diffs=array();
92 - $this->images=array();
93 - $this->links=array();
94 - $this->InFooter=false;
95 - $this->lasth=0;
96 - $this->FontFamily='';
97 - $this->FontStyle='';
98 - $this->FontSizePt=12;
99 - $this->underline=false;
100 - $this->DrawColor='0 G';
101 - $this->FillColor='0 g';
102 - $this->TextColor='0 g';
103 - $this->ColorFlag=false;
104 - $this->ws=0;
105 - //Standard fonts
106 - $this->CoreFonts=array('courier'=>'Courier','courierB'=>'Courier-Bold','courierI'=>'Courier-Oblique','courierBI'=>'Courier-BoldOblique',
107 - 'helvetica'=>'Helvetica','helveticaB'=>'Helvetica-Bold','helveticaI'=>'Helvetica-Oblique','helveticaBI'=>'Helvetica-BoldOblique',
108 - 'times'=>'Times-Roman','timesB'=>'Times-Bold','timesI'=>'Times-Italic','timesBI'=>'Times-BoldItalic',
109 - 'symbol'=>'Symbol','zapfdingbats'=>'ZapfDingbats');
110 - //Scale factor
111 - if($unit=='pt')
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 -
183 -function 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 -
193 -function 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 -
201 -function SetTopMargin($margin)
202 -{
203 - //Set top margin
204 - $this->tMargin=$margin;
205 -}
206 -
207 -function SetRightMargin($margin)
208 -{
209 - //Set right margin
210 - $this->rMargin=$margin;
211 -}
212 -
213 -function 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 -
221 -function 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 -
234 -function SetCompression($compress)
235 -{
236 - //Set page compression
237 - if(function_exists('gzcompress'))
238 - $this->compress=$compress;
239 - else
240 - $this->compress=false;
241 -}
242 -
243 -function SetTitle($title)
244 -{
245 - //Title of document
246 - $this->title=$title;
247 -}
248 -
249 -function SetSubject($subject)
250 -{
251 - //Subject of document
252 - $this->subject=$subject;
253 -}
254 -
255 -function SetAuthor($author)
256 -{
257 - //Author of document
258 - $this->author=$author;
259 -}
260 -
261 -function SetKeywords($keywords)
262 -{
263 - //Keywords of document
264 - $this->keywords=$keywords;
265 -}
266 -
267 -function SetCreator($creator)
268 -{
269 - //Creator of document
270 - $this->creator=$creator;
271 -}
272 -
273 -function AliasNbPages($alias='{nb}')
274 -{
275 - //Define an alias for total number of pages
276 - $this->AliasNbPages=$alias;
277 -}
278 -
279 -function Error($msg)
280 -{
281 - //Fatal error
282 - die('<B>FPDF error: </B>'.$msg);
283 -}
284 -
285 -function Open()
286 -{
287 - //Begin document
288 - $this->state=1;
289 -}
290 -
291 -function 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 -
308 -function 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 -
375 -function Header()
376 -{
377 - //To be implemented in your own inherited class
378 -}
379 -
380 -function Footer()
381 -{
382 - //To be implemented in your own inherited class
383 -}
384 -
385 -function PageNo()
386 -{
387 - //Get current page number
388 - return $this->page;
389 -}
390 -
391 -function 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 -
402 -function 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 -
414 -function 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 -
424 -function 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 -
436 -function 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 -
444 -function 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 -
450 -function 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 -
462 -function 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 -
510 -function 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 -
570 -function 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 -
581 -function 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 -
589 -function 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 -
599 -function 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 -
605 -function 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 -
616 -function AcceptPageBreak()
617 -{
618 - //Accept automatic page break or not
619 - return $this->AutoPageBreak;
620 -}
621 -
622 -function 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 -
701 -function 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 -
814 -function 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 -
895 -function 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 -
945 -function 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 -
955 -function GetX()
956 -{
957 - //Get x position
958 - return $this->x;
959 -}
960 -
961 -function 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 -
970 -function GetY()
971 -{
972 - //Get y position
973 - return $this->y;
974 -}
975 -
976 -function 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 -
986 -function SetXY($x,$y)
987 -{
988 - //Set x and y positions
989 - $this->SetY($y);
990 - $this->SetX($x);
991 -}
992 -
993 -function 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 -*******************************************************************************/
1066 -function _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 -
1076 -function _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 -
1083 -function _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 -
1154 -function _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 -
1271 -function _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 -
1319 -function _putxobjectdict()
1320 -{
1321 - foreach($this->images as $image)
1322 - $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
1323 -}
1324 -
1325 -function _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 -
1337 -function _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 -
1350 -function _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 -
1366 -function _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 -
1386 -function _putheader()
1387 -{
1388 - $this->_out('%PDF-'.$this->PDFVersion);
1389 -}
1390 -
1391 -function _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 -
1398 -function _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 -
1433 -function _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 -
1472 -function _endpage()
1473 -{
1474 - //End of page contents
1475 - $this->state=1;
1476 -}
1477 -
1478 -function _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 -
1486 -function _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 -
1495 -function _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 -
1519 -function _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 -
1602 -function _freadint($f)
1603 -{
1604 - //Read a 4-byte integer from file
1605 - $a=unpack('Ni',fread($f,4));
1606 - return $a['i'];
1607 -}
1608 -
1609 -function _textstring($s)
1610 -{
1611 - //Format a text string
1612 - return '('.$this->_escape($s).')';
1613 -}
1614 -
1615 -function _escape($s)
1616 -{
1617 - //Add \ before \, ( and )
1618 - return str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$s)));
1619 -}
1620 -
1621 -function _putstream($s)
1622 -{
1623 - $this->_out('stream');
1624 - $this->_out($s);
1625 - $this->_out('endstream');
1626 -}
1627 -
1628 -function _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
1640 -if(isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT']=='contype')
1641 -{
1642 - header('Content-Type: application/pdf');
1643 - exit;
1644 -}
1645 -
1646 -}
1647 -?>
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 +
12 +if(!class_exists('FPDF'))
13 +{
14 +define('FPDF_VERSION','1.53');
15 +
16 +class FPDF
17 +{
18 +//Private properties
19 +var $page; //current page number
20 +var $n; //current object number
21 +var $offsets; //array of object offsets
22 +var $buffer; //buffer holding in-memory PDF
23 +var $pages; //array containing pages
24 +var $state; //current document state
25 +var $compress; //compression flag
26 +var $DefOrientation; //default orientation
27 +var $CurOrientation; //current orientation
28 +var $OrientationChanges; //array indicating orientation changes
29 +var $k; //scale factor (number of points in user unit)
30 +var $fwPt,$fhPt; //dimensions of page format in points
31 +var $fw,$fh; //dimensions of page format in user unit
32 +var $wPt,$hPt; //current dimensions of page in points
33 +var $w,$h; //current dimensions of page in user unit
34 +var $lMargin; //left margin
35 +var $tMargin; //top margin
36 +var $rMargin; //right margin
37 +var $bMargin; //page break margin
38 +var $cMargin; //cell margin
39 +var $x,$y; //current position in user unit for cell positioning
40 +var $lasth; //height of last cell printed
41 +var $LineWidth; //line width in user unit
42 +var $CoreFonts; //array of standard font names
43 +var $fonts; //array of used fonts
44 +var $FontFiles; //array of font files
45 +var $diffs; //array of encoding differences
46 +var $images; //array of used images
47 +var $PageLinks; //array of links in pages
48 +var $links; //array of internal links
49 +var $FontFamily; //current font family
50 +var $FontStyle; //current font style
51 +var $underline; //underlining flag
52 +var $CurrentFont; //current font info
53 +var $FontSizePt; //current font size in points
54 +var $FontSize; //current font size in user unit
55 +var $DrawColor; //commands for drawing color
56 +var $FillColor; //commands for filling color
57 +var $TextColor; //commands for text color
58 +var $ColorFlag; //indicates whether fill and text colors are different
59 +var $ws; //word spacing
60 +var $AutoPageBreak; //automatic page breaking
61 +var $PageBreakTrigger; //threshold used to trigger page breaks
62 +var $InFooter; //flag set when processing footer
63 +var $ZoomMode; //zoom display mode
64 +var $LayoutMode; //layout display mode
65 +var $title; //title
66 +var $subject; //subject
67 +var $author; //author
68 +var $keywords; //keywords
69 +var $creator; //creator
70 +var $AliasNbPages; //alias for total number of pages
71 +var $PDFVersion; //PDF version number
72 +
73 +/*******************************************************************************
74 +* *
75 +* Public methods *
76 +* *
77 +*******************************************************************************/
78 +function FPDF($orientation='P',$unit='mm',$format='A4')
79 +{
80 + //Some checks
81 + $this->_dochecks();
82 + //Initialization of properties
83 + $this->page=0;
84 + $this->n=2;
85 + $this->buffer='';
86 + $this->pages=array();
87 + $this->OrientationChanges=array();
88 + $this->state=0;
89 + $this->fonts=array();
90 + $this->FontFiles=array();
91 + $this->diffs=array();
92 + $this->images=array();
93 + $this->links=array();
94 + $this->InFooter=false;
95 + $this->lasth=0;
96 + $this->FontFamily='';
97 + $this->FontStyle='';
98 + $this->FontSizePt=12;
99 + $this->underline=false;
100 + $this->DrawColor='0 G';
101 + $this->FillColor='0 g';
102 + $this->TextColor='0 g';
103 + $this->ColorFlag=false;
104 + $this->ws=0;
105 + //Standard fonts
106 + $this->CoreFonts=array('courier'=>'Courier','courierB'=>'Courier-Bold','courierI'=>'Courier-Oblique','courierBI'=>'Courier-BoldOblique',
107 + 'helvetica'=>'Helvetica','helveticaB'=>'Helvetica-Bold','helveticaI'=>'Helvetica-Oblique','helveticaBI'=>'Helvetica-BoldOblique',
108 + 'times'=>'Times-Roman','timesB'=>'Times-Bold','timesI'=>'Times-Italic','timesBI'=>'Times-BoldItalic',
109 + 'symbol'=>'Symbol','zapfdingbats'=>'ZapfDingbats');
110 + //Scale factor
111 + if($unit=='pt')
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 +
183 +function 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 +
193 +function 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 +
201 +function SetTopMargin($margin)
202 +{
203 + //Set top margin
204 + $this->tMargin=$margin;
205 +}
206 +
207 +function SetRightMargin($margin)
208 +{
209 + //Set right margin
210 + $this->rMargin=$margin;
211 +}
212 +
213 +function 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 +
221 +function 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 +
234 +function SetCompression($compress)
235 +{
236 + //Set page compression
237 + if(function_exists('gzcompress'))
238 + $this->compress=$compress;
239 + else
240 + $this->compress=false;
241 +}
242 +
243 +function SetTitle($title)
244 +{
245 + //Title of document
246 + $this->title=$title;
247 +}
248 +
249 +function SetSubject($subject)
250 +{
251 + //Subject of document
252 + $this->subject=$subject;
253 +}
254 +
255 +function SetAuthor($author)
256 +{
257 + //Author of document
258 + $this->author=$author;
259 +}
260 +
261 +function SetKeywords($keywords)
262 +{
263 + //Keywords of document
264 + $this->keywords=$keywords;
265 +}
266 +
267 +function SetCreator($creator)
268 +{
269 + //Creator of document
270 + $this->creator=$creator;
271 +}
272 +
273 +function AliasNbPages($alias='{nb}')
274 +{
275 + //Define an alias for total number of pages
276 + $this->AliasNbPages=$alias;
277 +}
278 +
279 +function Error($msg)
280 +{
281 + //Fatal error
282 + die('<B>FPDF error: </B>'.$msg);
283 +}
284 +
285 +function Open()
286 +{
287 + //Begin document
288 + $this->state=1;
289 +}
290 +
291 +function 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 +
308 +function 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 +
375 +function Header()
376 +{
377 + //To be implemented in your own inherited class
378 +}
379 +
380 +function Footer()
381 +{
382 + //To be implemented in your own inherited class
383 +}
384 +
385 +function PageNo()
386 +{
387 + //Get current page number
388 + return $this->page;
389 +}
390 +
391 +function 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 +
402 +function 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 +
414 +function 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 +
424 +function 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 +
436 +function 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 +
444 +function 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 +
450 +function 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 +
462 +function 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 +
510 +function 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 +
570 +function 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 +
581 +function 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 +
589 +function 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 +
599 +function 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 +
605 +function 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 +
616 +function AcceptPageBreak()
617 +{
618 + //Accept automatic page break or not
619 + return $this->AutoPageBreak;
620 +}
621 +
622 +function 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 +
701 +function 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 +
814 +function 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 +
895 +function 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 +
945 +function 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 +
955 +function GetX()
956 +{
957 + //Get x position
958 + return $this->x;
959 +}
960 +
961 +function 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 +
970 +function GetY()
971 +{
972 + //Get y position
973 + return $this->y;
974 +}
975 +
976 +function 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 +
986 +function SetXY($x,$y)
987 +{
988 + //Set x and y positions
989 + $this->SetY($y);
990 + $this->SetX($x);
991 +}
992 +
993 +function 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 +*******************************************************************************/
1066 +function _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 +
1076 +function _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 +
1083 +function _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 +
1154 +function _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 +
1271 +function _putimages()
1272 +{
1273 + $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
1274 + reset($this->images);
1275 + foreach ($this->images as $file => $info)
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 +
1319 +function _putxobjectdict()
1320 +{
1321 + foreach($this->images as $image)
1322 + $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
1323 +}
1324 +
1325 +function _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 +
1337 +function _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 +
1350 +function _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 +
1366 +function _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 +
1386 +function _putheader()
1387 +{
1388 + $this->_out('%PDF-'.$this->PDFVersion);
1389 +}
1390 +
1391 +function _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 +
1398 +function _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 +
1433 +function _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 +
1472 +function _endpage()
1473 +{
1474 + //End of page contents
1475 + $this->state=1;
1476 +}
1477 +
1478 +function _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 +
1486 +function _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 +
1495 +function _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 +
1519 +function _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 +
1602 +function _freadint($f)
1603 +{
1604 + //Read a 4-byte integer from file
1605 + $a=unpack('Ni',fread($f,4));
1606 + return $a['i'];
1607 +}
1608 +
1609 +function _textstring($s)
1610 +{
1611 + //Format a text string
1612 + return '('.$this->_escape($s).')';
1613 +}
1614 +
1615 +function _escape($s)
1616 +{
1617 + //Add \ before \, ( and )
1618 + return str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$s)));
1619 +}
1620 +
1621 +function _putstream($s)
1622 +{
1623 + $this->_out('stream');
1624 + $this->_out($s);
1625 + $this->_out('endstream');
1626 +}
1627 +
1628 +function _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
1640 +if(isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT']=='contype')
1641 +{
1642 + header('Content-Type: application/pdf');
1643 + exit;
1644 +}
1645 +
1646 +}
1647 +?>